diff --git a/include/alloca.h b/include/alloca.h new file mode 100644 index 000000000..4e8720f7e --- /dev/null +++ b/include/alloca.h @@ -0,0 +1,7 @@ +#ifndef ALLOCA_H +#define ALLOCA_H + +void* alloca(u32); +#define alloca __builtin_alloca + +#endif diff --git a/include/bgm.h b/include/bgm.h new file mode 100644 index 000000000..4cd19c957 --- /dev/null +++ b/include/bgm.h @@ -0,0 +1,6 @@ +#ifndef BGM_H +#define BGM_H + +#define NA_BGM_STOP 0x100000FF + +#endif diff --git a/include/functions.h b/include/functions.h index e82550b41..31d685c8b 100644 --- a/include/functions.h +++ b/include/functions.h @@ -139,22 +139,22 @@ void StackCheck_Cleanup(StackEntry* entry); StackStatus StackCheck_GetState(StackEntry* entry); u32 StackCheck_CheckAll(void); u32 StackCheck_Check(StackEntry* entry); -// void GfxPrint_InitDlist(void); -// void GfxPrint_SetColor(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void GfxPrint_SetPosPx(void); -// void GfxPrint_SetPos(void); +void GfxPrint_InitDlist(GfxPrint*); +void GfxPrint_SetColor(GfxPrint*, u32, u32, u32, u32); +void GfxPrint_SetPosPx(GfxPrint*, s32, s32); +void GfxPrint_SetPos(GfxPrint*, s32, s32); void GfxPrint_SetBasePosPx(GfxPrint* this, s32 param_2, s32 param_3); void GfxPrint_PrintCharImpl(GfxPrint* this, u8 c); void GfxPrint_PrintChar(GfxPrint* this, u8 c); -// void GfxPrint_PrintStringWithSize(void); -// void GfxPrint_PrintString(void); -// void GfxPrint_Callback(void); -// void GfxPrint_Init(void); -// void GfxPrint_Destroy(void); -// void GfxPrint_Open(void); -// void GfxPrint_Close(void); -// void GfxPrint_VPrintf(void); -// void GfxPrint_Printf(void); +void GfxPrint_PrintStringWithSize(GfxPrint*, const void*, size_t, size_t); +void GfxPrint_PrintString(GfxPrint*, const char*); +GfxPrint* GfxPrint_Callback(GfxPrint*, const char*, size_t); +void GfxPrint_Init(GfxPrint*); +void GfxPrint_Destroy(GfxPrint*); +void GfxPrint_Open(GfxPrint*, Gfx*); +Gfx* GfxPrint_Close(GfxPrint*); +void GfxPrint_VPrintf(GfxPrint*, const char*, va_list); +void GfxPrint_Printf(GfxPrint*, const char*, ...); // void MtxConv_F2L(void); // void MtxConv_L2F(void); void __assert(const char* file, u32 lineNum); @@ -807,8 +807,8 @@ s32 func_800B863C(Actor* actor, GlobalContext* globalCtx); u32 func_800B867C(Actor* actor, GlobalContext* globalCtx); UNK_TYPE4 func_800B86C8(Actor* actor1, GlobalContext* globalCtx, Actor* actor2); s32 func_800B8708(GlobalContext* globalCtx); -// void func_800B8718(void); -// void func_800B874C(void); +s32 func_800B8718(Actor* actor, GlobalContext* globalCtx); +void func_800B874C(Actor* actor, GlobalContext* globalCtx, f32 arg2, f32 arg3); // void func_800B8804(void); // void func_800B882C(void); // void func_800B886C(void); @@ -887,13 +887,13 @@ Actor* func_800BC444(GlobalContext* globalCtx, Actor* actor, f32 arg2); // void func_800BC4EC(void); // void func_800BC5B8(void); s32 func_800BC5EC(GlobalContext* globalCtx, Actor* actor); -void func_800BC620(Vec3f* arg0, Vec3f* arg1, UNK_TYPE arg2, GlobalContext* globalCtx); +void func_800BC620(Vec3f* arg0, Vec3f* arg1, u8 arg2, GlobalContext* globalCtx); // void func_800BC770(void); // void func_800BC7D8(void); // void func_800BC848(void); // void func_800BC8B8(void); // void func_800BCB50(void); -void func_800BCB70(Actor* actor, s16 arg1, s16 arg2, s16 arg3, s16 arg4); +void func_800BCB70(Actor* actor, u16 arg1, u16 arg2, s16 arg3, s16 arg4); void func_800BCBF4(Vec3f* uParm1, GlobalContext* globalCtx); void func_800BCC68(Vec3f* param_1, GlobalContext* globalCtx); UNK_RET func_800BCCDC(Vec3s* points, u8 pathcount, Vec3f* pos1, Vec3f* pos2, UNK_TYPE parm5); @@ -1762,13 +1762,13 @@ void func_800F9824(GlobalContext* globalCtx, EnvironmentContext* envCtx, View* v // void func_800FA39C(void); // void func_800FA3C4(void); // void func_800FA9FC(void); -// void func_800FAAB4(void); +void func_800FAAB4(GlobalContext* globalCtx, u8 arg1); // void func_800FAC20(void); // void func_800FAF74(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE1 param_5); // void func_800FB010(void); void func_800FB320(GlobalContext* globalCtx, u8 param_2); // void func_800FB388(void); -// void func_800FB758(void); +void func_800FB758(GlobalContext* globalCtx); // void func_800FB9B4(void); // void func_800FBCBC(void); // void func_800FBDEC(void); @@ -1814,7 +1814,7 @@ void func_800FE658(f32 arg0); // void func_800FEA50(void); void func_800FEAB0(void); // void func_800FEAC0(void); -// void func_800FEAF4(void); +void func_800FEAF4(EnvironmentContext* envCtx); void* Lib_MemCpy(void* dest, void* src, size_t size); void* Lib_MemSet(void* buffer, s32 value, size_t size); f32 Math_CosS(s16 angle); @@ -2127,7 +2127,7 @@ void func_8010E9F0(s16 arg0, s16 arg1); // void func_8010EB50(void); // void func_8010EBA0(void); // void func_8010EC54(void); -// void func_8010EE74(void); +void func_8010EE74(GlobalContext* globalCtx, s32 day); void Interface_ChangeAlpha(u16 param_1); // void func_8010EF9C(void); // void func_8010F0D4(void); @@ -2142,7 +2142,7 @@ void func_80112B40(GlobalContext* globalCtx, s32 arg1); u32 Item_Give(GlobalContext* globalCtx, u8 param_2); // void func_801143CC(void); UNK_TYPE func_80114978(UNK_TYPE arg0); -// void func_801149A0(void); +void func_801149A0(s32 arg0, s16 arg1); // void func_80114A9C(void); // void func_80114B84(void); // void func_80114CA0(void); @@ -2820,8 +2820,8 @@ void Sram_IncrementDay(void); u32 Sram_CalcChecksum(u8* data, u32 length); // void func_80144628(void); // void Sram_GenerateRandomSaveFields(void); -// void func_80144890(void); -// void func_80144968(void); +void func_80144890(void); +void Sram_InitDebugSave(void); // void func_80144A94(void); // void func_80144E78(void); // void func_8014546C(void); @@ -2879,7 +2879,7 @@ void func_80150D08(GlobalContext* globalCtx, u32 uParm2); // void func_801514B0(void); void func_801518B0(GlobalContext* globalCtx, u16 textId, Actor* Actor); void func_80151938(GlobalContext* globalCtx, u16 textId); -void func_80151A68(GlobalContext* globalCtx, u16 param_2); +void func_80151A68(GlobalContext* globalCtx, u16 textId); void func_80151BB4(GlobalContext* globalCtx, u32 uParm2); // void func_80151C9C(void); // void func_80151DA4(void); @@ -3058,7 +3058,7 @@ void func_80169EFC(GlobalContext* globalCtx); s32 FrameAdvance_IsEnabled(GlobalContext* globalCtx); // UNK_TYPE4 func_8016A02C(s32 param_1, s32 param_2, s16* param_3); // void func_8016A0AC(void); -// void func_8016A168(void); +s32 func_8016A168(void); // void func_8016A178(void); // void func_8016A268(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE1 param_5, UNK_TYPE1 param_6); void Play_Init(GameState* gameState); @@ -3792,7 +3792,7 @@ void func_8019AEC0(UNK_PTR param_1, UNK_PTR param_2); // void func_8019B38C(void); // void func_8019B3D0(void); // void func_8019B4B8(void); -// void func_8019B544(void); +void func_8019B544(u16 arg0); // void func_8019B568(void); // void func_8019B5AC(void); // void func_8019B5EC(void); @@ -3804,7 +3804,7 @@ void func_8019AEC0(UNK_PTR param_1, UNK_PTR param_2); // void func_8019C1D0(void); // void func_8019C268(void); // void func_8019C2E4(void); -// void func_8019C300(void); +void func_8019C300(s32 arg0); // void func_8019C398(void); // void func_8019C5A0(void); // void func_8019C8D8(void); @@ -3871,7 +3871,7 @@ void func_8019FE74(f32* arg0, f32 arg1, UNK_TYPE arg2); // void func_8019FF9C(void); // void func_801A0048(void); // void func_801A00EC(void); -// void func_801A0124(void); +void func_801A0124(Vec3f* pos, u8 arg1); // void func_801A0184(void); // void func_801A01C4(void); void func_801A0204(UNK_TYPE); @@ -4014,7 +4014,7 @@ void func_801A7794(u32 param_1, u32 param_2, u32 param_3); // void func_801A7B10(void); // void func_801A7D04(void); // void func_801A7D84(void); -void func_801A89A8(s32 arg0); +void Audio_QueueSeqCmd(u32 arg0); // void func_801A89D0(void); s32 func_801A8A50(s32 param1); // void func_801A8ABC(void); diff --git a/include/macros.h b/include/macros.h index e0e6c8e7c..fc03fa4ff 100644 --- a/include/macros.h +++ b/include/macros.h @@ -26,6 +26,17 @@ (curState)->nextGameStateInit = (GameStateFunc)newInit; \ (curState)->nextGameStateSize = sizeof(newStruct) +#define SET_FULLSCREEN_VIEWPORT(view) \ + { \ + Viewport viewport; \ + viewport.bottomY = SCREEN_HEIGHT; \ + viewport.rightX = SCREEN_WIDTH; \ + viewport.topY = 0; \ + viewport.leftX = 0; \ + View_SetViewport(view, &viewport); \ + } \ + (void)0 + #define PLAYER ((Player*)globalCtx->actorCtx.actorList[ACTORCAT_PLAYER].first) #define FIRST_ENEMY ((Actor*)globalCtx->actorCtx.actorList[ACTORCAT_ENEMY].first) @@ -38,6 +49,7 @@ #define CURRENT_DAY (((void)0, gSaveContext.day) % 5) #define CLOCK_TIME(hr, min) ((s32)(((hr) * 60 + (min)) * 0x10000 / (24 * 60))) +#define CLOCK_TIME_MINUTE (CLOCK_TIME(0, 1)) #define SLOT(item) gItemSlots[item] #define AMMO(item) gSaveContext.inventory.ammo[SLOT(item)] @@ -56,6 +68,7 @@ #define TAKE_EQUIPPED_ITEM(equip) (gSaveContext.equips.equipment = ((((void)0, gSaveContext.equips.equipment) & (gEquipNegMasks[equip])) | (u16)(0 << gEquipShifts[equip]))) #define CUR_FORM_EQUIP(button) (gSaveContext.equips.buttonItems[gSaveContext.playerForm == PLAYER_FORM_HUMAN ? 0 : gSaveContext.playerForm][button]) #define CHECK_QUEST_ITEM(item) (((void)0, gSaveContext.inventory.questItems) & gBitFlags[item]) +#define REMOVE_QUEST_ITEM(item) (gSaveContext.inventory.questItems = (((void)0, gSaveContext.inventory.questItems) & (-1 - gBitFlags[item]))) #define CAPACITY(upg, value) gUpgradeCapacities[upg][value] #define CUR_CAPACITY(upg) CAPACITY(upg, CUR_UPG_VALUE(upg) - 4) diff --git a/include/variables.h b/include/variables.h index 0783d8dc6..aa6957033 100644 --- a/include/variables.h +++ b/include/variables.h @@ -910,7 +910,7 @@ extern UNK_TYPE1 D_801BA550; // extern UNK_TYPE1 D_801BB100; // extern UNK_TYPE2 D_801BB124; // extern UNK_TYPE2 D_801BB128; -// extern UNK_TYPE1 D_801BB12C; +extern u8 D_801BB12C; // extern UNK_TYPE1 D_801BB130; extern cutscene_update_func sCsStateHandlers1[5]; extern cutscene_update_func sCsStateHandlers2[5]; @@ -949,7 +949,7 @@ extern GameStateOverlay daytelopGameStateInfo; // extern UNK_TYPE2 D_801BDA74; // extern UNK_TYPE2 D_801BDA78; // extern UNK_TYPE2 D_801BDA7C; -// extern UNK_TYPE4 D_801BDA9C; +extern s32 D_801BDA9C; extern UNK_TYPE4 D_801BDAA0; // extern UNK_TYPE4 D_801BDAA4; // extern UNK_TYPE2 D_801BDAA8; @@ -977,7 +977,7 @@ extern u8 kanfontOrdering[92]; // extern UNK_TYPE1 D_801BDBA0; // extern UNK_TYPE1 D_801BDBA4; // extern UNK_TYPE1 D_801BDBA8; -// extern UNK_TYPE1 D_801BDBB0; +extern u8 D_801BDBB0; // extern UNK_TYPE1 D_801BDBB4; // extern UNK_TYPE1 D_801BDBB8; // extern UNK_TYPE1 D_801BDBBC; @@ -3310,7 +3310,7 @@ extern s16 D_801F4E4C; extern f32 D_801F4E70; // extern UNK_TYPE1 D_801F4E74; // extern UNK_TYPE1 D_801F4E78; -// extern UNK_TYPE1 D_801F4E7A; +extern s16 D_801F4E7A; // extern UNK_TYPE1 D_801F4E80; // extern UNK_TYPE1 D_801F4EE0; // extern UNK_TYPE1 D_801F4EE8; @@ -3952,8 +3952,14 @@ extern UNK_TYPE D_0400E3D8; extern UNK_TYPE D_0400E408; extern UNK_TYPE D_0400E410; extern UNK_TYPE D_0400E418; -extern UNK_TYPE D_0400EB7C; -extern UNK_TYPE D_040117A8; +extern CollisionHeader D_0400E710; // Pink Deku Flower collision +extern AnimationHeader D_0400EB7C; // Deku Flower intense flutter animation +extern Gfx D_0400ED80; // Pink Deku Flower display list +extern SkeletonHeader D_04011518; // Pink Deku Flower skeleton +extern AnimationHeader D_040117A8; // Deku Flower small flutter animation +extern CollisionHeader D_040118D8; // Gold Deku Flower collision +extern Gfx D_04011BD0; // Gold Deku Flower display list +extern SkeletonHeader D_040127E8; // Gold Deku Flower skeleton extern UNK_TYPE D_04012860; extern UNK_TYPE D_040128BC; extern UNK_TYPE D_04015FA0; diff --git a/include/z64.h b/include/z64.h index 81636b14d..e762f892b 100644 --- a/include/z64.h +++ b/include/z64.h @@ -16,6 +16,7 @@ #include "xstdio.h" #include "unk.h" +#include "bgm.h" #include "sfx.h" #include "color.h" #include "ichain.h" diff --git a/include/z64item.h b/include/z64item.h index a5939c0dc..11c0201d6 100644 --- a/include/z64item.h +++ b/include/z64item.h @@ -20,7 +20,8 @@ typedef enum { } UpgradeType; typedef enum { - /* 0x01 */ ITEM_BOW = 0x01, + /* 0x00 */ ITEM_OCARINA, + /* 0x01 */ ITEM_BOW, /* 0x06 */ ITEM_BOMB = 0x06, /* 0x07 */ ITEM_BOMBCHU, /* 0x08 */ ITEM_STICK, diff --git a/include/z64light.h b/include/z64light.h index 567fb84e6..90ee01fb0 100644 --- a/include/z64light.h +++ b/include/z64light.h @@ -93,9 +93,7 @@ typedef enum LightType { /* 0x02 */ LIGHT_POINT_GLOW } LightType; -typedef struct GlobalContext GlobalContext; - typedef void (*LightsBindFunc)(Lights* lights, LightParams* params, Vec3f* vec); -typedef void (*LightsPosBindFunc)(Lights* lights, LightParams* params, GlobalContext* globalCtx); +typedef void (*LightsPosBindFunc)(Lights* lights, LightParams* params, struct GlobalContext* globalCtx); #endif diff --git a/include/z64player.h b/include/z64player.h index 0e25fcd86..8bab2605f 100644 --- a/include/z64player.h +++ b/include/z64player.h @@ -176,7 +176,7 @@ typedef struct Player { /* 0x386 */ u16 unk_386; /* 0x388 */ Actor* unk_388; /* 0x38C */ s16 unk_38C; - /* 0x390 */ Actor* unk_390; + /* 0x390 */ Actor* rideActor; /* 0x394 */ u8 unk_394; /* 0x395 */ u8 unk_395; /* 0x396 */ u8 unk_396; diff --git a/spec b/spec index 0eb4cdf1f..0faeb1229 100644 --- a/spec +++ b/spec @@ -704,16 +704,14 @@ beginseg name "ovl_select" compress include "build/src/overlays/gamestates/ovl_select/z_select.o" - include "build/data/ovl_select/ovl_select.data.o" - include "build/data/ovl_select/ovl_select.reloc.o" + include "build/src/overlays/gamestates/ovl_select/ovl_select_reloc.o" endseg beginseg name "ovl_opening" compress include "build/src/overlays/gamestates/ovl_opening/z_opening.o" - include "build/data/ovl_opening/ovl_opening.data.o" - include "build/data/ovl_opening/ovl_opening.reloc.o" + include "build/src/overlays/gamestates/ovl_opening/ovl_opening_reloc.o" endseg beginseg @@ -1182,8 +1180,7 @@ beginseg name "ovl_En_Rd" compress include "build/src/overlays/actors/ovl_En_Rd/z_en_rd.o" - include "build/data/ovl_En_Rd/ovl_En_Rd.data.o" - include "build/data/ovl_En_Rd/ovl_En_Rd.reloc.o" + include "build/src/overlays/actors/ovl_En_Rd/ovl_En_Rd_reloc.o" endseg beginseg @@ -2916,9 +2913,11 @@ beginseg name "ovl_En_Test4" compress include "build/src/overlays/actors/ovl_En_Test4/z_en_test4.o" - include "build/data/ovl_En_Test4/ovl_En_Test4.data.o" - include "build/data/ovl_En_Test4/ovl_En_Test4.bss.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_En_Test4/ovl_En_Test4_reloc.o" +#else include "build/data/ovl_En_Test4/ovl_En_Test4.reloc.o" +#endif endseg beginseg @@ -3207,8 +3206,7 @@ beginseg name "ovl_Obj_Etcetera" compress include "build/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.o" - include "build/data/ovl_Obj_Etcetera/ovl_Obj_Etcetera.data.o" - include "build/data/ovl_Obj_Etcetera/ovl_Obj_Etcetera.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Etcetera/ovl_Obj_Etcetera_reloc.o" endseg beginseg @@ -4486,8 +4484,7 @@ beginseg name "ovl_En_Zot" compress include "build/src/overlays/actors/ovl_En_Zot/z_en_zot.o" - include "build/data/ovl_En_Zot/ovl_En_Zot.data.o" - include "build/data/ovl_En_Zot/ovl_En_Zot.reloc.o" + include "build/src/overlays/actors/ovl_En_Zot/ovl_En_Zot_reloc.o" endseg beginseg @@ -5311,9 +5308,7 @@ beginseg name "ovl_En_Thiefbird" compress include "build/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.o" - include "build/data/ovl_En_Thiefbird/ovl_En_Thiefbird.data.o" - include "build/data/ovl_En_Thiefbird/ovl_En_Thiefbird.bss.o" - include "build/data/ovl_En_Thiefbird/ovl_En_Thiefbird.reloc.o" + include "build/src/overlays/actors/ovl_En_Thiefbird/ovl_En_Thiefbird_reloc.o" endseg beginseg @@ -5523,8 +5518,7 @@ beginseg name "ovl_En_Ending_Hero6" compress include "build/src/overlays/actors/ovl_En_Ending_Hero6/z_en_ending_hero6.o" - include "build/data/ovl_En_Ending_Hero6/ovl_En_Ending_Hero6.data.o" - include "build/data/ovl_En_Ending_Hero6/ovl_En_Ending_Hero6.reloc.o" + include "build/src/overlays/actors/ovl_En_Ending_Hero6/ovl_En_Ending_Hero6_reloc.o" endseg beginseg diff --git a/src/code/code_801A7B10.c b/src/code/code_801A7B10.c index a8bd825b7..707996820 100644 --- a/src/code/code_801A7B10.c +++ b/src/code/code_801A7B10.c @@ -6,7 +6,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A7D84.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A89A8.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/Audio_QueueSeqCmd.s") #pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A89D0.s") diff --git a/src/code/z_sram_NES.c b/src/code/z_sram_NES.c index 689382ba9..5b5b2f5f0 100644 --- a/src/code/z_sram_NES.c +++ b/src/code/z_sram_NES.c @@ -18,7 +18,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80144890.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80144968.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/Sram_InitDebugSave.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80144A94.s") diff --git a/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.c b/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.c index 5879c5cb9..9f06cdc16 100644 --- a/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.c +++ b/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.c @@ -304,7 +304,7 @@ void EnBji01_DialogueHandler(EnBji01* this, GlobalContext* globalCtx) { void func_809CD634(EnBji01* this, GlobalContext* globalCtx) { func_801A5BD0(0x6F); - func_801A89A8(0xE0000101); + Audio_QueueSeqCmd(0xE0000101); globalCtx->nextEntranceIndex = 0x54A0; /* Termina Field from telescope */ gSaveContext.respawn[0].entranceIndex = globalCtx->nextEntranceIndex; func_80169EFC(globalCtx); /* Load new entrance? */ @@ -363,7 +363,7 @@ void EnBji01_Init(Actor* thisx, GlobalContext* globalCtx) { case 0x4C20: /* Observatory from Termina Field telescope */ this->actor.flags |= 0x10000; func_801A5BD0(0); - func_801A89A8(0xE0000100); + Audio_QueueSeqCmd(0xE0000100); this->actor.params = ENBJI01_PARAMS_LOOKED_THROUGH_TELESCOPE; func_809CCE98(this, globalCtx); break; diff --git a/src/overlays/actors/ovl_En_Ending_Hero6/z_en_ending_hero6.c b/src/overlays/actors/ovl_En_Ending_Hero6/z_en_ending_hero6.c index 048e4c7a2..cfd596646 100644 --- a/src/overlays/actors/ovl_En_Ending_Hero6/z_en_ending_hero6.c +++ b/src/overlays/actors/ovl_En_Ending_Hero6/z_en_ending_hero6.c @@ -1,3 +1,9 @@ +/* + * File: z_en_ending_hero6.c + * Overlay: ovl_En_Ending_Hero6 + * Description: + */ + #include "z_en_ending_hero6.h" #define FLAGS 0x00000009 @@ -9,9 +15,40 @@ void EnEndingHero6_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnEndingHero6_Update(Actor* thisx, GlobalContext* globalCtx); void EnEndingHero6_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80C23E18(EnEndingHero6* this, GlobalContext* globalCtx); +void EnEndingHero6_InitSkelAnime(EnEndingHero6* this, s32 npcIndex); +void EnEndingHero6_SetupIdle(EnEndingHero6* this); +void EnEndingHero6_Idle(EnEndingHero6* this, GlobalContext* globalCtx); + +extern FlexSkeletonHeader D_0600B0CC; // object_dt +extern FlexSkeletonHeader D_06007908; // object_bai +extern FlexSkeletonHeader D_06007150; // object_toryo +extern FlexSkeletonHeader D_0600D640; // object_sdn +extern FlexSkeletonHeader D_0600A850; // object_daiku + +extern AnimationHeader D_06000BE0; // object_dt +extern AnimationHeader D_060011C0; // object_bai +extern AnimationHeader D_06000E50; // object_toryo +extern AnimationHeader D_06002A84; // object_sdn +extern AnimationHeader D_06002FA0; // object_daiku + +// object_daiku +extern Gfx D_060070C0[]; +extern Gfx D_06006FB0[]; +extern Gfx D_06006E80[]; +extern Gfx D_06006D70[]; +extern Gfx D_0600A390_dl[]; + +// object_dt +extern TexturePtr D_06007350; +extern TexturePtr D_06009590; +extern TexturePtr D_06009F90; +extern TexturePtr D_0600A790; +extern TexturePtr D_0600AB90; + +extern TexturePtr D_06007750; +extern TexturePtr D_0600A390_tex; +extern TexturePtr D_0600A490; -#if 0 const ActorInit En_Ending_Hero6_InitVars = { ACTOR_EN_ENDING_HERO6, ACTORCAT_NPC, @@ -24,20 +61,131 @@ const ActorInit En_Ending_Hero6_InitVars = { (ActorFunc)EnEndingHero6_Draw, }; -#endif +static FlexSkeletonHeader* sSkeletons[] = { &D_0600B0CC, &D_06007908, &D_06007150, &D_0600D640, &D_0600A850, + &D_0600A850, &D_0600A850, &D_0600A850, &D_0600A850 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ending_Hero6/EnEndingHero6_Init.s") +static AnimationHeader* sAnimations[] = { &D_06000BE0, &D_060011C0, &D_06000E50, &D_06002A84, &D_06002FA0, + &D_06002FA0, &D_06002FA0, &D_06002FA0, &D_06002FA0 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ending_Hero6/EnEndingHero6_Destroy.s") +static s32 sLimbCounts[] = { 15, 20, 17, 17, 17, 17, 17, 17, 17 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ending_Hero6/func_80C23D60.s") +void EnEndingHero6_Init(Actor* thisx, GlobalContext* globalCtx) { + EnEndingHero6* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ending_Hero6/func_80C23DDC.s") + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + Actor_SetScale(&this->actor, 0.01f); + this->actor.targetMode = 6; + this->actor.gravity = -3.0f; + SkelAnime_InitSV(globalCtx, &this->skelAnime, sSkeletons[this->npcIndex], sAnimations[this->npcIndex], + this->jointTable, this->morphTable, sLimbCounts[this->npcIndex]); + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 25.0f); + EnEndingHero6_SetupIdle(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ending_Hero6/func_80C23E18.s") +void EnEndingHero6_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ending_Hero6/EnEndingHero6_Update.s") +void EnEndingHero6_InitSkelAnime(EnEndingHero6* this, s32 npcIndex) { + this->animIndex = npcIndex; + this->frameCount = SkelAnime_GetFrameCount(&sAnimations[npcIndex]->common); + SkelAnime_ChangeAnim(&this->skelAnime, sAnimations[this->animIndex], 1.0f, 0.f, this->frameCount, 0, 0.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ending_Hero6/func_80C23F14.s") +void EnEndingHero6_SetupIdle(EnEndingHero6* this) { + EnEndingHero6_InitSkelAnime(this, this->npcIndex); + this->isIdle = 1; + this->actionFunc = EnEndingHero6_Idle; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ending_Hero6/EnEndingHero6_Draw.s") +void EnEndingHero6_Idle(EnEndingHero6* this, GlobalContext* globalCtx) { + SkelAnime_FrameUpdateMatrix(&this->skelAnime); +} + +void EnEndingHero6_Update(Actor* thisx, GlobalContext* globalCtx) { + EnEndingHero6* this = THIS; + + if (this->timer != 0) { + this->timer--; + } + + this->actor.shape.rot.y = this->actor.world.rot.y; + + if (this->blinkTimer == 0) { + this->eyeState++; + if (this->eyeState >= 3) { + this->eyeState = 0; + this->blinkTimer = (s16)Rand_ZeroFloat(60.0f) + 20; + } + } + + this->actionFunc(this, globalCtx); + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 50.0f, 0x1D); +} + +void EnEndingHero6_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Gfx* D_80C2426C[] = { D_060070C0, D_06006FB0, D_06006E80, D_06006D70, D_0600A390_dl }; + EnEndingHero6* this = THIS; + s32 index; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (this->npcIndex >= 4 && limbIndex == 15) { + index = this->npcIndex - 4; + gSPDisplayList(POLY_OPA_DISP++, D_80C2426C[index]); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnEndingHero6_Draw(Actor* thisx, GlobalContext* globalCtx) { + static TexturePtr D_80C24280[] = { &D_06007350, &D_06009590, &D_06009F90, &D_0600A790, &D_0600AB90 }; + static TexturePtr D_80C24294[] = { &D_06007750, &D_0600A390_tex, &D_0600A490 }; + s32 pad; + EnEndingHero6* this = THIS; + s32 index = 0; + + if (this->isIdle == 1) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + + if (this->objectIndex >= 0 && Object_IsLoaded(&globalCtx->objectCtx, this->objectIndex)) { + gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[this->objectIndex].segment); + + switch (this->npcIndex) { + case 4: + gDPSetEnvColor(POLY_OPA_DISP++, 170, 10, 70, 255); + break; + case 5: + gDPSetEnvColor(POLY_OPA_DISP++, 170, 200, 255, 255); + break; + case 6: + gDPSetEnvColor(POLY_OPA_DISP++, 0, 230, 70, 255); + break; + case 7: + gDPSetEnvColor(POLY_OPA_DISP++, 200, 0, 150, 255); + break; + case 8: + gDPSetEnvColor(POLY_OPA_DISP++, 245, 155, 0, 255); + break; + } + + if (this->npcIndex == 0) { + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80C24280[this->eyeState])); + + if (this->eyeState < 3) { + index = this->eyeState; + } + + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80C24294[index])); + } + + SkelAnime_DrawSV(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, + this->skelAnime.dListCount, NULL, EnEndingHero6_PostLimbDraw, &this->actor); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_En_Ending_Hero6/z_en_ending_hero6.h b/src/overlays/actors/ovl_En_Ending_Hero6/z_en_ending_hero6.h index 2cbdb2980..4f8989634 100644 --- a/src/overlays/actors/ovl_En_Ending_Hero6/z_en_ending_hero6.h +++ b/src/overlays/actors/ovl_En_Ending_Hero6/z_en_ending_hero6.h @@ -9,9 +9,18 @@ typedef void (*EnEndingHero6ActionFunc)(struct EnEndingHero6*, GlobalContext*); typedef struct EnEndingHero6 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x134]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[20]; + /* 0x0200 */ Vec3s morphTable[20]; /* 0x0278 */ EnEndingHero6ActionFunc actionFunc; - /* 0x027C */ char unk_27C[0x18]; + /* 0x027C */ s32 animIndex; + /* 0x0280 */ s32 npcIndex; + /* 0x0284 */ s8 objectIndex; + /* 0x0286 */ s16 timer; + /* 0x0288 */ s16 blinkTimer; + /* 0x028A */ s16 eyeState; + /* 0x028C */ f32 frameCount; + /* 0x0290 */ s16 isIdle; } EnEndingHero6; // size = 0x294 extern const ActorInit En_Ending_Hero6_InitVars; diff --git a/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c b/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c index 319bb02d8..bace8a29b 100644 --- a/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c +++ b/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c @@ -76,7 +76,7 @@ const ActorInit En_Fsn_InitVars = { (ActorFunc)EnFsn_Draw, }; -ActorAnimationEntryS sAnimations[] = { +static ActorAnimationEntryS sAnimations[] = { { &D_06012C34, 1.0f, 0, -1, 0, 0 }, { &D_060131FC, 1.0f, 0, -1, 0, 0 }, { &D_0600C58C, 1.0f, 0, -1, 2, 0 }, { &D_0600C58C, -1.0f, 0, -1, 2, 0 }, { &D_0600E3EC, 1.0f, 0, -1, 2, 0 }, { &D_0600F00C, 1.0f, 0, -1, 0, 0 }, { &D_0600CB3C, 1.0f, 0, -1, 2, 0 }, { &D_0600D354, 1.0f, 0, -1, 0, 0 }, { &D_060138B0, 1.0f, 0, -1, 2, 0 }, diff --git a/src/overlays/actors/ovl_En_Horse/z_en_horse.h b/src/overlays/actors/ovl_En_Horse/z_en_horse.h index 234552143..7efae12fc 100644 --- a/src/overlays/actors/ovl_En_Horse/z_en_horse.h +++ b/src/overlays/actors/ovl_En_Horse/z_en_horse.h @@ -7,7 +7,9 @@ struct EnHorse; typedef struct EnHorse { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x450]; + /* 0x144 */ char unk_144[0x00C]; + /* 0x150 */ s32 unk_150; + /* 0x154 */ char unk_154[0x440]; } EnHorse; // size = 0x594 extern const ActorInit En_Horse_InitVars; diff --git a/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c b/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c index 613caad0a..1e5dd6e6e 100644 --- a/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c +++ b/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c @@ -1699,7 +1699,7 @@ void func_80B4627C(EnInvadepoh* this, GlobalContext* globalCtx) { } else { func_80B454BC(this, globalCtx); func_80B452EC(this, globalCtx); - func_801A89A8(0x800D); + Audio_QueueSeqCmd(0x800D); func_80B46F88(this); } } else if (D_80B4E940 == 3) { @@ -1987,7 +1987,7 @@ void func_80B46EE8(EnInvadepoh* this, GlobalContext* globalCtx) { this->actionTimer--; if (this->actionTimer <= 0) { ActorCutscene_Stop(D_80B50404[0]); - func_801A89A8(0x800D); + Audio_QueueSeqCmd(0x800D); func_80B46F88(this); } } diff --git a/src/overlays/actors/ovl_En_Ma4/z_en_ma4.c b/src/overlays/actors/ovl_En_Ma4/z_en_ma4.c index a0d27353a..6f4c463cf 100644 --- a/src/overlays/actors/ovl_En_Ma4/z_en_ma4.c +++ b/src/overlays/actors/ovl_En_Ma4/z_en_ma4.c @@ -750,8 +750,8 @@ void EnMa4_HorsebackGameWait(EnMa4* this, GlobalContext* globalCtx) { void EnMa4_SetupHorsebackGameEnd(EnMa4* this, GlobalContext* globalCtx) { gSaveContext.weekEventReg[0x8] &= (u8)~0x01; this->actionFunc = EnMa4_HorsebackGameEnd; - func_801A89A8(0x100000FF); - func_801A89A8(0x8041); + Audio_QueueSeqCmd(NA_BGM_STOP); + Audio_QueueSeqCmd(0x8041); } void EnMa4_HorsebackGameEnd(EnMa4* this, GlobalContext* globalCtx) { diff --git a/src/overlays/actors/ovl_En_Rd/z_en_rd.c b/src/overlays/actors/ovl_En_Rd/z_en_rd.c index e0cb90c26..0e58c9029 100644 --- a/src/overlays/actors/ovl_En_Rd/z_en_rd.c +++ b/src/overlays/actors/ovl_En_Rd/z_en_rd.c @@ -1,3 +1,9 @@ +/* + * File: z_en_rd.c + * Overlay: ovl_En_Rd + * Description: Redead / Gibdo + */ + #include "z_en_rd.h" #define FLAGS 0x00000415 @@ -9,27 +15,57 @@ void EnRd_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnRd_Update(Actor* thisx, GlobalContext* globalCtx); void EnRd_Draw(Actor* thisx, GlobalContext* globalCtx); +s32 func_808D41FC(GlobalContext* globalCtx); +void func_808D4308(EnRd* this); void func_808D43AC(EnRd* this, GlobalContext* globalCtx); +void func_808D45D4(EnRd* this); void func_808D4660(EnRd* this, GlobalContext* globalCtx); +void func_808D47DC(EnRd* this); void func_808D4868(EnRd* this, GlobalContext* globalCtx); void func_808D49E4(EnRd* this, GlobalContext* globalCtx); +void func_808D4A90(EnRd* this); void func_808D4B20(EnRd* this, GlobalContext* globalCtx); void func_808D4CA8(EnRd* this, GlobalContext* globalCtx); +void func_808D4DC4(EnRd* this); void func_808D4E60(EnRd* this, GlobalContext* globalCtx); void func_808D506C(EnRd* this, GlobalContext* globalCtx); +void func_808D53C0(EnRd* this, GlobalContext* globalCtx); void func_808D5440(EnRd* this, GlobalContext* globalCtx); +void func_808D5660(EnRd* this); void func_808D56E4(EnRd* this, GlobalContext* globalCtx); +void func_808D586C(EnRd* this); void func_808D58CC(EnRd* this, GlobalContext* globalCtx); +void func_808D5C54(EnRd* this); void func_808D5CCC(EnRd* this, GlobalContext* globalCtx); +void func_808D5D88(EnRd* this); void func_808D5DF4(EnRd* this, GlobalContext* globalCtx); +void func_808D5E98(EnRd* this); void func_808D5F18(EnRd* this, GlobalContext* globalCtx); +void func_808D6008(EnRd* this); void func_808D6054(EnRd* this, GlobalContext* globalCtx); +void func_808D60B0(EnRd* this); void func_808D6130(EnRd* this, GlobalContext* globalCtx); void func_808D6200(EnRd* this, GlobalContext* globalCtx); void func_808D6388(EnRd* this, GlobalContext* globalCtx); void func_808D65BC(EnRd* this, GlobalContext* globalCtx); -#if 0 +extern FlexSkeletonHeader D_060053E8; +extern AnimationHeader D_06006678; +extern AnimationHeader D_06006B08; +extern AnimationHeader D_06006EEC; +extern AnimationHeader D_060073A4; +extern AnimationHeader D_06007BBC; +extern AnimationHeader D_060081A8; +extern AnimationHeader D_06009298; +extern AnimationHeader D_06009900; +extern AnimationHeader D_0600A450; +extern AnimationHeader D_0600ABE0; +extern FlexSkeletonHeader D_06010B88; +extern AnimationHeader D_060113EC; +extern AnimationHeader D_060118D8; +extern AnimationHeader D_06011DB8; +extern AnimationHeader D_0601216C; + const ActorInit En_Rd_InitVars = { ACTOR_EN_RD, ACTORCAT_ENEMY, @@ -42,15 +78,27 @@ const ActorInit En_Rd_InitVars = { (ActorFunc)EnRd_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_808D70E0 = { - { COLTYPE_HIT0, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0xF7EFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HIT0, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK1, + { 0x00000000, 0x00, 0x00 }, + { 0xF7EFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 20, 70, 0, { 0, 0, 0 } }, }; -// static DamageTable sDamageTable = { -static DamageTable D_808D710C = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(2, 0xF), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -85,126 +133,1139 @@ static DamageTable D_808D710C = { /* Powder Keg */ DMG_ENTRY(1, 0xF), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808D712C[] = { +static InitChainEntry sInitChain[] = { ICHAIN_F32(targetArrowOffset, 2000, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 10, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -3500, ICHAIN_STOP), }; -#endif +void EnRd_Init(Actor* thisx, GlobalContext* globalCtx) { + EnRd* this = THIS; + s32 pad; -extern ColliderCylinderInit D_808D70E0; -extern DamageTable D_808D710C; -extern InitChainEntry D_808D712C[]; + Actor_ProcessInitChain(&this->actor, sInitChain); + this->actor.targetMode = 0; + this->actor.colChkInfo.damageTable = &sDamageTable; + ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f); + this->unk_3DA = this->unk_3D8 = 0; + this->actor.focus.pos = this->actor.world.pos; + this->actor.focus.pos.y += 50.0f; + this->actor.colChkInfo.mass = MASS_HEAVY; + this->actor.colChkInfo.health = 8; + this->unk_3DE = 255; + this->unk_3F1 = -1; + this->unk_3DC = ENRD_GET_FF00(thisx); -extern UNK_TYPE D_06006678; -extern UNK_TYPE D_06006EEC; -extern UNK_TYPE D_060073A4; -extern UNK_TYPE D_060081A8; -extern UNK_TYPE D_06009298; -extern UNK_TYPE D_06009900; -extern UNK_TYPE D_0600A450; -extern UNK_TYPE D_0600ABE0; -extern UNK_TYPE D_060113EC; -extern UNK_TYPE D_060118D8; -extern UNK_TYPE D_06011DB8; -extern UNK_TYPE D_0601216C; + if (ENRD_GET_80(&this->actor)) { + this->actor.params |= 0xFF00; + } else { + this->actor.params &= 0xFF; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/EnRd_Init.s") + if (this->actor.params >= ENRD_GET_MINUS_1) { + SkelAnime_InitSV(globalCtx, &this->skelAnime, &D_06010B88, &D_0600ABE0, this->jointTable, this->morphTable, 26); + } else { + SkelAnime_InitSV(globalCtx, &this->skelAnime, &D_060053E8, &D_0600ABE0, this->jointTable, this->morphTable, 26); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/EnRd_Destroy.s") + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D4190.s") + if (this->actor.params >= ENRD_GET_MINUS_2) { + switch (this->actor.params) { + case 5: + if (!func_808D41FC(globalCtx)) { + func_808D45D4(this); + } else { + this->actor.hintId = 0x2A; + func_808D4308(this); + } + this->unkFunc = func_808D45D4; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D41FC.s") + case 6: + if (!func_808D41FC(globalCtx)) { + func_808D47DC(this); + } else { + this->actor.hintId = 0x2A; + func_808D4308(this); + } + this->unkFunc = func_808D47DC; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D4260.s") + case 7: + if (!func_808D41FC(globalCtx)) { + func_808D4A90(this); + } else { + this->actor.hintId = 0x2A; + func_808D4308(this); + } + this->unkFunc = func_808D4A90; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D4308.s") + default: + if (this->actor.params == ENRD_GET_MINUS_2) { + this->actor.hintId = 0x2D; + } else { + this->actor.hintId = 0x2A; + } + func_808D4308(this); + this->unkFunc = func_808D4308; + break; + } + } else { + func_808D4DC4(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D43AC.s") + SkelAnime_FrameUpdateMatrix(&this->skelAnime); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D45D4.s") + if (this->actor.params == ENRD_GET_3) { + this->actor.flags |= 0x80; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D4660.s") + if (this->actor.params == ENRD_GET_4) { + s32 pad2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D47DC.s") + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_OBJ_ICE_POLY, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, this->actor.world.rot.x, + this->actor.world.rot.y, this->actor.world.rot.z, 0xFF4B); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D4868.s") +void EnRd_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnRd* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D49E4.s") + if (gSaveContext.unk_3F58 != 0) { + gSaveContext.unk_3F58 = 0; + } + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D4A90.s") +void func_808D4190(GlobalContext* globalCtx, EnRd* this, s32 arg2) { + Actor* actor = globalCtx->actorCtx.actorList[ACTORCAT_ENEMY].first; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D4B20.s") + while (actor != NULL) { + if ((actor->id != ACTOR_EN_RD) || (this == (EnRd*)actor) || (actor->params < ENRD_GET_0)) { + actor = actor->next; + continue; + } else if (arg2 != 0) { + actor->parent = &this->actor; + } else if (this == (EnRd*)actor->parent) { + actor->parent = NULL; + } + actor = actor->next; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D4CA8.s") +s32 func_808D41FC(GlobalContext* globalCtx) { + if ((Player_GetMask(globalCtx) == PLAYER_MASK_GIBDO_MASK) || + (Player_GetMask(globalCtx) == PLAYER_MASK_CAPTAINS_HAT) || + (Player_GetMask(globalCtx) == PLAYER_MASK_GAROS_MASK)) { + return false; + } + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D4DC4.s") +void func_808D4260(EnRd* this, GlobalContext* globalCtx) { + if ((this->actor.params >= ENRD_GET_5) && (this->actionFunc != func_808D4660) && + (this->actionFunc != func_808D4868) && (this->actionFunc != func_808D4B20) && + (this->actionFunc != func_808D65BC) && (this->actionFunc != func_808D58CC) && + (this->actionFunc != func_808D6200) && (this->actionFunc != func_808D6388)) { + if (!func_808D41FC(globalCtx)) { + this->unkFunc(this); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D4E60.s") +void func_808D4308(EnRd* this) { + if (this->actor.params != ENRD_GET_2) { + SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_0600ABE0, -6.0f); + } else { + SkelAnime_ChangeAnimDefaultRepeat(&this->skelAnime, &D_060081A8); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D4FE0.s") + this->unk_3EF = 0; + this->unk_3D6 = (Rand_ZeroOne() * 10.0f) + 5.0f; + this->actor.speedXZ = 0.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actionFunc = func_808D43AC; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D506C.s") +void func_808D43AC(EnRd* this, GlobalContext* globalCtx) { + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + Math_SmoothStepToS(&this->unk_3D8, 0, 1, 100, 0); + Math_SmoothStepToS(&this->unk_3DA, 0, 1, 100, 0); + if ((this->actor.params == ENRD_GET_2) && func_801378B8(&this->skelAnime, 0.0f)) { + if (Rand_ZeroOne() >= 0.5f) { + SkelAnime_ChangeAnimDefaultRepeat(&this->skelAnime, &D_060081A8); + } else { + SkelAnime_ChangeAnimDefaultRepeat(&this->skelAnime, &D_06007BBC); + } + } else { + this->unk_3D6--; + if (this->unk_3D6 == 0) { + this->unk_3D6 = (Rand_ZeroOne() * 10.0f) + 10.0f; + this->skelAnime.animCurrentFrame = 0.0f; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D53C0.s") + if (this->actor.parent != NULL) { + if (this->unk_3EC == 0) { + if (this->actor.params != ENRD_GET_2) { + func_808D5660(this); + } else { + func_808D6008(this); + } + } + } else { + if (this->unk_3EC != 0) { + if (this->actor.params != ENRD_GET_2) { + func_808D5C54(this); + } else { + func_808D6008(this); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D5440.s") + this->unk_3EC = 0; + if ((this->actor.xzDistToPlayer <= 150.0f) && func_800B715C(globalCtx)) { + if ((this->actor.params != ENRD_GET_2) && (this->unk_3EC == 0)) { + func_808D5C54(this); + } else { + func_808D6008(this); + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D5660.s") + if ((globalCtx->gameplayFrames & 0x5F) == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D56E4.s") +void func_808D45D4(EnRd* this) { + SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_0601216C, -6.0f); + this->unk_3EF = 14; + this->unk_3D6 = (Rand_ZeroOne() * 10.0f) + 5.0f; + this->unk_3E4 = 0; + this->actor.speedXZ = 0.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actionFunc = func_808D4660; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D586C.s") +void func_808D4660(EnRd* this, GlobalContext* globalCtx) { + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + Math_SmoothStepToS(&this->unk_3D8, 0, 1, 100, 0); + Math_SmoothStepToS(&this->unk_3DA, 0, 1, 100, 0); + if (this->unk_3EC != 0) { + func_808D5C54(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D58CC.s") + this->unk_3EC = 0; + if ((this->actor.xzDistToPlayer <= 150.0f) && func_808D41FC(globalCtx) && func_800B715C(globalCtx)) { + if (this->actor.params == ENRD_GET_MINUS_2) { + this->actor.hintId = 0x2D; + } else { + this->actor.hintId = 0x2A; + } + SkelAnime_ChangeAnim(&this->skelAnime, &D_060073A4, 0.0f, 0.0f, 19.0f, 2, -10.0f); + this->actionFunc = func_808D49E4; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D5C54.s") + if (func_808D41FC(globalCtx)) { + if (this->actor.params == ENRD_GET_MINUS_2) { + this->actor.hintId = 0x2D; + } else { + this->actor.hintId = 0x2A; + } + func_808D4308(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D5CCC.s") + if ((globalCtx->gameplayFrames & 0x5F) == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D5D88.s") +void func_808D47DC(EnRd* this) { + SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_06011DB8, -6.0f); + this->unk_3EF = 15; + this->unk_3D6 = (Rand_ZeroOne() * 10.0f) + 5.0f; + this->unk_3E4 = 0; + this->actor.speedXZ = 0.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actionFunc = func_808D4868; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D5DF4.s") +void func_808D4868(EnRd* this, GlobalContext* globalCtx) { + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + Math_SmoothStepToS(&this->unk_3D8, 0, 1, 100, 0); + Math_SmoothStepToS(&this->unk_3DA, 0, 1, 100, 0); + if (this->unk_3EC != 0) { + func_808D5C54(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D5E98.s") + this->unk_3EC = 0; + if ((this->actor.xzDistToPlayer <= 150.0f) && func_808D41FC(globalCtx) && func_800B715C(globalCtx)) { + if (this->actor.params == ENRD_GET_MINUS_2) { + this->actor.hintId = 0x2D; + } else { + this->actor.hintId = 0x2A; + } + SkelAnime_ChangeAnim(&this->skelAnime, &D_060073A4, 0.0f, 0.0f, 19.0f, 2, -10.0f); + this->actionFunc = func_808D49E4; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D5F18.s") + if (func_808D41FC(globalCtx)) { + if (this->actor.params == ENRD_GET_MINUS_2) { + this->actor.hintId = 0x2D; + } else { + this->actor.hintId = 0x2A; + } + func_808D4308(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D6008.s") + if ((globalCtx->gameplayFrames & 0x5F) == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D6054.s") +void func_808D49E4(EnRd* this, GlobalContext* globalCtx) { + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + if ((globalCtx->gameplayFrames & 0x5F) == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D60B0.s") + this->unk_3E4++; + if (this->unk_3E4 > 10) { + if ((this->actor.params != ENRD_GET_2) && (this->unk_3EC == 0)) { + func_808D5C54(this); + } else { + func_808D6008(this); + } + this->unk_3E4 = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D6130.s") +void func_808D4A90(EnRd* this) { + SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_060118D8, -6.0f); + this->unk_3EF = 16; + this->unk_3D6 = (Rand_ZeroOne() * 10.0f) + 5.0f; + this->unk_3E4 = 4370; + this->actor.speedXZ = 0.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actionFunc = func_808D4B20; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D616C.s") +void func_808D4B20(EnRd* this, GlobalContext* globalCtx) { + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + Math_SmoothStepToS(&this->unk_3D8, 0, 1, 100, 0); + Math_SmoothStepToS(&this->unk_3DA, 0, 1, 100, 0); + if (this->unk_3EC != 0) { + func_808D5C54(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D6200.s") + this->unk_3EC = 0; + if ((this->actor.xzDistToPlayer <= 150.0f) && func_808D41FC(globalCtx) && func_800B715C(globalCtx)) { + if (this->actor.params == ENRD_GET_MINUS_2) { + this->actor.hintId = 0x2D; + } else { + this->actor.hintId = 0x2A; + } + this->actionFunc = func_808D4CA8; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D6310.s") + if (func_808D41FC(globalCtx)) { + if (this->actor.params == ENRD_GET_MINUS_2) { + this->actor.hintId = 0x2D; + } else { + this->actor.hintId = 0x2A; + } + func_808D4308(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D6388.s") + if ((globalCtx->gameplayFrames & 0x5F) == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D64D0.s") + if (func_801378B8(&this->skelAnime, this->skelAnime.animFrameCount)) { + this->unk_3E4 = 4370; + } else if (func_801378B8(&this->skelAnime, 15.0f)) { + this->unk_3E4 = 6554; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D65BC.s") + this->actor.world.rot.y -= this->unk_3E4; + this->actor.shape.rot.y = this->actor.world.rot.y; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D66A0.s") +void func_808D4CA8(EnRd* this, GlobalContext* globalCtx) { + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + if ((globalCtx->gameplayFrames & 0x5F) == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D6814.s") + this->actor.world.rot.y -= this->unk_3E4; + this->actor.shape.rot.y = this->actor.world.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D6A94.s") + this->unk_3E4 -= 100; + if ((this->unk_3E4 < 2100) && (this->unk_3E4 >= 2000)) { + SkelAnime_ChangeAnim(&this->skelAnime, &D_060073A4, 0.0f, 0.0f, 19.0f, 2, -10.0f); + } else if (this->unk_3E4 < 1000) { + if ((this->actor.params != ENRD_GET_2) && (this->unk_3EC == 0)) { + func_808D5C54(this); + } else { + func_808D6008(this); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D6B64.s") +void func_808D4DC4(EnRd* this) { + SkelAnime_ChangeAnim(&this->skelAnime, &D_0600ABE0, 0.0f, 0.0f, SkelAnime_GetFrameCount(&D_0600ABE0.common), 0, + -6.0f); + this->unk_3EF = 13; + this->unk_3D6 = 6; + this->actor.shape.rot.x = -0x4000; + this->actor.gravity = 0.0f; + this->actor.shape.yOffset = 0.0f; + this->actor.speedXZ = 0.0f; + this->actionFunc = func_808D4E60; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/EnRd_Update.s") +void func_808D4E60(EnRd* this, GlobalContext* globalCtx) { + if (this->actor.shape.rot.x != -0x4000) { + Math_SmoothStepToS(&this->actor.shape.rot.x, 0, 1, 0x7D0, 0); + if (Math_SmoothStepToF(&this->actor.world.pos.y, this->actor.home.pos.y, 0.3f, 2.0f, 0.3f) == 0.0f) { + this->actor.gravity = -3.5f; + func_808D4308(this); + } + } else { + if (this->actor.world.pos.y == this->actor.home.pos.y) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D6DA0.s") + if (Math_SmoothStepToF(&this->actor.world.pos.y, this->actor.home.pos.y + 50.0f, 0.3f, 2.0f, 0.3f) == 0.0f) { + if (this->unk_3D6 != 0) { + this->unk_3D6--; + Math_SmoothStepToF(&this->actor.speedXZ, 6.0f, 0.3f, 1.0f, 0.3f); + } else if (Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 0.3f, 1.0f, 0.3f) == 0.0f) { + Math_SmoothStepToS(&this->actor.shape.rot.x, 0, 1, 0x7D0, 0); + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/func_808D6DFC.s") +void func_808D4FE0(EnRd* this, GlobalContext* globalCtx) { + f32 frameCount = SkelAnime_GetFrameCount(&D_060113EC.common); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rd/EnRd_Draw.s") + SkelAnime_ChangeAnim(&this->skelAnime, &D_060113EC, 1.0f, 4.0f, frameCount, 1, -4.0f); + this->actor.speedXZ = 0.4f; + this->unk_3EF = 4; + this->actionFunc = func_808D506C; +} + +void func_808D506C(EnRd* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + s32 pad; + s16 sp36 = ((this->actor.yawTowardsPlayer - this->actor.shape.rot.y) - this->unk_3D8) - this->unk_3DA; + + this->skelAnime.animPlaybackSpeed = this->actor.speedXZ; + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 1, 250, 0); + Math_SmoothStepToS(&this->unk_3D8, 0, 1, 100, 0); + Math_SmoothStepToS(&this->unk_3DA, 0, 1, 100, 0); + this->actor.world.rot.y = this->actor.shape.rot.y; + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + + if (Actor_DistanceToPoint(&player->actor, &this->actor.home.pos) >= 150.0f) { + func_808D53C0(this, globalCtx); + } + + if ((ABS_ALT(sp36) < 0x1554) && (Actor_DistanceBetweenActors(&this->actor, &player->actor) <= 150.0f)) { + if (!(player->stateFlags1 & (0x200000 | 0x80000 | 0x40000 | 0x4000 | 0x2000 | 0x80)) && + !(player->stateFlags2 & 0x4080)) { + if (this->unk_3ED == 0) { + if (!(this->unk_3DC & 0x80)) { + player->actor.freezeTimer = 40; + func_80123E90(globalCtx, &this->actor); + PLAYER->unk_A78 = &this->actor; + func_8013ECE0(this->actor.xzDistToPlayer, 255, 20, 150); + } + this->unk_3ED = 60; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_AIM); + } + } else { + func_808D53C0(this, globalCtx); + } + } + + if (this->unk_3EE != 0) { + this->unk_3EE--; + } + + if (!this->unk_3EE && (Actor_DistanceBetweenActors(&this->actor, &player->actor) <= 45.0f) && + Actor_IsActorFacingLink(&this->actor, 0x38E3)) { + player->actor.freezeTimer = 0; + if ((player->transformation == PLAYER_FORM_GORON) || (player->transformation == PLAYER_FORM_DEKU)) { + if (Actor_DistanceToPoint(&this->actor, &this->actor.home.pos) < 150.0f) { + func_808D5D88(this); + } else { + func_808D53C0(this, globalCtx); + } + } else if (globalCtx->grabPlayer(globalCtx, player)) { + this->actor.flags &= ~1; + func_808D586C(this); + } + } else if (this->actor.params > ENRD_GET_0) { + if (this->actor.parent != NULL) { + func_808D5660(this); + } else { + this->unk_3EC = 0; + } + } + + if (func_801378B8(&this->skelAnime, 10.0f) || func_801378B8(&this->skelAnime, 22.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_WALK); + } else if ((globalCtx->gameplayFrames & 0x5F) == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + } +} + +void func_808D53C0(EnRd* this, GlobalContext* globalCtx) { + SkelAnime_ChangeAnim(&this->skelAnime, &D_060113EC, 0.5f, 0.0f, SkelAnime_GetFrameCount(&D_060113EC.common), 1, + -4.0f); + this->unk_3EF = 2; + this->actionFunc = func_808D5440; +} + +void func_808D5440(EnRd* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + s32 pad; + s16 sp36 = Actor_YawToPoint(&this->actor, &this->actor.home.pos); + + if (Actor_DistanceToPoint(&this->actor, &this->actor.home.pos) >= 5.0f) { + Math_SmoothStepToS(&this->actor.shape.rot.y, sp36, 1, 450, 0); + } else { + this->actor.speedXZ = 0.0f; + if (!Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 1, 450, 0)) { + if (this->actor.params != ENRD_GET_2) { + func_808D4308(this); + } else { + func_808D60B0(this); + } + } + } + + Math_SmoothStepToS(&this->unk_3D8, 0, 1, 100, 0); + Math_SmoothStepToS(&this->unk_3DA, 0, 1, 100, 0); + this->actor.world.rot.y = this->actor.shape.rot.y; + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + + if (!(player->stateFlags1 & (0x200000 | 0x80000 | 0x40000 | 0x4000 | 0x2000 | 0x80)) && + !(player->stateFlags2 & 0x4080) && (player->transformation != PLAYER_FORM_GORON) && + (player->transformation != PLAYER_FORM_DEKU) && + (Actor_DistanceToPoint(&player->actor, &this->actor.home.pos) < 150.0f)) { + this->actor.targetMode = 0; + func_808D4FE0(this, globalCtx); + } else if (this->actor.params > ENRD_GET_0) { + if (this->actor.parent != NULL) { + func_808D5660(this); + } else { + this->unk_3EC = 0; + } + } + + if (func_801378B8(&this->skelAnime, 10.0f) || func_801378B8(&this->skelAnime, 22.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_WALK); + } else if ((globalCtx->gameplayFrames & 0x5F) == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + } +} + +void func_808D5660(EnRd* this) { + f32 frameCount = SkelAnime_GetFrameCount(&D_060113EC.common); + + SkelAnime_ChangeAnim(&this->skelAnime, &D_060113EC, 0.5f, 0.0f, frameCount, 1, -4.0f); + this->unk_3EF = 3; + this->unk_3EC = 1; + this->actionFunc = func_808D56E4; +} + +void func_808D56E4(EnRd* this, GlobalContext* globalCtx) { + s32 pad; + s16 yaw; + Vec3f sp2C; + + if (this->actor.parent != NULL) { + sp2C = this->actor.parent->world.pos; + yaw = Actor_YawToPoint(&this->actor, &sp2C); + + Math_SmoothStepToS(&this->actor.shape.rot.y, yaw, 1, 250, 0); + if (Actor_DistanceToPoint(&this->actor, &sp2C) >= 45.0f) { + this->actor.speedXZ = 0.4f; + } else { + this->actor.speedXZ = 0.0f; + if (this->actor.params != ENRD_GET_2) { + func_808D4308(this); + } else { + func_808D60B0(this); + } + } + Math_SmoothStepToS(&this->unk_3D8, 0, 1, 100, 0); + Math_SmoothStepToS(&this->unk_3DA, 0, 1, 100, 0); + } else { + func_808D4FE0(this, globalCtx); + } + + this->actor.world.rot.y = this->actor.shape.rot.y; + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + + if (func_801378B8(&this->skelAnime, 10.0f) || func_801378B8(&this->skelAnime, 22.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_WALK); + } else if ((globalCtx->gameplayFrames & 0x5F) == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + } +} + +void func_808D586C(EnRd* this) { + SkelAnime_ChangeAnimDefaultStop(&this->skelAnime, &D_06006EEC); + this->unk_3D6 = 0; + this->unk_3EB = 0; + this->unk_3EA = 200; + this->unk_3EF = 10; + this->actor.speedXZ = 0.0f; + this->actionFunc = func_808D58CC; +} + +void func_808D58CC(EnRd* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + s32 pad; + + if (SkelAnime_FrameUpdateMatrix(&this->skelAnime)) { + this->unk_3EB++; + } + + switch (this->unk_3EB) { + case 1: + SkelAnime_ChangeAnimDefaultRepeat(&this->skelAnime, &D_06006678); + this->unk_3EB++; + globalCtx->damagePlayer(globalCtx, -8); + func_8013ECE0(this->actor.xzDistToPlayer, 255, 1, 12); + this->unk_3EA = 20; + + case 0: + Math_SmoothStepToS(&this->unk_3D8, 0, 1, 1500, 0); + Math_SmoothStepToS(&this->unk_3DA, 0, 1, 1500, 0); + + case 2: + if (!(player->stateFlags2 & 0x80) || (player->unk_B62 != 0)) { + if ((player->unk_B62 != 0) && (player->stateFlags2 & 0x80)) { + player->stateFlags2 &= ~0x80; + player->unk_AE8 = 100; + } + SkelAnime_ChangeAnim(&this->skelAnime, &D_06006B08, 0.5f, 0.0f, + SkelAnime_GetFrameCount(&D_06006B08.common), 3, 0.0f); + this->unk_3EB++; + this->unk_3EF = 4; + break; + } + + switch (player->transformation) { + case 0: + case 1: + case 2: + case 3: + break; + + case 4: + Math_SmoothStepToF(&this->actor.shape.yOffset, -1500.0f, 1.0f, 150.0f, 0.0f); + break; + } + + Math_SmoothStepToF(&this->actor.world.pos.x, + (Math_SinS(player->actor.shape.rot.y) * -25.0f) + player->actor.world.pos.x, 1.0f, 10.0f, + 0.0f); + Math_SmoothStepToF(&this->actor.world.pos.y, player->actor.world.pos.y, 1.0f, 10.0f, 0.0f); + Math_SmoothStepToF(&this->actor.world.pos.z, + (Math_CosS(player->actor.shape.rot.y) * -25.0f) + player->actor.world.pos.z, 1.0f, 10.0f, + 0.0f); + Math_SmoothStepToS(&this->actor.shape.rot.y, player->actor.shape.rot.y, 1, 6000, 0); + + if (func_801378B8(&this->skelAnime, 0.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_ATTACK); + } + + this->unk_3EA--; + if (this->unk_3EA == 0) { + globalCtx->damagePlayer(globalCtx, -8); + func_8013ECE0(this->actor.xzDistToPlayer, 240, 1, 12); + this->unk_3EA = 20; + func_800B8E58(&player->actor, player->ageProperties->unk_92 + 0x6805); + } + break; + + case 3: + if (player->transformation != PLAYER_FORM_FIERCE_DEITY) { + Math_SmoothStepToF(&this->actor.shape.yOffset, 0.0f, 1.0f, 400.0f, 0.0f); + } + break; + + case 4: + if (player->transformation != PLAYER_FORM_FIERCE_DEITY) { + Math_SmoothStepToF(&this->actor.shape.yOffset, 0.0f, 1.0f, 400.0f, 0.0f); + } + this->actor.targetMode = 0; + this->actor.flags |= 1; + this->unk_3ED = 10; + this->unk_3EE = 15; + func_808D4FE0(this, globalCtx); + break; + } +} + +void func_808D5C54(EnRd* this) { + SkelAnime_ChangeAnim(&this->skelAnime, &D_060073A4, 0.0f, 0.0f, SkelAnime_GetFrameCount(&D_060073A4.common), 2, + 0.0f); + this->unk_3EF = 7; + this->actionFunc = func_808D5CCC; +} + +void func_808D5CCC(EnRd* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + s16 temp_v0 = ((this->actor.yawTowardsPlayer - this->actor.shape.rot.y) - this->unk_3D8) - this->unk_3DA; + + if (ABS_ALT(temp_v0) < 0x2008) { + if (!(this->unk_3DC & 0x80)) { + player->actor.freezeTimer = 60; + func_8013ECE0(this->actor.xzDistToPlayer, 255, 20, 150); + func_80123E90(globalCtx, &this->actor); + } + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_AIM); + func_808D4FE0(this, globalCtx); + } +} + +void func_808D5D88(EnRd* this) { + this->unk_3EF = 8; + SkelAnime_ChangeAnimTransitionStop(&this->skelAnime, &D_06009900, -6.0f); + this->actor.speedXZ = -2.0f; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_DAMAGE); + this->unk_3EF = 8; + this->actionFunc = func_808D5DF4; +} + +void func_808D5DF4(EnRd* this, GlobalContext* globalCtx) { + if (this->actor.speedXZ < 0.0f) { + this->actor.speedXZ += 0.15f; + } + + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + Math_SmoothStepToS(&this->unk_3D8, 0, 1, 300, 0); + Math_SmoothStepToS(&this->unk_3DA, 0, 1, 300, 0); + if (SkelAnime_FrameUpdateMatrix(&this->skelAnime)) { + this->actor.world.rot.y = this->actor.shape.rot.y; + func_808D5E98(this); + } +} + +void func_808D5E98(EnRd* this) { + f32 frameCount = SkelAnime_GetFrameCount(&D_060113EC.common); + + SkelAnime_ChangeAnim(&this->skelAnime, &D_060113EC, 0.5f, 0.0f, frameCount, 1, -4.0f); + this->unk_3EF = 9; + this->unk_3D4 = 0; + this->actionFunc = func_808D5F18; +} + +void func_808D5F18(EnRd* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->actor.world.rot.y, BINANG_ROT180(this->actor.yawTowardsPlayer), 5, 3500, 200); + this->actor.shape.rot.y = this->actor.world.rot.y; + if (this->unk_3D4 > 60) { + func_808D53C0(this, globalCtx); + this->unk_3D4 = 0; + } else { + this->unk_3D8 = Math_SinS(this->unk_3D4 * 4000) * (9583.0f * ((60 - this->unk_3D4) / 60.0f)); + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + this->unk_3D4++; + } +} + +void func_808D6008(EnRd* this) { + SkelAnime_ChangeAnimTransitionStop(&this->skelAnime, &D_0600A450, -4.0f); + this->unk_3EF = 5; + this->actionFunc = func_808D6054; +} + +void func_808D6054(EnRd* this, GlobalContext* globalCtx) { + if (SkelAnime_FrameUpdateMatrix(&this->skelAnime)) { + if (this->actor.parent != NULL) { + func_808D5660(this); + } else { + func_808D5C54(this); + } + } +} + +void func_808D60B0(EnRd* this) { + SkelAnime_ChangeAnim(&this->skelAnime, &D_0600A450, -1.0f, SkelAnime_GetFrameCount(&D_0600A450.common), 0.0f, 2, + -4.0f); + this->unk_3EF = 6; + this->actionFunc = func_808D6130; +} + +void func_808D6130(EnRd* this, GlobalContext* globalCtx) { + if (SkelAnime_FrameUpdateMatrix(&this->skelAnime)) { + func_808D4308(this); + } +} + +void func_808D616C(EnRd* this) { + this->actor.shape.yOffset = 0.0f; + SkelAnime_ChangeAnimTransitionStop(&this->skelAnime, &D_06009900, -6.0f); + if (this->actor.bgCheckFlags & 1) { + this->actor.speedXZ = -2.0f; + } + + this->actor.flags |= 1; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_DAMAGE); + this->unk_3EF = 11; + this->actionFunc = func_808D6200; +} + +void func_808D6200(EnRd* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + + if (this->actor.speedXZ < 0.0f) { + this->actor.speedXZ += 0.15f; + } + + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + Math_SmoothStepToS(&this->unk_3D8, 0, 1, 300, 0); + Math_SmoothStepToS(&this->unk_3DA, 0, 1, 300, 0); + + if (SkelAnime_FrameUpdateMatrix(&this->skelAnime)) { + this->actor.world.rot.y = this->actor.shape.rot.y; + if (this->actor.parent != NULL) { + func_808D5660(this); + } else if (Actor_DistanceToPoint(&player->actor, &this->actor.home.pos) >= 150.0f) { + func_808D53C0(this, globalCtx); + } else { + func_808D4FE0(this, globalCtx); + } + this->unk_3F1 = -1; + } +} + +void func_808D6310(EnRd* this) { + SkelAnime_ChangeAnimTransitionStop(&this->skelAnime, &D_06009298, -1.0f); + this->unk_3EF = 12; + this->unk_3D6 = 300; + this->actor.flags &= ~1; + this->actor.speedXZ = 0.0f; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_DEAD); + this->actionFunc = func_808D6388; +} + +void func_808D6388(EnRd* this, GlobalContext* globalCtx) { + if (this->actor.category != 6) { + func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, 6); + } + + Math_SmoothStepToS(&this->unk_3D8, 0, 1, 2000, 0); + Math_SmoothStepToS(&this->unk_3DA, 0, 1, 2000, 0); + + if (SkelAnime_FrameUpdateMatrix(&this->skelAnime)) { + if (this->unk_3D6 == 0) { + if (!Flags_GetSwitch(globalCtx, this->unk_3DC & 0x7F)) { + Actor_SetSwitchFlag(globalCtx, this->unk_3DC & 0x7F); + } + + if (this->unk_3DE != 0) { + if (this->unk_3DE == 180) { + func_808D4190(globalCtx, this, 0); + } + this->actor.scale.y -= (75.0f / 1000000.0f); + this->unk_3DE -= 5; + } else { + Actor_MarkForDeath(&this->actor); + } + } else { + this->unk_3D6--; + } + } else if (func_801378B8(&this->skelAnime, 33.0f) || func_801378B8(&this->skelAnime, 40.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_GERUDOFT_DOWN); + } +} + +void func_808D64D0(EnRd* this) { + this->unk_3EF = 1; + this->unk_3D6 = 0xA; + this->actor.speedXZ = 0.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; + if (gSaveContext.unk_3F58 != 0) { + this->unk_3E9 = 1; + this->unk_3E0 = 600; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_LIGHT_ARROW_HIT); + func_800BCB70(&this->actor, 0x8000, 0x80C8, 0, 255); + } else if (this->unk_3F0 == 1) { + func_800BCB70(&this->actor, 0, 0xC8, 0, 40); + } else if (this->unk_3F0 == 12) { + func_800BCB70(&this->actor, 0, 0xC8, 0, 40); + } + this->actionFunc = func_808D65BC; +} + +void func_808D65BC(EnRd* this, GlobalContext* globalCtx) { + if (this->unk_3D6 > 0) { + this->unk_3D6--; + } + + if (this->unk_3E9 != 0) { + if (this->unk_3E0 != 0) { + this->unk_3E0--; + if (this->unk_3E0 >= 255) { + func_800BCB70(&this->actor, 0x8000, 0x80C8, 0, 255); + } + + if (this->unk_3E0 == 0) { + this->unk_3E9 = 0; + gSaveContext.unk_3F58 = 0; + } + } + } + + if (this->actor.colorFilterTimer == 0) { + if (this->actor.colChkInfo.health == 0) { + func_808D4190(globalCtx, this, 1); + func_808D6310(this); + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x90); + } else { + func_808D616C(this); + } + } +} + +void func_808D66A0(EnRd* this, GlobalContext* globalCtx) { + s16 phi_v0 = (this->actor.yawTowardsPlayer - this->actor.shape.rot.y) - this->unk_3DA; + s16 temp_v0 = CLAMP(phi_v0, -0x1F4, 0x1F4); + + phi_v0 -= this->unk_3D8; + phi_v0 = CLAMP(phi_v0, -0x1F4, 0x1F4); + + if (BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y) >= 0) { + this->unk_3DA += ABS_ALT(temp_v0); + this->unk_3D8 += ABS_ALT(phi_v0); + } else { + this->unk_3DA -= ABS_ALT(temp_v0); + this->unk_3D8 -= ABS_ALT(phi_v0); + } + + this->unk_3DA = CLAMP(this->unk_3DA, -0x495F, 0x495F); + this->unk_3D8 = CLAMP(this->unk_3D8, -0x256F, 0x256F); +} + +void func_808D6814(EnRd* this, GlobalContext* globalCtx) { + s32 pad; + Player* player = PLAYER; + + if ((gSaveContext.unk_3F58 != 0) && (this->actor.shape.rot.x == 0) && (this->unk_3E9 == 0) && + (this->unk_3EF != 11) && (this->unk_3EF != 12) && (this->unk_3EF != 1)) { + func_808D64D0(this); + return; + } + + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + this->unk_3F0 = this->actor.colChkInfo.damageEffect; + + if (this->unk_3EF == 13) { + return; + } + + func_800BE258(&this->actor, &this->collider.info); + + if (player->unk_ADC != 0) { + this->unk_3F1 = player->unk_ADD; + } + + switch (this->unk_3F0) { + case 12: + if ((this->actionFunc != func_808D58CC) && + ((this->actionFunc != func_808D65BC) || (this->unk_3D6 == 0))) { + this->unk_3E6 = 40; + this->unk_3E8 = 30; + this->unk_294 = 1.0f; + func_808D64D0(this); + } + return; + + case 1: + func_808D64D0(this); + return; + + case 2: + func_800BCB70(&this->actor, 0x4000, 255, 0, 40); + this->unk_3E6 = 180; + this->unk_3E8 = 0; + this->unk_3E9 = 0; + this->unk_3E0 = 0; + this->unk_294 = 1.0f; + break; + + case 4: + func_800BCB70(&this->actor, 0x4000, 255, 0, 40); + this->unk_3E6 = 60; + this->unk_3E8 = 20; + this->unk_3E9 = 0; + this->unk_3E0 = 0; + this->unk_294 = 1.0f; + break; + + case 15: + func_800BCB70(&this->actor, 0x4000, 255, 0, 8); + this->unk_3E9 = 0; + this->unk_3E0 = 0; + break; + + case 14: + func_800BCB70(&this->actor, 0x4000, 255, 0, 8); + this->unk_3E9 = 0; + this->unk_3E0 = 0; + this->actor.colChkInfo.health = 0; + break; + + default: + return; + } + + Actor_ApplyDamage(&this->actor); + if (this->actor.colChkInfo.health == 0) { + func_808D4190(globalCtx, this, 1); + func_808D6310(this); + Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.world.pos, 0x90); + } else { + func_808D616C(this); + } + } +} + +void func_808D6A94(EnRd* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + + if ((this->actor.colChkInfo.health > 0) && (this->unk_3EF != 10)) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + if (((this->unk_3EF != 11) || ((player->unk_ADC != 0) && (player->unk_ADD != this->unk_3F1))) && + ((this->actionFunc != func_808D65BC) || (this->unk_3D6 == 0))) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + } +} + +void func_808D6B64(EnRd* this, GlobalContext* globalCtx) { + if (this->unk_3E6 > 0) { + this->unk_3E6--; + } + + if (this->unk_3E6 < 20) { + Math_SmoothStepToF(&this->unk_298, 0.0f, 0.5f, 0.03f, 0.0f); + this->unk_294 = this->unk_3E6 * 0.05f; + } else { + Math_SmoothStepToF(&this->unk_298, 0.5f, 0.1f, 0.02f, 0.0f); + } +} + +void EnRd_Update(Actor* thisx, GlobalContext* globalCtx) { + EnRd* this = THIS; + + func_808D6814(this, globalCtx); + if ((gSaveContext.unk_3F58 != 0) && (this->unk_3E9 == 0)) { + gSaveContext.unk_3F58 = 0; + } + + if ((this->unk_3F0 != 6) && ((this->unk_3EF != 13) || (this->unk_3F0 != 2))) { + if (this->unk_3ED != 0) { + this->unk_3ED--; + } + + this->actionFunc(this, globalCtx); + + if ((this->unk_3EF != 10) && (this->actor.speedXZ != 0.0f)) { + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + } + + if ((this->actor.shape.rot.x == 0) && (this->unk_3EF != 10) && (this->actor.speedXZ != 0.0f)) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 20.0f, 35.0f, 0x1D); + } + + if (this->unk_3EF == 7) { + func_808D66A0(this, globalCtx); + } + } + + this->actor.focus.pos = this->actor.world.pos; + this->actor.focus.pos.y += 50.0f; + func_808D6A94(this, globalCtx); + func_808D4260(this, globalCtx); + func_808D6B64(this, globalCtx); +} + +s32 EnRd_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, + Gfx** gfx) { + EnRd* this = THIS; + + if (limbIndex == 23) { + rot->y += this->unk_3D8; + } else if (limbIndex == 12) { + rot->y += this->unk_3DA; + } + return false; +} + +void EnRd_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { + EnRd* this = THIS; + + if ((this->unk_3E6 != 0) && + ((limbIndex == 3) || (limbIndex == 4) || (limbIndex == 6) || (limbIndex == 8) || (limbIndex == 9) || + (limbIndex == 11) || (limbIndex == 14) || (limbIndex == 16) || (limbIndex == 17) || (limbIndex == 18) || + (limbIndex == 20) || (limbIndex == 21) || (limbIndex == 22) || (limbIndex == 24) || (limbIndex == 25))) { + SysMatrix_GetStateTranslation(&this->unk_1DC[this->unk_290]); + this->unk_290++; + } +} + +void EnRd_Draw(Actor* thisx, GlobalContext* globalCtx) { + static Vec3f D_808D7138 = { 0.25f, 0.25f, 0.25f }; + s32 pad; + EnRd* this = THIS; + Vec3f sp54 = this->actor.world.pos; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + this->unk_290 = 0; + + if (this->unk_3DE == 255) { + func_8012C28C(globalCtx->state.gfxCtx); + + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, this->unk_3DE); + gSPSegment(POLY_OPA_DISP++, 0x08, D_801AEFA0); + + POLY_OPA_DISP = SkelAnime_DrawSV2(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, + this->skelAnime.dListCount, EnRd_OverrideLimbDraw, EnRd_PostLimbDraw, + &this->actor, POLY_OPA_DISP); + + func_800BC620(&sp54, &D_808D7138, 255, globalCtx); + } else { + func_8012C2DC(globalCtx->state.gfxCtx); + + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->unk_3DE); + gSPSegment(POLY_XLU_DISP++, 0x08, D_801AEF88); + + POLY_XLU_DISP = + SkelAnime_DrawSV2(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, + this->skelAnime.dListCount, EnRd_OverrideLimbDraw, NULL, &this->actor, POLY_XLU_DISP); + func_800BC620(&sp54, &D_808D7138, this->unk_3DE, globalCtx); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + if (this->unk_3E6 > 0) { + func_800BE680(globalCtx, &this->actor, this->unk_1DC, ARRAY_COUNT(this->unk_1DC), this->unk_298, 0.5f, + this->unk_294, this->unk_3E8); + } +} diff --git a/src/overlays/actors/ovl_En_Rd/z_en_rd.h b/src/overlays/actors/ovl_En_Rd/z_en_rd.h index 69d723450..2c6637d76 100644 --- a/src/overlays/actors/ovl_En_Rd/z_en_rd.h +++ b/src/overlays/actors/ovl_En_Rd/z_en_rd.h @@ -6,12 +6,54 @@ struct EnRd; typedef void (*EnRdActionFunc)(struct EnRd*, GlobalContext*); +typedef void (*EnRdFunc)(struct EnRd*); + +#define ENRD_GET_80(thisx) ((thisx)->params & 0x80) +#define ENRD_GET_FF00(thisx) (((thisx)->params & 0xFF00) >> 8) + +enum { + /* -2 */ ENRD_GET_MINUS_2 = -2, + /* -1 */ ENRD_GET_MINUS_1 = -1, + /* 0x00 */ ENRD_GET_0 = 0, + /* 0x01 */ ENRD_GET_1, + /* 0x02 */ ENRD_GET_2, + /* 0x03 */ ENRD_GET_3, + /* 0x04 */ ENRD_GET_4, + /* 0x05 */ ENRD_GET_5, +}; typedef struct EnRd { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnRdActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x268]; + /* 0x018C */ EnRdFunc unkFunc; + /* 0x0190 */ ColliderCylinder collider; + /* 0x01DC */ Vec3f unk_1DC[15]; + /* 0x0290 */ s32 unk_290; + /* 0x0294 */ f32 unk_294; + /* 0x0298 */ f32 unk_298; + /* 0x029C */ Vec3s jointTable[26]; + /* 0x0338 */ Vec3s morphTable[26]; + /* 0x03D4 */ s16 unk_3D4; + /* 0x03D6 */ s16 unk_3D6; + /* 0x03D8 */ s16 unk_3D8; + /* 0x03DA */ s16 unk_3DA; + /* 0x03DC */ s16 unk_3DC; + /* 0x03DE */ s16 unk_3DE; + /* 0x03E0 */ s16 unk_3E0; + /* 0x03E2 */ s16 unk_3E2; + /* 0x03E4 */ s16 unk_3E4; + /* 0x03E6 */ s16 unk_3E6; + /* 0x03E8 */ u8 unk_3E8; + /* 0x03E9 */ u8 unk_3E9; + /* 0x03EA */ u8 unk_3EA; + /* 0x03EB */ u8 unk_3EB; + /* 0x03EC */ u8 unk_3EC; + /* 0x03ED */ u8 unk_3ED; + /* 0x03EE */ u8 unk_3EE; + /* 0x03EF */ u8 unk_3EF; + /* 0x03F0 */ u8 unk_3F0; + /* 0x03F1 */ s8 unk_3F1; } EnRd; // size = 0x3F4 extern const ActorInit En_Rd_InitVars; diff --git a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c index fa872c109..eb7f9910a 100644 --- a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c +++ b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c @@ -1144,7 +1144,7 @@ void func_80BAD230(EnSuttari* this, GlobalContext* globalCtx) { this->textId = 0x2A31; func_801518B0(globalCtx, this->textId, &this->actor); this->flags1 |= 0x4000; - func_801A89A8(0x8003); + Audio_QueueSeqCmd(0x8003); this->actionFunc = func_80BAD380; } else { ActorCutscene_SetIntentToPlay(this->cutscenes[1]); @@ -1205,7 +1205,7 @@ void func_80BAD380(EnSuttari* this, GlobalContext* globalCtx) { gSaveContext.weekEventReg[0x21] |= 8; } this->actor.speedXZ = 0.0f; - func_801A89A8(0x101400FF); + Audio_QueueSeqCmd(0x101400FF); this->flags2 |= 4; EnSuttari_SetNextEntrance(globalCtx, 0xD670); } else { @@ -1438,7 +1438,7 @@ void EnSuttari_Destroy(Actor* thisx, GlobalContext* globalCtx) { EnSuttari* this = THIS; if ((globalCtx->sceneNum == SCENE_BACKTOWN) && !(this->flags2 & 4)) { - func_801A89A8(0x101400FF); + Audio_QueueSeqCmd(0x101400FF); } Collider_DestroyCylinder(globalCtx, &this->collider); } diff --git a/src/overlays/actors/ovl_En_Test4/z_en_test4.c b/src/overlays/actors/ovl_En_Test4/z_en_test4.c index 05bcb647d..1abbd9617 100644 --- a/src/overlays/actors/ovl_En_Test4/z_en_test4.c +++ b/src/overlays/actors/ovl_En_Test4/z_en_test4.c @@ -1,4 +1,12 @@ +/* + * File: z_en_test4.c + * Overlay: ovl_En_Test4 + * Description: Day transition effects + */ + #include "z_en_test4.h" +#include "overlays/gamestates/ovl_daytelop/z_daytelop.h" +#include "overlays/actors/ovl_En_Horse/z_en_horse.h" #define FLAGS 0x00100030 @@ -11,7 +19,6 @@ void EnTest4_Update(Actor* thisx, GlobalContext* globalCtx); void func_80A42AB8(EnTest4* this, GlobalContext* globalCtx); void func_80A42F20(EnTest4* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Test4_InitVars = { ACTOR_EN_TEST4, ACTORCAT_SWITCH, @@ -24,28 +31,558 @@ const ActorInit En_Test4_InitVars = { (ActorFunc)NULL, }; +static s32 sIsLoaded = false; +// "Night of ..." +static s16 sNightMessages1[] = { 0x1BB4, 0x1BB5, 0x1BB6 }; +// "Dawn of ..." (Note: first two message are the same) +static s16 sDayMessages1[] = { 0x1BB2, 0x1BB2, 0x1BB3 }; +// "Night of ..." +static s16 sNightMessages2[] = { 0x1BB4, 0x1BB5, 0x1BB6 }; +// "Dawn of ..." (Note: first two message are the same) +static s16 sDayMessages2[] = { 0x1BB2, 0x1BB2, 0x1BB3 }; +static u16 D_80A43364[] = { CLOCK_TIME(6, 0), CLOCK_TIME(18, 0) }; + +static s16 sCutscenes[2]; +static s16 sCurrentCs; + +void func_80A41D70(EnTest4* this, GlobalContext* globalCtx) { + if (this->unk_144 != 0) { + func_80151A68(globalCtx, sNightMessages1[CURRENT_DAY - 1]); + } else if ((sCutscenes[this->unk_144] < 0) || ((globalCtx->actorCtx.unk5 & 2) != 0)) { + if (globalCtx->actorCtx.unk5 & 2) { + Sram_IncrementDay(); + gSaveContext.time = CLOCK_TIME(6, 0); + func_80151A68(globalCtx, sDayMessages1[CURRENT_DAY - 1]); + } else { + this->unk_144 = 0; + this->unk_146 = gSaveContext.time += CLOCK_TIME_MINUTE; + } + + func_8010EE74(globalCtx, CURRENT_DAY); + D_801BDBC8 = 0xFE; + func_800FB758(globalCtx); + func_800FEAF4(&globalCtx->envCtx); + this->actionFunc = func_80A42AB8; + } + + if (gSaveContext.cutsceneTrigger == 0) { + if ((sCutscenes[this->unk_144] >= 0) && !(globalCtx->actorCtx.unk5 & 2)) { + this->actionFunc = func_80A42F20; + sCurrentCs = sCutscenes[this->unk_144]; + this->transitionCsTimer = 0; + gSaveContext.eventInf[1] |= 0x80; + } else if (this->unk_144 == 0) { + play_sound(NA_SE_EV_CHICKEN_CRY_M); + } else { + func_8019F128(NA_SE_EV_DOG_CRY_EVENING); + } + } else { + this->actionFunc = func_80A42AB8; + if (this->unk_144 == 0) { + this->unk_144 = 1; + } else { + this->unk_144 = 0; + } + + this->unk_146 = gSaveContext.time += CLOCK_TIME_MINUTE; + } +} + +void func_80A41FA4(EnTest4* this, GlobalContext* globalCtx) { + if (this->unk_144 != 0) { + func_80151A68(globalCtx, sNightMessages2[CURRENT_DAY - 1]); + } else if ((sCutscenes[this->unk_144] < 0) || ((globalCtx->actorCtx.unk5 & 2) != 0)) { + Sram_IncrementDay(); + gSaveContext.time = CLOCK_TIME(6, 0); + func_8010EE74(globalCtx, CURRENT_DAY); + func_80151A68(globalCtx, sDayMessages2[CURRENT_DAY - 1]); + D_801BDBC8 = 0xFE; + func_800FB758(globalCtx); + func_800FEAF4(&globalCtx->envCtx); + this->actionFunc = func_80A42AB8; + } + + if (gSaveContext.cutsceneTrigger == 0) { + if ((sCutscenes[this->unk_144] >= 0) && ((globalCtx->actorCtx.unk5 & 2) == 0)) { + this->actionFunc = func_80A42F20; + sCurrentCs = sCutscenes[this->unk_144]; + this->transitionCsTimer = 0; + gSaveContext.eventInf[1] |= 0x80; + } else if (this->unk_144 == 0) { + play_sound(NA_SE_EV_CHICKEN_CRY_M); + } else { + func_8019F128(NA_SE_EV_DOG_CRY_EVENING); + } + } else { + this->actionFunc = func_80A42AB8; + if (this->unk_144 == 0) { + this->unk_144 = 1; + } else { + this->unk_144 = 0; + } + + this->unk_146 = gSaveContext.time += CLOCK_TIME_MINUTE; + } +} + +// Bells on last day +void func_80A42198(EnTest4* this) { + if ((gSaveContext.time >= CLOCK_TIME(6, 0)) && (gSaveContext.time <= CLOCK_TIME(18, 0))) { + if (gSaveContext.time < CLOCK_TIME(17, 30)) { + this->nextBellTime = CLOCK_TIME(17, 30); + } else if (gSaveContext.time < CLOCK_TIME(17, 36)) { + this->nextBellTime = CLOCK_TIME(17, 36); + } else if (gSaveContext.time < CLOCK_TIME(17, 42)) { + this->nextBellTime = CLOCK_TIME(17, 42); + } else if (gSaveContext.time < CLOCK_TIME(17, 48)) { + this->nextBellTime = CLOCK_TIME(17, 48); + } else if (gSaveContext.time < CLOCK_TIME(17, 54)) { + this->nextBellTime = CLOCK_TIME(17, 54); + } else { + this->nextBellTime = CLOCK_TIME(0, 0); + } + } else if (gSaveContext.time > CLOCK_TIME(6, 0)) { + this->nextBellTime = CLOCK_TIME(0, 0); + } else if (gSaveContext.time < CLOCK_TIME(0, 10)) { + this->nextBellTime = CLOCK_TIME(0, 10); + } else if (gSaveContext.time < CLOCK_TIME(0, 20)) { + this->nextBellTime = CLOCK_TIME(0, 20); + } else if (gSaveContext.time < CLOCK_TIME(0, 30)) { + this->nextBellTime = CLOCK_TIME(0, 30); + } else if (gSaveContext.time < CLOCK_TIME(0, 40)) { + this->nextBellTime = CLOCK_TIME(0, 40); + } else if (gSaveContext.time < CLOCK_TIME(0, 50)) { + this->nextBellTime = CLOCK_TIME(0, 50); + } else if (gSaveContext.time < CLOCK_TIME(1, 0)) { + this->nextBellTime = CLOCK_TIME(1, 0); + } else if (gSaveContext.time < CLOCK_TIME(1, 10)) { + this->nextBellTime = CLOCK_TIME(1, 10); + } else if (gSaveContext.time < CLOCK_TIME(1, 20)) { + this->nextBellTime = CLOCK_TIME(1, 20); + } else if (gSaveContext.time < CLOCK_TIME(1, 30) - 1) { + this->nextBellTime = CLOCK_TIME(1, 30) - 1; + } else if (gSaveContext.time < CLOCK_TIME(1, 40) - 1) { + this->nextBellTime = CLOCK_TIME(1, 40) - 1; + } else if (gSaveContext.time < CLOCK_TIME(1, 50) - 1) { + this->nextBellTime = CLOCK_TIME(1, 50) - 1; + } else if (gSaveContext.time < CLOCK_TIME(2, 0)) { + this->nextBellTime = CLOCK_TIME(2, 0); + } else if (gSaveContext.time < CLOCK_TIME(2, 10)) { + this->nextBellTime = CLOCK_TIME(2, 10); + } else if (gSaveContext.time < CLOCK_TIME(2, 20)) { + this->nextBellTime = CLOCK_TIME(2, 20); + } else if (gSaveContext.time < CLOCK_TIME(2, 30)) { + this->nextBellTime = CLOCK_TIME(2, 30); + } else if (gSaveContext.time < CLOCK_TIME(2, 40)) { + this->nextBellTime = CLOCK_TIME(2, 40); + } else if (gSaveContext.time < CLOCK_TIME(2, 50)) { + this->nextBellTime = CLOCK_TIME(2, 50); + } else if (gSaveContext.time < CLOCK_TIME(3, 0)) { + this->nextBellTime = CLOCK_TIME(3, 0); + } else if (gSaveContext.time < CLOCK_TIME(3, 10)) { + this->nextBellTime = CLOCK_TIME(3, 10); + } else if (gSaveContext.time < CLOCK_TIME(3, 20)) { + this->nextBellTime = CLOCK_TIME(3, 20); + } else if (gSaveContext.time < CLOCK_TIME(3, 30)) { + this->nextBellTime = CLOCK_TIME(3, 30); + } else if (gSaveContext.time < CLOCK_TIME(3, 40)) { + this->nextBellTime = CLOCK_TIME(3, 40); + } else if (gSaveContext.time < CLOCK_TIME(3, 50)) { + this->nextBellTime = CLOCK_TIME(3, 50); + } else if (gSaveContext.time < CLOCK_TIME(4, 0)) { + this->nextBellTime = CLOCK_TIME(4, 0); + } else if (gSaveContext.time < CLOCK_TIME(4, 10)) { + this->nextBellTime = CLOCK_TIME(4, 10); + } else if (gSaveContext.time < CLOCK_TIME(4, 20)) { + this->nextBellTime = CLOCK_TIME(4, 20); + } else if (gSaveContext.time < CLOCK_TIME(4, 30) - 1) { + this->nextBellTime = CLOCK_TIME(4, 30) - 1; + } else if (gSaveContext.time < CLOCK_TIME(4, 40) - 1) { + this->nextBellTime = CLOCK_TIME(4, 40) - 1; + } else if (gSaveContext.time < CLOCK_TIME(4, 50) - 1) { + this->nextBellTime = CLOCK_TIME(4, 50) - 1; + } else if (gSaveContext.time < CLOCK_TIME(5, 0)) { + this->nextBellTime = CLOCK_TIME(5, 0); + } else if (gSaveContext.time < CLOCK_TIME(5, 5)) { + this->nextBellTime = CLOCK_TIME(5, 5); + } else if (gSaveContext.time < CLOCK_TIME(5, 10)) { + this->nextBellTime = CLOCK_TIME(5, 10); + } else if (gSaveContext.time < CLOCK_TIME(5, 15) - 1) { + this->nextBellTime = CLOCK_TIME(5, 15) - 1; + } else if (gSaveContext.time < CLOCK_TIME(5, 20)) { + this->nextBellTime = CLOCK_TIME(5, 20); + } else if (gSaveContext.time < CLOCK_TIME(5, 25) - 1) { + this->nextBellTime = CLOCK_TIME(5, 25) - 1; + } else if (gSaveContext.time < CLOCK_TIME(5, 30)) { + this->nextBellTime = CLOCK_TIME(5, 30); + } else if (gSaveContext.time < CLOCK_TIME(5, 33) - 1) { + this->nextBellTime = CLOCK_TIME(5, 33) - 1; + } else if (gSaveContext.time < CLOCK_TIME(5, 36)) { + this->nextBellTime = CLOCK_TIME(5, 36); + } else if (gSaveContext.time < CLOCK_TIME(5, 39) - 1) { + this->nextBellTime = CLOCK_TIME(5, 39) - 1; + } else if (gSaveContext.time < CLOCK_TIME(5, 42)) { + this->nextBellTime = CLOCK_TIME(5, 42); + } else if (gSaveContext.time < CLOCK_TIME(5, 45)) { + this->nextBellTime = CLOCK_TIME(5, 45); + } else if (gSaveContext.time < CLOCK_TIME(5, 48)) { + this->nextBellTime = CLOCK_TIME(5, 48); + } else if (gSaveContext.time < CLOCK_TIME(5, 51)) { + this->nextBellTime = CLOCK_TIME(5, 51); + } else if (gSaveContext.time < CLOCK_TIME(5, 54)) { + this->nextBellTime = CLOCK_TIME(5, 54); + } else if (gSaveContext.time < CLOCK_TIME(5, 57)) { + this->nextBellTime = CLOCK_TIME(5, 57); + } else if (gSaveContext.time < CLOCK_TIME(6, 0)) { + this->nextBellTime = CLOCK_TIME(6, 0); + } +} + +// Bells on first and second day +void func_80A425E4(EnTest4* this, GlobalContext* globalCtx) { + gSaveContext.unk_3F64 = 1000.0f; + + if ((gSaveContext.time >= CLOCK_TIME(6, 0)) && (gSaveContext.time < CLOCK_TIME(18, 0))) { + if (gSaveContext.time < CLOCK_TIME(17, 30)) { + this->nextBellTime = CLOCK_TIME(17, 30); + } else if (gSaveContext.time < CLOCK_TIME(17, 36)) { + this->nextBellTime = CLOCK_TIME(17, 36); + } else if (gSaveContext.time < CLOCK_TIME(17, 42)) { + this->nextBellTime = CLOCK_TIME(17, 42); + } else if (gSaveContext.time < CLOCK_TIME(17, 48)) { + this->nextBellTime = CLOCK_TIME(17, 48); + } else if (gSaveContext.time < CLOCK_TIME(17, 54)) { + this->nextBellTime = CLOCK_TIME(17, 54); + } else { + this->nextBellTime = CLOCK_TIME(5, 30); + } + } else { + if (gSaveContext.time < CLOCK_TIME(5, 30)) { + this->nextBellTime = CLOCK_TIME(5, 30); + } else if (gSaveContext.time < CLOCK_TIME(5, 36)) { + this->nextBellTime = CLOCK_TIME(5, 36); + } else if (gSaveContext.time < CLOCK_TIME(5, 42)) { + this->nextBellTime = CLOCK_TIME(5, 42); + gSaveContext.unk_3F64 -= 50.0f; + } else if (gSaveContext.time < CLOCK_TIME(5, 48)) { + this->nextBellTime = CLOCK_TIME(5, 48); + gSaveContext.unk_3F64 -= 100.0f; + } else if (gSaveContext.time < CLOCK_TIME(5, 54)) { + this->nextBellTime = CLOCK_TIME(5, 54); + gSaveContext.unk_3F64 -= 150.0f; + } else if (gSaveContext.time < CLOCK_TIME(6, 0)) { + this->nextBellTime = CLOCK_TIME(17, 30); + gSaveContext.unk_3F64 -= 200.0f; + } else { + this->nextBellTime = CLOCK_TIME(17, 30); + } + + if ((sCutscenes[this->unk_144] < 0) || ((globalCtx->actorCtx.unk5 & 2) != 0) || (CURRENT_DAY == 3) || + (gSaveContext.time >= CLOCK_TIME(17, 0))) { + gSaveContext.unk_3F64 = 1000.0f; + } + if (gSaveContext.unk_3F64 != 1000.0f) { + gSaveContext.unk_3F60 = 1; + } + } +} + +#ifdef NON_MATCHING +// 1 instruction in the wrong place +void EnTest4_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 dayTemp; + EnTest4* this = THIS; + Player* player = PLAYER; + s8 temp_v0 = this->actor.cutscene; + + sCutscenes[0] = temp_v0; + if (temp_v0 >= 0) { + ActorCutscene* temp_v0_2 = ActorCutscene_GetCutscene(sCutscenes[0]); + + gSaveContext.eventInf[5] |= 0x4; + sCutscenes[1] = temp_v0_2->additionalCutscene; + } else { + gSaveContext.eventInf[5] &= (u8)~0x4; + sCutscenes[1] = sCutscenes[0]; + } + + if (sIsLoaded || (gSaveContext.eventInf[2] & 0x80)) { + Actor_MarkForDeath(&this->actor); + } else { + sIsLoaded = true; + this->actor.room = -1; + gSaveContext.unk_3F60 = 0; + gSaveContext.unk_3F64 = 1000.0f; + if (CURRENT_DAY == 0) { + if (gSaveContext.time < CLOCK_TIME(6, 1)) { + gSaveContext.time = CLOCK_TIME(6, 0); + gSaveContext.gameMode = 0; + do { + GameState* state = &globalCtx->state; + state->running = false; + } while (0); + SET_NEXT_GAMESTATE(&globalCtx->state, Daytelop_Init, DaytelopContext); + this->unk_144 = 1; + gSaveContext.time = CLOCK_TIME(6, 0); + Actor_MarkForDeath(&this->actor); + } else { + gSaveContext.day = 1; + dayTemp = gSaveContext.day; + gSaveContext.daysElapsed = dayTemp; + this->unk_144 = 1; + this->unk_146 = gSaveContext.time; + this->actionFunc = func_80A42AB8; + } + } else if (gSaveContext.time == CLOCK_TIME(6, 0)) { + this->unk_144 = 0; + func_80A41D70(this, globalCtx); + if ((gSaveContext.cutsceneTrigger == 0) && (sCutscenes[this->unk_144] >= 0) && + !(globalCtx->actorCtx.unk5 & 2)) { + player->stateFlags1 |= 0x200; + } + } else { + if ((gSaveContext.time > CLOCK_TIME(18, 0)) || (gSaveContext.time < CLOCK_TIME(6, 0))) { + this->unk_144 = 0; + } else { + this->unk_144 = 1; + } + this->unk_146 = gSaveContext.time; + this->actionFunc = func_80A42AB8; + } + } + + if (CURRENT_DAY == 3) { + func_80A42198(this); + } else { + func_80A425E4(this, globalCtx); + } + + this->lastBellTime = gSaveContext.time; + if ((sCutscenes[this->unk_144] < 0) || (globalCtx->actorCtx.unk5 & 2)) { + gSaveContext.unk_3F60 = 0; + gSaveContext.unk_3F64 = 1000.0f; + } +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test4/EnTest4_Init.s") #endif -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test4/func_80A41D70.s") +void EnTest4_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test4/func_80A41FA4.s") +void func_80A42AB8(EnTest4* this, GlobalContext* globalCtx) { + Player* player = PLAYER; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test4/func_80A42198.s") + if ((globalCtx->unk_18B4A == 0) && (func_801690CC(globalCtx) == 0) && (globalCtx->numSetupActors <= 0) && + (globalCtx->roomCtx.unk31 == 0) && (func_8016A168() == 0)) { + s16 temp_a2; + u16 temp_a0 = D_80A43364[this->unk_144]; + s16 temp_a3; + s16 bellDiff; + s16 new_var; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test4/func_80A425E4.s") + temp_a3 = gSaveContext.time - temp_a0; + temp_a2 = this->unk_146 - temp_a0; + bellDiff = this->lastBellTime - this->nextBellTime; + new_var = gSaveContext.time - this->nextBellTime; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test4/EnTest4_Init.s") + if ((temp_a3 * temp_a2) <= 0) { + gSaveContext.unk_3CA7 = 1; + if (globalCtx->actorCtx.unk5 & 0x4) { + globalCtx->actorCtx.unk5 &= ~0x4; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test4/EnTest4_Destroy.s") + if (temp_a0 != CLOCK_TIME(6, 0)) { + func_80A41FA4(this, globalCtx); + } else if (temp_a0 == CLOCK_TIME(6, 0)) { + if (CURRENT_DAY == 3) { + func_8011C808(globalCtx); + Actor_MarkForDeath(&this->actor); + gSaveContext.eventInf[1] |= 0x80; + } else if (((sCutscenes[this->unk_144] < 0) || (globalCtx->actorCtx.unk5 & 2)) && CURRENT_DAY != 3) { + func_80A41FA4(this, globalCtx); + } else { + gSaveContext.unk_3F64 = 0.0f; + func_80169DCC(globalCtx, 0, Entrance_CreateIndexFromSpawn(0), player->unk_3CE, 0xBFF, + &player->unk_3C0, player->unk_3CC); + func_80169EFC(globalCtx); + if (player->stateFlags1 & 0x800000) { + EnHorse* rideActor = (EnHorse*)player->rideActor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test4/func_80A42AB8.s") + if ((rideActor->unk_150 == 0) || (rideActor->unk_150 == 2)) { + if (CURRENT_DAY < 3) { + D_801BDA9C = 1; + } else { + D_801BDA9C = 0; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test4/func_80A42F20.s") + gSaveContext.respawnFlag = -4; + gSaveContext.eventInf[2] |= 0x80; + Actor_MarkForDeath(&this->actor); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test4/func_80A430C8.s") + if ((sCutscenes[this->unk_144] >= 0) && ((globalCtx->actorCtx.unk5 & 2) == 0)) { + player->stateFlags1 |= 0x200; + this->unk_146 = gSaveContext.time; + } else { + if (this->unk_144 == 0) { + this->unk_144 = 1; + } else { + this->unk_144 = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test4/func_80A431C8.s") + this->unk_146 = gSaveContext.time += CLOCK_TIME_MINUTE; + } + } else if ((new_var * bellDiff) <= 0) { + func_801A0124(&this->actor.projectedPos, (this->actor.params >> 5) & 0xF); + this->lastBellTime = gSaveContext.time; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test4/func_80A4323C.s") + if (CURRENT_DAY == 3) { + if ((this->nextBellTime == CLOCK_TIME(0, 0)) && + ((gSaveContext.inventory.items[ITEM_OCARINA] == ITEM_NONE) || + (globalCtx->sceneNum == SCENE_CLOCKTOWER))) { + s32 phi_v0; + u32 entranceIndex = gSaveContext.entranceIndex; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test4/EnTest4_Update.s") + if ((globalCtx->actorCtx.unk5 & 2)) { + phi_v0 = 0xCFF; + } else { + phi_v0 = 0xBFF; + } + func_80169DCC(globalCtx, 1, entranceIndex, player->unk_3CE, phi_v0, &player->unk_3C0, + player->unk_3CC); + + if ((globalCtx->sceneNum == SCENE_TENMON_DAI) || (globalCtx->sceneNum == SCENE_00KEIKOKU)) { + globalCtx->nextEntranceIndex = 0x5400; + } else { + globalCtx->nextEntranceIndex = 0xD800; + } + gSaveContext.nextCutsceneIndex = 0xFFF1; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 2; + player->stateFlags1 |= 0x200; + Actor_MarkForDeath(&this->actor); + } + func_80A42198(this); + } else { + func_80A425E4(this, globalCtx); + } + } + } +} + +void func_80A42F20(EnTest4* this, GlobalContext* globalCtx) { + if (!this->transitionCsTimer) { + if (sCurrentCs >= 0) { + if (ActorCutscene_GetCanPlayNext(sCurrentCs) == 0) { + ActorCutscene_SetIntentToPlay(sCurrentCs); + } else { + ActorCutscene_Start(sCurrentCs, &this->actor); + this->transitionCsTimer = 1; + } + } else { + this->transitionCsTimer = 1; + } + } else if (this->transitionCsTimer < 60) { + this->transitionCsTimer++; + if (this->transitionCsTimer == 10) { + if (this->unk_144 == 0) { + play_sound(NA_SE_EV_CHICKEN_CRY_M); + } else { + func_8019F128(NA_SE_EV_DOG_CRY_EVENING); + } + } + if (this->transitionCsTimer == 60) { + Player* player = PLAYER; + + gSaveContext.time += CLOCK_TIME_MINUTE; + this->unk_146 = gSaveContext.time; + globalCtx->numSetupActors = -globalCtx->numSetupActors; + player->stateFlags1 &= ~0x200; + } + } else { + this->actionFunc = func_80A42AB8; + if (this->unk_144 == 0) { + this->unk_144 = 1; + } else { + this->unk_144 = 0; + } + + if (sCurrentCs >= 0) { + ActorCutscene_Stop(sCurrentCs); + } + gSaveContext.unk_3F22 = 0; + gSaveContext.eventInf[1] &= (u8)~0x80; + Interface_ChangeAlpha(50); + } +} + +void func_80A430C8(EnTest4* this, GlobalContext* globalCtx) { + if ((CURRENT_DAY == 2) && (gSaveContext.time >= CLOCK_TIME(7, 0)) && (gSaveContext.time < CLOCK_TIME(17, 30)) && + (globalCtx->envCtx.unk_F2[2] == 0)) { + // rain? + + D_801BDBB0 = 1; + func_800FD78C(globalCtx); + globalCtx->envCtx.unk_E3 = 1; + globalCtx->envCtx.unk_F2[0] = 0x3C; + } else { + if (globalCtx->envCtx.unk_F2[0] != 0) { + if ((globalCtx->state.frames % 4) == 0) { + globalCtx->envCtx.unk_F2[0]--; + if ((globalCtx->envCtx.unk_F2[0]) == 8) { + func_800FD858(globalCtx); + } + } + } + } + + if (D_801BDBB0 == 1) { + this->state = TEST4_STATE_1; + } +} + +void func_80A431C8(EnTest4* this, GlobalContext* globalCtx) { + if (((gSaveContext.time >= CLOCK_TIME(17, 30)) && (gSaveContext.time < CLOCK_TIME(23, 0)) && + (globalCtx->envCtx.unk_F2[0] != 0)) || + (globalCtx->envCtx.unk_F2[2] != 0)) { + D_801BDBB0 = 0; + globalCtx->envCtx.unk_E3 = 2; + } + + if (D_801BDBB0 == 0) { + this->state = TEST4_STATE_0; + } +} + +void func_80A4323C(EnTest4* this, GlobalContext* globalCtx) { + s32 temp_v0 = (this->actor.params >> 0xA) * 0x64; + + if (temp_v0 > 0) { + D_801F4E7A = temp_v0; + } +} + +void EnTest4_Update(Actor* thisx, GlobalContext* globalCtx) { + EnTest4* this = THIS; + Player* player = PLAYER; + + if (!(player->stateFlags1 & 2)) { + this->actionFunc(this, globalCtx); + + if (func_800FE4B8(globalCtx) != 0) { + switch (this->state) { + case TEST4_STATE_0: + func_80A430C8(this, globalCtx); + break; + case TEST4_STATE_1: + func_80A431C8(this, globalCtx); + break; + } + } + func_80A4323C(this, globalCtx); + } +} diff --git a/src/overlays/actors/ovl_En_Test4/z_en_test4.h b/src/overlays/actors/ovl_En_Test4/z_en_test4.h index 54db025a8..4927c337e 100644 --- a/src/overlays/actors/ovl_En_Test4/z_en_test4.h +++ b/src/overlays/actors/ovl_En_Test4/z_en_test4.h @@ -9,10 +9,20 @@ typedef void (*EnTest4ActionFunc)(struct EnTest4*, GlobalContext*); typedef struct EnTest4 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xC]; + /* 0x0144 */ s8 unk_144; // 0 on night, 1 on day + /* 0x0145 */ u8 transitionCsTimer; + /* 0x0146 */ u16 unk_146; + /* 0x0148 */ u16 nextBellTime; // Next time the bell will sound + /* 0x014A */ u16 lastBellTime; // Last time the bell sounded + /* 0x014C */ u8 state; /* 0x0150 */ EnTest4ActionFunc actionFunc; } EnTest4; // size = 0x154 +typedef enum { + /* 0 */ TEST4_STATE_0, + /* 1 */ TEST4_STATE_1 +} EnTest4State; + extern const ActorInit En_Test4_InitVars; #endif // Z_EN_TEST4_H diff --git a/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c b/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c index ff11005fc..d0a7b9498 100644 --- a/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c +++ b/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c @@ -1,3 +1,9 @@ +/* + * File: z_en_thiefbird.c + * Overlay: ovl_En_Thiefbird + * Description: Takkuri + */ + #include "z_en_thiefbird.h" #define FLAGS 0x80001205 @@ -9,17 +15,39 @@ void EnThiefbird_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnThiefbird_Update(Actor* thisx, GlobalContext* globalCtx); void EnThiefbird_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80C11538(EnThiefbird* this); void func_80C11590(EnThiefbird* this, GlobalContext* globalCtx); +void func_80C118E4(EnThiefbird* this); void func_80C1193C(EnThiefbird* this, GlobalContext* globalCtx); void func_80C11D14(EnThiefbird* this, GlobalContext* globalCtx); +void func_80C11DC0(EnThiefbird* this); void func_80C11DF0(EnThiefbird* this, GlobalContext* globalCtx); void func_80C1215C(EnThiefbird* this, GlobalContext* globalCtx); +void func_80C12308(EnThiefbird* this); void func_80C12378(EnThiefbird* this, GlobalContext* globalCtx); +void func_80C1242C(EnThiefbird* this); void func_80C124B0(EnThiefbird* this, GlobalContext* globalCtx); +void func_80C126A8(EnThiefbird* this); void func_80C126D8(EnThiefbird* this, GlobalContext* globalCtx); +void func_80C12744(EnThiefbird* this); void func_80C127F4(EnThiefbird* this, GlobalContext* globalCtx); -#if 0 +extern AnimationHeader D_06000088; +extern AnimationHeader D_06000278; +extern AnimationHeader D_06000604; +extern Gfx D_06003060[]; +extern Gfx D_060030D8[]; +extern UNK_PTR D_060033B0; +extern UNK_PTR D_06003D58; +extern UNK_TYPE D_06004348; +extern UNK_TYPE D_06004B88; +extern UNK_TYPE D_060055E0; +extern FlexSkeletonHeader D_060061A0; +extern AnimationHeader D_060063C4; + +static Vec3f D_80C13920; +static s32 D_80C1392C; + const ActorInit En_Thiefbird_InitVars = { ACTOR_EN_THIEFBIRD, ACTORCAT_ENEMY, @@ -32,33 +60,58 @@ const ActorInit En_Thiefbird_InitVars = { (ActorFunc)EnThiefbird_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[3] = { -static ColliderJntSphElementInit D_80C135C0[3] = { +static ColliderJntSphElementInit sJntSphElementsInit[3] = { { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 1, { { 0, 0, 0 }, 24 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 9, { { 900, -600, 0 }, 20 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON, + OCELEM_ON, + }, { 12, { { 1200, 0, 0 }, 9 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80C1362C = { - { COLTYPE_HIT3, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 3, D_80C135C0, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_HIT3, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 3, + sJntSphElementsInit, }; -// sColChkInfoInit -static CollisionCheckInfoInit D_80C1363C = { 24, 15, 30, 30 }; +static CollisionCheckInfoInit sColChkInfoInit = { 24, 15, 30, 30 }; -// static DamageTable sDamageTable = { -static DamageTable D_80C13644 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x1), /* Deku Stick */ DMG_ENTRY(1, 0x0), /* Horse trample */ DMG_ENTRY(1, 0x0), @@ -93,93 +146,1022 @@ static DamageTable D_80C13644 = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80C13670[] = { +static s16 D_80C13664[] = { ITEM00_ARROWS_10, ITEM00_BOMBS_B, ITEM00_RUPEE_GREEN, + ITEM00_RUPEE_BLUE, ITEM00_RUPEE_RED, ITEM00_RUPEE_PURPLE }; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 3000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 1000, ICHAIN_CONTINUE), ICHAIN_S8(hintId, 35, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 500, ICHAIN_STOP), }; -#endif +void EnThiefbird_Init(Actor* thisx, GlobalContext* globalCtx) { + EnThiefbird* this = THIS; + s32 i; + ColliderJntSphElementDim* dim; -extern ColliderJntSphElementInit D_80C135C0[3]; -extern ColliderJntSphInit D_80C1362C; -extern CollisionCheckInfoInit D_80C1363C; -extern DamageTable D_80C13644; -extern InitChainEntry D_80C13670[]; + Actor_ProcessInitChain(&this->actor, sInitChain); + SkelAnime_InitSV(globalCtx, &this->skelAnime, &D_060061A0, &D_06000604, this->jointTable, this->morphTable, 17); + Collider_InitAndSetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements); -extern UNK_TYPE D_06000088; -extern UNK_TYPE D_06000278; -extern UNK_TYPE D_06000604; -extern UNK_TYPE D_06003060; -extern UNK_TYPE D_060033B0; -extern UNK_TYPE D_060063C4; + for (i = 0; i < ARRAY_COUNT(this->colliderElements); i++) { + dim = &this->collider.elements[i].dim; + dim->worldSphere.radius = dim->modelSphere.radius; + dim->worldSphere.center.x = this->actor.world.pos.x; + dim->worldSphere.center.y = this->actor.world.pos.y; + dim->worldSphere.center.z = this->actor.world.pos.z; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/EnThiefbird_Init.s") + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + ActorShape_Init(&this->actor.shape, 1500.0f, func_800B3FC0, 35.0f); + if (this->actor.params == 1) { + D_80C1392C = 1; + Math_Vec3f_Copy(&D_80C13920, &this->actor.world.pos); + Actor_MarkForDeath(&this->actor); + } else if ((gSaveContext.roomInf[126][5] & 0xFF000000) >> 0x18) { + Actor_MarkForDeath(&this->actor); + } else { + func_80C11538(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/EnThiefbird_Destroy.s") +void EnThiefbird_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnThiefbird* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C10984.s") + Collider_DestroyJntSph(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C10B0C.s") +void func_80C10984(EnThiefbird* this, s32 arg1) { + s32 i; + EnThiefbirdUnkStruct* ptr = &this->unk_3F0[0]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C10DE8.s") + for (i = 0; i < ARRAY_COUNT(this->unk_3F0); i++, ptr++) { + if (ptr->unk_22 == 0) { + ptr->unk_22 = (s32)Rand_ZeroFloat(20.0f) + 40; + ptr->unk_00.x = randPlusMinusPoint5Scaled(30.0f) + this->actor.focus.pos.x; + ptr->unk_00.y = randPlusMinusPoint5Scaled(30.0f) + this->actor.focus.pos.y; + ptr->unk_00.z = randPlusMinusPoint5Scaled(30.0f) + this->actor.focus.pos.z; + ptr->unk_0C.x = randPlusMinusPoint5Scaled(5.0f); + ptr->unk_0C.y = Rand_ZeroOne() + 2.0f; + ptr->unk_0C.z = randPlusMinusPoint5Scaled(5.0f); + ptr->unk_1C = Rand_ZeroFloat(1000.0f); + ptr->unk_18 = (Rand_ZeroFloat(20.0f) + 40.0f) * 0.0001f; + ptr->unk_1E = Rand_Next() >> 0x10; + arg1--; + if (arg1 == 0) { + break; + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C10E98.s") +s32 func_80C10B0C(EnThiefbird* this, GlobalContext* globalCtx) { + static UNK_TYPE D_80C13680[] = { &D_06004348, &D_06004B88, &D_060055E0 }; + s32 isItemFound = false; + s32 phi_a3 = 0; + s32 i = 18; + s32 phi_t0_3; + s16 sp1E = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C11338.s") + for (; i < ARRAY_COUNT(gSaveContext.inventory.items); i++) { + if ((gSaveContext.inventory.items[i] >= ITEM_BOTTLE) && (gSaveContext.inventory.items[i] <= ITEM_POTION_BLUE)) { + isItemFound = true; + sp1E = gSaveContext.inventory.items[i]; + break; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C11454.s") + if (gSaveContext.playerForm == PLAYER_FORM_HUMAN) { + phi_a3 = CUR_EQUIP_VALUE_VOID(EQUIP_SWORD); + if (gSaveContext.inventory.items[gItemSlots[16]] == ITEM_SWORD_GREAT_FAIRY) { + phi_a3 += 4; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C114C0.s") + if (isItemFound && (phi_a3 != 0)) { + if (Rand_ZeroOne() < 0.6f) { + isItemFound = false; + } else { + phi_a3 = 0; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C11538.s") + if (isItemFound) { + func_801149A0(sp1E, i); + this->unk_3E8 = &D_060033B0; + if (!func_80152498(&globalCtx->msgCtx)) { + func_801518B0(globalCtx, 0xF4, NULL); + } + phi_t0_3 = 0x12; + } else if (phi_a3 != 0) { + if (phi_a3 >= 5) { + if (Rand_ZeroOne() < 0.5f) { + phi_a3 -= 4; + } else { + phi_a3 = 4; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C11590.s") + phi_t0_3 = phi_a3 + 0x4C; + if (phi_a3 == 4) { + func_801149A0(16, 16); + this->unk_3E8 = &D_06003D58; + phi_t0_3 = 0x10; + } else { + CUR_FORM_EQUIP(EQUIP_SLOT_B) = ITEM_NONE; + TAKE_EQUIPPED_ITEM(EQUIP_SWORD); + this->unk_3E8 = D_80C13680[phi_a3 - 1]; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C118E4.s") + if (!func_80152498(&globalCtx->msgCtx)) { + func_801518B0(globalCtx, 0xF5, NULL); + } + } else { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C1193C.s") + if (!((gSaveContext.roomInf[126][5] & 0xFF000000) >> 0x18)) { + gSaveContext.roomInf[126][5] = (gSaveContext.roomInf[126][5] & 0xFFFFFF) | ((phi_t0_3 & 0xFF) << 0x18); + } else { + gSaveContext.roomInf[126][5] = (gSaveContext.roomInf[126][5] & 0xFF00FFFF) | ((phi_t0_3 & 0xFF) << 0x10); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C11C60.s") + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C11D14.s") +void func_80C10DE8(s32 items[], s32 count, s32 item) { + s32 i; + s32 idx = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C11DC0.s") + for (i = 0; i < count; i++) { + s32 j = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C11DF0.s") + while (items[idx] != -1) { + idx = (idx + 5) % 8; + if (j == 8) { + break; + } + j++; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C11F6C.s") + items[idx] = item; + idx = (idx + 5) % 8; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C1215C.s") +s32 func_80C10E98(GlobalContext* globalCtx) { + Player* player = PLAYER; + s32 phi_s0_2; + s32 phi_s2; + s32 spB0; + s32 spAC; + s32 spA8; + s16 phi_s3 = 0; + s32 spA0; + s32 pad2; + s32 sp98; + s32 i; + s32 sp74[8]; + s32 sp5C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C12308.s") + for (i = 0; i < ARRAY_COUNT(sp74); i++) { + sp74[i] = ITEM00_NO_DROP; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C12378.s") + if (AMMO(ITEM_BOMB) >= 5) { + spB0 = 1; + sp74[1] = ITEM00_BOMBS_B; + if (1) {} + } else { + spB0 = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C1242C.s") + if (AMMO(ITEM_BOW) >= 10) { + spAC = 1; + sp74[5] = ITEM00_ARROWS_10; + } else { + spAC = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C124B0.s") + sp98 = (gSaveContext.rupees / 4) * 3; + phi_s0_2 = sp98 / 50; + sp5C = (-spB0 - spAC); + sp5C += 8; + if (sp5C < phi_s0_2) { + phi_s0_2 = sp5C; + } + phi_s2 = phi_s0_2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C126A8.s") + for (i = 0; i < phi_s2; i++) { + if (Rand_ZeroOne() < 0.5f) { + phi_s0_2--; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C126D8.s") + i = sp5C - phi_s0_2; + if (i) {} + sp5C = phi_s0_2 * 50; + sp98 -= sp5C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C12744.s") + func_80C10DE8(sp74, phi_s0_2, ITEM00_RUPEE_PURPLE); + spA0 = sp98 / 20; + if (i < spA0) { + spA0 = i; + } + i -= spA0; + sp98 -= spA0 * 20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C127F4.s") + func_80C10DE8(sp74, spA0, ITEM00_RUPEE_RED); + phi_s2 = sp98 / 5; + if (i < phi_s2) { + phi_s2 = i; + } + i -= phi_s2; + sp98 -= phi_s2 * 5; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C12B1C.s") + func_80C10DE8(sp74, phi_s2, ITEM00_RUPEE_BLUE); + if (i < sp98) { + spA8 = i; + } else { + spA8 = sp98; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C12D00.s") + func_80C10DE8(sp74, spA8, ITEM00_RUPEE_GREEN); + if ((spB0 + spAC + phi_s0_2 + spA0 + phi_s2 + spA8) == 0) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/EnThiefbird_Update.s") + { + Vec3f sp64; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C130EC.s") + for (i = 0; i < ARRAY_COUNT(sp74); i++) { + sp64.x = (Math_SinS(phi_s3) * 40.0f) + player->actor.world.pos.x; + sp64.y = player->actor.world.pos.y + 20.0f; + sp64.z = (Math_CosS(phi_s3) * 40.0f) + player->actor.world.pos.z; + if (sp74[i] != ITEM00_NO_DROP) { + EnItem00* temp_s1_5 = Item_DropCollectible(globalCtx, &sp64, sp74[i]); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C1315C.s") + if (temp_s1_5 != NULL) { + temp_s1_5->actor.velocity.y = Rand_ZeroFloat(3.0f) + 6.0f; + temp_s1_5->actor.speedXZ = Rand_ZeroFloat(3.0f) + 3.0f; + temp_s1_5->actor.world.rot.y = phi_s3; + } + phi_s3 += (s16)(0x10000 / (spB0 + spAC + phi_s0_2 + spA0 + phi_s2 + spA8)); + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/func_80C13354.s") + AMMO(ITEM_BOMB) -= spB0 * 5; + AMMO(ITEM_BOW) -= spAC * 10; + func_801159EC(-((phi_s0_2 * 50) + (spA0 * 20) + (phi_s2 * 5) + spA8)); + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Thiefbird/EnThiefbird_Draw.s") +void func_80C11338(EnThiefbird* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + EnItem00* item = NULL; + f32 phi_f20 = 5000.0f; + s32 i; + f32 temp_f0; + + this->unk_3EC = NULL; + + do { + item = (EnItem00*)func_ActorCategoryIterateById(globalCtx, &item->actor, ACTORCAT_MISC, ACTOR_EN_ITEM00); + if (item != NULL) { + if (item->unk152 > 0) { + if (Actor_XZDistanceBetweenActors(&player->actor, &item->actor) > 10.0f) { + for (i = 0; i < ARRAY_COUNT(D_80C13664); i++) { + if (item->actor.params == D_80C13664[i]) { + break; + } + } + + if (i != ARRAY_COUNT(D_80C13664)) { + temp_f0 = Actor_DistanceBetweenActors(&this->actor, &item->actor); + if (temp_f0 < phi_f20) { + this->unk_3EC = item; + phi_f20 = temp_f0; + } + } + } + } + item = (EnItem00*)item->actor.next; + } + } while (item != NULL); +} + +void func_80C11454(EnThiefbird* this) { + this->unk_18C = 10; + this->unk_3D8 = 0.5f; + this->unk_3DC = 0.75f; + this->unk_3D4 = 1.0f; + this->actor.flags &= ~0x200; + func_800BCB70(&this->actor, 0x4000, 255, 0, 80); +} + +void func_80C114C0(EnThiefbird* this, GlobalContext* globalCtx) { + if (this->unk_18C == 10) { + this->unk_18C = 0; + this->unk_3D4 = 0.0f; + func_800BF7CC(globalCtx, &this->actor, this->unk_350, 11, 2, 0.2f, 0.2f); + this->actor.flags |= 0x200; + } +} + +void func_80C11538(EnThiefbird* this) { + SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_06000604, -4.0f); + this->unk_18E = 60; + this->collider.base.acFlags |= AC_ON; + this->actionFunc = func_80C11590; +} + +void func_80C11590(EnThiefbird* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + s32 sp38; + + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + sp38 = func_801378B8(&this->skelAnime, 0.0f); + this->actor.speedXZ = (Rand_ZeroOne() * 1.5f) + 3.0f; + + if (this->actor.bgCheckFlags & 8) { + this->unk_192 = this->actor.wallYaw; + } else { + if (Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) > 300.0f) { + this->unk_192 = Actor_YawToPoint(&this->actor, &this->actor.home.pos); + } + } + + if (!Math_SmoothStepToS(&this->actor.shape.rot.y, this->unk_192, 5, 0x300, 0x10) && (sp38 != 0) && + (Rand_ZeroOne() < 0.1f)) { + s16 yaw = Actor_YawToPoint(&this->actor, &this->actor.home.pos) - this->actor.shape.rot.y; + + if (yaw > 0) { + this->unk_192 += Rand_S16Offset(4096, 4096); + } else { + this->unk_192 -= Rand_S16Offset(4096, 4096); + } + Audio_PlayActorSound2(&this->actor, NA_SE_EN_THIEFBIRD_VOICE); + } + + if ((this->actor.yDistToWater > -40.0f) || (this->actor.bgCheckFlags & 1)) { + this->unk_190 = -4096; + } else if (this->actor.world.pos.y < (this->actor.home.pos.y - 75.0f)) { + this->unk_190 = -Rand_S16Offset(2048, 2048); + } else if ((this->actor.home.pos.y + 75.0f) < this->actor.world.pos.y) { + this->unk_190 = Rand_S16Offset(2048, 2048); + } + + if (!Math_SmoothStepToS(&this->actor.shape.rot.x, this->unk_190, 10, 0x100, 8) && (sp38 != 0) && + (Rand_ZeroOne() < 0.1f)) { + if (this->actor.home.pos.y < this->actor.world.pos.y) { + this->unk_190 -= Rand_S16Offset(0x400, 0x400); + } else { + this->unk_190 += Rand_S16Offset(0x400, 0x400); + } + + this->unk_190 = CLAMP(this->unk_190, -4096, 4096); + } + + if (this->unk_18E != 0) { + this->unk_18E--; + } + + if ((this->unk_18E == 0) && (this->actor.xzDistToPlayer < 300.0f) && !(player->stateFlags1 & 0x800000) && + (Player_GetMask(globalCtx) != PLAYER_MASK_STONE_MASK) && (this->actor.yDistToWater < -40.0f)) { + func_80C118E4(this); + } +} + +void func_80C118E4(EnThiefbird* this) { + SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_060063C4, -10.0f); + this->unk_18E = 300; + this->actionFunc = func_80C1193C; + this->actor.speedXZ = 5.0f; +} + +void func_80C1193C(EnThiefbird* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + s16 pitch; + + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + if (func_801378B8(&this->skelAnime, 1.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KAICHO_FLUTTER); + } + + if (this->unk_18E != 0) { + this->unk_18E--; + } + + pitch = Actor_PitchBetweenActors(&this->actor, &player->actor); + pitch = CLAMP(pitch, -0x2800, 0x2800); + Math_SmoothStepToS(&this->actor.shape.rot.x, pitch, 4, 0x800, 0x80); + if (this->actor.bgCheckFlags & 8) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.wallYaw, 6, 0x1000, 0x100); + } else if (Actor_IsActorFacingLink(&this->actor, 0x3C00) || (this->actor.xzDistToPlayer > 120.0f)) { + s16 rot = BINANG_ROT180(this->actor.yawTowardsPlayer - player->actor.shape.rot.y); + + if (rot > 0x4000) { + rot = this->actor.yawTowardsPlayer + 0x3000; + } else if (rot < -0x4000) { + rot = this->actor.yawTowardsPlayer - 0x3000; + } else { + rot = this->actor.yawTowardsPlayer; + } + Math_SmoothStepToS(&this->actor.shape.rot.y, rot, 4, 0x1000, 0x100); + } + + if ((this->unk_18E == 0) || (player->stateFlags1 & 0x800000) || + (Player_GetMask(globalCtx) == PLAYER_MASK_STONE_MASK) || (this->collider.base.atFlags & AT_HIT) || + (this->actor.bgCheckFlags & 1) || (this->actor.yDistToWater > -40.0f)) { + if (this->collider.base.atFlags & AT_HIT) { + this->collider.base.atFlags &= ~AT_HIT; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_THIEFBIRD_VOICE); + if (!(this->collider.base.atFlags & AT_BOUNCED)) { + if ((D_80C1392C != 0) && CUR_UPG_VALUE(UPG_QUIVER) && + (!((gSaveContext.roomInf[126][5] & 0xFF000000) >> 0x18) || + !((gSaveContext.roomInf[126][5] & 0xFF0000) >> 0x10)) && + (Rand_ZeroOne() < 0.5f) && func_80C10B0C(this, globalCtx)) { + func_80C1242C(this); + } else if (func_80C10E98(globalCtx)) { + func_80C11338(this, globalCtx); + func_80C12744(this); + } else { + func_80C11538(this); + } + } else { + func_80C12308(this); + } + } else { + func_80C11538(this); + } + } +} + +void func_80C11C60(EnThiefbird* this) { + this->actor.speedXZ = 0.0f; + this->actor.velocity.y = 0.0f; + SkelAnime_ChangeAnimDefaultStop(&this->skelAnime, &D_06000088); + this->actor.bgCheckFlags &= ~1; + this->actor.shape.rot.x = 0; + this->unk_18E = 40; + this->actor.velocity.y = 0.0f; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_THIEFBIRD_DEAD); + func_800BCB70(&this->actor, 0x4000, 255, 0, 40); + this->collider.base.acFlags &= ~AC_ON; + this->actor.flags |= 0x10; + this->unk_192 = 0x1C00; + this->actionFunc = func_80C11D14; +} + +void func_80C11D14(EnThiefbird* this, GlobalContext* globalCtx) { + this->actor.colorFilterTimer = 40; + if (this->unk_18E != 0) { + this->unk_18E--; + } + + if (this->unk_18C == 10) { + if (this->unk_18E < 38) { + func_80C114C0(this, globalCtx); + this->actor.speedXZ = 4.0f; + } else { + return; + } + } + + if (this->unk_18E < 20) { + Math_ScaledStepToS(&this->unk_192, 0, 0x200); + } + + this->actor.shape.rot.y += this->unk_192; + if (this->unk_18E == 0) { + func_80C11DC0(this); + } +} + +void func_80C11DC0(EnThiefbird* this) { + this->actor.flags &= ~1; + this->actionFunc = func_80C11DF0; + this->actor.gravity = -0.5f; +} + +void func_80C11DF0(EnThiefbird* this, GlobalContext* globalCtx) { + s32 i; + s32 j; + + if (Math_ScaledStepToS(&this->actor.shape.rot.x, -0x8000, 0x800)) { + Math_ScaledStepToS(&this->unk_192, 0x1C00, 0x200); + this->actor.shape.rot.y += this->unk_192; + } + + if ((this->actor.bgCheckFlags & 1) || (this->actor.floorHeight == BGCHECK_Y_MIN)) { + for (i = 0; i < ARRAY_COUNT(this->unk_350); i++) { + func_800B3030(globalCtx, &this->unk_350[i], &D_801D15B0, &D_801D15B0, 0x8C, 0, 0); + } + + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 11, NA_SE_EN_EXTINCT); + Item_DropCollectible(globalCtx, &this->actor.world.pos, ITEM00_RUPEE_ORANGE); + + for (i = 0; i < ARRAY_COUNT(D_80C13664); i++) { + for (j = 0; j < this->unk_196[i]; j++) { + Item_DropCollectible(globalCtx, &this->actor.world.pos, D_80C13664[i]); + } + } + + Actor_MarkForDeath(&this->actor); + } +} + +void func_80C11F6C(EnThiefbird* this, GlobalContext* globalCtx) { + SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_06000278, -4.0f); + func_80C10984(this, 15); + if (this->actor.colChkInfo.damageEffect != 3) { + this->actor.speedXZ = 4.0f; + } else { + this->actor.speedXZ = 0.0f; + } + + if (this->actor.colChkInfo.damageEffect == 5) { + func_800BCB70(&this->actor, 0, 255, 0, 40); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + } else if (this->actor.colChkInfo.damageEffect == 1) { + func_800BCB70(&this->actor, 0, 255, 0, 40); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + } else { + func_800BCB70(&this->actor, 0x4000, 255, 0, 40); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_THIEFBIRD_DAMAGE); + } + + this->collider.base.acFlags &= ~AC_ON; + if (this->unk_3E8 == 0) { + this->unk_190 = -0x1000; + this->unk_192 = BINANG_ROT180(this->actor.yawTowardsPlayer); + } else { + this->unk_190 = Actor_PitchToPoint(&this->actor, &D_80C13920); + } + + this->unk_18E = 40; + if (Rand_ZeroOne() < 0.9f) { + Item_DropCollectible(globalCtx, &this->actor.focus.pos, ITEM00_RUPEE_GREEN); + } + + if (Rand_ZeroOne() < 0.6f) { + Item_DropCollectible(globalCtx, &this->actor.focus.pos, ITEM00_RUPEE_GREEN); + } + + if (Rand_ZeroOne() < 0.3f) { + Item_DropCollectible(globalCtx, &this->actor.focus.pos, ITEM00_RUPEE_GREEN); + } + this->actionFunc = func_80C1215C; +} + +void func_80C1215C(EnThiefbird* this, GlobalContext* globalCtx) { + f32 sp2C; + + if (this->unk_18E != 0) { + this->unk_18E--; + } + + if (this->unk_18C == 10) { + if (this->unk_18E < 38) { + func_80C114C0(this, globalCtx); + this->actor.speedXZ = 4.0f; + } else { + return; + } + } + + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + if (this->actor.bgCheckFlags & 8) { + this->unk_192 = this->actor.wallYaw; + } else if (this->unk_3E8 == 0) { + this->unk_192 = BINANG_ROT180(this->actor.yawTowardsPlayer); + } else { + this->unk_192 = Actor_YawToPoint(&this->actor, &D_80C13920); + this->unk_190 = Actor_PitchToPoint(&this->actor, &D_80C13920); + } + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->unk_192, 6, 0x1000, 0x100); + Math_SmoothStepToS(&this->actor.shape.rot.x, this->unk_190, 5, 0x100, 0x10); + sp2C = (this->unk_18E * 153.6f) + 0x800; + this->actor.shape.rot.z = Math_SinS(this->unk_18E * 0x1999) * sp2C; + if (this->unk_18E == 0) { + if (this->unk_3E8 != 0) { + func_80C1242C(this); + } else if (this->unk_3EC != 0) { + func_80C12744(this); + } else { + func_80C11538(this); + } + } +} + +void func_80C12308(EnThiefbird* this) { + SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_06000278, -4.0f); + func_80C10984(this, 15); + this->unk_190 = -0x1000; + this->unk_192 = BINANG_ROT180(this->actor.yawTowardsPlayer); + this->unk_18E = 40; + this->actionFunc = func_80C12378; +} + +void func_80C12378(EnThiefbird* this, GlobalContext* globalCtx) { + if (this->unk_18E != 0) { + this->unk_18E--; + } + + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + if (this->actor.bgCheckFlags & 8) { + this->unk_192 = this->actor.wallYaw; + } else { + this->unk_192 = BINANG_ROT180(this->actor.yawTowardsPlayer); + } + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->unk_192, 6, 0x1000, 0x100); + Math_SmoothStepToS(&this->actor.shape.rot.x, this->unk_190, 5, 0x100, 0x10); + + if (this->unk_18E == 0) { + func_80C11538(this); + } +} + +void func_80C1242C(EnThiefbird* this) { + SkelAnime_ChangeAnim(&this->skelAnime, &D_06000278, 2.0f, 0.0f, 0.0f, 0, -4.0f); + this->actor.flags |= 0x10; + this->collider.base.acFlags |= AC_ON; + this->actionFunc = func_80C124B0; + this->actor.speedXZ = 12.0f; +} + +void func_80C124B0(EnThiefbird* this, GlobalContext* globalCtx) { + Actor* temp_v0; + s16 temp_v1; + + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + if (this->actor.bgCheckFlags & 8) { + this->unk_192 = this->actor.wallYaw; + } else { + this->unk_192 = Actor_YawToPoint(&this->actor, &D_80C13920); + } + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->unk_192, 6, 0x1000, 0x100); + Math_SmoothStepToS(&this->actor.shape.rot.x, Actor_PitchToPoint(&this->actor, &D_80C13920), 6, 0x1000, 0x100); + temp_v0 = func_800BC270(globalCtx, &this->actor, 80.0f, 0x138B0); + if (temp_v0 != NULL) { + temp_v1 = temp_v0->world.rot.x - Actor_PitchToPoint(temp_v0, &this->actor.focus.pos); + if (ABS_ALT(temp_v1) < 0x1800) { + if (temp_v1 > 0) { + this->unk_3E0 = 25.0f; + } else { + this->unk_3E0 = -25.0f; + } + } + } + + if (!Math_StepToF(&this->unk_3E0, 0.0f, 5.0f)) { + this->actor.world.pos.x += + this->unk_3E0 * Math_SinS(this->actor.shape.rot.x) * Math_SinS(this->actor.shape.rot.y); + this->actor.world.pos.y += this->unk_3E0 * Math_CosS(this->actor.shape.rot.x); + this->actor.world.pos.x += + this->unk_3E0 * Math_SinS(this->actor.shape.rot.x) * Math_CosS(this->actor.shape.rot.y); + } + + if (Actor_DistanceToPoint(&this->actor, &D_80C13920) < 1000.0f) { + func_80C126A8(this); + } +} + +void func_80C126A8(EnThiefbird* this) { + this->actor.flags &= ~1; + this->collider.base.acFlags &= ~AC_ON; + this->actionFunc = func_80C126D8; +} + +void func_80C126D8(EnThiefbird* this, GlobalContext* globalCtx) { + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + Math_ApproachS(&this->actor.shape.rot.x, 0x3000, 6, 0x1000); + if (this->actor.yDistToPlayer > 100.0f) { + Actor_MarkForDeath(&this->actor); + } +} + +void func_80C12744(EnThiefbird* this) { + SkelAnime_ChangeAnimTransitionRepeat(&this->skelAnime, &D_06000604, -4.0f); + SkelAnime_ChangeAnim(&this->skelAnime, &D_06000604, 1.0f, 0.0f, 0.0f, 1, -4.0f); + this->unk_190 = 0; + this->collider.base.acFlags |= AC_ON; + this->actor.flags |= 0x10; + this->actionFunc = func_80C127F4; + this->actor.speedXZ = 4.0f; + this->skelAnime.animPlaybackSpeed = 3.0f; +} + +void func_80C127F4(EnThiefbird* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + s16 temp_v0; + f32 temp_f0; + + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + if ((this->unk_3EC != NULL) && ((this->unk_3EC->actor.update == NULL) || (this->unk_3EC->unk152 == 0) || + (Actor_XZDistanceBetweenActors(&player->actor, &this->unk_3EC->actor) <= 10.0f))) { + this->unk_3EC = NULL; + } + + if (this->unk_190 == -0x3800) { + if (Math_ScaledStepToS(&this->unk_194, this->unk_190, 0xE00)) { + this->unk_190 = 0; + } + } else { + Math_ScaledStepToS(&this->unk_194, 0, 0x200); + } + + if (this->unk_3EC == NULL) { + func_80C11338(this, globalCtx); + } + + if (this->unk_3EC != NULL) { + if (this->actor.bgCheckFlags & 8) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.wallYaw, 3, 0x2000, 0x100); + } else { + Math_SmoothStepToS(&this->actor.shape.rot.y, Actor_YawBetweenActors(&this->actor, &this->unk_3EC->actor), 3, + 0x2000, 0x100); + } + temp_v0 = Math_Vec3f_Pitch(&this->unk_350[9], &this->unk_3EC->actor.world.pos); + temp_v0 = CLAMP(temp_v0, -0x3000, 0x3000); + Math_SmoothStepToS(&this->actor.shape.rot.x, temp_v0, 4, 0x800, 0x80); + temp_f0 = Actor_DistanceToPoint(&this->unk_3EC->actor, &this->unk_350[9]); + this->actor.speedXZ = (0.02f * temp_f0) + 2.0f; + this->actor.speedXZ = CLAMP_MAX(this->actor.speedXZ, 4.0f); + if ((this->unk_3EC->actor.speedXZ <= 0.0f) && (temp_f0 < 40.0f)) { + s32 i; + + this->unk_3EC->unk152 = 0; + for (i = 0; i < ARRAY_COUNT(D_80C13664); i++) { + if (this->unk_3EC->actor.params == D_80C13664[i]) { + this->unk_196[i]++; + break; + } + } + this->unk_3EC = NULL; + this->unk_194 = 0x100; + this->unk_190 = -0x3800; + } + } else { + this->actor.speedXZ = 4.0f; + if (this->actor.bgCheckFlags & 8) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.wallYaw, 6, 0x1000, 0x100); + } else { + Math_SmoothStepToS(&this->actor.shape.rot.y, BINANG_ROT180(this->actor.yawTowardsPlayer), 6, 0x1000, 0x100); + } + + Math_SmoothStepToS(&this->actor.shape.rot.x, -0x800, 4, 0x800, 0x80); + if (this->unk_194 == 0) { + this->actor.flags &= ~0x10; + func_80C11538(this); + } + } +} + +void func_80C12B1C(EnThiefbird* this, GlobalContext* globalCtx) { + ColliderJntSphElement* sph; + s32 i; + + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + this->collider.base.atFlags &= ~AT_HIT; + func_800BE258(&this->actor, this->collider.elements); + func_80C114C0(this, globalCtx); + this->unk_194 = 0; + + for (i = 0; i < ARRAY_COUNT(this->colliderElements); i++) { + if (this->collider.elements[i].info.bumperFlags & 2) { + break; + } + } + + if (this->actor.colChkInfo.damageEffect == 3) { + func_80C11454(this); + } else if (this->actor.colChkInfo.damageEffect == 4) { + this->unk_18C = 20; + this->unk_3D8 = 0.5f; + this->unk_3D4 = 4.0f; + if (i != ARRAY_COUNT(this->colliderElements)) { + sph = &this->collider.elements[i]; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, sph->info.bumper.hitPos.x, + sph->info.bumper.hitPos.y, sph->info.bumper.hitPos.z, 0, 0, 0, CLEAR_TAG_LARGE_LIGHT_RAYS); + } + } else if (this->actor.colChkInfo.damageEffect == 2) { + this->unk_18C = 0; + this->unk_3D8 = 0.5f; + this->unk_3D4 = 4.0f; + } else if (this->actor.colChkInfo.damageEffect == 5) { + this->unk_18C = 0x1E; + this->unk_3D8 = 0.5f; + this->unk_3D4 = 2.0f; + } + + if (this->unk_3E8 != 0) { + this->actor.colChkInfo.damage = 0; + } + + if (!Actor_ApplyDamage(&this->actor)) { + this->actor.colChkInfo.health = 0; + Enemy_StartFinishingBlow(globalCtx, &this->actor); + func_80C10984(this, 40); + func_80C11C60(this); + } else { + func_80C11F6C(this, globalCtx); + } + } +} + +void func_80C12D00(EnThiefbird* this) { + static Vec3f D_80C1368C = { 0.0f, -0.15f, 0.0f }; + s32 i; + f32 phi_f20; + EnThiefbirdUnkStruct* ptr = &this->unk_3F0[0]; + + for (i = 0; i < ARRAY_COUNT(this->unk_3F0); i++, ptr++) { + if (ptr->unk_22) { + ptr->unk_22--; + Math_Vec3f_Sum(&ptr->unk_00, &ptr->unk_0C, &ptr->unk_00); + Math_Vec3f_Sum(&ptr->unk_0C, &D_80C1368C, &ptr->unk_0C); + ptr->unk_1C++; + Math_StepToF(&ptr->unk_0C.x, 0.0f, 0.05f); + Math_StepToF(&ptr->unk_0C.z, 0.0f, 0.05f); + if (ptr->unk_0C.y < -0.5f) { + ptr->unk_0C.y = -0.5f; + } + + if ((i % 2) != 0) { + phi_f20 = -1.0f; + } else { + phi_f20 = 1.0f; + } + + ptr->unk_20 = Math_SinS(ptr->unk_1C * 0x7D0) * 0x2000; + ptr->unk_1E += (s16)(0x666 * fabsf(Math_SinS(ptr->unk_1C * 0xBB8)) * phi_f20); + } + } +} + +void EnThiefbird_Update(Actor* thisx, GlobalContext* globalCtx2) { + EnThiefbird* this = THIS; + GlobalContext* globalCtx = globalCtx2; + + func_80C12B1C(this, globalCtx); + this->actionFunc(this, globalCtx); + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actor.world.rot.x = -this->actor.shape.rot.x; + if (this->actor.colChkInfo.health != 0) { + Actor_SetVelocityAndMoveXYRotation(&this->actor); + } else { + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + } + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 25.0f, 25.0f, 50.0f, 7); + if (this->actionFunc == func_80C1193C) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if (this->collider.base.acFlags & AC_ON) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + if (this->unk_3D4 > 0.0f) { + if (this->unk_18C != 10) { + Math_StepToF(&this->unk_3D4, 0.0f, 0.05f); + this->unk_3D8 = (this->unk_3D4 + 1.0f) * 0.25f; + this->unk_3D8 = CLAMP_MAX(this->unk_3D8, 0.5f); + } else if (!Math_StepToF(&this->unk_3DC, 0.5f, 0.0125f)) { + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } + } + + func_80C12D00(this); + if (((this->skelAnime.animCurrentSeg == &D_06000604) && func_801378B8(&this->skelAnime, 13.0f)) || + ((this->skelAnime.animCurrentSeg == &D_06000278) && func_801378B8(&this->skelAnime, 1.0f))) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KAICHO_FLUTTER); + } +} + +s32 EnThiefbird_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnThiefbird* this = THIS; + + if ((limbIndex == 10) || (limbIndex == 11)) { + this->unk_3E4 = *dList; + *dList = NULL; + } else if (limbIndex == 16) { + *dList = NULL; + } else if (limbIndex == 8) { + rot->z += this->unk_194; + } + + return false; +} + +void EnThiefbird_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static s8 D_80C13698[] = { + -1, 0, -1, 1, 3, -1, 2, 5, -1, -1, 7, 8, 9, -1, -1, 10, -1, + }; + EnThiefbird* this = THIS; + s32 pad; + Gfx* gfx; + s8 idx; + + Collider_UpdateSpheres(limbIndex, &this->collider); + if ((limbIndex == 10) || (limbIndex == 11)) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + gfx = POLY_OPA_DISP; + SysMatrix_NormalizeXYZ(&globalCtx->mf_187FC); + gSPMatrix(&gfx[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&gfx[1], this->unk_3E4); + POLY_OPA_DISP = &gfx[2]; + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } else if (limbIndex == 16) { + if (this->unk_3E8 != 0) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (this->unk_3E8 == &D_060033B0) { + gfx = POLY_XLU_DISP; + } else { + gfx = POLY_OPA_DISP; + } + + gSPMatrix(&gfx[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&gfx[1], this->unk_3E8); + + if (this->unk_3E8 == &D_060033B0) { + POLY_XLU_DISP = &gfx[2]; + } else { + POLY_OPA_DISP = &gfx[2]; + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + } + + idx = D_80C13698[limbIndex]; + if (idx != -1) { + if (idx == 9) { + SysMatrix_GetStateTranslationAndScaledX(1000.0f, &this->unk_350[idx]); + } else { + SysMatrix_GetStateTranslation(&this->unk_350[idx]); + if ((idx == 3) || (idx == 5)) { + SysMatrix_GetStateTranslationAndScaledX(2000.0f, &this->unk_350[idx + 1]); + } + } + } +} + +void func_80C13354(EnThiefbird* this, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + s32 i; + Gfx* gfx; + EnThiefbirdUnkStruct* ptr = &this->unk_3F0[0]; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gfx = POLY_OPA_DISP; + gSPDisplayList(&gfx[0], &sSetupDL[6 * 25]); + gSPDisplayList(&gfx[1], D_06003060); + gfx = &gfx[2]; + + for (i = 0; i < ARRAY_COUNT(this->unk_3F0); i++, ptr++) { + if (ptr->unk_22 != 0) { + SysMatrix_InsertTranslation(ptr->unk_00.x, ptr->unk_00.y, ptr->unk_00.z, MTXMODE_NEW); + SysMatrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_RotateY(ptr->unk_1E, MTXMODE_APPLY); + SysMatrix_InsertZRotation_s(ptr->unk_20, MTXMODE_APPLY); + SysMatrix_InsertTranslation(0.0f, -10.0f, 0.0f, MTXMODE_APPLY); + Matrix_Scale(ptr->unk_18, ptr->unk_18, 1.0f, MTXMODE_APPLY); + + gSPMatrix(&gfx[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&gfx[1], D_060030D8); + gfx = &gfx[2]; + } + } + POLY_OPA_DISP = gfx; + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnThiefbird_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnThiefbird* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawSV(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, this->skelAnime.dListCount, + EnThiefbird_OverrideLimbDraw, EnThiefbird_PostLimbDraw, &this->actor); + if (this->actor.colorFilterTimer > 0) { + func_800AE5A0(globalCtx); + } + func_80C13354(this, globalCtx); + func_800BE680(globalCtx, &this->actor, this->unk_350, 11, this->unk_3D8, this->unk_3DC, this->unk_3D4, + this->unk_18C); + Math_Vec3s_ToVec3f(&this->actor.focus.pos, &this->collider.elements[1].dim.worldSphere.center); +} diff --git a/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.h b/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.h index 3a28d8dc9..7e3e3c32a 100644 --- a/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.h +++ b/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.h @@ -7,11 +7,39 @@ struct EnThiefbird; typedef void (*EnThiefbirdActionFunc)(struct EnThiefbird*, GlobalContext*); +typedef struct { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ Vec3f unk_0C; + /* 0x18 */ f32 unk_18; + /* 0x1C */ s16 unk_1C; + /* 0x1E */ s16 unk_1E; + /* 0x20 */ s16 unk_20; + /* 0x22 */ s16 unk_22; +} EnThiefbirdUnkStruct; // size = 0x24 + typedef struct EnThiefbird { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnThiefbirdActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x804]; + /* 0x018C */ u8 unk_18C; + /* 0x018E */ s16 unk_18E; + /* 0x0190 */ s16 unk_190; + /* 0x0192 */ s16 unk_192; + /* 0x0194 */ s16 unk_194; + /* 0x0196 */ s16 unk_196[6]; + /* 0x01A2 */ Vec3s jointTable[17]; + /* 0x0208 */ Vec3s morphTable[17]; + /* 0x0270 */ ColliderJntSph collider; + /* 0x0290 */ ColliderJntSphElement colliderElements[3]; + /* 0x0350 */ Vec3f unk_350[11]; + /* 0x03D4 */ f32 unk_3D4; + /* 0x03D8 */ f32 unk_3D8; + /* 0x03DC */ f32 unk_3DC; + /* 0x03E0 */ f32 unk_3E0; + /* 0x03E4 */ Gfx* unk_3E4; + /* 0x03E8 */ UNK_PTR unk_3E8; + /* 0x03EC */ EnItem00* unk_3EC; + /* 0x03F0 */ EnThiefbirdUnkStruct unk_3F0[40]; } EnThiefbird; // size = 0x990 extern const ActorInit En_Thiefbird_InitVars; diff --git a/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c b/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c index 5a347da46..4db53de3c 100644 --- a/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c +++ b/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c @@ -44,7 +44,6 @@ const ActorInit En_Weather_Tag_InitVars = { extern f32 D_801F4E74; extern u8 D_801BDBB8; extern u8 D_801BDBB4; -extern u8 D_801BDBB0; extern u8 D_801F4E30; extern s16 D_801F4E7A; diff --git a/src/overlays/actors/ovl_En_Zot/z_en_zot.c b/src/overlays/actors/ovl_En_Zot/z_en_zot.c index 026a5a7bc..b49ccaef1 100644 --- a/src/overlays/actors/ovl_En_Zot/z_en_zot.c +++ b/src/overlays/actors/ovl_En_Zot/z_en_zot.c @@ -1,3 +1,9 @@ +/* + * File: z_en_zot.c + * Overlay: ovl_En_Zot + * Description: Great Bay - Zora With Directions to Zora Hall + */ + #include "z_en_zot.h" #define FLAGS 0x00000019 @@ -9,7 +15,36 @@ void EnZot_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnZot_Update(Actor* thisx, GlobalContext* globalCtx); void EnZot_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80B96BEC(EnZot* this, s16 arg1, u8 arg2); +void func_80B97100(EnZot* this, GlobalContext* globalCtx); +void func_80B97240(EnZot* this, GlobalContext* globalCtx); +void func_80B97708(EnZot* this, GlobalContext* globalCtx); +void func_80B97B5C(EnZot* this, GlobalContext* globalCtx); +void func_80B97CC8(EnZot* this, GlobalContext* globalCtx); +void func_80B97FD0(EnZot* this, GlobalContext* globalCtx); +void func_80B980FC(EnZot* this, GlobalContext* globalCtx); +void func_80B98728(EnZot* this, GlobalContext* globalCtx); +void func_80B98998(EnZot* this, GlobalContext* globalCtx); +void func_80B98CA8(EnZot* this, GlobalContext* globalCtx); +void func_80B990A4(EnZot* this, GlobalContext* globalCtx); +void func_80B992C0(EnZot* this, GlobalContext* globalCtx); +void func_80B99384(EnZot* this, GlobalContext* globalCtx); + +extern AnimationHeader D_06002898; +extern AnimationHeader D_06004248; +extern UNK_PTR D_060050A0; +extern UNK_PTR D_060058A0; +extern UNK_PTR D_060060A0; +extern FlexSkeletonHeader D_0600D208; +extern AnimationHeader D_0600DE20; +extern AnimationHeader D_0600DF54; +extern AnimationHeader D_0600E400; +extern AnimationHeader D_0600EDF0; +extern AnimationHeader D_0600F4E8; +extern AnimationHeader D_0600FDF0; +extern AnimationHeader D_06010B18; +extern AnimationHeader D_06011424; + const ActorInit En_Zot_InitVars = { ACTOR_EN_ZOT, ACTORCAT_NPC, @@ -22,123 +57,1363 @@ const ActorInit En_Zot_InitVars = { (ActorFunc)EnZot_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B998E0 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_ENEMY, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_ENEMY, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 30, 40, 0, { 0, 0, 0 } }, }; -#endif +void func_80B965D0(EnZot* this, GlobalContext* globalCtx) { + s32 i; -extern ColliderCylinderInit D_80B998E0; + if ((this->path != NULL) && (this->path->count >= 5)) { + Vec3s* points = (Vec3s*)Lib_SegmentedToVirtual(this->path->points); -extern UNK_TYPE D_06004248; + for (i = 0; i < ARRAY_COUNT(this->unk_2D8); i++, points++) { + if (this->unk_2D8[i] == NULL) { + this->unk_2D8[i] = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_OBJ_TSUBO, points->x, points->y, + points->z, 0, 0, 0, 0x13F); + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B965D0.s") +void EnZot_Init(Actor* thisx, GlobalContext* globalCtx2) { + EnZot* this = THIS; + GlobalContext* globalCtx = globalCtx2; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/EnZot_Init.s") + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 20.0f); + Actor_SetScale(&this->actor, 0.01f); + this->actionFunc = func_80B97100; + SkelAnime_InitSV(globalCtx, &this->skelAnime, &D_0600D208, &D_06004248, this->jointTable, this->morphTable, 20); + SkelAnime_ChangeAnimDefaultRepeat(&this->skelAnime, &D_0600DE20); + this->unk_2F0 = 0; + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/EnZot_Destroy.s") + this->unk_2F2 = 0; + this->unk_2F4 = 0; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->actor.world.rot.z = this->actor.shape.rot.z = 0; + this->actor.targetMode = 6; + this->actor.minVelocityY = -4.0f; + this->actor.gravity = -4.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B96BEC.s") + switch (ENZOT_GET_1F(thisx)) { + case 0: + this->actionFunc = func_80B97240; + this->actor.textId = 0; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B96CE4.s") + case 1: + this->actionFunc = func_80B97708; + for (i = 0; i < ARRAY_COUNT(this->unk_2D8); i++) { + this->unk_2D8[i] = NULL; + } + if (ENZOT_GET_FC00(&this->actor) != 0x3F) { + this->path = &globalCtx->setupPathList[ENZOT_GET_FC00(&this->actor)]; + this->unk_2D4 = 0; + func_80B965D0(this, globalCtx); + } else { + this->path = NULL; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B96D4C.s") + case 2: + case 3: + case 4: + this->actionFunc = func_80B97B5C; + if (ENZOT_GET_FC00(&this->actor) != 0x3F) { + this->path = &globalCtx->setupPathList[ENZOT_GET_FC00(&this->actor)]; + } else { + this->path = NULL; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B96DF0.s") + case 5: + this->unk_2F2 |= 4; + this->actionFunc = func_80B97FD0; + if (ENZOT_GET_FC00(&this->actor) != 0x3F) { + this->path = &globalCtx->setupPathList[ENZOT_GET_FC00(&this->actor)]; + } else { + this->path = NULL; + } + func_80B96BEC(this, 5, 0); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B96E5C.s") + case 6: + this->actionFunc = func_80B98998; + func_80B96BEC(this, 2, 0); + this->actor.colChkInfo.cylRadius = 0; + this->actor.shape.yOffset = -1400.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B96FB0.s") + case 7: + this->actionFunc = func_80B98998; + func_80B96BEC(this, 0, 0); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B97100.s") + case 8: + this->actor.flags |= 0x2000000; + this->actionFunc = func_80B98CA8; + func_80B96BEC(this, 5, 0); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B97110.s") + case 9: + this->actionFunc = func_80B990A4; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B97194.s") + case 10: + this->actionFunc = func_80B992C0; + func_80B96BEC(this, 1, 0); + if (ENZOT_GET_FC00(&this->actor) != 0x3F) { + this->path = &globalCtx->setupPathList[ENZOT_GET_FC00(&this->actor)]; + } else { + this->path = NULL; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B97240.s") + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + this->actionFunc = func_80B98998; + func_80B96BEC(this, 2, 0); + this->actor.colChkInfo.cylRadius = 0; + this->actor.shape.yOffset = -1400.0f; + if (!(gSaveContext.weekEventReg[55] & 0x80)) { + Actor_MarkForDeath(&this->actor); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B972E8.s") + case 18: + this->actionFunc = func_80B99384; + if (!(gSaveContext.weekEventReg[55] & 0x80)) { + Actor_MarkForDeath(&this->actor); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B973BC.s") + case 19: + func_80B96BEC(this, 7, 0); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B975F8.s") + case 20: + func_80B96BEC(this, 8, 2); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B9765C.s") + case 21: + func_80B96BEC(this, 9, 2); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B97708.s") + case 22: + this->actionFunc = func_80B980FC; + if (ENZOT_GET_FC00(&this->actor) != 0x3F) { + this->path = &globalCtx->setupPathList[ENZOT_GET_FC00(&this->actor)]; + } else { + this->path = NULL; + } + this->actor.home.rot.x = this->actor.home.rot.z; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B9787C.s") + if ((ENZOT_GET_1F(thisx) >= 2) && (ENZOT_GET_1F(thisx) < 11) && (gSaveContext.weekEventReg[55] & 0x80)) { + Actor_MarkForDeath(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B979DC.s") +void EnZot_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnZot* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B97A44.s") + Collider_DestroyCylinder(globalCtx, &this->collider); + if (ENZOT_GET_1F(&this->actor) == 8) { + gSaveContext.weekEventReg[41] &= (u8)~0x20; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B97B5C.s") +void func_80B96BEC(EnZot* this, s16 arg1, u8 arg2) { + static AnimationHeader* sAnimations[] = { + &D_0600DE20, &D_06002898, &D_0600F4E8, &D_0600E400, &D_0600FDF0, + &D_06010B18, &D_06011424, &D_0600EDF0, &D_0600DF54, &D_0600DF54, + }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B97BF8.s") + if ((arg1 >= 0) && (arg1 < 10)) { + if (arg1 >= 8) { + SkelAnime_ChangeAnim(&this->skelAnime, sAnimations[arg1], 0.0f, arg1 - 8, arg1 - 8, arg2, 0.0f); + } else { + SkelAnime_ChangeAnim(&this->skelAnime, sAnimations[arg1], 1.0f, 0.0f, + SkelAnime_GetFrameCount(&sAnimations[arg1]->common), arg2, -5.0f); + } + this->unk_2F0 = arg1; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B97C40.s") +s32 func_80B96CE4(EnZot* this) { + s32 i; + s32 count = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B97CC8.s") + for (i = 0; i < ARRAY_COUNT(this->unk_2D8); i++) { + if (this->unk_2D8[i] == NULL) { + count++; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B97D6C.s") + return count; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B97E0C.s") +void func_80B96D4C(EnZot* this) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B97E4C.s") + for (i = 0; i < ARRAY_COUNT(this->unk_2D8); i++) { + if ((this->unk_2D8[i] != NULL) && (this->unk_2D8[i]->update == NULL)) { + this->unk_2D8[i] = NULL; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B97FD0.s") +s32 func_80B96DF0(EnZot* this, GlobalContext* globalCtx) { + if (Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx) && Actor_IsActorFacingLink(&this->actor, 0x3000) && + (this->actor.xzDistToPlayer < 100.0f)) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B980FC.s") +s32 func_80B96E5C(EnZot* this) { + Path* path = this->path; + Vec3s* points; + f32 temp_f12; + f32 temp_f14; + f32 phi_f2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B98178.s") + if (path == NULL) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B98348.s") + points = &((Vec3s*)Lib_SegmentedToVirtual(path->points))[this->unk_2D4]; + temp_f12 = points->x - this->actor.world.pos.x; + temp_f14 = points->z - this->actor.world.pos.z; + this->actor.world.rot.y = Math_Atan2S(temp_f12, temp_f14); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.world.rot.y, 2, 2000, 200); + phi_f2 = SQ(this->actor.speedXZ) * SQ(3.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B9849C.s") + if (this->unk_2D4 == 0) { + phi_f2 = SQ(20.0f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B9854C.s") + if ((SQ(temp_f12) + SQ(temp_f14)) < phi_f2) { + this->unk_2D4++; + if (this->unk_2D4 >= path->count) { + this->actor.world.pos.x = points->x; + this->actor.world.pos.z = points->z; + return true; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B985EC.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B98728.s") +s32 func_80B96FB0(EnZot* this) { + Path* path = this->path; + Vec3s* points; + f32 temp_f12; + f32 temp_f14; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B98998.s") + if (path == NULL) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B98A4C.s") + points = &((Vec3s*)Lib_SegmentedToVirtual(path->points))[this->unk_2D4]; + temp_f12 = points->x - this->actor.world.pos.x; + temp_f14 = points->z - this->actor.world.pos.z; + this->actor.world.rot.y = Math_Atan2S(temp_f12, temp_f14); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.world.rot.y, 2, 2000, 200); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B98AD0.s") + if ((SQ(temp_f12) + SQ(temp_f14)) < SQ(10.0f)) { + if (this->unk_2F2 & 0x20) { + this->unk_2D4--; + if (this->unk_2D4 < 0) { + this->unk_2D4 = 1; + this->unk_2F2 &= ~0x20; + return true; + } + } else { + this->unk_2D4++; + if (this->unk_2D4 >= path->count) { + this->unk_2D4 = path->count - 1; + this->unk_2F2 |= 0x20; + return true; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B98BF4.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B98CA8.s") +void func_80B97100(EnZot* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B98E10.s") +void func_80B97110(EnZot* this, GlobalContext* globalCtx) { + u16 textId; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B98F30.s") + if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + textId = 0x125F; + if (gSaveContext.weekEventReg[28] & 0x80) { + textId = 0x1261; + } else { + gSaveContext.weekEventReg[28] |= 0x80; + } + } else { + textId = 0x125C; + if (gSaveContext.weekEventReg[28] & 0x40) { + textId = 0x125E; + } else { + gSaveContext.weekEventReg[28] |= 0x40; + } + } + func_801518B0(globalCtx, textId, &this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B98F94.s") +void func_80B97194(EnZot* this, GlobalContext* globalCtx) { + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + switch (globalCtx->msgCtx.unk11F04) { + case 0x125C: + case 0x125F: + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B990A4.s") + case 0x125D: + case 0x125E: + case 0x1260: + case 0x1261: + func_801477B4(globalCtx); + this->actionFunc = func_80B97240; + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B99160.s") +void func_80B97240(EnZot* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + this->actionFunc = func_80B97194; + func_80B97110(this, globalCtx); + } else if ((this->actor.xzDistToPlayer < 100.0f) && Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx) && + Actor_IsActorFacingLink(&this->actor, 0x3000)) { + func_800B8614(&this->actor, globalCtx, 120.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B991E4.s") +void func_80B972E8(EnZot* this, GlobalContext* globalCtx) { + u16 textId; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B992C0.s") + if (gSaveContext.weekEventReg[29] & 0x10) { + if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + textId = 0x126A; + if (gSaveContext.weekEventReg[29] & 1) { + textId = 0x126D; + } else { + gSaveContext.weekEventReg[29] |= 1; + } + } else { + textId = 0x1267; + if (gSaveContext.weekEventReg[29] & 2) { + textId = 0x1269; + } else { + gSaveContext.weekEventReg[29] |= 2; + } + } + } else if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + textId = 0x1265; + if (gSaveContext.weekEventReg[29] & 4) { + textId = 0x1266; + } else { + gSaveContext.weekEventReg[29] |= 4; + } + } else { + textId = 0x1262; + if (gSaveContext.weekEventReg[29] & 8) { + textId = 0x1264; + } else { + gSaveContext.weekEventReg[29] |= 8; + } + } + func_801518B0(globalCtx, textId, &this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B99384.s") +void func_80B973BC(EnZot* this, GlobalContext* globalCtx) { + func_80B96D4C(this); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0x800, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + switch (globalCtx->msgCtx.unk11F04) { + case 0x126E: + case 0x1270: + case 0x1273: + case 0x1274: + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/EnZot_Update.s") + case 0x1272: + func_80151938(globalCtx, 0x126F); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B99580.s") + case 0x126F: + func_801159EC(90); + func_80151938(globalCtx, 0x1270); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B995A4.s") + case 0x1275: + if (gSaveContext.rupees < 10) { + func_80151938(globalCtx, 0x1277); + } else { + func_80151938(globalCtx, 0x1278); + func_801159EC(-10); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/func_80B99758.s") + case 0x1276: + func_80151938(globalCtx, 0x1275); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zot/EnZot_Draw.s") + case 0x1271: + case 0x1277: + case 0x1278: + case 0x1279: + func_801477B4(globalCtx); + func_80B965D0(this, globalCtx); + this->actor.flags &= ~0x10000; + this->actor.textId = 0; + this->actionFunc = func_80B97708; + if ((this->actor.cutscene != -1) && !(this->unk_2F2 & 1)) { + ActorCutscene_Stop(this->actor.cutscene); + } + this->unk_2F2 &= ~1; + break; + } + } + + if (this->unk_2F2 & 1) { + if (this->actor.cutscene == -1) { + this->unk_2F2 &= ~1; + } else if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } else if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + this->unk_2F2 &= ~1; + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } + } +} + +void func_80B975F8(EnZot* this, GlobalContext* globalCtx) { + func_80B96D4C(this); + if (func_800B84D0(&this->actor, globalCtx)) { + this->actionFunc = func_80B973BC; + } else { + func_800B8500(&this->actor, globalCtx, 10000.0f, 1000.0f, 0); + } +} + +void func_80B9765C(EnZot* this, GlobalContext* globalCtx) { + if (1) { + do { } while (0); } + + func_80B96D4C(this); + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + u16 temp = globalCtx->msgCtx.unk11F04; + u32 temp2; + + if ((temp == 0x1262) || (temp == 0x1267) || (temp == 0x126A) || (temp == 0x126B)) { + temp2 = temp; + func_80151938(globalCtx, temp2 + 1); + } else { + func_801477B4(globalCtx); + this->actionFunc = func_80B97708; + } + } +} + +void func_80B97708(EnZot* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + s32 phi_v1; + + func_80B96D4C(this); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 2, 0x400, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (func_800B84D0(&this->actor, globalCtx)) { + this->actionFunc = func_80B9765C; + func_80B972E8(this, globalCtx); + return; + } + + if (!(player->stateFlags1 & 0x2000000)) { + phi_v1 = func_80B96CE4(this); + } else { + phi_v1 = 0; + } + + if (phi_v1 != 0) { + gSaveContext.weekEventReg[29] |= 0x10; + this->actor.flags |= 0x10000; + if (phi_v1 == 5) { + if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + this->actor.textId = 0x126E; + } else { + this->actor.textId = 0x1272; + } + } else if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + this->actor.textId = 0x1273; + } else { + this->actor.textId = 0x1276; + } + this->unk_2F2 |= 1; + func_80B975F8(this, globalCtx); + this->actionFunc = func_80B975F8; + } else if (func_80B96DF0(this, globalCtx)) { + func_800B8614(&this->actor, globalCtx, 120.0f); + } +} + +void func_80B9787C(EnZot* this, GlobalContext* globalCtx) { + u16 textId; + + if (this->actor.textId == 0) { + if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + switch (ENZOT_GET_1F(&this->actor)) { + case 2: + if (gSaveContext.weekEventReg[37] & 0x40) { + textId = 0x127E; + } else { + textId = 0x127C; + gSaveContext.weekEventReg[37] |= 0x40; + } + break; + + case 3: + if (gSaveContext.weekEventReg[38] & 1) { + textId = 0x1284; + } else { + textId = 0x1282; + gSaveContext.weekEventReg[38] |= 1; + } + break; + + default: + if (gSaveContext.weekEventReg[38] & 4) { + textId = 0x128A; + } else { + textId = 0x1288; + gSaveContext.weekEventReg[38] |= 4; + } + break; + } + } else { + switch (ENZOT_GET_1F(&this->actor)) { + case 2: + if (gSaveContext.weekEventReg[37] & 0x20) { + textId = 0x127B; + } else { + textId = 0x1279; + gSaveContext.weekEventReg[37] |= 0x20; + } + break; + + case 3: + if (gSaveContext.weekEventReg[37] & 0x80) { + textId = 0x1281; + } else { + textId = 0x127F; + gSaveContext.weekEventReg[37] |= 0x80; + } + break; + + default: + if (gSaveContext.weekEventReg[38] & 2) { + textId = 0x1287; + } else { + textId = 0x1285; + gSaveContext.weekEventReg[38] |= 2; + } + break; + } + } + func_801518B0(globalCtx, textId, &this->actor); + } +} + +void func_80B979DC(EnZot* this, GlobalContext* globalCtx) { + if (func_80B96E5C(this)) { + this->actionFunc = func_80B97B5C; + func_80B96BEC(this, 0, 0); + this->actor.speedXZ = 0.0f; + } else { + this->actor.speedXZ = 1.5f; + } +} + +void func_80B97A44(EnZot* this, GlobalContext* globalCtx) { + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + switch (globalCtx->msgCtx.unk11F04) { + case 0x1279: + case 0x127C: + case 0x127F: + case 0x1282: + case 0x1285: + case 0x1288: + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + break; + + case 0x127D: + case 0x127E: + case 0x1283: + case 0x1284: + case 0x1289: + case 0x128A: + func_801477B4(globalCtx); + if (!(this->unk_2F2 & 2)) { + this->unk_2F2 |= 2; + this->actionFunc = func_80B979DC; + func_80B96BEC(this, 1, 0); + } else { + this->actionFunc = func_80B97B5C; + } + break; + + default: + func_801477B4(globalCtx); + this->actionFunc = func_80B97B5C; + break; + } + } +} + +void func_80B97B5C(EnZot* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 2, 0x400, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (func_800B84D0(&this->actor, globalCtx)) { + this->actionFunc = func_80B97A44; + func_80B9787C(this, globalCtx); + } else if (func_80B96DF0(this, globalCtx)) { + func_800B8614(&this->actor, globalCtx, 120.0f); + } +} + +void func_80B97BF8(EnZot* this, GlobalContext* globalCtx) { + u16 textId; + + if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + textId = 0x128C; + } else { + textId = 0x128B; + } + func_801518B0(globalCtx, textId, &this->actor); +} + +void func_80B97C40(EnZot* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0x800, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + func_801477B4(globalCtx); + this->actionFunc = func_80B97CC8; + } +} + +void func_80B97CC8(EnZot* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + this->actionFunc = func_80B97C40; + func_801518B0(globalCtx, 0x128B, &this->actor); + } else if (Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx) && (this->actor.xzDistToPlayer < 100.0f)) { + func_800B8614(&this->actor, globalCtx, 120.0f); + } +} + +void func_80B97D6C(EnZot* this, GlobalContext* globalCtx) { + if (func_80B96E5C(this)) { + this->actionFunc = func_80B97CC8; + this->actor.speedXZ = 0.0f; + func_80B96BEC(this, 0, 0); + } else { + this->actor.speedXZ = 8.0f; + } + + if (func_801378B8(&this->skelAnime, 0.0f) || func_801378B8(&this->skelAnime, 5.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_ZORA_WALK); + } +} + +void func_80B97E0C(EnZot* this, GlobalContext* globalCtx) { + if (this->unk_2F2 & 0x40) { + this->actionFunc = func_80B97D6C; + func_80B96BEC(this, 3, 0); + } +} + +void func_80B97E4C(EnZot* this, GlobalContext* globalCtx) { + if (1) { + do { } while (0); } + + if (this->unk_2F2 & 0x40) { + func_80B96BEC(this, 0, 0); + } + + if (!(this->unk_2F2 & 4)) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0x800, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; + } + + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + switch (globalCtx->msgCtx.unk11F04) { + case 0x128C: + this->unk_2F2 &= ~4; + func_80B96BEC(this, 6, 2); + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + break; + + case 0x128D: + case 0x128E: + case 0x128F: + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + break; + + case 0x1290: + func_801477B4(globalCtx); + this->actionFunc = func_80B97D6C; + this->unk_2F2 |= 4; + func_80B96BEC(this, 3, 0); + gSaveContext.weekEventReg[38] |= 8; + break; + + case 0x128B: + func_801477B4(globalCtx); + this->actionFunc = func_80B97FD0; + break; + } + } +} + +void func_80B97FD0(EnZot* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 2, 0x800, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (func_800B84D0(&this->actor, globalCtx)) { + this->actionFunc = func_80B97E4C; + func_80B97BF8(this, globalCtx); + } else if (gSaveContext.weekEventReg[38] & 8) { + if ((this->actor.xzDistToPlayer < 120.0f) && (gSaveContext.playerForm == PLAYER_FORM_ZORA)) { + this->unk_2F2 |= 4; + this->actionFunc = func_80B97E0C; + func_80B96BEC(this, 6, 2); + } + } else if (Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx) && (this->actor.xzDistToPlayer < 100.0f)) { + func_800B8614(&this->actor, globalCtx, 120.0f); + } +} + +void func_80B980FC(EnZot* this, GlobalContext* globalCtx) { + if (this->actor.home.rot.x > 0) { + this->actor.home.rot.x--; + } else if (func_80B96E5C(this)) { + this->actionFunc = func_80B97100; + this->actor.speedXZ = 0.0f; + } else { + this->actor.speedXZ = 8.0f; + if (this->unk_2F0 != 3) { + func_80B96BEC(this, 3, 0); + } + } +} + +void func_80B98178(EnZot* this, GlobalContext* globalCtx) { + u16 textId; + s32 phi_v0; + + switch (ENZOT_GET_1F(&this->actor)) { + case 6: + if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + if (CURRENT_DAY == 3) { + textId = 0x129D; + } else if (gSaveContext.weekEventReg[39] & 1) { + textId = 0x129C; + } else { + textId = 0x129B; + gSaveContext.weekEventReg[39] |= 1; + } + } else if (gSaveContext.weekEventReg[38] & 0x80) { + textId = 0x1293; + } else { + textId = 0x1291; + gSaveContext.weekEventReg[38] |= 0x80; + } + break; + + case 7: + if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.weekEventReg[39] & 4) { + textId = 0x12AA; + } else { + textId = 0x12A6; + gSaveContext.weekEventReg[39] |= 4; + } + } else if (Flags_GetSwitch(globalCtx, this->actor.home.rot.z & 0x7F)) { + textId = 0x12A0; + } else if (gSaveContext.weekEventReg[39] & 2) { + textId = 0x12A5; + } else { + textId = 0x12A2; + gSaveContext.weekEventReg[39] |= 2; + } + break; + + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + phi_v0 = (ENZOT_GET_1F(&this->actor) * 4) - 44; + if (gSaveContext.weekEventReg[79] & 1) { + phi_v0 += 2; + } + + if (gSaveContext.playerForm != PLAYER_FORM_ZORA) { + phi_v0++; + } + textId = phi_v0 + 0x1302; + break; + + default: + if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + textId = 0x129F; + } else { + textId = 0x1295; + } + break; + } + func_801518B0(globalCtx, textId, &this->actor); +} + +void func_80B98348(EnZot* this, GlobalContext* globalCtx) { + s16 y; + + if (ENZOT_GET_1F(&this->actor) == 7) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0x800, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; + } else if (Actor_IsActorFacingLink(&this->actor, 0x3000)) { + this->unk_2F2 &= ~8; + } else { + this->unk_2F2 |= 8; + Math_SmoothStepToS(&this->unk_2C4.x, 0, 6, 6200, 100); + Math_SmoothStepToS(&this->unk_2CA.x, 0, 6, 6200, 100); + y = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + if (y > 0) { + Math_SmoothStepToS(&this->unk_2C4.y, 0x3000, 6, 6200, 100); + Math_SmoothStepToS(&this->unk_2CA.y, 0x1000, 6, 6200, 100); + } else { + Math_SmoothStepToS(&this->unk_2C4.y, -0x3000, 6, 6200, 100); + Math_SmoothStepToS(&this->unk_2CA.y, -0x1000, 6, 6200, 100); + } + } +} + +void func_80B9849C(EnZot* this, GlobalContext* globalCtx) { + func_80B98348(this, globalCtx); + if (func_800B84D0(&this->actor, globalCtx)) { + if (this->unk_2D4 == 2) { + func_801518B0(globalCtx, 0x12AD, &this->actor); + } else { + func_801518B0(globalCtx, 0x12B0, &this->actor); + } + this->actionFunc = func_80B98728; + } else { + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + } +} + +void func_80B9854C(EnZot* this, GlobalContext* globalCtx) { + func_80B98348(this, globalCtx); + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + this->actionFunc = func_80B9849C; + this->actor.flags |= 0x10000; + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + } else { + func_800B8A1C(&this->actor, globalCtx, this->unk_2D4, 10000.0f, 50.0f); + } +} + +void func_80B985EC(EnZot* this, GlobalContext* globalCtx) { + s32 temp_v0; + Player* player = PLAYER; + + func_80B98348(this, globalCtx); + if (func_80152498(&globalCtx->msgCtx) == 0x10) { + temp_v0 = func_80123810(globalCtx); + if (temp_v0 > 0) { + func_801477B4(globalCtx); + if ((temp_v0 == 0x13) && CHECK_QUEST_ITEM(25) && func_8013A4C4(4)) { + if (func_8013A4C4(5) && func_8013A4C4(6)) { + player->actor.textId = 0x12AE; + } else { + player->actor.textId = 0x12AC; + } + REMOVE_QUEST_ITEM(25); + } else { + player->actor.textId = 0x12AB; + } + this->actionFunc = func_80B98728; + } else if (temp_v0 < 0) { + func_80151938(globalCtx, 0x12AB); + this->actionFunc = func_80B98728; + } + } +} + +void func_80B98728(EnZot* this, GlobalContext* globalCtx) { + func_80B98348(this, globalCtx); + + switch (func_80152498(&globalCtx->msgCtx)) { + case 4: + if (func_80147624(globalCtx) && (globalCtx->msgCtx.unk11F04 == 0x1293)) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_8019F208(); + func_80151938(globalCtx, 0x1294); + break; + + case 1: + func_8019F230(); + func_80151938(globalCtx, 0x1298); + break; + } + } + break; + + case 5: + if (func_80147624(globalCtx)) { + switch (globalCtx->msgCtx.unk11F04) { + case 0x1291: + case 0x1292: + case 0x1296: + case 0x1298: + case 0x1299: + case 0x129B: + case 0x129D: + case 0x129E: + case 0x12A0: + case 0x12A2: + case 0x12A3: + case 0x12A4: + case 0x12A6: + case 0x12A7: + case 0x12A8: + case 0x12AE: + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + break; + + case 0x12A9: + case 0x12AA: + func_80151938(globalCtx, 0xFF); + this->actionFunc = func_80B985EC; + break; + + case 0x1294: + if (CURRENT_DAY == 3) { + func_80151938(globalCtx, 0x1296); + } else { + func_80151938(globalCtx, 0x1295); + } + break; + + case 0x12AB: + func_801477B4(globalCtx); + this->actionFunc = func_80B98998; + break; + + case 0x12AC: + func_801477B4(globalCtx); + this->unk_2D4 = 2; + this->actionFunc = func_80B9854C; + func_80B9854C(this, globalCtx); + break; + + case 0x12AF: + func_801477B4(globalCtx); + this->unk_2D4 = 4; + this->actionFunc = func_80B9854C; + func_80B9854C(this, globalCtx); + break; + + default: + func_801477B4(globalCtx); + this->actionFunc = func_80B98998; + this->actor.flags &= ~0x10000; + break; + } + } + break; + } +} + +void func_80B98998(EnZot* this, GlobalContext* globalCtx) { + this->unk_2F2 &= ~8; + if (func_800B84D0(&this->actor, globalCtx)) { + this->actionFunc = func_80B98728; + func_80B98178(this, globalCtx); + } else if ((this->actor.xzDistToPlayer < 100.0f) && Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx) && + Actor_IsActorFacingLink(&this->actor, 0x7000)) { + func_800B8614(&this->actor, globalCtx, 120.0f); + } +} + +void func_80B98A4C(EnZot* this, GlobalContext* globalCtx) { + u16 textId; + + if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.weekEventReg[39] & 0x80) { + textId = 0x12B6; + } else { + textId = 0x12B4; + gSaveContext.weekEventReg[39] |= 0x80; + } + } else if (gSaveContext.weekEventReg[39] & 0x40) { + textId = 0x12B3; + } else { + textId = 0x12B1; + gSaveContext.weekEventReg[39] |= 0x40; + } + func_801518B0(globalCtx, textId, &this->actor); +} + +void func_80B98AD0(EnZot* this, GlobalContext* globalCtx) { + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + switch (globalCtx->msgCtx.unk11F04) { + case 0x12B1: + case 0x12B4: + case 0x12B7: + case 0x12B9: + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + break; + + case 0x12B8: + func_801477B4(globalCtx); + this->actionFunc = func_80B98CA8; + gSaveContext.weekEventReg[41] &= (u8)~0x20; + func_8019C300(0); + break; + + case 0x12BA: + func_801477B4(globalCtx); + this->actionFunc = func_80B98CA8; + gSaveContext.weekEventReg[41] |= 0x20; + func_8019C300(0); + break; + + default: + func_801477B4(globalCtx); + this->actionFunc = func_80B98CA8; + break; + } + } +} + +void func_80B98BF4(EnZot* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + this->actor.flags &= ~0x10000; + if (gSaveContext.weekEventReg[41] & 0x20) { + func_801518B0(globalCtx, 0x12B7, &this->actor); + this->actionFunc = func_80B98AD0; + } else { + func_801518B0(globalCtx, 0x12B9, &this->actor); + this->actionFunc = func_80B98AD0; + } + } else { + func_800B8614(&this->actor, globalCtx, 120.0f); + } +} + +void func_80B98CA8(EnZot* this, GlobalContext* globalCtx) { + if (func_800B8718(&this->actor, globalCtx)) { + globalCtx->msgCtx.unk1202A = 4; + func_8019B544(0xFFFF); + this->actionFunc = func_80B98BF4; + this->actor.flags |= 0x10000; + func_800B8614(&this->actor, globalCtx, 120.0f); + } else if (func_800B84D0(&this->actor, globalCtx)) { + this->actionFunc = func_80B98AD0; + func_80B98A4C(this, globalCtx); + } else { + if ((this->actor.xzDistToPlayer < 100.0f) && Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx)) { + func_800B8614(&this->actor, globalCtx, 120.0f); + } + + if ((gSaveContext.playerForm == PLAYER_FORM_ZORA) || (this->actor.xzDistToPlayer < 100.0f)) { + func_800B874C(&this->actor, globalCtx, 120.0, 100.0f); + } + } + + if (this->actor.xzDistToPlayer > 100.0f) { + gSaveContext.weekEventReg[41] &= (u8)~0x20; + } +} + +void func_80B98E10(EnZot* this, GlobalContext* globalCtx) { + u16 textId; + + if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + if (Flags_GetSwitch(globalCtx, this->actor.home.rot.z & 0x7F)) { + if (gSaveContext.weekEventReg[40] & 4) { + textId = 0x12C5; + } else { + textId = 0x12C3; + gSaveContext.weekEventReg[40] |= 4; + } + } else if (gSaveContext.weekEventReg[40] & 2) { + textId = 0x12C2; + } else { + textId = 0x12C0; + gSaveContext.weekEventReg[40] |= 2; + } + } else { + if (Flags_GetSwitch(globalCtx, this->actor.home.rot.z & 0x7F)) { + if (this->unk_2F2 & 0x10) { + textId = 0x12BF; + } else { + textId = 0x12BE; + this->unk_2F2 |= 0x10; + } + } else if (gSaveContext.weekEventReg[40] & 1) { + textId = 0x12BC; + } else { + gSaveContext.weekEventReg[40] |= 1; + this->unk_2F2 |= 4; + textId = 0x12BB; + } + } + func_801518B0(globalCtx, textId, &this->actor); +} + +void func_80B98F30(EnZot* this, GlobalContext* globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + this->actionFunc = func_80B990A4; + } else { + func_800B8A1C(&this->actor, globalCtx, 2, 10000.0f, 50.0f); + } +} + +void func_80B98F94(EnZot* this, GlobalContext* globalCtx) { + if (!(this->unk_2F2 & 4)) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0x800, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; + } + + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + switch (globalCtx->msgCtx.unk11F04) { + case 0x12BB: + this->unk_2F2 &= ~4; + + case 0x12BC: + case 0x12C0: + case 0x12C3: + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + break; + + case 0x12BE: + func_801477B4(globalCtx); + this->actionFunc = func_80B98F30; + func_80B98F30(this, globalCtx); + break; + + default: + func_801477B4(globalCtx); + this->actionFunc = func_80B990A4; + break; + } + } +} + +void func_80B990A4(EnZot* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 2, 0x400, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (func_800B84D0(&this->actor, globalCtx)) { + this->actionFunc = func_80B98F94; + func_80B98E10(this, globalCtx); + } else if (Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx) && (this->actor.xzDistToPlayer < 100.0f)) { + func_800B8614(&this->actor, globalCtx, 120.0f); + } +} + +void func_80B99160(EnZot* this, GlobalContext* globalCtx) { + u16 textId; + + if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.weekEventReg[40] & 0x10) { + textId = 0x12CD; + } else { + textId = 0x12CA; + gSaveContext.weekEventReg[40] |= 0x10; + } + } else if (gSaveContext.weekEventReg[40] & 8) { + textId = 0x12C9; + } else { + textId = 0x12C6; + gSaveContext.weekEventReg[40] |= 8; + } + func_801518B0(globalCtx, textId, &this->actor); +} + +void func_80B991E4(EnZot* this, GlobalContext* globalCtx) { + if (1) { + do { } while (0); } + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0x800, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + u16 temp = globalCtx->msgCtx.unk11F04; + u32 temp2; + + if ((temp == 0x12C6) || (temp == 0x12C7) || (temp == 0x12CA) || (temp == 0x12CB)) { + temp2 = temp; + func_80151938(globalCtx, temp2 + 1); + } else { + func_801477B4(globalCtx); + this->actionFunc = func_80B992C0; + func_80B96BEC(this, 1, 0); + } + } +} + +void func_80B992C0(EnZot* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + this->actionFunc = func_80B991E4; + func_80B99160(this, globalCtx); + this->actor.speedXZ = 0.0f; + func_80B96BEC(this, 0, 0); + } else { + if (Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx) && (this->actor.xzDistToPlayer < 100.0f)) { + func_800B8614(&this->actor, globalCtx, 120.0f); + } + this->actor.speedXZ = 1.5f; + func_80B96FB0(this); + } +} + +void func_80B99384(EnZot* this, GlobalContext* globalCtx) { +} + +void EnZot_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnZot* this = THIS; + + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 15.0f, 30.0f, 5); + + this->unk_2F2 &= ~0x40; + if (SkelAnime_FrameUpdateMatrix(&this->skelAnime) && (this->unk_2F0 != 0)) { + this->unk_2F2 |= 0x40; + } + + this->actionFunc(this, globalCtx); + if (!(this->unk_2F2 & 8)) { + if (!(this->unk_2F2 & 4) && func_80B96DF0(this, globalCtx)) { + func_800E9250(globalCtx, &this->actor, &this->unk_2C4, &this->unk_2CA, this->actor.focus.pos); + } else { + Math_SmoothStepToS(&this->unk_2C4.x, 0, 6, 6200, 100); + Math_SmoothStepToS(&this->unk_2C4.y, 0, 6, 6200, 100); + Math_SmoothStepToS(&this->unk_2CA.x, 0, 6, 6200, 100); + Math_SmoothStepToS(&this->unk_2CA.y, 0, 6, 6200, 100); + } + } + + if (DECR(this->unk_2EE) == 0) { + this->unk_2EE = Rand_S16Offset(60, 60); + } + + this->unk_2EC = this->unk_2EE; + if (this->unk_2EC > 2) { + this->unk_2EC = 0; + } +} + +Gfx* func_80B99580(GraphicsContext* gfxCtx) { + Gfx* dList = GRAPH_ALLOC(gfxCtx, sizeof(Gfx) * 2); + + gSPEndDisplayList(dList); + + return dList; +} + +s32 EnZot_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnZot* this = THIS; + s32 pad; + + if (limbIndex == 15) { + SysMatrix_InsertTranslation(1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + SysMatrix_InsertXRotation_s(this->unk_2C4.y, MTXMODE_APPLY); + SysMatrix_InsertZRotation_s(this->unk_2C4.x, MTXMODE_APPLY); + SysMatrix_InsertTranslation(-1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + } + + if (limbIndex == 8) { + SysMatrix_InsertXRotation_s(this->unk_2CA.y * -1, MTXMODE_APPLY); + SysMatrix_InsertZRotation_s(this->unk_2CA.x * -1, MTXMODE_APPLY); + } + + if (((this->unk_2F0 == 8) || (this->unk_2F0 == 9)) && + ((limbIndex == 8) || (limbIndex == 10) || (limbIndex == 13))) { + rot->y += (s16)(Math_SinS(globalCtx->state.frames * ((limbIndex * 50) + 0x814)) * 200.0f); + rot->z += (s16)(Math_CosS(globalCtx->state.frames * ((limbIndex * 50) + 0x940)) * 200.0f); + } + return false; +} + +void EnZot_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Vec3f D_80B99934 = { 400.0f, 0.0f, 0.0f }; + EnZot* this = THIS; + + if (limbIndex == 15) { + SysMatrix_MultiplyVector3fByState(&D_80B99934, &this->actor.focus.pos); + } +} + +void EnZot_Draw(Actor* thisx, GlobalContext* globalCtx) { + UNK_PTR sp4C[] = { + &D_060050A0, + &D_060058A0, + &D_060060A0, + }; + EnZot* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sp4C[this->unk_2EC])); + gSPSegment(POLY_OPA_DISP++, 0x0C, func_80B99580(globalCtx->state.gfxCtx)); + + SkelAnime_DrawSV(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, this->skelAnime.dListCount, + EnZot_OverrideLimbDraw, EnZot_PostLimbDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Zot/z_en_zot.h b/src/overlays/actors/ovl_En_Zot/z_en_zot.h index 0a5b8137a..06fb724ae 100644 --- a/src/overlays/actors/ovl_En_Zot/z_en_zot.h +++ b/src/overlays/actors/ovl_En_Zot/z_en_zot.h @@ -7,9 +7,25 @@ struct EnZot; typedef void (*EnZotActionFunc)(struct EnZot*, GlobalContext*); +#define ENZOT_GET_1F(thisx) ((thisx)->params & 0x1F) +#define ENZOT_GET_FC00(thisx) (((thisx)->params & 0xFC00) >> 0xA) + typedef struct EnZot { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1B4]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ ColliderCylinder collider; + /* 0x01D4 */ Vec3s jointTable[20]; + /* 0x024C */ Vec3s morphTable[20]; + /* 0x02C4 */ Vec3s unk_2C4; + /* 0x02CA */ Vec3s unk_2CA; + /* 0x02D0 */ Path* path; + /* 0x02D4 */ s32 unk_2D4; + /* 0x02D8 */ Actor* unk_2D8[5]; + /* 0x02EC */ s16 unk_2EC; + /* 0x02EE */ s16 unk_2EE; + /* 0x02F0 */ s16 unk_2F0; + /* 0x02F2 */ u16 unk_2F2; + /* 0x02F4 */ s16 unk_2F4; /* 0x02F8 */ EnZotActionFunc actionFunc; } EnZot; // size = 0x2FC diff --git a/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.c b/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.c index 48e200ca1..b5272432e 100644 --- a/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.c +++ b/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.c @@ -1,3 +1,9 @@ +/* + * File: z_obj_etcetera.c + * Overlay: ovl_Obj_Etcetera + * Description: Deku Flower + */ + #include "z_obj_etcetera.h" #define FLAGS 0x00000010 @@ -8,12 +14,12 @@ void ObjEtcetera_Init(Actor* thisx, GlobalContext* globalCtx); void ObjEtcetera_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjEtcetera_Update(Actor* thisx, GlobalContext* globalCtx); -void func_80A7BF08(ObjEtcetera* this, GlobalContext* globalCtx); -void func_80A7C168(ObjEtcetera* this, GlobalContext* globalCtx); -void func_80A7C1F0(ObjEtcetera* this, GlobalContext* globalCtx); -void func_80A7C308(ObjEtcetera* this, GlobalContext* globalCtx); +void ObjEtcetera_PlaySmallFlutterAnimation(ObjEtcetera* this, GlobalContext* globalCtx); +void ObjEtcetera_DoIntenseOscillation(ObjEtcetera* this, GlobalContext* globalCtx); +void ObjEtcetera_Setup(ObjEtcetera* this, GlobalContext* globalCtx); +void ObjEtcetera_DrawIdle(Actor* thisx, GlobalContext* globalCtx); +void ObjEtcetera_DrawAnimated(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Etcetera_InitVars = { ACTOR_OBJ_ETCETERA, ACTORCAT_BG, @@ -26,35 +32,290 @@ const ActorInit Obj_Etcetera_InitVars = { (ActorFunc)NULL, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A7C790 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x01000202, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x01000202, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 20, 14, 0, { 0, 0, 0 } }, }; -#endif - extern ColliderCylinderInit D_80A7C790; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/ObjEtcetera_Init.s") +static s16 objectIds[] = { + GAMEPLAY_KEEP, + GAMEPLAY_KEEP, + GAMEPLAY_KEEP, + GAMEPLAY_KEEP, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/ObjEtcetera_Destroy.s") +/** + * Most interactions with a Deku Flower cause it to slightly oscillate on the X and Z axes. + * When these small oscillations happen, the game determines how to scale the appropriate + * axes by using this table. + */ +static f32 oscillationTable[] = { + -1.0, -1.0, -1.0, -0.7, 0.0, 0.7, 1.0, 0.7, 0.0, -0.7, -1.0, -0.7, 0.0, 0.7, 1.0, 0.7, 0.0, -0.7, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/func_80A7BDC8.s") +void ObjEtcetera_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjEtcetera* this = THIS; + s32 objectIndex; + s32 type = DEKU_FLOWER_TYPE(&this->dyna.actor); + s32 floorBgId; + Vec3f pos; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/func_80A7BE8C.s") + if ((type < DEKU_FLOWER_TYPE_PINK) || (type >= DEKU_FLOWER_TYPE_MAX)) { + type = DEKU_FLOWER_TYPE_PINK; + } + objectIndex = Object_GetIndex(&globalCtx->objectCtx, objectIds[type]); + if (objectIndex >= 0) { + this->objIndex = objectIndex; + } + pos.x = this->dyna.actor.world.pos.x; + pos.y = this->dyna.actor.world.pos.y + 10.0f; + pos.z = this->dyna.actor.world.pos.z; + func_800C411C(&globalCtx->colCtx, &this->dyna.actor.floorPoly, &floorBgId, &this->dyna.actor, &pos); + this->dyna.actor.floorBgId = floorBgId; + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit); + Collider_UpdateCylinder(&this->dyna.actor, &this->collider); + this->actionFunc = ObjEtcetera_Setup; + Actor_SetScale(&this->dyna.actor, 0.01f); + this->dyna.actor.scale.y = 0.02f; + this->burrowFlag = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/func_80A7BF08.s") +void ObjEtcetera_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjEtcetera* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/func_80A7C168.s") + BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/func_80A7C1F0.s") +void ObjEtcetera_DoNormalOscillation(ObjEtcetera* this, GlobalContext* globalCtx) { + if (this->oscillationTimer > 0) { + s32 requiredScopeTemp; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/func_80A7C308.s") + Actor_SetScale(&this->dyna.actor, + (oscillationTable[globalCtx->gameplayFrames % 18] * (0.0001f * this->oscillationTimer)) + 0.01f); + this->dyna.actor.scale.y = 0.02f; + this->oscillationTimer--; + } else { + Actor_SetScale(&this->dyna.actor, 0.01f); + this->dyna.actor.scale.y = 0.02f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/ObjEtcetera_Update.s") +void ObjEtcetera_StartSmallFlutterAnimation(ObjEtcetera* this) { + SkelAnime_ChangeAnim(&this->skelAnime, &D_040117A8, 1.0f, 0.0f, SkelAnime_GetFrameCount(&D_040117A8.common), 2, + 0.0f); + this->dyna.actor.draw = ObjEtcetera_DrawAnimated; + this->actionFunc = ObjEtcetera_PlaySmallFlutterAnimation; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/func_80A7C690.s") +void ObjEtcetera_Idle(ObjEtcetera* this, GlobalContext* globalCtx) { + s16 minOscillationTimer; + Player* player = PLAYER; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/func_80A7C718.s") + if ((player->stateFlags3 & 0x200) && (this->dyna.actor.xzDistToPlayer < 20.0f)) { + // Player is launching out of the Deku Flower + SkelAnime_ChangeAnim(&this->skelAnime, &D_0400EB7C, 1.0f, 0.0f, SkelAnime_GetFrameCount(&D_0400EB7C.common), 2, + 0.0f); + this->dyna.actor.draw = ObjEtcetera_DrawAnimated; + this->actionFunc = ObjEtcetera_DoIntenseOscillation; + Actor_SetScale(&this->dyna.actor, 0.01f); + this->dyna.actor.scale.y = 0.02f; + this->intenseOscillationScale = 0.003f; + this->oscillationTimer = 30; + this->burrowFlag &= ~1; + } else if ((player->stateFlags3 & 0x2000) && (this->dyna.actor.xzDistToPlayer < 30.0f) && + (this->dyna.actor.yDistToPlayer > 0.0f)) { + // Player is hovering above the Deku Flower + minOscillationTimer = 10 - (s32)(this->dyna.actor.yDistToPlayer * 0.05f); + if (this->oscillationTimer < minOscillationTimer) { + this->oscillationTimer = minOscillationTimer; + } + } else { + if (func_800CAF70(&this->dyna)) { + if (!(this->burrowFlag & 1)) { + // Player is walking onto the Deku Flower, or falling on it from a height + this->oscillationTimer = 10; + ObjEtcetera_StartSmallFlutterAnimation(this); + } else if ((player->actor.speedXZ > 0.1f) || ((player->unk_ABC < 0.0f) && !(player->stateFlags3 & 0x100))) { + // Player is walking on top of the Deku Flower, is at the very start of burrowing, or is at the very + // start of launching + this->oscillationTimer = 10; + } + this->burrowFlag |= 1; + } else { + if (this->burrowFlag & 1) { + // Player is walking off the Deku Flower + this->oscillationTimer = 10; + ObjEtcetera_StartSmallFlutterAnimation(this); + } + this->burrowFlag &= ~1; + } + } + if ((this->collider.base.acFlags & AC_HIT)) { + this->oscillationTimer = 10; + ObjEtcetera_StartSmallFlutterAnimation(this); + } + ObjEtcetera_DoNormalOscillation(this, globalCtx); +} + +void ObjEtcetera_PlaySmallFlutterAnimation(ObjEtcetera* this, GlobalContext* globalCtx) { + if (func_800CAF70(&this->dyna)) { + this->burrowFlag |= 1; + } else { + this->burrowFlag &= ~1; + } + if (SkelAnime_FrameUpdateMatrix(&this->skelAnime)) { + this->dyna.actor.draw = ObjEtcetera_DrawIdle; + this->actionFunc = ObjEtcetera_Idle; + } + ObjEtcetera_DoNormalOscillation(this, globalCtx); +} + +void ObjEtcetera_DoIntenseOscillation(ObjEtcetera* this, GlobalContext* globalCtx) { + // In order to match, we are seemingly required to access scale.x at one point + // without using this. We can create a thisx or dyna pointer to achieve that, but + // it's more likely they used dyna given that func_800CAF70 takes a DynaPolyActor. + DynaPolyActor* dyna = &this->dyna; + f32 scaleTemp; + + if (func_800CAF70(dyna)) { + this->burrowFlag |= 1; + } else { + this->burrowFlag &= ~1; + } + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + if (this->oscillationTimer > 0) { + this->oscillationTimer--; + } else { + this->dyna.actor.draw = ObjEtcetera_DrawIdle; + this->actionFunc = ObjEtcetera_Idle; + Actor_SetScale(&this->dyna.actor, 0.01f); + this->dyna.actor.scale.y = 0.02f; + this->oscillationTimer = 0; + this->intenseOscillationScale = 0.0f; + return; + } + this->intenseOscillationScale *= 0.8f; + this->intenseOscillationScale -= (this->dyna.actor.scale.x - 0.01f) * 0.4f; + scaleTemp = dyna->actor.scale.x + this->intenseOscillationScale; + Actor_SetScale(&this->dyna.actor, scaleTemp); + this->dyna.actor.scale.y = 2.0f * scaleTemp; +} + +void ObjEtcetera_Setup(ObjEtcetera* this, GlobalContext* globalCtx) { + CollisionHeader* colHeader = NULL; + s32 type; + CollisionHeader* collisionHeaders[] = { &D_0400E710, &D_0400E710, &D_040118D8, &D_040118D8 }; + s32 pad; + CollisionHeader* thisCollisionHeader; + + type = DEKU_FLOWER_TYPE(&this->dyna.actor); + if ((type < DEKU_FLOWER_TYPE_PINK) || (type >= DEKU_FLOWER_TYPE_MAX)) { + type = DEKU_FLOWER_TYPE_PINK; + } + + if (Object_IsLoaded(&globalCtx->objectCtx, this->objIndex)) { + this->dyna.actor.objBankIndex = this->objIndex; + Actor_SetObjectSegment(globalCtx, &this->dyna.actor); + BcCheck3_BgActorInit(&this->dyna, 1); + thisCollisionHeader = collisionHeaders[type]; + if (thisCollisionHeader != 0) { + BgCheck_RelocateMeshHeader(thisCollisionHeader, &colHeader); + } + this->dyna.bgId = BgCheck_AddActorMesh(globalCtx, &globalCtx->colCtx.dyna, &this->dyna, colHeader); + + type = DEKU_FLOWER_TYPE(&this->dyna.actor); + switch (type) { + case DEKU_FLOWER_TYPE_PINK: + case DEKU_FLOWER_TYPE_PINK_SPAWNED_FROM_MAD_SCRUB: + SkelAnime_Init(globalCtx, &this->skelAnime, &D_04011518, &D_0400EB7C, this->jointTable, + this->morphTable, 11); + this->dList = &D_0400ED80; + break; + case DEKU_FLOWER_TYPE_GOLD: + case DEKU_FLOWER_TYPE_GOLD_SPAWNED_FROM_MAD_SCRUB: + this->dList = &D_04011BD0; + SkelAnime_Init(globalCtx, &this->skelAnime, &D_040127E8, &D_0400EB7C, this->jointTable, + this->morphTable, 11); + this->collider.dim.height = 20; + break; + } + + type = DEKU_FLOWER_TYPE(&this->dyna.actor); + switch (type) { + case DEKU_FLOWER_TYPE_PINK: + case DEKU_FLOWER_TYPE_GOLD: + this->dyna.actor.draw = ObjEtcetera_DrawIdle; + this->actionFunc = ObjEtcetera_Idle; + Actor_SetScale(&this->dyna.actor, 0.01f); + this->dyna.actor.scale.y = 0.02f; + this->dyna.actor.focus.pos.y = this->dyna.actor.home.pos.y + 10.0f; + this->dyna.actor.targetMode = 3; + break; + case DEKU_FLOWER_TYPE_PINK_SPAWNED_FROM_MAD_SCRUB: + case DEKU_FLOWER_TYPE_GOLD_SPAWNED_FROM_MAD_SCRUB: + SkelAnime_ChangeAnim(&this->skelAnime, &D_0400EB7C, 1.0f, 0.0f, + SkelAnime_GetFrameCount(&D_0400EB7C.common), 2, 0.0f); + this->dyna.actor.draw = ObjEtcetera_DrawAnimated; + this->actionFunc = ObjEtcetera_DoIntenseOscillation; + Actor_SetScale(&this->dyna.actor, 0.0f); + this->oscillationTimer = 30; + this->intenseOscillationScale = 0.0f; + this->dyna.actor.focus.pos.y = this->dyna.actor.home.pos.y + 10.0f; + this->dyna.actor.targetMode = 3; + break; + } + } +} + +void ObjEtcetera_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjEtcetera* this = THIS; + CollisionPoly* floorPoly; + u8 floorBgId = this->dyna.actor.floorBgId; + + if (floorBgId == BGCHECK_SCENE) { + floorPoly = this->dyna.actor.floorPoly; + if (floorPoly != NULL && this->burrowFlag & 1) { + func_800FAAB4(globalCtx, func_800C9C9C(&globalCtx->colCtx, floorPoly, floorBgId)); + } + } + this->actionFunc(this, globalCtx); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void ObjEtcetera_DrawIdle(Actor* thisx, GlobalContext* globalCtx) { + ObjEtcetera* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C28C(globalCtx->state.gfxCtx); + gSPDisplayList(POLY_OPA_DISP++, this->dList); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void ObjEtcetera_DrawAnimated(Actor* thisx, GlobalContext* globalCtx) { + ObjEtcetera* this = THIS; + + func_8012C5B0(globalCtx->state.gfxCtx); + SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, NULL, NULL, &this->dyna.actor); +} diff --git a/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h b/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h index 13f667c1c..f5642ff28 100644 --- a/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h +++ b/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h @@ -3,14 +3,32 @@ #include "global.h" +#define DEKU_FLOWER_TYPE(thisx) (((thisx)->params & 0xFF80) >> 7) + +typedef enum { + /* 0 */ DEKU_FLOWER_TYPE_PINK, + /* 1 */ DEKU_FLOWER_TYPE_PINK_SPAWNED_FROM_MAD_SCRUB, + /* 2 */ DEKU_FLOWER_TYPE_GOLD, + /* 3 */ DEKU_FLOWER_TYPE_GOLD_SPAWNED_FROM_MAD_SCRUB, + /* 4 */ DEKU_FLOWER_TYPE_MAX, +} DekuFlowerType; + struct ObjEtcetera; typedef void (*ObjEtceteraActionFunc)(struct ObjEtcetera*, GlobalContext*); typedef struct ObjEtcetera { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x13C]; - /* 0x0280 */ ObjEtceteraActionFunc actionFunc; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ SkelAnime skelAnime; + /* 0x1A0 */ ColliderCylinder collider; + /* 0x1EC */ Vec3s jointTable[11]; + /* 0x22E */ Vec3s morphTable[11]; + /* 0x270 */ f32 intenseOscillationScale; + /* 0x274 */ s16 oscillationTimer; + /* 0x276 */ u16 burrowFlag; + /* 0x278 */ s8 objIndex; + /* 0x27C */ Gfx* dList; + /* 0x280 */ ObjEtceteraActionFunc actionFunc; } ObjEtcetera; // size = 0x284 extern const ActorInit Obj_Etcetera_InitVars; diff --git a/src/overlays/gamestates/ovl_opening/z_opening.c b/src/overlays/gamestates/ovl_opening/z_opening.c index e086158fc..b19955071 100644 --- a/src/overlays/gamestates/ovl_opening/z_opening.c +++ b/src/overlays/gamestates/ovl_opening/z_opening.c @@ -1,18 +1,64 @@ /* * File: z_opening.c * Overlay: ovl_opening - * Description: + * Description: Initializes the game into the title screen */ #include "z_opening.h" -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_opening/Opening_SetupForTitleCutscene.s") +void Opening_SetupForTitleCutscene(OpeningContext* this) { + static s32 openingEntrances[] = { 0x1C00, 0x1C10 }; + static s32 openingCutscenes[] = { 0xFFFA, 0xFFFA }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_opening/func_80803EA0.s") + gSaveContext.eventInf[1] &= (u8)~0x80; + gSaveContext.gameMode = 1; -void Opening_Main(GameState* thisx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_opening/Opening_Main.s") + func_80144890(); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_opening/Opening_Destroy.s") + gSaveContext.entranceIndex = openingEntrances[D_801BB12C]; + gSaveContext.nextCutsceneIndex = gSaveContext.cutscene = openingCutscenes[D_801BB12C]; + gSaveContext.sceneSetupIndex = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_opening/Opening_Init.s") + gSaveContext.time = CLOCK_TIME(8, 0); + gSaveContext.day = 1; + + { + GameState* thisx = &this->gameState; + thisx->running = false; + } + SET_NEXT_GAMESTATE(&this->gameState, Play_Init, GlobalContext); + gSaveContext.playerForm = PLAYER_FORM_HUMAN; +} + +void func_80803EA0(OpeningContext* this) { + SREG(33) |= 1; +} + +void Opening_Main(GameState* thisx) { + OpeningContext* this = (OpeningContext*)thisx; + + func_8012CF0C(this->gameState.gfxCtx, 0, 1, 0, 0, 0); + Opening_SetupForTitleCutscene(this); + func_80803EA0(this); +} + +void Opening_Destroy(GameState* thisx) { + ShrinkWindow_Fini(); +} + +void Opening_Init(GameState* thisx) { + OpeningContext* this = (OpeningContext*)thisx; + + Game_SetFramerateDivisor(&this->gameState, 1); + SysMatrix_StateAlloc(&this->gameState); + ShrinkWindow_Init(); + View_Init(&this->view, this->gameState.gfxCtx); + this->gameState.main = Opening_Main; + this->gameState.destroy = Opening_Destroy; + + gSaveContext.respawnFlag = 0; + gSaveContext.respawn[4].entranceIndex = 0xFF; + gSaveContext.respawn[5].entranceIndex = 0xFF; + gSaveContext.respawn[6].entranceIndex = 0xFF; + gSaveContext.respawn[7].entranceIndex = 0xFF; +} diff --git a/src/overlays/gamestates/ovl_opening/z_opening.h b/src/overlays/gamestates/ovl_opening/z_opening.h index 81a12f630..809767fe4 100644 --- a/src/overlays/gamestates/ovl_opening/z_opening.h +++ b/src/overlays/gamestates/ovl_opening/z_opening.h @@ -7,8 +7,8 @@ void Opening_Init(GameState* thisx); void Opening_Destroy(GameState* thisx); typedef struct { - /* 0x000 */ GameState common; - /* 0x0A4 */ UNK_TYPE1 padA4[0x4]; + /* 0x000 */ GameState gameState; + /* 0x0A4 */ UNK_TYPE1 unk_A4[0x4]; /* 0x0A8 */ View view; } OpeningContext; // size = 0x210 diff --git a/src/overlays/gamestates/ovl_select/z_select.c b/src/overlays/gamestates/ovl_select/z_select.c index 20484f13b..da6808725 100644 --- a/src/overlays/gamestates/ovl_select/z_select.c +++ b/src/overlays/gamestates/ovl_select/z_select.c @@ -1,40 +1,934 @@ /* * File: z_select.c * Overlay: ovl_select - * Description: + * Description: Debug map select */ #include "z_select.h" +#include "alloca.h" +#include "overlays/gamestates/ovl_title/z_title.h" -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_select/D_80802390.s") +void Select_LoadTitle(SelectContext* this) { + { + GameState* gameState = &this->state; + gameState->running = false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_select/func_80800910.s") + SET_NEXT_GAMESTATE(&this->state, Title_Init, TitleContext); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_select/func_80800930.s") +void Select_LoadGame(SelectContext* this, u32 entranceIndex, s32 opt) { + if (gSaveContext.fileNum == 0xFF) { + Sram_InitDebugSave(); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_select/func_80800A44.s") + gSaveContext.buttonStatus[0] = BTN_ENABLED; + gSaveContext.buttonStatus[1] = BTN_ENABLED; + gSaveContext.buttonStatus[2] = BTN_ENABLED; + gSaveContext.buttonStatus[3] = BTN_ENABLED; + gSaveContext.buttonStatus[4] = BTN_ENABLED; + gSaveContext.unk_3F1E = 0; + gSaveContext.unk_3F20 = 0; + gSaveContext.unk_3F22 = 0; + gSaveContext.unk_3F24 = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_select/func_808013B8.s") + Audio_QueueSeqCmd(NA_BGM_STOP); + gSaveContext.entranceIndex = entranceIndex; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_select/D_8080343C.s") + if (opt != 0) { + gSaveContext.entranceIndex = + Entrance_CreateIndex((s32)gSaveContext.entranceIndex >> 9, opt, gSaveContext.entranceIndex & 0xF); + } + if (gSaveContext.entranceIndex == 0xC000) { + gSaveContext.day = 0; + gSaveContext.time = CLOCK_TIME(6, 0) - 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_select/func_80801594.s") + gSaveContext.respawn[0].entranceIndex = 0xFFFF; + gSaveContext.seqIndex = 0xFF; + gSaveContext.nightSeqIndex = 0xFF; + gSaveContext.showTitleCard = true; + gSaveContext.respawnFlag = 0; + gSaveContext.respawn[4].entranceIndex = 0xFF; + gSaveContext.respawn[5].entranceIndex = 0xFF; + gSaveContext.respawn[6].entranceIndex = 0xFF; + gSaveContext.respawn[7].entranceIndex = 0xFF; + D_801BDBB0 = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_select/D_80803588.s") + do { + GameState* gameState = &this->state; + gameState->running = false; + } while (0); + SET_NEXT_GAMESTATE(&this->state, Play_Init, GlobalContext); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_select/func_80801620.s") +// "Translation" ("Actual name") +static SceneSelectEntry sScenes[] = { + // " 0: OP Woods for Cutscene Use" (" 0: Forest Opening Scene") + { " 0:OP\x8Cデモ\x8Dヨウ シンリン", Select_LoadGame, 0x1C00 }, + // " 0-0: Lost Woods" (" 0-0: Lost Woods") + { " 0-0:\x8Dマヨイ ノ モリ", Select_LoadGame, 0xC400 }, + // " 1: Town Outskirts" (" 1: Termina Field") + { " 1:\x8Cタウン \x8Dコウガイ", Select_LoadGame, 0x5400 }, + // " 1-0: Astral Observatory" (" 1-0: Astral Observatory") + { " 1-0:\x8Dテンモンカンソクジョ", Select_LoadGame, 0x4C00 }, + // " 1 - 1: Astral Observatory Telescope" (" 1 - 1: Astral Observatory - Telescope") + { " 1-1:\x8Dテンモンカンソクジョ デ ボウエンキョウ", Select_LoadGame, 0x54A0 }, + // " 1 - 2: Ikana Graveyard" (" 1 - 2: Ikana Canyon Graveyard") + { " 1-2:\x8Cイカーナ \x8Dノ ハカバ", Select_LoadGame, 0x8000 }, + // " 2: Romani Ranch" (" 2: Romani Ranch") + { " 2:\x8Cロマニー \x8Dボクジョウ", Select_LoadGame, 0x6400 }, + // " 3: Milk Road" (" 3: Milk Road") + { " 3:\x8Cミルクロード", Select_LoadGame, 0x3E00 }, + // " 4: Main Building" (" 4: Ranch House") + { " 4:\x8Dオモヤ", Select_LoadGame, 0x610 }, + // " 5: Cow Shed" (" 5: Cow Shed") + { " 5:\x8Dウシゴヤ", Select_LoadGame, 0x600 }, + // " 6: Cucco Shed" (" 6: Cucco Shed") + { " 6:\x8Cコッコ \x8Dゴヤ", Select_LoadGame, 0x7E00 }, + // " 7: Dog Racing Area" (" 7: Doggy Racetrack") + { " 7:\x8Cドッグレース\x8Dジョウ", Select_LoadGame, 0x7C00 }, + // " 8: Gorman Track" (" 8: Gorman Track") + { " 8:\x8Cゴーマン トラック", Select_LoadGame, 0xCE00 }, + // " 10: Mountain Village -Winter-" (" 10: Mountain Village - Winter") + { " 10:\x8Dヤマザト -フユ-", Select_LoadGame, 0x9A00 }, + // " 10 - 0: Mountain Village -Spring-" (" 10 - 0: Mountain Village - Spring") + { " 10-0:\x8Dヤマザト -ハル-", Select_LoadGame, 0xAE00 }, + // " 10 - 1: Mountain Village Blacksmith" (" 10 - 1: Mountain Smithy") + { " 10-1:\x8Dヤマザト ノ カジヤ", Select_LoadGame, 0x5200 }, + // " 11: Goron Village -Winter-" (" 11: Goron Village - Winter") + { " 11:\x8Cゴロン\x8D ノ サト -フユ-", Select_LoadGame, 0x9400 }, + // " 11-0: Goron Village -Spring-" (" 11-0: Goron Village - Spring") + { " 11-0:\x8Cゴロン\x8D ノ サト -ハル-", Select_LoadGame, 0x8A00 }, + // " 11-1: Goron Shrine" (" 11-1: Goron Shrine") + { " 11-1:\x8Cゴロン\x8D ノ ホコラ", Select_LoadGame, 0x5E00 }, + // " 11-2: Lone Peak Shrine" (" 11-2: Lone Peak Shrine") + { " 11-2:\x8Dハナレヤマ ノ ホコラ", Select_LoadGame, 0x1500 }, + // " 11-3: Goron Shop" (" 11-3: Goron Shop") + { " 11-3:\x8Cゴロン \x8Dノ ミセ", Select_LoadGame, 0x7400 }, + // " 12: Snowhead" (" 12: Snowhead") + { " 12:\x8Cスノーヘッド", Select_LoadGame, 0xB200 }, + // " 13: Blizzard Path" (" 13: Path to Goron Village - Part 1") + { " 13:\x8Dフブキ ノ ミチ", Select_LoadGame, 0x3200 }, + // " 14: Snowball Path" (" 14: Path to Goron Village - Part 2") + { " 14:\x8Dユキダマ ノ ミチ", Select_LoadGame, 0xB000 }, + // " 15: Goron Racetrack" (" 15: Goron Racetrack") + { " 15:\x8Cゴロンレース \x8Dジョウ", Select_LoadGame, 0xD000 }, + // " 16: Goron Grave" (" 16: Darmani's Grave") + { " 16:\x8Cゴロン \x8Dノ ハカ", Select_LoadGame, 0x9600 }, + // " 17: Snow Field Battle -Winter-" (" 17: Path to Goron Village - Winter") + { " 17:\x8Dセツゲン \x8Cバトル \x8D-フユ-", Select_LoadGame, 0xB400 }, + // " 17-0: Snow Field Battle -Spring-" (" 17-0: Path to Goron Village - Spring") + { " 17-0:\x8Dセツゲン \x8Cバトル \x8D-ハル-", Select_LoadGame, 0xB600 }, + // " 20: Swampland" (" 20: Southern Swamp") + { " 20:\x8Dヌマチ", Select_LoadGame, 0x8400 }, + // " 20-0: Swampland - Afterwards" (" 20-0: Southern Swamp - After Odolwa") + { " 20-0:\x8Dヌマチ ソノゴ", Select_LoadGame, 0xC00 }, + // " 20-1: Swamp Tourist Information" (" 20-1: Tourist Information") + { " 20-1:\x8Dヌマ ノ カンコウアンナイ", Select_LoadGame, 0xA800 }, + // " 20-2: Magic Hags' Potion Shop" (" 20-2: Magic Hags' Potion Shop") + { " 20-2:\x8Dマホウオババ ノ クスリヤ", Select_LoadGame, 0x400 }, + // " 21: Wood Mountain" (" 21: Woodfall") + { " 21:\x8Cウッドマウンテン", Select_LoadGame, 0x8600 }, + // " 21-0: Deku Princess's Prison" (" 21-0: Deku Princess's Prison [Cutscene: Tatl Apologizes]") + { " 21-0:\x8Cデク\x8Dヒメ ノ ロウヤ", Select_LoadGame, 0x3010 }, + // " 22: Deku Castle" (" 22: Deku Palace") + { " 22:\x8Cデクナッツ \x8Dノ シロ", Select_LoadGame, 0x5000 }, + // " 22-0: Boe Hole 0" (" 22-0: Deku Palace Grotto 0 - Deku Baba & Butterflies, Entrance 1") + { " 22-0:\x8Cクロスケ \x8Dノ アナ0", Select_LoadGame, 0x1460 }, + // " 22-1: Boe Hole 1" (" 22-1: Deku Palace Grotto 1 - Deku Baba & Butterflies, Entrance 2") + { " 22-1:\x8Cクロスケ \x8Dノ アナ1", Select_LoadGame, 0x14E0 }, + // " 22-2: Boe Hole 2" (" 22-2: Deku Palace Grotto 2 - Skullwalltula Wall, Lower Entrance") + { " 22-2:\x8Cクロスケ \x8Dノ アナ2", Select_LoadGame, 0x1480 }, + // " 22-3: Boe Hole 3" (" 22-3: Deku Palace Grotto 3 - Skullwalltula Wall, Upper Entrance") + { " 22-3:\x8Cクロスケ \x8Dノ アナ3", Select_LoadGame, 0x14F0 }, + // " 22-4: Boe Hole 4" (" 22-4: Deku Palace Grotto 4 - Bean Seller") + { " 22-4:\x8Cクロスケ \x8Dノ アナ4", Select_LoadGame, 0x14C0 }, + // " 24: Beast Path" (" 24: Road to Swamp") + { " 24:\x8Dケモノミチ", Select_LoadGame, 0x7A00 }, + // " 24-0: Forest Shooting Gallery" (" 24-0: Swamp Shooting Gallery") + { " 24-0:\x8Dモリ ノ シャテキジョウ", Select_LoadGame, 0x4200 }, + // " 25: Deku King's Chamber" (" 25: Deku Palace Throne Room") + { " 25:\x8Cデク\x8Dオウ ノ マ", Select_LoadGame, 0x7600 }, + // " 26: Woods of Mystery" (" 26: Woods of Mystery") + { " 26:\x8Dフシギ ノ モリ", Select_LoadGame, 0xC200 }, + // " 30: Great Bay Coast" (" 30: Great Bay Coast - Entrance Area") + { " 30:\x8Cグレートベイ\x8D ノ カイガン", Select_LoadGame, 0x6800 }, + // " 30-0: Ocean Laboratory" (" 30-0: Marine Research Lab") + { " 30-0:\x8Dカイヨウ ケンキュウジョ", Select_LoadGame, 0x5800 }, + // " 30-1: Fisherman's House" (" 30-1: Fisherman's Hut") + { " 30-1:\x8Dリョウシ ノ イエ", Select_LoadGame, 0x7200 }, + // " 30-2: Pointed Rock" (" 30-2: Twin Pillars") + { " 30-2:\x8Dトンガリ イワ", Select_LoadGame, 0x4400 }, + // " 31: Cape" (" 31: Great Bay Coast - River Area") + { " 31:\x8Dミサキ", Select_LoadGame, 0x6A00 }, + // " 32: Outside of Pirates' Fortress" (" 32: Pirates' Fortress - Exterior") + { " 32:\x8Dカイゾクノトリデマエ", Select_LoadGame, 0x7000 }, + // " 32-0: Pirates' Fortress" (" 32-0: Pirates' Fortress - Courtyard") + { " 32-0:\x8Dカイゾクノトリデ", Select_LoadGame, 0x2200 }, + // " 32-1: Pirates' Fortress - Telescope" (" 32-1: Pirates' Fortress - Secret Entrance (Looking Through + // Telescope)") + { " 32-1:\x8Dカイゾクノトリデ ボウエンキョウ", Select_LoadGame, 0x22A0 }, + // " 32-2: Pirates' Fortress - Interior 0" (" 32-2: Pirates' Fortress - Throne Room") + { " 32-2:\x8Dカイゾクノトリデナイブ0", Select_LoadGame, 0x4000 }, + // " 32-3: Pirates' Fortress - Interior 1" (" 32-3: Pirates' Fortress - View of Throne Room, Wasp Nest") + { " 32-3:\x8Dカイゾクノトリデナイブ1", Select_LoadGame, 0x4010 }, + // " 32-4: Pirates' Fortress - Interior 2" (" 32-4: Pirates' Fortress - Tempting Treasure Chest, Leading to 32-5") + { " 32-4:\x8Dカイゾクノトリデナイブ2", Select_LoadGame, 0x4020 }, + // " 32-5: Pirates' Fortress - Interior 3" (" 32-5: Pirates' Fortress - Zora Egg Room, One Shell Blade") + { " 32-5:\x8Dカイゾクノトリデナイブ3", Select_LoadGame, 0x4030 }, + // " 32-6: Pirates' Fortress - Interior 4" (" 32-6: Pirates' Fortress - Oil Drum Room, Leading to 32-7") + { " 32-6:\x8Dカイゾクノトリデナイブ4", Select_LoadGame, 0x4040 }, + // " 32-7: Pirates' Fortress - Interior 5" (" 32-7: Pirates' Fortress - Zora Egg Room, One Shell Blade") + { " 32-7:\x8Dカイゾクノトリデナイブ5", Select_LoadGame, 0x4050 }, + // " 32-8: Pirates' Fortress - Interior 6" (" 32-8: Pirates' Fortress - Fenced Indoor Walkway, Leading to 32-9") + { " 32-8:\x8Dカイゾクノトリデナイブ6", Select_LoadGame, 0x4060 }, + // " 32-9: Pirates' Fortress - Interior 7" (" 32-9: Pirates' Fortress - Zora Egg Room, One Desbreko & Treasure + // Chest") + { " 32-9:\x8Dカイゾクノトリデナイブ7", Select_LoadGame, 0x4070 }, + // " 32-10: Pirates' Fortress - Interior 8" (" 32-10: Pirates' Fortress - End of Secret Entrance (Telescope + // Room)") + { " 32-10:\x8Dカイゾクノトリデナイブ8", Select_LoadGame, 0x4080 }, + // " 32-11: Pirates' Fortress - Interior 9" (" 32-11: Pirates' Fortress - Start of Secret Entrance") + { " 32-11:\x8Dカイゾクノトリデナイブ9", Select_LoadGame, 0x4090 }, + // " 33: Zora Shrine" (" 33: Zora Hall") + { " 33:\x8Cゾーラ \x8Dノ ホコラ", Select_LoadGame, 0x6000 }, + // " 33-0: Zora Shop" (" 33-0: Zora Shop") + { " 33-0:\x8Cゾーラ \x8Dノ ミセ", Select_LoadGame, 0x9250 }, + // " 33-1: Zora Waiting Room" (" 33-1: Mikau & Tijo's Room") + { " 33-1:\x8Cゾーラ \x8Dノ ヒカエシツ", Select_LoadGame, 0x9200 }, + // " 34: Great Bay" (" 34: Great Bay [Cutscene: Pirates Approach Temple]") + { " 34:\x8Cグレートベイ", Select_LoadGame, 0xBE00 }, + // " 35: Mountain Stream Above Falls" (" 35: Waterfall Rapids") + { " 35:\x8Dタキウエ ノ ケイリュウ", Select_LoadGame, 0x8E00 }, + // " 40: Rock Building Shaft" (" 40: Stone Tower") + { " 40:\x8Cロックビル\x8D ノ タテアナ", Select_LoadGame, 0xAA00 }, + // " 40-0: Heaven & Earth Are Overturned" (" 40-0: Stone Tower [Cutscene: Tower is Flipped]") + { " 40-0:\x8Dテンチ ギャクテン", Select_LoadGame, 0xAC00 }, + // " 41: Road to Ikana" (" 41: Road to Ikana") + { " 41:\x8Cイカーナ \x8Dヘノ ミチ", Select_LoadGame, 0xA000 }, + // " 42: Ancient Castle of Ikana" (" 42: Ancient Castle of Ikana") + { " 42:\x8Cイカーナ\x8D コジョウ", Select_LoadGame, 0x3400 }, + // " 42-0: Ancient Castle of Ikana - Interior" (" 42-0: Ancient Castle of Ikana - Interior") + { " 42-0:\x8Cイカーナ\x8D ノ コジョウ ナイブ", Select_LoadGame, 0x3430 }, + // " 42-B: Ancient Castle of Ikana - Boss Room" (" 42-B: Ikana King's Throne") + { " 42-B:\x8Cイカーナ\x8D ノ コジョウ \x8Cボス\x8Dベヤ", Select_LoadGame, 0xA600 }, + // " 43: Ikana Canyon" (" 43: Ikana Canyon") + { " 43:\x8Cイカーナ \x8Dケイコク", Select_LoadGame, 0x2000 }, + // " 43-0: Ikana Canyon Cave" (" 43-0: Sharp's Cave") + { " 43-0:\x8Cイカーナ \x8Dケイコク ドウクツ", Select_LoadGame, 0x20E0 }, + // " 43-1: Secom's House" (" 43-1: Sakon's Hideout") + { " 43-1:\x8Cセコム \x8Dノ イエ", Select_LoadGame, 0x9800 }, + // " 43-2: Music Box House" (" 43-2: Music Box House") + { " 43-2:\x8Cオルゴール ハウス", Select_LoadGame, 0xA400 }, + // " 50: Clock Town -East-" (" 50: East Clock Town") + { " 50:\x8Cクロックタウン \x8D-ヒガシ-", Select_LoadGame, 0xD200 }, + // " 50-0: Town Target Range" (" 50-0: Shooting Gallery") + { " 50-0:\x8Dマチ ノ シャテキジョウ", Select_LoadGame, 0x3A00 }, + // " 50-1: Honey and Darling's Shop" (" 50-1: Honey & Darling's Shop") + { " 50-1:\x8Cハニー アンド ダーリン \x8Dノ ミセ", Select_LoadGame, 0x800 }, + // " 50-2: Treasure Chest Shop" (" 50-2: Treasure Chest Shop") + { " 50-2:\x8Dタカラバコヤ", Select_LoadGame, 0x2800 }, + // " 50-3: Pots 'n' Pans Inn" (" 50-3: Stockpot Inn") + { " 50-3:\x8Cナベ\x8Dカマ テイ", Select_LoadGame, 0xBC00 }, + // " 50-4: Mayor's House" (" 50-4: The Mayor's Residence") + { " 50-4:\x8Dチョウチョウ ノ イエ", Select_LoadGame, 0 }, + // " 50-5: Milk Bar" (" 50-5: Milk Bar") + { " 50-5:\x8Cミルクバー", Select_LoadGame, 0x2400 }, + // " 51: Clock Town -West-" (" 51: West Clock Town") + { " 51:\x8Cクロックタウン \x8D-ニシ-", Select_LoadGame, 0xD400 }, + // " 51-0: Bomb Shop" (" 51-0: Bomb Shop") + { " 51-0:\x8Dバクダン ヤ", Select_LoadGame, 0xCA00 }, + // " 51-1: Maniac Mart" (" 51-1: Curiosity Shop") + { " 51-1:\x8Cマニ\x8Dヤ", Select_LoadGame, 0xE00 }, + // " 51-2: General Store" (" 51-2: Trading Post") + { " 51-2:\x8Dザッカ ヤ", Select_LoadGame, 0x6200 }, + // " 51-3: Sword Dojo" (" 51-3: Swordsman's School") + { " 51-3:\x8Dケンドウジョウ", Select_LoadGame, 0xA200 }, + // " 51-4: Post House" (" 51-4: Post Office") + { " 51-4:\x8Dポストハウス", Select_LoadGame, 0x5600 }, + // " 51-5: Lottery Shop" (" 51-5: Lottery Shop") + { " 51-5:\x8Dタカラクジヤ", Select_LoadGame, 0x6C00 }, + // " 52: Clock Town -North-" (" 52: North Clock Town") + { " 52:\x8Cクロックタウン \x8D-キタ-", Select_LoadGame, 0xD600 }, + // " 53: Clocktown -South-" (" 53: South Clock Town") + { " 53:\x8Cクロックタウン \x8D-ミナミ-", Select_LoadGame, 0xD800 }, + // " 53-0: Clock Tower Interior" (" 53-0: Clock Tower Interior") + { " 53-0:\x8Dトケイトウナイブ", Select_LoadGame, 0xC000 }, + // " 54: Clock Tower Rooftop" (" 54: Clock Tower Rooftop") + { " 54:\x8Dトケイトウ オクジョウ", Select_LoadGame, 0x2C00 }, + // " 55: Laundry Area" (" 55: Laundry Pool") + { " 55:\x8Dセンタクジョウ", Select_LoadGame, 0xDA00 }, + // " 55-0: Maniac Mart - Rear Entrance" (" 55-0: Curiosity Shop - Back Room") + { " 55-0:\x8Cマニ\x8Dヤ ノ ウラグチ", Select_LoadGame, 0xE10 }, + // " 55-1: Maniac Mart - Peephole" (" 55-1: Curiosity Shop Back Room - Peephole") + { " 55-1:\x8Cマニ\x8Dヤ ノ ノゾキアナ", Select_LoadGame, 0xE20 }, + // "100: Wood Mountain Temple" ("100: Woodfall Temple") + { "100:\x8Cウッドマウンテン \x8Dノ シンデン", Select_LoadGame, 0x3000 }, + // "100-B: Wood Mountain Temple - Boss" ("100-B: Odolwa's Lair") + { "100-B:\x8Cウッドマウンテン \x8Dノ シンデン\x8C-ボス-", Select_LoadGame, 0x3800 }, + // "101: Snowhead Temple" ("101: Snowhead Temple") + { "101:\x8Cスノーヘッド \x8Dノ シンデン", Select_LoadGame, 0x3C00 }, + // "101-B: Snowhead Temple - Boss" ("101-B: Goht's Lair") + { "101-B:\x8Cスノーヘッド \x8Dノ シンデン\x8C-ボス-", Select_LoadGame, 0x8200 }, + // "102: Great Bay Temple" ("102: Great Bay Temple") + { "102:\x8Cグレートベイ \x8Dノ シンデン", Select_LoadGame, 0x8C00 }, + // "102-B: Great Bay Temple - Boss" ("102-B: Gyorg's Lair") + { "102-B:\x8Cグレートベイ \x8Dノ シンデン\x8C-ボス-", Select_LoadGame, 0xB800 }, + // "103: Rock Building Temple -Top Side-" ("103: Stone Tower Temple") + { "103:\x8Cロックビル \x8Dノ シンデン-オモテー", Select_LoadGame, 0x2600 }, + // "103-0: Rock Building Temple -Underside-" ("103-0: Stone Tower Temple - Flipped") + { "103-0:\x8Cロックビル \x8Dノ シンデン-ウラー", Select_LoadGame, 0x2A00 }, + // "103-B: Rock Building Temple - Boss" ("103-B: Twinmold's Lair") + { "103-B:\x8Cロックビル \x8Dノ シンデン\x8C-ボス-", Select_LoadGame, 0x6600 }, + // "104: Steppe" ("104: On the Moon") + { "104:\x8Cソウゲン", Select_LoadGame, 0xC800 }, + // "104-0: Last Deku Dungeon" ("104-0: Deku Trial") + { "104-0:\x8Cラスト デク ダンジョン", Select_LoadGame, 0x4E00 }, + // "104-1: Last Goron Dungeon" ("104-1: Goron Trial") + { "104-1:\x8Cラスト ゴロン ダンジョン", Select_LoadGame, 0x7800 }, + // "104-2: Last Zora Dungeon" ("104-2: Zora Trial") + { "104-2:\x8Cラスト ゾーラ ダンジョン", Select_LoadGame, 0x8800 }, + // "104-3: Last Link Dungeon" ("104-3: Link Trial") + { "104-3:\x8Cラスト リンク ダンジョン", Select_LoadGame, 0xC600 }, + // "104-B: Last Dungeon -Boss-" ("104-B: Majora's Lair") + { "104-B:\x8Cラストダンジョン -ボス-", Select_LoadGame, 0x200 }, + // "119: Deku Shrine" ("119: Deku Shrine") + { "119:\x8Cデクナッツ \x8Dノ ホコラ", Select_LoadGame, 0x9E00 }, + // "121: Secret Shrine" ("121: Secret Shrine") + { "121:\x8Dヒミツ ノ ホコラ", Select_LoadGame, 0xBA00 }, + // "122: Opening Dungeon" ("122: Pond Area [Cutscene: Falling of the Cliff]") + { "122:\x8Cオープニング ダンジョン", Select_LoadGame, 0x2E00 }, + // "123: Giants' Chamber" ("123: Giants' Chamber") + { "123:\x8Dキョジン ノ マ", Select_LoadGame, 0xCC00 }, + // "126: Deku Minigame" ("126: Deku Rupee Minigame") + { "126:\x8Cデクナッツ ミニゲーム", Select_LoadGame, 0x3600 }, + // "127-0: Fairy Fountain 0" ("127-0: Fairy Fountain - Clock Town") + { "127-0:\x8Dヨウセイ ノ イズミ 0", Select_LoadGame, 0x4600 }, + // "127-1: Fairy Fountain 1" ("127-1: Fairy Fountain - Woodfall") + { "127-1:\x8Dヨウセイ ノ イズミ 1", Select_LoadGame, 0x4610 }, + // "127-2: Fairy Fountain 2" ("127-2: Fairy Fountain - Snowhead") + { "127-2:\x8Dヨウセイ ノ イズミ 2", Select_LoadGame, 0x4620 }, + // "127-3: Fairy Fountain 3" ("127-3: Fairy Fountain - Great Bay Coast") + { "127-3:\x8Dヨウセイ ノ イズミ 3", Select_LoadGame, 0x4630 }, + // "127-4: Fairy Fountain 4" ("127-4: Fairy Fountain - Ikana Canyon") + { "127-4:\x8Dヨウセイ ノ イズミ 4", Select_LoadGame, 0x4640 }, + // "128: Swamp Spider Manor" ("128: Swamp Spider House") + { "128:\x8Dヌマ ノ クモヤカタ", Select_LoadGame, 0x4800 }, + // "129: Ocean Spider Manor" ("129: Oceanside Spider House") + { "129:\x8Dウミ ノ クモヤカタ", Select_LoadGame, 0x4A00 }, + // "130: Beneath the Graves - Dampe" ("130: Beneath the Graveyard") + { "130:\x8Dハカ ノ シタ-\x8Cダンペイ-", Select_LoadGame, 0x5A00 }, + // "131: Beneath the Well" ("131: Beneath the Well") + { "131:\x8Dイド ノ シタ", Select_LoadGame, 0x9000 }, + // "132: Ghost Hut" (" 132: Ghost Hut") + { "132:\x8Dユウレイゴヤ", Select_LoadGame, 0x9C00 }, + // "133-0: Beneath the Graves 0" ("133-0: Beneath the Graveyard - Part 1") + { "133-0:\x8Dハカ ノ シタ0", Select_LoadGame, 0xA00 }, + // "133-1: Beneath the Graves 1" ("133-1: Beneath the Graveyard - Part 2") + { "133-1:\x8Dハカ ノ シタ1", Select_LoadGame, 0xA10 }, + // "134-0: Secret Grotto 0" ("134-0: Secret Grotto - Four Gossip Stones") + { "134-0:\x8Dカクシアナ 0", Select_LoadGame, 0x1400 }, + // "134-1: Secret Grotto 1" ("134-1: Secret Grotto - Four Gossip Stones, Skulltula") + { "134-1:\x8Dカクシアナ 1", Select_LoadGame, 0x1410 }, + // "134-2: Secret Grotto 2" ("134-2: Secret Grotto - Four Gossip Stones, Water Puddles") + { "134-2:\x8Dカクシアナ 2", Select_LoadGame, 0x1420 }, + // "134-3: Secret Grotto 3" ("134-3: Secret Grotto - Four Gossip Stones, Water Puddle With Bugs") + { "134-3:\x8Dカクシアナ 3", Select_LoadGame, 0x1430 }, + // "134-4: Secret Grotto 4" ("134-4: Secret Grotto - Chest with Blue Rupee, Deku Babas") + { "134-4:\x8Dカクシアナ 4", Select_LoadGame, 0x1440 }, + // "134-5: Secret Grotto 5" ("134-5: Secret Grotto - Hot Spring, Deku Babas, Large Stones") + { "134-5:\x8Dカクシアナ5", Select_LoadGame, 0x1450 }, + // "134-7: Secret Grotto 7" ("134-7: Secret Grotto - Two Dondogos") + { "134-7:\x8Dカクシアナ 7", Select_LoadGame, 0x1470 }, + // "134-9: Secret Grotto 9" ("134-9: Secret Grotto - Tall Grass With Box, Pot, Bugs") + { "134-9:\x8Dカクシアナ 9", Select_LoadGame, 0x1490 }, + // "134-10: Secret Grotto 10" ("134-10: Secret Grotto - Two Cows Surrounded by Grass") + { "134-10:\x8Dカクシアナ10", Select_LoadGame, 0x14A0 }, + // "134-11: Secret Grotto 11" ("134-11: Secret Grotto - Watery Hole Filled with Underwater Babas, Fish") + { "134-11:\x8Dカクシアナ11", Select_LoadGame, 0x14B0 }, + // "134-13: Secret Grotto 13" ("134-13: Secret Grotto - Peahat in Center") + { "134-13:\x8Dカクシアナ13", Select_LoadGame, 0x14D0 }, + // "X 1: SPOT00" ("X 1: Opening [Cutscene: Opening Cutscene]") + { "X 1:SPOT00", Select_LoadGame, 0x1C00 }, + // "Title" ("Title Screen") + { "title", (void*)Select_LoadTitle, 0x0000 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_select/func_808016E8.s") +void Select_UpdateMenu(SelectContext* this) { + s32 playerForm; + Input* controller1 = CONTROLLER1(this); + s32 stickY; + s32 pad[2]; + s16 i; + s32 updateRate; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_select/func_8080194C.s") + if (this->verticalInputAccumulator == 0) { + if (CHECK_BTN_ALL(controller1->press.button, BTN_A) || CHECK_BTN_ALL(controller1->press.button, BTN_START)) { + for (i = 0; i < ARRAY_COUNT(gSaveContext.unk_3EC0); i++) { + gSaveContext.unk_3DD0[i] = 0; + gSaveContext.unk_3DE0[i] = 0; + gSaveContext.unk_3E18[i] = 0; + gSaveContext.unk_3E50[i] = 0; + gSaveContext.unk_3E88[i] = 0; + gSaveContext.unk_3EC0[i] = 0; + } + gSaveContext.minigameState = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_select/func_808019FC.s") + if (this->scenes[this->currentScene].loadFunc != NULL) { + this->scenes[this->currentScene].loadFunc(this, this->scenes[this->currentScene].entranceIndex, + this->opt); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_select/func_80801A64.s") + if (CHECK_BTN_ALL(controller1->press.button, BTN_B)) { + playerForm = gSaveContext.playerForm - 1; + if (playerForm < PLAYER_FORM_FIERCE_DEITY) { + playerForm = PLAYER_FORM_HUMAN; + } + gSaveContext.playerForm = playerForm; + } -void Select_Main(GameState* thisx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_select/Select_Main.s") + if (CHECK_BTN_ALL(controller1->press.button, BTN_Z)) { + if (gSaveContext.cutscene == 0x8000) { + gSaveContext.cutscene = 0; + } else if (gSaveContext.cutscene == 0) { + gSaveContext.cutscene = 0x8800; + } else if (gSaveContext.cutscene == 0x8800) { + gSaveContext.cutscene = 0xFFF0; + } else if (gSaveContext.cutscene == 0xFFF0) { + gSaveContext.cutscene = 0xFFF1; + } else if (gSaveContext.cutscene == 0xFFF1) { + gSaveContext.cutscene = 0xFFF2; + } else if (gSaveContext.cutscene == 0xFFF2) { + gSaveContext.cutscene = 0xFFF3; + } else if (gSaveContext.cutscene == 0xFFF3) { + gSaveContext.cutscene = 0xFFF4; + } else if (gSaveContext.cutscene == 0xFFF4) { + gSaveContext.cutscene = 0xFFF5; + } else if (gSaveContext.cutscene == 0xFFF5) { + gSaveContext.cutscene = 0xFFF6; + } else if (gSaveContext.cutscene == 0xFFF6) { + gSaveContext.cutscene = 0xFFF7; + } else if (gSaveContext.cutscene == 0xFFF7) { + gSaveContext.cutscene = 0xFFF8; + } else if (gSaveContext.cutscene == 0xFFF8) { + gSaveContext.cutscene = 0xFFF9; + } else if (gSaveContext.cutscene == 0xFFF9) { + gSaveContext.cutscene = 0xFFFA; + } else if (gSaveContext.cutscene == 0xFFFA) { + gSaveContext.cutscene = 0x8000; + } + } else if (CHECK_BTN_ALL(controller1->press.button, BTN_R)) { + if (gSaveContext.cutscene == 0x8000) { + gSaveContext.cutscene = 0xFFFA; + } else if (gSaveContext.cutscene == 0) { + gSaveContext.cutscene = 0x8000; + } else if (gSaveContext.cutscene == 0x8800) { + gSaveContext.cutscene = 0; + } else if (gSaveContext.cutscene == 0xFFF0) { + gSaveContext.cutscene = 0x8800; + } else if (gSaveContext.cutscene == 0xFFF1) { + gSaveContext.cutscene = 0xFFF0; + } else if (gSaveContext.cutscene == 0xFFF2) { + gSaveContext.cutscene = 0xFFF1; + } else if (gSaveContext.cutscene == 0xFFF3) { + gSaveContext.cutscene = 0xFFF2; + } else if (gSaveContext.cutscene == 0xFFF4) { + gSaveContext.cutscene = 0xFFF3; + } else if (gSaveContext.cutscene == 0xFFF5) { + gSaveContext.cutscene = 0xFFF4; + } else if (gSaveContext.cutscene == 0xFFF6) { + gSaveContext.cutscene = 0xFFF5; + } else if (gSaveContext.cutscene == 0xFFF7) { + gSaveContext.cutscene = 0xFFF6; + } else if (gSaveContext.cutscene == 0xFFF8) { + gSaveContext.cutscene = 0xFFF7; + } else if (gSaveContext.cutscene == 0xFFF9) { + gSaveContext.cutscene = 0xFFF8; + } else if (gSaveContext.cutscene == 0xFFFA) { + gSaveContext.cutscene = 0xFFF9; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_select/Select_Destroy.s") + gSaveContext.isNight = false; + if (gSaveContext.cutscene == 0x8800) { + gSaveContext.isNight = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_select/Select_Init.s") + if (CHECK_BTN_ALL(controller1->press.button, BTN_CUP)) { + this->opt--; + } + if (CHECK_BTN_ALL(controller1->press.button, BTN_CDOWN)) { + this->opt++; + } + + if (CHECK_BTN_ALL(controller1->press.button, BTN_CLEFT)) { + if (gSaveContext.day > 1) { + gSaveContext.day--; + } + } + + if (CHECK_BTN_ALL(controller1->press.button, BTN_CRIGHT)) { + if (gSaveContext.day < 4) { + gSaveContext.day++; + } + } + + updateRate = R_UPDATE_RATE; + stickY = controller1->rel.stick_y; + if (stickY != 0) { + this->verticalInput = (updateRate * stickY) / 7; + } else { + if (CHECK_BTN_ALL(controller1->press.button, BTN_DUP)) { + if (this->lockUp == true) { + this->timerUp = 0; + } + if (this->timerUp == 0) { + this->timerUp = 20; + this->lockUp = true; + + play_sound(NA_SE_IT_SWORD_IMPACT); + this->verticalInput = updateRate; + } + } + + if (CHECK_BTN_ALL(controller1->cur.button, BTN_DUP) && (this->timerUp == 0)) { + play_sound(NA_SE_IT_SWORD_IMPACT); + this->verticalInput = updateRate * 3; + } + + if (CHECK_BTN_ALL(controller1->press.button, BTN_DDOWN)) { + if (this->lockDown == true) { + this->timerDown = 0; + } + if (this->timerDown == 0) { + this->timerDown = 20; + this->lockDown = true; + play_sound(NA_SE_IT_SWORD_IMPACT); + this->verticalInput = -updateRate; + } + } + if (CHECK_BTN_ALL(controller1->cur.button, BTN_DDOWN) && (this->timerDown == 0)) { + play_sound(NA_SE_IT_SWORD_IMPACT); + this->verticalInput = -updateRate * 3; + } + + if (CHECK_BTN_ALL(controller1->press.button, BTN_DLEFT) || + CHECK_BTN_ALL(controller1->cur.button, BTN_DLEFT)) { + play_sound(NA_SE_IT_SWORD_IMPACT); + this->verticalInput = updateRate; + } + + if (CHECK_BTN_ALL(controller1->press.button, BTN_DRIGHT) || + CHECK_BTN_ALL(controller1->cur.button, BTN_DRIGHT)) { + play_sound(NA_SE_IT_SWORD_IMPACT); + this->verticalInput = -updateRate; + } + } + } + + if (CHECK_BTN_ALL(controller1->press.button, BTN_L)) { + this->pageDownIndex++; + this->pageDownIndex = + (this->pageDownIndex + ARRAY_COUNT(this->pageDownStops)) % ARRAY_COUNT(this->pageDownStops); + this->currentScene = this->topDisplayedScene = this->pageDownStops[this->pageDownIndex]; + } + + this->verticalInputAccumulator += this->verticalInput; + + if (this->verticalInputAccumulator < -7) { + this->verticalInput = 0; + this->verticalInputAccumulator = 0; + + this->currentScene++; + this->currentScene = (this->currentScene + this->count) % this->count; + + if (this->currentScene == ((this->topDisplayedScene + 19 + this->count) % this->count)) { + this->topDisplayedScene++; + this->topDisplayedScene = (this->topDisplayedScene + this->count) % this->count; + } + } + + if (this->verticalInputAccumulator > 7) { + this->verticalInput = 0; + this->verticalInputAccumulator = 0; + if (this->currentScene == this->topDisplayedScene) { + this->topDisplayedScene -= 2; + this->topDisplayedScene = (this->topDisplayedScene + this->count) % this->count; + } + + this->currentScene--; + this->currentScene = (this->currentScene + this->count) % this->count; + if (this->currentScene == ((this->topDisplayedScene + this->count) % this->count)) { + this->topDisplayedScene--; + this->topDisplayedScene = (this->topDisplayedScene + this->count) % this->count; + } + } + + this->currentScene = (this->currentScene + this->count) % this->count; + this->topDisplayedScene = (this->topDisplayedScene + this->count) % this->count; + + dREG(80) = this->currentScene; + dREG(81) = this->topDisplayedScene; + dREG(82) = this->pageDownIndex; + + if (this->timerUp != 0) { + this->timerUp--; + } + if (this->timerUp == 0) { + this->lockUp = false; + } + + if (this->timerDown != 0) { + this->timerDown--; + } + if (this->timerDown == 0) { + this->lockDown = false; + } +} + +void Select_PrintMenu(SelectContext* this, GfxPrint* printer) { + s32 i; + + GfxPrint_SetColor(printer, 255, 155, 150, 255); + GfxPrint_SetPos(printer, 12, 2); + GfxPrint_Printf(printer, "ZELDA MAP SELECT"); + + GfxPrint_SetColor(printer, 255, 255, 255, 255); + for (i = 0; i < 20; i++) { + s32 sceneIndex; + char* sceneName; + + GfxPrint_SetPos(printer, 9, i + 4); + sceneIndex = (this->topDisplayedScene + i + this->count) % this->count; + if (sceneIndex == this->currentScene) { + GfxPrint_SetColor(printer, 255, 20, 20, 255); + } else { + GfxPrint_SetColor(printer, 200, 200, 55, 255); + } + + sceneName = this->scenes[sceneIndex].name; + if (sceneName == NULL) { + sceneName = "**Null**"; + } + GfxPrint_Printf(printer, "%s", sceneName); + } + + GfxPrint_SetColor(printer, 155, 55, 150, 255); + GfxPrint_SetPos(printer, 20, 26); + GfxPrint_Printf(printer, "OPT=%d", this->opt); +} + +// clang-format off +static const char* sLoadingMessages[] = { + // "Please wait a minute", + "\x8Dシバラクオマチクダサイ", + // "Hold on a sec", + "\x8Dチョット マッテネ", + // "Wait a moment", + "\x8Cウェイト ア モーメント", + // "Loading", + "\x8Cロード\x8Dチュウ", + // "Now working", + "\x8Dナウ ワーキング", + // "Now creating", + "\x8Dイマ ツクッテマス", + // "It's not broken", + "\x8Dコショウジャナイヨ", + // "Coffee Break", + "\x8Cコーヒー ブレイク", + // "Please set B side", + "\x8C" "Bメンヲセットシテクダサイ", + // "Be patient, now", + "\x8Dジット\x8Cガマン\x8Dノ\x8Cコ\x8Dデアッタ", + // "Please wait just a minute", + "\x8Dイマシバラクオマチクダサイ", + // "Don't worry, don't worry. Take a break, take a break", + "\x8Dアワテナイアワテナイ。ヒトヤスミヒトヤスミ。", +}; +// clang-format on + +void Select_PrintLoadingMessage(SelectContext* this, GfxPrint* printer) { + s32 index; + + GfxPrint_SetPos(printer, 10, 15); + GfxPrint_SetColor(printer, 255, 255, 255, 255); + + index = Rand_ZeroOne() * ARRAY_COUNT(sLoadingMessages); + GfxPrint_Printf(printer, "%s", sLoadingMessages[index]); +} + +// clang-format off +// Second column is unused +static const char* sFormLabel[][2] = { + // "17 (Adult)" // 17 (Daitetsujin) + {"\x8D""17(オトナ)", "\x8D""17(ダイテツジン)"}, + // "30 (Goron)" // 30 (Ice Cream -1) + {"\x8C""30(ゴロン)", "\x8C""30(アイスクリーム-1)"}, + // "78 (Zora)" // 78 (Carmen +1) + {"\x8C""78(ゾーラ)", "\x8C""78(カルメン+1)"}, + // "12 (Deku)" // 12 (Majestic) + {"\x8C""12(デクナッツ)", "\x8C""12(マジェスティック)"}, + // "5 (Child)" // 5 (NTT Kodomo) + {"\x8D""5(コドモ)", "\x8C""5(NTTコドモ)"}, +}; +// clang-format on + +void Select_PrintAgeSetting(SelectContext* this, GfxPrint* printer, s32 playerForm) { + s32 pad; + const char* age; + const char*(*ageTemp)[2]; + const char*(*phi_v1)[2]; + s32 phi_v0; + + if ((playerForm >= PLAYER_FORM_FIERCE_DEITY) && (playerForm < PLAYER_FORM_MAX)) { + ageTemp = &sFormLabel[playerForm]; + phi_v1 = ageTemp + 1; + + // This loop doesn't do anything + for (phi_v0 = 8; phi_v0 >= 0; phi_v0 -= 8) { + if (phi_v1 != 0) { + break; + } + phi_v1--; + } + if (phi_v1) {} + + age = (*ageTemp)[0]; + } else { + age = NULL; + } + + GfxPrint_SetPos(printer, 4, 26); + GfxPrint_SetColor(printer, 255, 255, 55, 255); + if (age != NULL) { + GfxPrint_Printf(printer, "Age:%s", age); + } else { + // clang-format off + GfxPrint_Printf(printer, "Age:" "???" "(%d)", playerForm); + // clang-format on + } +} + +void Select_PrintCutsceneSetting(SelectContext* this, GfxPrint* printer, u16 csIndex) { + const char* stage; + const char* day; + + GfxPrint_SetPos(printer, 4, 25); + GfxPrint_SetColor(printer, 255, 255, 55, 255); + + // "-jara" used in these strings is a Kokiri speech quirk word + switch (csIndex) { + case 0: + // clang-format off + // "Afternoon-jara" + gSaveContext.time = CLOCK_TIME(12, 0); stage = "\x8Dオヒル\x8Cジャラ"; + // clang-format on + break; + + case 0x8000: + // clang-format off + // "Morning-jara" + gSaveContext.time = CLOCK_TIME(6, 0) + 1; stage = "\x8Dアサ \x8Cジャラ"; + // clang-format on + break; + + case 0x8800: + gSaveContext.time = CLOCK_TIME(18, 1); + // "Night-jara" + stage = "\x8Dヨル \x8Cジャラ"; + break; + + case 0xFFF0: + // clang-format off + // "Cutscene 00" + gSaveContext.time = CLOCK_TIME(12, 0); stage = "デモ00"; + // clang-format on + break; + case 0xFFF1: + // "Cutscene 01" + stage = "デモ01"; + break; + case 0xFFF2: + // "Cutscene 02" + stage = "デモ02"; + break; + case 0xFFF3: + // "Cutscene 03" + stage = "デモ03"; + break; + case 0xFFF4: + // "Cutscene 04" + stage = "デモ04"; + break; + case 0xFFF5: + // "Cutscene 05" + stage = "デモ05"; + break; + case 0xFFF6: + // "Cutscene 06" + stage = "デモ06"; + break; + case 0xFFF7: + // "Cutscene 07" + stage = "デモ07"; + break; + case 0xFFF8: + // "Cutscene 08" + stage = "デモ08"; + break; + case 0xFFF9: + // "Cutscene 09" + stage = "デモ09"; + break; + case 0xFFFA: + // "Cutscene 0A" + stage = "デモ0A"; + break; + + default: + stage = "???"; + break; + } + gSaveContext.environmentTime = gSaveContext.time; + GfxPrint_Printf(printer, "Stage:\x8C%s", stage); + + GfxPrint_SetPos(printer, 23, 25); + GfxPrint_SetColor(printer, 255, 255, 55, 255); + + switch (gSaveContext.day) { + case 1: + // "The First Day" + day = "\x8Dサイショノヒ"; + break; + case 2: + // "The Next Day" + day = "\x8Dツギノヒ"; + break; + case 3: + // "The Final Day" + day = "\x8Dサイゴノヒ"; + break; + case 4: + // "Clear Day" + day = "\x8Dクリアーノヒ"; + break; + default: + gSaveContext.day = 1; + // "The First Day" + day = "\x8Dサイショノヒ"; + break; + } + + GfxPrint_Printf(printer, "Day:\x8D%s", day); +} + +void Select_DrawMenu(SelectContext* this) { + GraphicsContext* gfxCtx = this->state.gfxCtx; + GfxPrint* printer; + + OPEN_DISPS(gfxCtx); + + func_8012C4C0(gfxCtx); + + printer = alloca(sizeof(GfxPrint)); + GfxPrint_Init(printer); + GfxPrint_Open(printer, POLY_OPA_DISP); + + Select_PrintMenu(this, printer); + Select_PrintAgeSetting(this, printer, ((void)0, gSaveContext.playerForm)); + Select_PrintCutsceneSetting(this, printer, ((void)0, gSaveContext.cutscene)); + + POLY_OPA_DISP = GfxPrint_Close(printer); + GfxPrint_Destroy(printer); + + CLOSE_DISPS(gfxCtx); +} + +void Select_DrawLoadingScreen(SelectContext* this) { + GraphicsContext* gfxCtx = this->state.gfxCtx; + GfxPrint printer; + + OPEN_DISPS(gfxCtx); + + func_8012C4C0(gfxCtx); + + GfxPrint_Init(&printer); + GfxPrint_Open(&printer, POLY_OPA_DISP); + + Select_PrintLoadingMessage(this, &printer); + + POLY_OPA_DISP = GfxPrint_Close(&printer); + GfxPrint_Destroy(&printer); + + CLOSE_DISPS(gfxCtx); +} + +void Select_Draw(SelectContext* this) { + GraphicsContext* gfxCtx = this->state.gfxCtx; + + func_8012CF0C(gfxCtx, 1, 1, 0, 0, 0); + + SET_FULLSCREEN_VIEWPORT(&this->view); + View_RenderView(&this->view, 0xF); + if (!this->state.running) { + Select_DrawLoadingScreen(this); + } else { + Select_DrawMenu(this); + } +} + +void Select_Main(GameState* thisx) { + SelectContext* this = (SelectContext*)thisx; + + Select_UpdateMenu(this); + Select_Draw(this); +} + +void Select_Destroy(GameState* thisx) { + ShrinkWindow_Fini(); +} + +void Select_Init(GameState* thisx) { + SelectContext* this = (SelectContext*)thisx; + + this->state.main = Select_Main; + this->state.destroy = Select_Destroy; + + this->scenes = sScenes; + this->topDisplayedScene = 0; + this->currentScene = 0; + this->pageDownStops[0] = 0; + this->pageDownStops[1] = 19; + this->pageDownStops[2] = 37; + this->pageDownStops[3] = 51; + this->pageDownStops[4] = 59; + this->pageDownStops[5] = 73; + this->pageDownStops[6] = 91; + this->pageDownIndex = 0; + this->opt = 0; + this->count = ARRAY_COUNT(sScenes); + + ShrinkWindow_Init(); + View_Init(&this->view, this->state.gfxCtx); + this->view.flags = (0x08 | 0x02); + this->verticalInputAccumulator = 0; + this->verticalInput = 0; + this->timerUp = 0; + this->timerDown = 0; + this->lockUp = false; + this->lockDown = false; + this->unk_274 = 0; + + if ((dREG(80) >= 0) && (dREG(80) < this->count)) { + this->currentScene = dREG(80); + this->topDisplayedScene = dREG(81); + this->pageDownIndex = dREG(82); + } + + Game_SetFramerateDivisor(&this->state, 1); + gSaveContext.cutscene = 0; + gSaveContext.playerForm = PLAYER_FORM_HUMAN; + gSaveContext.linkAge = 0; +} diff --git a/src/overlays/gamestates/ovl_select/z_select.h b/src/overlays/gamestates/ovl_select/z_select.h index 14e0023e1..a454a098b 100644 --- a/src/overlays/gamestates/ovl_select/z_select.h +++ b/src/overlays/gamestates/ovl_select/z_select.h @@ -3,12 +3,39 @@ #include "global.h" +struct SelectContext; + void Select_Init(GameState* thisx); void Select_Destroy(GameState* thisx); +typedef void (*Select_LoadFunc)(struct SelectContext*, u32, s32); + typedef struct { - GameState state; - char unk_A4[0x1DC]; + /* 0x00 */ char* name; + /* 0x04 */ Select_LoadFunc loadFunc; + /* 0x08 */ s32 entranceIndex; +} SceneSelectEntry; // size = 0xC + +typedef struct SelectContext { + /* 0x000 */ GameState state; + /* 0x0A8 */ View view; + /* 0x210 */ s32 count; + /* 0x214 */ SceneSelectEntry* scenes; + /* 0x218 */ s32 currentScene; + /* 0x21C */ s32 pageDownIndex; // Index of pageDownStops + /* 0x220 */ s32 pageDownStops[7]; + /* 0x23C */ char unk_23C[0xC]; + /* 0x248 */ s32 opt; // (Option): This name is the one the menu uses to show this value. It can be used to change in which entrance the player spawns in the selected scene + /* 0x24C */ s32 topDisplayedScene; // The scene which is currently at the top of the screen + /* 0x250 */ char unk_250[0xC]; + /* 0x25C */ s32 verticalInputAccumulator; + /* 0x260 */ s32 verticalInput; + /* 0x264 */ s32 timerUp; + /* 0x268 */ s32 timerDown; + /* 0x26C */ s32 lockUp; + /* 0x270 */ s32 lockDown; + /* 0x274 */ s32 unk_274; // unused + /* 0x278 */ UNK_TYPE1 unk_278[0x08]; } SelectContext; // size = 0x280 #endif diff --git a/tools/actorfixer.py b/tools/actorfixer.py index 3f5bade7f..16100c926 100755 --- a/tools/actorfixer.py +++ b/tools/actorfixer.py @@ -20,6 +20,7 @@ animdict ={ "func_800F0568": "Audio_PlaySoundAtPosition", "func_8016970C": "Play_CameraSetAtEye", "func_800BBA88": "Enemy_StartFinishingBlow", + "func_801A89A8": "Audio_QueueSeqCmd", } def replace_anim(file): diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 2f3ba42d4..a222825ec 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -2796,7 +2796,7 @@ 0x80144628:("func_80144628",), 0x80144684:("Sram_GenerateRandomSaveFields",), 0x80144890:("func_80144890",), - 0x80144968:("func_80144968",), + 0x80144968:("Sram_InitDebugSave",), 0x80144A94:("func_80144A94",), 0x80144E78:("func_80144E78",), 0x8014546C:("func_8014546C",), @@ -4059,7 +4059,7 @@ 0x801A7B10:("func_801A7B10",), 0x801A7D04:("func_801A7D04",), 0x801A7D84:("func_801A7D84",), - 0x801A89A8:("func_801A89A8",), + 0x801A89A8:("Audio_QueueSeqCmd",), 0x801A89D0:("func_801A89D0",), 0x801A8A50:("func_801A8A50",), 0x801A8ABC:("func_801A8ABC",), @@ -4093,16 +4093,16 @@ 0x8080066C:("Title_Main",), 0x8080071C:("Title_Destroy",), 0x8080074C:("Title_Init",), - 0x80800910:("func_80800910",), - 0x80800930:("func_80800930",), - 0x80800A44:("func_80800A44",), - 0x808013B8:("func_808013B8",), - 0x80801594:("func_80801594",), - 0x80801620:("func_80801620",), - 0x808016E8:("func_808016E8",), - 0x8080194C:("func_8080194C",), - 0x808019FC:("func_808019FC",), - 0x80801A64:("func_80801A64",), + 0x80800910:("Select_LoadTitle",), + 0x80800930:("Select_LoadGame",), + 0x80800A44:("Select_UpdateMenu",), + 0x808013B8:("Select_PrintMenu",), + 0x80801594:("Select_PrintLoadingMessage",), + 0x80801620:("Select_PrintAgeSetting",), + 0x808016E8:("Select_PrintCutsceneSetting",), + 0x8080194C:("Select_DrawMenu",), + 0x808019FC:("Select_DrawLoadingScreen",), + 0x80801A64:("Select_Draw",), 0x80801AFC:("Select_Main",), 0x80801B28:("Select_Destroy",), 0x80801B4C:("Select_Init",), @@ -6392,8 +6392,8 @@ 0x808D6A94:("func_808D6A94",), 0x808D6B64:("func_808D6B64",), 0x808D6C10:("EnRd_Update",), - 0x808D6DA0:("func_808D6DA0",), - 0x808D6DFC:("func_808D6DFC",), + 0x808D6DA0:("EnRd_OverrideLimbDraw",), + 0x808D6DFC:("EnRd_PostLimbDraw",), 0x808D6ED8:("EnRd_Draw",), 0x808D7550:("BgF40Flift_Init",), 0x808D75BC:("BgF40Flift_Destroy",), @@ -11103,15 +11103,15 @@ 0x80A7AFA8:("EnJso2_Draw",), 0x80A7BC70:("ObjEtcetera_Init",), 0x80A7BD80:("ObjEtcetera_Destroy",), - 0x80A7BDC8:("func_80A7BDC8",), - 0x80A7BE8C:("func_80A7BE8C",), - 0x80A7BF08:("func_80A7BF08",), - 0x80A7C168:("func_80A7C168",), - 0x80A7C1F0:("func_80A7C1F0",), - 0x80A7C308:("func_80A7C308",), + 0x80A7BDC8:("ObjEtcetera_DoNormalOscillation",), + 0x80A7BE8C:("ObjEtcetera_StartSmallFlutterAnimation",), + 0x80A7BF08:("ObjEtcetera_Idle",), + 0x80A7C168:("ObjEtcetera_PlaySmallFlutterAnimation",), + 0x80A7C1F0:("ObjEtcetera_DoIntenseOscillation",), + 0x80A7C308:("ObjEtcetera_Setup",), 0x80A7C5EC:("ObjEtcetera_Update",), - 0x80A7C690:("func_80A7C690",), - 0x80A7C718:("func_80A7C718",), + 0x80A7C690:("ObjEtcetera_DrawIdle",), + 0x80A7C718:("ObjEtcetera_DrawAnimated",), 0x80A7C990:("func_80A7C990",), 0x80A7CA18:("func_80A7CA18",), 0x80A7CBC4:("func_80A7CBC4",), @@ -14940,8 +14940,8 @@ 0x80B99384:("func_80B99384",), 0x80B99394:("EnZot_Update",), 0x80B99580:("func_80B99580",), - 0x80B995A4:("func_80B995A4",), - 0x80B99758:("func_80B99758",), + 0x80B995A4:("EnZot_OverrideLimbDraw",), + 0x80B99758:("EnZot_PostLimbDraw",), 0x80B99798:("EnZot_Draw",), 0x80B9A0B0:("ObjTree_Init",), 0x80B9A1BC:("ObjTree_Destroy",), @@ -16781,8 +16781,8 @@ 0x80C12B1C:("func_80C12B1C",), 0x80C12D00:("func_80C12D00",), 0x80C12ED4:("EnThiefbird_Update",), - 0x80C130EC:("func_80C130EC",), - 0x80C1315C:("func_80C1315C",), + 0x80C130EC:("EnThiefbird_OverrideLimbDraw",), + 0x80C1315C:("EnThiefbird_PostLimbDraw",), 0x80C13354:("func_80C13354",), 0x80C134D0:("EnThiefbird_Draw",), 0x80C13930:("EnJgameTsn_Init",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index cc79d6fe8..a7bc54164 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -978,13 +978,13 @@ 0x801BDBA0:("D_801BDBA0","UNK_TYPE1","",0x1), 0x801BDBA4:("D_801BDBA4","UNK_TYPE1","",0x1), 0x801BDBA8:("D_801BDBA8","UNK_TYPE1","",0x1), - 0x801BDBB0:("D_801BDBB0","UNK_TYPE1","",0x1), + 0x801BDBB0:("D_801BDBB0","u8","",0x1), 0x801BDBB4:("D_801BDBB4","UNK_TYPE1","",0x1), 0x801BDBB8:("D_801BDBB8","UNK_TYPE1","",0x1), 0x801BDBBC:("D_801BDBBC","UNK_TYPE1","",0x1), 0x801BDBC0:("D_801BDBC0","UNK_TYPE1","",0x1), 0x801BDBC4:("D_801BDBC4","UNK_TYPE1","",0x1), - 0x801BDBC8:("D_801BDBC8","UNK_TYPE1","",0x1), + 0x801BDBC8:("D_801BDBC8","u8","",0x1), 0x801BDBCC:("D_801BDBCC","UNK_TYPE1","",0x1), 0x801BDCF4:("D_801BDCF4","UNK_TYPE1","",0x1), 0x801BE38E:("D_801BE38E","UNK_TYPE1","",0x1), @@ -4064,7 +4064,7 @@ 0x801F4E70:("D_801F4E70","UNK_TYPE1","",0x1), 0x801F4E74:("D_801F4E74","UNK_TYPE1","",0x1), 0x801F4E78:("D_801F4E78","UNK_TYPE1","",0x1), - 0x801F4E7A:("D_801F4E7A","UNK_TYPE1","",0x1), + 0x801F4E7A:("D_801F4E7A","s16","",0x2), 0x801F4E80:("D_801F4E80","UNK_TYPE1","",0x1), 0x801F4EE0:("D_801F4EE0","UNK_TYPE1","",0x1), 0x801F4EE8:("D_801F4EE8","UNK_TYPE1","",0x1), @@ -4609,9 +4609,9 @@ 0x80800868:("D_80800868","UNK_TYPE1","",0x1), 0x80800870:("D_80800870","UNK_TYPE1","",0x1), 0x80800880:("titleUnknownVector3f","Vec3f","",0xc), - 0x80801C80:("D_80801C80","UNK_PTR","",0x4), - 0x80802334:("D_80802334","UNK_PTR","",0x4), - 0x80802364:("D_80802364","UNK_PTR","",0x4), + 0x80801C80:("sScenes","UNK_PTR","",0x4), + 0x80802334:("sLoadingMessages","UNK_PTR","",0x4), + 0x80802364:("sFormLabel","UNK_PTR","",0x4), 0x80802390:("D_80802390","char","[]",0x1), 0x808023AC:("D_808023AC","char","[]",0x1), 0x808023C4:("D_808023C4","char","[]",0x1), @@ -11773,14 +11773,14 @@ 0x80A41D68:("D_80A41D68","UNK_TYPE1","",0x1), 0x80A41D6C:("D_80A41D6C","UNK_TYPE1","",0x1), 0x80A43320:("En_Test4_InitVars","ActorInit","",0x20), - 0x80A43340:("D_80A43340","UNK_TYPE4","",0x4), - 0x80A43342:("D_80A43342","UNK_TYPE1","",0x1), - 0x80A4334A:("D_80A4334A","UNK_TYPE1","",0x1), - 0x80A43352:("D_80A43352","UNK_TYPE1","",0x1), - 0x80A4335A:("D_80A4335A","UNK_TYPE1","",0x1), - 0x80A43364:("D_80A43364","UNK_TYPE1","",0x1), - 0x80A434D0:("D_80A434D0","s16","[2]",0x4), - 0x80A434D4:("D_80A434D4","UNK_TYPE1","",0x1), + 0x80A43340:("sIsLoaded","s32","[3]",0x6), + 0x80A43342:("sNightMessages1","s16","[3]",0x6), + 0x80A4334A:("sDayMessages1","s16","[3]",0x6), + 0x80A43352:("sNightMessages2","s16","[3]",0x6), + 0x80A4335A:("sDayMessages2","s16","[3]",0x6), + 0x80A43364:("D_80A43364","u16","[2]",0x4), + 0x80A434D0:("sCutscenes","s16","[2]",0x4), + 0x80A434D4:("sCurrentCs","s16","",0x2), 0x80A449E0:("En_Bat_InitVars","UNK_TYPE1","",0x1), 0x80A44A00:("D_80A44A00","UNK_TYPE1","",0x1), 0x80A44A2C:("D_80A44A2C","UNK_TYPE1","",0x1), @@ -16988,13 +16988,13 @@ 0x80C23BD0:("En_Ending_Hero5_InitVars","UNK_TYPE1","",0x1), 0x80C23BF0:("D_80C23BF0","UNK_TYPE1","",0x1), 0x80C23C10:("jtbl_80C23C10","UNK_PTR","",0x4), - 0x80C241E0:("En_Ending_Hero6_InitVars","UNK_TYPE1","",0x1), - 0x80C24200:("D_80C24200","UNK_TYPE1","",0x1), - 0x80C24224:("D_80C24224","UNK_TYPE1","",0x1), - 0x80C24248:("D_80C24248","UNK_TYPE1","",0x1), - 0x80C2426C:("D_80C2426C","UNK_TYPE1","",0x1), - 0x80C24280:("D_80C24280","UNK_TYPE1","",0x1), - 0x80C24294:("D_80C24294","UNK_TYPE1","",0x1), + 0x80C241E0:("En_Ending_Hero6_InitVars","ActorInit","",0x20), + 0x80C24200:("D_80C24200","FlexSkeletonHeader*","[9]",0x24), + 0x80C24224:("D_80C24224","AnimationHeader*","[9]",0x24), + 0x80C24248:("D_80C24248","s32","[9]",0x24), + 0x80C2426C:("D_80C2426C","Gfx*","[5]",0x14), + 0x80C24280:("D_80C24280","TexturePtr","[5]",0x14), + 0x80C24294:("D_80C24294","TexturePtr","[3]",0xc), 0x80C242A0:("jtbl_80C242A0","UNK_PTR","",0x4), 0x80C250F0:("Dm_Gm_InitVars","UNK_TYPE1","",0x1), 0x80C25110:("D_80C25110","UNK_TYPE1","",0x1), diff --git a/tools/permuter_settings.toml b/tools/permuter_settings.toml index 82ce7cdfe..f5805056b 100644 --- a/tools/permuter_settings.toml +++ b/tools/permuter_settings.toml @@ -12,6 +12,7 @@ ABS = "int" SQ = "int" CLAMP = "int" CLOCK_TIME = "int" +CURRENT_DAY = "int" [decompme.compilers] "tools/ido_recomp/linux/7.1/cc" = "ido7.1" diff --git a/tools/sfxconvert.py b/tools/sfxconvert.py index 22044dd59..fbd7aa755 100755 --- a/tools/sfxconvert.py +++ b/tools/sfxconvert.py @@ -61,7 +61,9 @@ def fix_sfx_flag(id): if(id.endswith(' - SFX_FLAG')): splitdata = id.split('-') return splitdata[0].strip(), ' -' + splitdata[1] - if not(int(id,16) & 0x800): + if id.endswith("U"): + id = id[:-1] + if not(int(id, 16) & 0x800): newid = '0x' + format(int(id,16) + 0x800,'X') sfxFlag = ' - SFX_FLAG' else : diff --git a/tools/sizes/code_functions.csv b/tools/sizes/code_functions.csv index 4b031b6a4..e8f66fc01 100644 --- a/tools/sizes/code_functions.csv +++ b/tools/sizes/code_functions.csv @@ -2310,7 +2310,7 @@ asm/non_matchings/code/z_sram_NES/Sram_CalcChecksum.s,Sram_CalcChecksum,0x801445 asm/non_matchings/code/z_sram_NES/func_80144628.s,func_80144628,0x80144628,0x17 asm/non_matchings/code/z_sram_NES/Sram_GenerateRandomSaveFields.s,Sram_GenerateRandomSaveFields,0x80144684,0x83 asm/non_matchings/code/z_sram_NES/func_80144890.s,func_80144890,0x80144890,0x36 -asm/non_matchings/code/z_sram_NES/func_80144968.s,func_80144968,0x80144968,0x4B +asm/non_matchings/code/z_sram_NES/Sram_InitDebugSave.s,Sram_InitDebugSave,0x80144968,0x4B asm/non_matchings/code/z_sram_NES/func_80144A94.s,func_80144A94,0x80144A94,0xF9 asm/non_matchings/code/z_sram_NES/func_80144E78.s,func_80144E78,0x80144E78,0x17D asm/non_matchings/code/z_sram_NES/func_8014546C.s,func_8014546C,0x8014546C,0x8B @@ -3573,7 +3573,7 @@ asm/non_matchings/code/code_801A5BD0/func_801A794C.s,func_801A794C,0x801A794C,0x asm/non_matchings/code/code_801A7B10/func_801A7B10.s,func_801A7B10,0x801A7B10,0x7D asm/non_matchings/code/code_801A7B10/func_801A7D04.s,func_801A7D04,0x801A7D04,0x20 asm/non_matchings/code/code_801A7B10/func_801A7D84.s,func_801A7D84,0x801A7D84,0x309 -asm/non_matchings/code/code_801A7B10/func_801A89A8.s,func_801A89A8,0x801A89A8,0xA +asm/non_matchings/code/code_801A7B10/Audio_QueueSeqCmd.s,Audio_QueueSeqCmd,0x801A89A8,0xA asm/non_matchings/code/code_801A7B10/func_801A89D0.s,func_801A89D0,0x801A89D0,0x20 asm/non_matchings/code/code_801A7B10/func_801A8A50.s,func_801A8A50,0x801A8A50,0x1B asm/non_matchings/code/code_801A7B10/func_801A8ABC.s,func_801A8ABC,0x801A8ABC,0x16 diff --git a/undefined_syms.txt b/undefined_syms.txt index bf19c9814..57eb32e56 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -379,8 +379,10 @@ D_0400E418 = 0x0400E418; D_0400E430 = 0x0400E430; D_0400EB7C = 0x0400EB7C; D_0400ED80 = 0x0400ED80; +D_0400E710 = 0x0400E710; D_04011518 = 0x04011518; D_040117A8 = 0x040117A8; +D_040118D8 = 0x040118D8; D_04011BD0 = 0x04011BD0; D_040127E8 = 0x040127E8; D_04012860 = 0x04012860; @@ -2087,6 +2089,32 @@ D_060070C0 = 0x060070C0; D_0600A390 = 0x0600A390; D_0600A850 = 0x0600A850; +// ovl_En_Ending_Hero6 + +D_0600B0CC = 0x0600B0CC; +D_06007908 = 0x06007908; +D_06007150 = 0x06007150; +D_0600D640 = 0x0600D640; +D_0600A850 = 0x0600A850; +D_06000BE0 = 0x06000BE0; +D_060011C0 = 0x060011C0; +D_06000E50 = 0x06000E50; +D_06002A84 = 0x06002A84; +D_06002FA0 = 0x06002FA0; +D_060070C0 = 0x060070C0; +D_06006FB0 = 0x06006FB0; +D_06006E80 = 0x06006E80; +D_06006D70 = 0x06006D70; +D_0600A390_dl = 0x0600A390; +D_06007350 = 0x06007350; +D_06009590 = 0x06009590; +D_06009F90 = 0x06009F90; +D_0600A790 = 0x0600A790; +D_0600AB90 = 0x0600AB90; +D_06007750 = 0x06007750; +D_0600A390_tex = 0x0600A390; +D_0600A490 = 0x0600A490; + // ovl_En_Estone D_06010240 = 0x06010240; @@ -3547,6 +3575,9 @@ D_060033B0 = 0x060033B0; D_06003D58 = 0x06003D58; D_060061A0 = 0x060061A0; D_060063C4 = 0x060063C4; +D_06004348 = 0x06004348; +D_06004B88 = 0x06004B88; +D_060055E0 = 0x060055E0; // ovl_En_Tite @@ -3781,9 +3812,20 @@ D_06015238 = 0x06015238; // ovl_En_Zot +D_06002898 = 0x06002898; D_06004248 = 0x06004248; +D_060050A0 = 0x060050A0; +D_060058A0 = 0x060058A0; +D_060060A0 = 0x060060A0; D_0600D208 = 0x0600D208; D_0600DE20 = 0x0600DE20; +D_0600DF54 = 0x0600DF54; +D_0600E400 = 0x0600E400; +D_0600EDF0 = 0x0600EDF0; +D_0600F4E8 = 0x0600F4E8; +D_0600FDF0 = 0x0600FDF0; +D_06010B18 = 0x06010B18; +D_06011424 = 0x06011424; // ovl_En_Zov