From 389a2bf33cffb43ddda59259f8114e2ff639acad Mon Sep 17 00:00:00 2001 From: Tom Overton Date: Sat, 13 May 2023 18:27:31 -0700 Subject: [PATCH] Document EnAob01 (doggy racetrack owner) and use macros for weekEventRegs in all dog racing files (#1234) * Document EnAob01 (doggy racetrack owner) and use macros for weekEventRegs in all dog racing files * Respond to first review * Respond to anon's review * Forgot a _FLAG_ on one of my flags * Respond to anon's review * Respond to engineer's review * Delete extra period * Undo the EVENTINF stuff I goofed up * Update comment * Fix bss * Respond to engineer's review --- include/z64save.h | 163 ++-- src/boot_O2_g3/z_std_dma.c | 1 + src/code/z_play.c | 1 - .../actors/ovl_En_Aob_01/z_en_aob_01.c | 919 +++++++++++------- .../actors/ovl_En_Aob_01/z_en_aob_01.h | 50 +- src/overlays/actors/ovl_En_Bat/z_en_bat.c | 1 - src/overlays/actors/ovl_En_Dg/z_en_dg.c | 18 +- src/overlays/actors/ovl_En_Horse/z_en_horse.c | 5 +- .../z_en_horse_game_check.c | 20 +- src/overlays/actors/ovl_En_In/z_en_in.c | 42 +- .../actors/ovl_En_Racedog/z_en_racedog.c | 20 +- .../actors/ovl_En_Racedog/z_en_racedog.h | 1 + src/overlays/actors/ovl_En_Ssh/z_en_ssh.c | 4 +- src/overlays/actors/ovl_En_Sth/z_en_sth.c | 8 +- .../actors/ovl_En_Suttari/z_en_suttari.c | 4 +- .../actors/ovl_Obj_Nozoki/z_obj_nozoki.c | 1 + tools/disasm/functions.txt | 64 +- tools/disasm/variables.txt | 4 +- tools/weekeventregconvert.py | 16 +- 19 files changed, 751 insertions(+), 591 deletions(-) diff --git a/include/z64save.h b/include/z64save.h index 1f59fea013..9d580803f1 100644 --- a/include/z64save.h +++ b/include/z64save.h @@ -594,7 +594,7 @@ typedef enum { #define WEEKEVENTREG_08_04 PACK_WEEKEVENTREG_FLAG(8, 0x04) #define WEEKEVENTREG_08_08 PACK_WEEKEVENTREG_FLAG(8, 0x08) #define WEEKEVENTREG_08_10 PACK_WEEKEVENTREG_FLAG(8, 0x10) -#define WEEKEVENTREG_08_20 PACK_WEEKEVENTREG_FLAG(8, 0x20) +#define WEEKEVENTREG_RECEIVED_DOGGY_RACETRACK_HEART_PIECE PACK_WEEKEVENTREG_FLAG(8, 0x20) // Related to final hours #define WEEKEVENTREG_08_40 PACK_WEEKEVENTREG_FLAG(8, 0x40) @@ -857,7 +857,7 @@ typedef enum { #define WEEKEVENTREG_34_02 PACK_WEEKEVENTREG_FLAG(34, 0x02) #define WEEKEVENTREG_34_04 PACK_WEEKEVENTREG_FLAG(34, 0x04) -#define WEEKEVENTREG_SWAMP_SPIDER_HOUSE_TALKED PACK_WEEKEVENTREG_FLAG(34, 0x08) +#define WEEKEVENTREG_TALKED_SWAMP_SPIDER_HOUSE_MAN PACK_WEEKEVENTREG_FLAG(34, 0x08) #define WEEKEVENTREG_34_10 PACK_WEEKEVENTREG_FLAG(34, 0x10) #define WEEKEVENTREG_34_20 PACK_WEEKEVENTREG_FLAG(34, 0x20) #define WEEKEVENTREG_RECEIVED_MASK_OF_TRUTH PACK_WEEKEVENTREG_FLAG(34, 0x40) @@ -924,62 +924,11 @@ typedef enum { #define WEEKEVENTREG_41_20 PACK_WEEKEVENTREG_FLAG(41, 0x20) #define WEEKEVENTREG_41_40 PACK_WEEKEVENTREG_FLAG(41, 0x40) #define WEEKEVENTREG_41_80 PACK_WEEKEVENTREG_FLAG(41, 0x80) -#define WEEKEVENTREG_42_01 PACK_WEEKEVENTREG_FLAG(42, 0x01) -#define WEEKEVENTREG_42_02 PACK_WEEKEVENTREG_FLAG(42, 0x02) -#define WEEKEVENTREG_42_04 PACK_WEEKEVENTREG_FLAG(42, 0x04) -#define WEEKEVENTREG_42_08 PACK_WEEKEVENTREG_FLAG(42, 0x08) -#define WEEKEVENTREG_42_10 PACK_WEEKEVENTREG_FLAG(42, 0x10) -#define WEEKEVENTREG_42_20 PACK_WEEKEVENTREG_FLAG(42, 0x20) -#define WEEKEVENTREG_42_40 PACK_WEEKEVENTREG_FLAG(42, 0x40) -#define WEEKEVENTREG_42_80 PACK_WEEKEVENTREG_FLAG(42, 0x80) -#define WEEKEVENTREG_43_01 PACK_WEEKEVENTREG_FLAG(43, 0x01) -#define WEEKEVENTREG_43_02 PACK_WEEKEVENTREG_FLAG(43, 0x02) -#define WEEKEVENTREG_43_04 PACK_WEEKEVENTREG_FLAG(43, 0x04) -#define WEEKEVENTREG_43_08 PACK_WEEKEVENTREG_FLAG(43, 0x08) -#define WEEKEVENTREG_43_10 PACK_WEEKEVENTREG_FLAG(43, 0x10) -#define WEEKEVENTREG_43_20 PACK_WEEKEVENTREG_FLAG(43, 0x20) -#define WEEKEVENTREG_43_40 PACK_WEEKEVENTREG_FLAG(43, 0x40) -#define WEEKEVENTREG_43_80 PACK_WEEKEVENTREG_FLAG(43, 0x80) -#define WEEKEVENTREG_44_01 PACK_WEEKEVENTREG_FLAG(44, 0x01) -#define WEEKEVENTREG_44_02 PACK_WEEKEVENTREG_FLAG(44, 0x02) -#define WEEKEVENTREG_44_04 PACK_WEEKEVENTREG_FLAG(44, 0x04) -#define WEEKEVENTREG_44_08 PACK_WEEKEVENTREG_FLAG(44, 0x08) -#define WEEKEVENTREG_44_10 PACK_WEEKEVENTREG_FLAG(44, 0x10) -#define WEEKEVENTREG_44_20 PACK_WEEKEVENTREG_FLAG(44, 0x20) -#define WEEKEVENTREG_44_40 PACK_WEEKEVENTREG_FLAG(44, 0x40) -#define WEEKEVENTREG_44_80 PACK_WEEKEVENTREG_FLAG(44, 0x80) -#define WEEKEVENTREG_45_01 PACK_WEEKEVENTREG_FLAG(45, 0x01) -#define WEEKEVENTREG_45_02 PACK_WEEKEVENTREG_FLAG(45, 0x02) -#define WEEKEVENTREG_45_04 PACK_WEEKEVENTREG_FLAG(45, 0x04) -#define WEEKEVENTREG_45_08 PACK_WEEKEVENTREG_FLAG(45, 0x08) -#define WEEKEVENTREG_45_10 PACK_WEEKEVENTREG_FLAG(45, 0x10) -#define WEEKEVENTREG_45_20 PACK_WEEKEVENTREG_FLAG(45, 0x20) -#define WEEKEVENTREG_45_40 PACK_WEEKEVENTREG_FLAG(45, 0x40) -#define WEEKEVENTREG_45_80 PACK_WEEKEVENTREG_FLAG(45, 0x80) -#define WEEKEVENTREG_46_01 PACK_WEEKEVENTREG_FLAG(46, 0x01) -#define WEEKEVENTREG_46_02 PACK_WEEKEVENTREG_FLAG(46, 0x02) -#define WEEKEVENTREG_46_04 PACK_WEEKEVENTREG_FLAG(46, 0x04) -#define WEEKEVENTREG_46_08 PACK_WEEKEVENTREG_FLAG(46, 0x08) -#define WEEKEVENTREG_46_10 PACK_WEEKEVENTREG_FLAG(46, 0x10) -#define WEEKEVENTREG_46_20 PACK_WEEKEVENTREG_FLAG(46, 0x20) -#define WEEKEVENTREG_46_40 PACK_WEEKEVENTREG_FLAG(46, 0x40) -#define WEEKEVENTREG_46_80 PACK_WEEKEVENTREG_FLAG(46, 0x80) -#define WEEKEVENTREG_47_01 PACK_WEEKEVENTREG_FLAG(47, 0x01) -#define WEEKEVENTREG_47_02 PACK_WEEKEVENTREG_FLAG(47, 0x02) -#define WEEKEVENTREG_47_04 PACK_WEEKEVENTREG_FLAG(47, 0x04) -#define WEEKEVENTREG_47_08 PACK_WEEKEVENTREG_FLAG(47, 0x08) -#define WEEKEVENTREG_47_10 PACK_WEEKEVENTREG_FLAG(47, 0x10) -#define WEEKEVENTREG_47_20 PACK_WEEKEVENTREG_FLAG(47, 0x20) -#define WEEKEVENTREG_47_40 PACK_WEEKEVENTREG_FLAG(47, 0x40) -#define WEEKEVENTREG_47_80 PACK_WEEKEVENTREG_FLAG(47, 0x80) -#define WEEKEVENTREG_48_01 PACK_WEEKEVENTREG_FLAG(48, 0x01) -#define WEEKEVENTREG_48_02 PACK_WEEKEVENTREG_FLAG(48, 0x02) -#define WEEKEVENTREG_48_04 PACK_WEEKEVENTREG_FLAG(48, 0x04) -#define WEEKEVENTREG_48_08 PACK_WEEKEVENTREG_FLAG(48, 0x08) -#define WEEKEVENTREG_48_10 PACK_WEEKEVENTREG_FLAG(48, 0x10) -#define WEEKEVENTREG_48_20 PACK_WEEKEVENTREG_FLAG(48, 0x20) -#define WEEKEVENTREG_48_40 PACK_WEEKEVENTREG_FLAG(48, 0x40) -#define WEEKEVENTREG_48_80 PACK_WEEKEVENTREG_FLAG(48, 0x80) + +// Used for storing the text ID offsets for the dogs in the Doggy Racetrack (56 entries) +// The number of weekEventRegs used needs to be kept in sync with RACEDOG_COUNT in z_en_aob_01.h +// PACK_WEEKEVENTREG_FLAG(42, 0x01) to PACK_WEEKEVENTREG_FLAG(48, 0x80) + #define WEEKEVENTREG_49_01 PACK_WEEKEVENTREG_FLAG(49, 0x01) #define WEEKEVENTREG_49_02 PACK_WEEKEVENTREG_FLAG(49, 0x02) #define WEEKEVENTREG_49_04 PACK_WEEKEVENTREG_FLAG(49, 0x04) @@ -1013,10 +962,7 @@ typedef enum { #define WEEKEVENTREG_52_04 PACK_WEEKEVENTREG_FLAG(52, 0x04) #define WEEKEVENTREG_52_08 PACK_WEEKEVENTREG_FLAG(52, 0x08) #define WEEKEVENTREG_52_10 PACK_WEEKEVENTREG_FLAG(52, 0x10) - -// cleared Stone Tower Temple #define WEEKEVENTREG_CLEARED_STONE_TOWER_TEMPLE PACK_WEEKEVENTREG_FLAG(52, 0x20) - #define WEEKEVENTREG_52_40 PACK_WEEKEVENTREG_FLAG(52, 0x40) #define WEEKEVENTREG_52_80 PACK_WEEKEVENTREG_FLAG(52, 0x80) #define WEEKEVENTREG_53_01 PACK_WEEKEVENTREG_FLAG(53, 0x01) @@ -1130,12 +1076,12 @@ typedef enum { #define WEEKEVENTREG_64_10 PACK_WEEKEVENTREG_FLAG(64, 0x10) #define WEEKEVENTREG_64_20 PACK_WEEKEVENTREG_FLAG(64, 0x20) #define WEEKEVENTREG_64_40 PACK_WEEKEVENTREG_FLAG(64, 0x40) -#define WEEKEVENTREG_64_80 PACK_WEEKEVENTREG_FLAG(64, 0x80) -#define WEEKEVENTREG_65_01 PACK_WEEKEVENTREG_FLAG(65, 0x01) -#define WEEKEVENTREG_65_02 PACK_WEEKEVENTREG_FLAG(65, 0x02) -#define WEEKEVENTREG_65_04 PACK_WEEKEVENTREG_FLAG(65, 0x04) -#define WEEKEVENTREG_65_08 PACK_WEEKEVENTREG_FLAG(65, 0x08) -#define WEEKEVENTREG_65_10 PACK_WEEKEVENTREG_FLAG(65, 0x10) +#define WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_DAY_1 PACK_WEEKEVENTREG_FLAG(64, 0x80) +#define WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_NIGHT_1 PACK_WEEKEVENTREG_FLAG(65, 0x01) +#define WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_DAY_2 PACK_WEEKEVENTREG_FLAG(65, 0x02) +#define WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_NIGHT_2 PACK_WEEKEVENTREG_FLAG(65, 0x04) +#define WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_DAY_3 PACK_WEEKEVENTREG_FLAG(65, 0x08) +#define WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_NIGHT_3 PACK_WEEKEVENTREG_FLAG(65, 0x10) #define WEEKEVENTREG_65_20 PACK_WEEKEVENTREG_FLAG(65, 0x20) #define WEEKEVENTREG_65_40 PACK_WEEKEVENTREG_FLAG(65, 0x40) #define WEEKEVENTREG_65_80 PACK_WEEKEVENTREG_FLAG(65, 0x80) @@ -1385,10 +1331,8 @@ typedef enum { #define WEEKEVENTREG_91_40 PACK_WEEKEVENTREG_FLAG(91, 0x40) #define WEEKEVENTREG_91_80 PACK_WEEKEVENTREG_FLAG(91, 0x80) -// RACE_FLAGS -//#define WEEKEVENTREG_92_01 PACK_WEEKEVENTREG_FLAG(92, 0x01) -//#define WEEKEVENTREG_92_02 PACK_WEEKEVENTREG_FLAG(92, 0x02) -//#define WEEKEVENTREG_92_04 PACK_WEEKEVENTREG_FLAG(92, 0x04) +// HORSE_RACE_STATE (3 entries) +// WEEKEVENTREG_92_01 to WEEKEVENTREG_92_04 #define WEEKEVENTREG_92_08 PACK_WEEKEVENTREG_FLAG(92, 0x08) #define WEEKEVENTREG_92_10 PACK_WEEKEVENTREG_FLAG(92, 0x10) @@ -1460,34 +1404,52 @@ typedef enum { #define SET_WEEKEVENTREG(flag) (WEEKEVENTREG((flag) >> 8) = GET_WEEKEVENTREG((flag) >> 8) | ((flag) & 0xFF)) #define CLEAR_WEEKEVENTREG(flag) (WEEKEVENTREG((flag) >> 8) = GET_WEEKEVENTREG((flag) >> 8) & (u8)~((flag) & 0xFF)) -#define WEEKEVENTREG_RACE_FLAG_END 0 -#define WEEKEVENTREG_RACE_FLAG_START 1 -#define WEEKEVENTREG_RACE_FLAG_2 2 -#define WEEKEVENTREG_RACE_FLAG_3 3 -#define WEEKEVENTREG_RACE_FLAG_4 4 -#define WEEKEVENTREG_RACE_FLAGS 7 +typedef enum { + /* 0 */ WEEKEVENTREG_HORSE_RACE_STATE_END, + /* 1 */ WEEKEVENTREG_HORSE_RACE_STATE_START, + /* 2 */ WEEKEVENTREG_HORSE_RACE_STATE_2, + /* 3 */ WEEKEVENTREG_HORSE_RACE_STATE_3, + /* 4 */ WEEKEVENTREG_HORSE_RACE_STATE_4, + /* 7 */ WEEKEVENTREG_HORSE_RACE_STATE_MAX = 7 +} WeekEventRegHorseRaceState; -#define GET_WEEKEVENTREG_RACE_FLAGS (WEEKEVENTREG(92) & WEEKEVENTREG_RACE_FLAGS) +#define GET_WEEKEVENTREG_HORSE_RACE_STATE (WEEKEVENTREG(92) & WEEKEVENTREG_HORSE_RACE_STATE_MAX) -#define SET_WEEKEVENTREG_RACE_FLAGS(flag) \ - { \ - WEEKEVENTREG(92) &= (u8)~WEEKEVENTREG_RACE_FLAGS; \ - WEEKEVENTREG(92) = WEEKEVENTREG(92) | (u8)((WEEKEVENTREG(92) & ~WEEKEVENTREG_RACE_FLAGS) | (flag)); \ - } \ +#define SET_WEEKEVENTREG_HORSE_RACE_STATE(state) \ + { \ + WEEKEVENTREG(92) &= (u8)~WEEKEVENTREG_HORSE_RACE_STATE_MAX; \ + WEEKEVENTREG(92) = WEEKEVENTREG(92) | (u8)((WEEKEVENTREG(92) & ~WEEKEVENTREG_HORSE_RACE_STATE_MAX) | (state)); \ + } \ (void)0 +#define GET_WEEKEVENTREG_DOG_RACE_TEXT(index, baseTextId) \ + (index % 2) ? (baseTextId + (((WEEKEVENTREG(42 + (index / 2))) & 0xF0) >> 4)) \ + : (baseTextId + ((WEEKEVENTREG(42 + (index / 2))) & 0x0F)); + +#define SET_WEEKEVENTREG_DOG_RACE_TEXT_OFFSETS(index, packedOffsets) \ + { \ + WEEKEVENTREG(42 + index) = ((void)0, WEEKEVENTREG(42 + index)) | packedOffsets; \ + } + +#define CLEAR_WEEKEVENTREG_DOG_RACE_TEXT_OFFSETS(index) \ + { \ + WEEKEVENTREG(42 + index) = 0; \ + } + /** * gSaveContext.eventInf */ -#define EVENTINF_00 0x00 -#define EVENTINF_01 0x01 -#define EVENTINF_02 0x02 -#define EVENTINF_03 0x03 -#define EVENTINF_04 0x04 -#define EVENTINF_05 0x05 -#define EVENTINF_06 0x06 -#define EVENTINF_07 0x07 +// gSaveContext.eventInf[0] is used to dog race information +// #define EVENTINF_00 0x00 +// #define EVENTINF_01 0x01 +// #define EVENTINF_02 0x02 +// #define EVENTINF_03 0x03 +// #define EVENTINF_04 0x04 +// #define EVENTINF_05 0x05 +// #define EVENTINF_06 0x06 +// #define EVENTINF_07 0x07 + #define EVENTINF_10 0x10 #define EVENTINF_11 0x11 #define EVENTINF_12 0x12 @@ -1561,6 +1523,25 @@ typedef enum { #define CLEAR_EVENTINF(flag) (gSaveContext.eventInf[(flag) >> 4] &= (u8)~(1 << ((flag) & 0xF))) #define CLEAR_EVENTINF_ALT(flag) (gSaveContext.eventInf[(flag) >> 4] &= ~(1 << ((flag) & 0xF))) +typedef enum { + /* 0 */ EVENTINF_DOG_RACE_STATE_NOT_STARTED, + /* 2 */ EVENTINF_DOG_RACE_STATE_STARTED = 2, + /* 3 */ EVENTINF_DOG_RACE_STATE_ENDED, + /* 7 */ EVENTINF_DOG_RACE_STATE_MAX = 7 +} EventInfDogRaceState; + +#define GET_EVENTINF_DOG_RACE_STATE (gSaveContext.eventInf[0] & EVENTINF_DOG_RACE_STATE_MAX) +#define SET_EVENTINF_DOG_RACE_STATE(state) \ + (gSaveContext.eventInf[0] = ((gSaveContext.eventInf[0] & (u8)~EVENTINF_DOG_RACE_STATE_MAX) | (state))) + +#define GET_EVENTINF_DOG_RACE_SELECTED_DOG_INDEX ((gSaveContext.eventInf[0] & (u8)~EVENTINF_DOG_RACE_STATE_MAX) >> 3) +#define SET_EVENTINF_DOG_RACE_SELECTED_DOG_INDEX(selectedDogIndex) \ + (gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & EVENTINF_DOG_RACE_STATE_MAX) | (selectedDogIndex << 3)) + +// This is exactly the same as the selected dog index; they never need both of them at the same time. +#define GET_EVENTINF_DOG_RACE_RACE_STANDING ((gSaveContext.eventInf[0] & (u8)~EVENTINF_DOG_RACE_STATE_MAX) >> 3) +#define SET_EVENTINF_DOG_RACE_RACE_STANDING(raceStanding) \ + (gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & EVENTINF_DOG_RACE_STATE_MAX) | (raceStanding << 3)) typedef enum { /* 0 */ DUNGEON_INDEX_WOODFALL_TEMPLE, diff --git a/src/boot_O2_g3/z_std_dma.c b/src/boot_O2_g3/z_std_dma.c index bbf8e4bed4..00d894f74a 100644 --- a/src/boot_O2_g3/z_std_dma.c +++ b/src/boot_O2_g3/z_std_dma.c @@ -1,3 +1,4 @@ +#include "prevent_bss_reordering.h" #include "global.h" #include "stack.h" #include "stackcheck.h" diff --git a/src/code/z_play.c b/src/code/z_play.c index 57386c97c8..ca0ebcbae1 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -1,4 +1,3 @@ -#include "prevent_bss_reordering.h" #include "global.h" #include "buffers.h" #include "z64debug_display.h" diff --git a/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.c b/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.c index 5aa7462983..45a413c267 100644 --- a/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.c +++ b/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.c @@ -12,27 +12,25 @@ #define THIS ((EnAob01*)thisx) -//! TODO: this file require macros for its uses of weekEventReg - void EnAob01_Init(Actor* thisx, PlayState* play); void EnAob01_Destroy(Actor* thisx, PlayState* play); void EnAob01_Update(Actor* thisx, PlayState* play); void EnAob01_Draw(Actor* thisx, PlayState* play); -void func_809C1C9C(EnAob01* this, PlayState* play); -void func_809C1D64(EnAob01* this, PlayState* play); -void func_809C2060(EnAob01* this, PlayState* play); -void func_809C21E0(EnAob01* this, PlayState* play); -void func_809C26E4(EnAob01* this, PlayState* play); -void func_809C2730(EnAob01* this, PlayState* play); -void func_809C2788(EnAob01* this, PlayState* play); -void func_809C2824(EnAob01* this, PlayState* play); -void func_809C28B8(EnAob01* this, PlayState* play); -void func_809C2A64(EnAob01* this, PlayState* play); -void func_809C2BE4(EnAob01* this, PlayState* play); -void func_809C2C9C(EnAob01* this, PlayState* play); -void func_809C2D0C(EnAob01* this, PlayState* play); -s32 func_809C2EC4(EnAob01* this, PlayState* play); +void EnAob01_BeforeRace_StartRace(EnAob01* this, PlayState* play); +void EnAob01_BeforeRace_RespondToPlayAgainQuestion(EnAob01* this, PlayState* play); +void EnAob01_BeforeRace_Idle(EnAob01* this, PlayState* play); +void EnAob01_BeforeRace_Talk(EnAob01* this, PlayState* play); +void EnAob01_Race_SkipNonRaceCutscene(EnAob01* this, PlayState* play); +void EnAob01_Race_HandleRaceCutscene(EnAob01* this, PlayState* play); +void EnAob01_Race_HandleRaceEndCutscene(EnAob01* this, PlayState* play); +void EnAob01_Race_StartCutscene(EnAob01* this, PlayState* play); +void EnAob01_AfterRace_GiveRaceResult(EnAob01* this, PlayState* play); +void EnAob01_AfterRace_GiveReward(EnAob01* this, PlayState* play); +void EnAob01_AfterRace_AfterGivingReward(EnAob01* this, PlayState* play); +void EnAob01_AfterRace_AskToPlayAgain(EnAob01* this, PlayState* play); +void EnAob01_AfterRace_Talk(EnAob01* this, PlayState* play); +s32 EnAob01_PlayerIsHoldingDog(EnAob01* this, PlayState* play); ActorInit En_Aob_01_InitVars = { ACTOR_EN_AOB_01, @@ -46,6 +44,22 @@ ActorInit En_Aob_01_InitVars = { (ActorFunc)EnAob01_Draw, }; +typedef enum { + /* 0 */ EN_AOB01_ANIM_IDLE_1, + /* 1 */ EN_AOB01_ANIM_LAUGH_START, + /* 2 */ EN_AOB01_ANIM_LAUGH_LOOP, + /* 3 */ EN_AOB01_ANIM_SURPRISE_START, + /* 4 */ EN_AOB01_ANIM_SURPRISE_LOOP, + /* 5 */ EN_AOB01_ANIM_IDLE_2, +} EnAob01Animation; + +typedef enum { + /* 0 */ EN_AOB01_EYE_OPEN, + /* 1 */ EN_AOB01_EYE_HALF, + /* 2 */ EN_AOB01_EYE_CLOSED, + /* 3 */ EN_AOB01_EYE_MAX, +} EnAob01EyeTexture; + static AnimationInfo sAnimationInfo[] = { { &gMamamuYanIdleAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, { &gMamamuYanLaughStartAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, 0.0f }, @@ -76,12 +90,16 @@ static ColliderCylinderInit sCylinderInit = { }; typedef struct { - Vec3f unk_00; - s16 unk_04; - s16 unk_06; -} EnAobStruct; + /* 0x0 */ Vec3f pos; + /* 0xC */ s16 rotY; + /* 0xE */ s16 pathIndex; +} DogInfo; // size = 0x10 -static EnAobStruct D_809C384C[] = { +/** + * Stores the starting position, y-rotation, and path index for all 14 dogs in the racetrack. + * This actor is responsible for spawning these dogs; they are not spawned as part of the scene. + */ +static DogInfo sDogInfo[RACEDOG_COUNT] = { { { -4130.0f, 150.0f, 1367.0f }, 84, 0 }, { { -4861.0f, 172.0f, 1606.0f }, 94, 4 }, { { -4139.0f, 155.0f, 2133.0f }, 73, 6 }, { { -4406.0f, 144.0f, 1416.0f }, 88, 2 }, { { -4156.0f, 155.0f, 1731.0f }, 42, 0 }, { { -4033.0f, 157.0f, 1994.0f }, -65, 1 }, @@ -91,105 +109,137 @@ static EnAobStruct D_809C384C[] = { { { -4827.0f, 168.0f, 1328.0f }, 115, 4 }, { { -4130.0f, 150.0f, 1367.0f }, 112, 0 }, }; -void func_809C10B0(EnAob01* this, s32 arg1) { +void EnAob01_Blink(EnAob01* this, s32 maxEyeIndex) { if (DECR(this->blinkTimer) == 0) { this->eyeIndex++; - if (this->eyeIndex >= arg1) { - this->eyeIndex = 0; + if (this->eyeIndex >= maxEyeIndex) { + this->eyeIndex = EN_AOB01_EYE_OPEN; this->blinkTimer = Rand_S16Offset(30, 30); } } } -void func_809C1124(void) { +/** + * Called every frame during the race in order to make in-game time pass. + */ +void EnAob01_AdvanceTime(void) { gSaveContext.save.time = ((void)0, gSaveContext.save.time) + (u16)R_TIME_SPEED; gSaveContext.save.time = ((void)0, gSaveContext.save.time) + (u16)((void)0, gSaveContext.save.timeSpeedOffset); } -void func_809C1158(EnAob01* this, PlayState* play) { - s32 temp_s0 = ENAOB01_GET_7E00_2(&this->actor); +/** + * Initializes all the paths that the dogs follow. + */ +void EnAob01_InitializeDogPaths(EnAob01* this, PlayState* play) { + s32 pathIndex = ENAOB01_GET_STARTING_DOG_PATH_INDEX(&this->actor); s16 i = 0; - if (temp_s0 != 0x3F) { + if (pathIndex != 0x3F) { do { - this->unk_1D8[i] = SubS_GetPathByIndex(play, temp_s0, 0x3F); - temp_s0 = this->unk_1D8[i]->unk1; + this->dogPaths[i] = SubS_GetPathByIndex(play, pathIndex, 0x3F); + pathIndex = this->dogPaths[i]->unk1; i++; - } while (temp_s0 != 0xFF); + } while (pathIndex != 0xFF); } } -void func_809C11EC(EnAob01* this, PlayState* play) { +/** + * Spawns the dogs that mill about the racetrack before and after each race. + */ +void EnAob01_SpawnDogs(EnAob01* this, PlayState* play) { s32 enDgParams; s16 i; - func_809C1158(this, play); + EnAob01_InitializeDogPaths(this, play); - for (i = 0; i < ARRAY_COUNT(D_809C384C); i++) { - enDgParams = ENDG_PARAMS(this->unk_1D8[D_809C384C[i].unk_06]->unk1, i); + for (i = 0; i < RACEDOG_COUNT; i++) { + enDgParams = ENDG_PARAMS(this->dogPaths[sDogInfo[i].pathIndex]->unk1, i); - this->unk_3F8[i] = Actor_SpawnAsChildAndCutscene( - &play->actorCtx, play, ACTOR_EN_DG, D_809C384C[i].unk_00.x, D_809C384C[i].unk_00.y, D_809C384C[i].unk_00.z, - 0, DEG_TO_BINANG(D_809C384C[i].unk_04), 0, enDgParams, (u16)CS_ID_NONE, this->actor.halfDaysBits, NULL); + this->dogs[i] = Actor_SpawnAsChildAndCutscene( + &play->actorCtx, play, ACTOR_EN_DG, sDogInfo[i].pos.x, sDogInfo[i].pos.y, sDogInfo[i].pos.z, 0, + DEG_TO_BINANG(sDogInfo[i].rotY), 0, enDgParams, (u16)CS_ID_NONE, this->actor.halfDaysBits, NULL); } } -void func_809C1304(EnAob01* this, PlayState* play) { +/** + * Spawns the dogs that run around the track during each race. + */ +void EnAob01_SpawnRacedogs(EnAob01* this, PlayState* play) { s16 i; - for (i = 0; i < ARRAY_COUNT(this->unk_3F8); i++) { - this->unk_3F8[i] = Actor_SpawnAsChildAndCutscene( - &play->actorCtx, play, ACTOR_EN_RACEDOG, (i * 15.0f) + -3897.0f, 130.0f, 1290.0f - (i * 10.0f), 0, 0x1555, - 0, (i << 5) | ENAOB01_GET_7E00_1(&this->actor), (u16)CS_ID_NONE, this->actor.halfDaysBits, NULL); + for (i = 0; i < RACEDOG_COUNT; i++) { + this->dogs[i] = Actor_SpawnAsChildAndCutscene(&play->actorCtx, play, ACTOR_EN_RACEDOG, (i * 15.0f) + -3897.0f, + 130.0f, 1290.0f - (i * 10.0f), 0, 0x1555, 0, + ENRACEDOG_PARAMS(i, ENAOB01_GET_RACEDOG_PATH_INDEX(&this->actor)), + (u16)CS_ID_NONE, this->actor.halfDaysBits, NULL); } } -s32 func_809C1424(EnAob01* this) { +/** + * If the racetrack owner is at the end of her laugh start animation, this function will + * transition her to her laugh loop animation. This function will return true if she is + * *either* in her laugh start or laugh loop animation, false otherwise. + */ +s32 EnAob01_ProcessLaughAnim(EnAob01* this) { s16 curFrame = this->skelAnime.curFrame; - s16 lastFrame = Animation_GetLastFrame(sAnimationInfo[this->unk_43C].animation); + s16 lastFrame = Animation_GetLastFrame(sAnimationInfo[this->animIndex].animation); - if (this->unk_43C == 1) { + if (this->animIndex == EN_AOB01_ANIM_LAUGH_START) { if (curFrame == lastFrame) { - this->unk_43C = 2; - Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, 2); + this->animIndex = EN_AOB01_ANIM_LAUGH_LOOP; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, EN_AOB01_ANIM_LAUGH_LOOP); return true; } - } else if (this->unk_43C == 2) { + } else if (this->animIndex == EN_AOB01_ANIM_LAUGH_LOOP) { return true; } + return false; } -s32 func_809C14D0(EnAob01* this) { +/** + * If the racetrack owner is at the end of her idle animation, this function will + * transition her to her surprise start animation. If the racetrack owner is at the + * end of her surprise start animation, this function will transition her to her + * surprise loop animation. This function will return true if she is *either* in + * her surprise start or surprise loop animation, false otherwise. + */ +s32 EnAob01_ProcessSurpriseAnim(EnAob01* this) { s16 curFrame = this->skelAnime.curFrame; - s16 lastFrame = Animation_GetLastFrame(sAnimationInfo[this->unk_43C].animation); + s16 lastFrame = Animation_GetLastFrame(sAnimationInfo[this->animIndex].animation); - if ((this->unk_43C == 0) || (this->unk_43C == 5)) { + if ((this->animIndex == EN_AOB01_ANIM_IDLE_1) || (this->animIndex == EN_AOB01_ANIM_IDLE_2)) { if (curFrame == lastFrame) { - this->unk_43C = 3; - Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, 3); + this->animIndex = EN_AOB01_ANIM_SURPRISE_START; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, EN_AOB01_ANIM_SURPRISE_START); return true; } - } else if (this->unk_43C == 3) { + } else if (this->animIndex == EN_AOB01_ANIM_SURPRISE_START) { if (curFrame == lastFrame) { - this->unk_43C = 4; - Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, 4); + this->animIndex = EN_AOB01_ANIM_SURPRISE_LOOP; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, EN_AOB01_ANIM_SURPRISE_LOOP); return true; } - } else if (this->unk_43C == 4) { + } else if (this->animIndex == EN_AOB01_ANIM_SURPRISE_LOOP) { return true; } + return false; } -s32 func_809C15BC(EnAob01* this) { +/** + * If the racetrack owner is at the end of her current animation, this function will + * transition her to her the idle animation. This function will return true if she is + * in her idle animation, false otherwise. + */ +s32 EnAob01_ProcessIdleAnim(EnAob01* this) { s16 curFrame = this->skelAnime.curFrame; - s16 lastFrame = Animation_GetLastFrame(sAnimationInfo[this->unk_43C].animation); + s16 lastFrame = Animation_GetLastFrame(sAnimationInfo[this->animIndex].animation); - if ((this->unk_43C != 0) && (this->unk_43C != 5)) { + if ((this->animIndex != EN_AOB01_ANIM_IDLE_1) && (this->animIndex != EN_AOB01_ANIM_IDLE_2)) { if (curFrame == lastFrame) { - this->unk_43C = 5; - Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, 5); + this->animIndex = EN_AOB01_ANIM_IDLE_2; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, EN_AOB01_ANIM_IDLE_2); return true; } } else { @@ -199,7 +249,7 @@ s32 func_809C15BC(EnAob01* this) { return false; } -void func_809C165C(EnAob01* this, PlayState* play) { +void EnAob01_UpdateCollision(EnAob01* this, PlayState* play) { this->collider.dim.pos.x = this->actor.world.pos.x; this->collider.dim.pos.y = this->actor.world.pos.y; this->collider.dim.pos.z = this->actor.world.pos.z; @@ -207,227 +257,238 @@ void func_809C165C(EnAob01* this, PlayState* play) { CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); } -void func_809C16DC(EnAob01* this, PlayState* play) { +/** + * Handles all parts of the conversation with the racetrack owner before the race begins. + */ +void EnAob01_BeforeRace_HandleConversation(EnAob01* this, PlayState* play) { Player* player = GET_PLAYER(play); - switch (this->unk_210) { + switch (this->textId) { case 0: - case 0x3524: - case 0x3535: - case 0x3548: - case 0x3549: - case 0x354A: + case 0x3524: // You can't play if you can't pay! + case 0x3535: // Really? + case 0x3548: // I can't let you play. (Goron) + case 0x3549: // I can't let you play. (Zora) + case 0x354A: // I can't let you play. (Deku) switch (gSaveContext.save.day) { case 1: if (!gSaveContext.save.isNight) { - if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_64_80)) { - SET_WEEKEVENTREG(WEEKEVENTREG_64_80); - this->unk_210 = 0x3520; + if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_DAY_1)) { + SET_WEEKEVENTREG(WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_DAY_1); + this->textId = 0x3520; // This is the Doggy Racetrack. (Day 1) } else { - this->unk_210 = 0x352F; + this->textId = 0x352F; // What do you want? } } else { - if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_65_01)) { - SET_WEEKEVENTREG(WEEKEVENTREG_65_01); - this->unk_210 = 0x3530; + if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_NIGHT_1)) { + SET_WEEKEVENTREG(WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_NIGHT_1); + this->textId = 0x3530; // This is the Doggy Racetrack. (Night 1) } else { - this->unk_210 = 0x352F; + this->textId = 0x352F; // What do you want? } } break; case 2: if (!gSaveContext.save.isNight) { - if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_65_02)) { - SET_WEEKEVENTREG(WEEKEVENTREG_65_02); - this->unk_210 = 0x3531; + if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_DAY_2)) { + SET_WEEKEVENTREG(WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_DAY_2); + this->textId = 0x3531; // This is the Doggy Racetrack. (Day 2) } else { - this->unk_210 = 0x352F; + this->textId = 0x352F; // What do you want? } } else { - if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_65_04)) { - SET_WEEKEVENTREG(WEEKEVENTREG_65_04); - this->unk_210 = 0x3532; + if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_NIGHT_2)) { + SET_WEEKEVENTREG(WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_NIGHT_2); + this->textId = 0x3532; // This is the Doggy Racetrack. (Night 2) } else { - this->unk_210 = 0x352F; + this->textId = 0x352F; // What do you want? } } break; case 3: if (!gSaveContext.save.isNight) { - if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_65_08)) { - SET_WEEKEVENTREG(WEEKEVENTREG_65_08); - this->unk_210 = 0x3533; + if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_DAY_3)) { + SET_WEEKEVENTREG(WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_DAY_3); + this->textId = 0x3533; // This is the Doggy Racetrack. (Day 3) } else { - this->unk_210 = 0x352F; + this->textId = 0x352F; // What do you want? } } else { - if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_65_10)) { - SET_WEEKEVENTREG(WEEKEVENTREG_65_10); - this->unk_210 = 0x3534; + if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_NIGHT_3)) { + SET_WEEKEVENTREG(WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_NIGHT_3); + this->textId = 0x3534; // This is the Doggy Racetrack. (Night 3) } else { - this->unk_210 = 0x352F; + this->textId = 0x352F; // What do you want? } } break; } break; - case 0x3520: - case 0x352F: - case 0x3530: - case 0x3531: - case 0x3532: - case 0x3533: - case 0x3534: - this->unk_210 = 0x3521; + case 0x3520: // This is the Doggy Racetrack. (Day 1) + case 0x352F: // What do you want? + case 0x3530: // This is the Doggy Racetrack. (Night 1) + case 0x3531: // This is the Doggy Racetrack. (Day 2) + case 0x3532: // This is the Doggy Racetrack. (Night 2) + case 0x3533: // This is the Doggy Racetrack. (Day 3) + case 0x3534: // This is the Doggy Racetrack. (Night 3) + this->textId = 0x3521; // Do you want to try the dog race? break; - case 0x3521: - if (this->unk_2D2 & 2) { - this->unk_2D2 &= ~2; + case 0x3521: // Do you want to try the dog race? + if (this->stateFlags & ENAOB01_FLAG_PLAYER_CONFIRMED_CHOICE) { + this->stateFlags &= ~ENAOB01_FLAG_PLAYER_CONFIRMED_CHOICE; switch (player->transformation) { case PLAYER_FORM_GORON: - this->unk_210 = 0x3548; - this->unk_2D2 |= 0x10; + this->textId = 0x3548; // I can't let you play. (Goron) + this->stateFlags |= ENAOB01_FLAG_CONVERSATION_OVER; break; case PLAYER_FORM_ZORA: - this->unk_210 = 0x3549; - this->unk_2D2 |= 0x10; + this->textId = 0x3549; // I can't let you play. (Zora) + this->stateFlags |= ENAOB01_FLAG_CONVERSATION_OVER; break; case PLAYER_FORM_DEKU: - this->unk_210 = 0x354A; - this->unk_2D2 |= 0x10; + this->textId = 0x354A; // I can't let you play. (Deku) + this->stateFlags |= ENAOB01_FLAG_CONVERSATION_OVER; break; case PLAYER_FORM_HUMAN: if (gSaveContext.save.saveInfo.playerData.rupees < 10) { - this->unk_210 = 0x3524; - this->unk_2D2 |= 0x10; + this->textId = 0x3524; // You can't play if you can't pay! + this->stateFlags |= ENAOB01_FLAG_CONVERSATION_OVER; } else { - this->unk_210 = 0x3522; - this->unk_2D2 |= 4; - this->unk_2D2 |= 0x10; + this->textId = 0x3522; // Bring me the fastest dog! + this->stateFlags |= ENAOB01_FLAG_PLAYER_TOLD_TO_PICK_A_DOG; + this->stateFlags |= ENAOB01_FLAG_CONVERSATION_OVER; } } } else { - this->unk_2D2 |= 0x10; - this->unk_210 = 0x3535; + this->stateFlags |= ENAOB01_FLAG_CONVERSATION_OVER; + this->textId = 0x3535; // Is that dog fine? } break; - case 0x3522: - case 0x3523: - if (this->unk_2D2 & 8) { - this->unk_210 = 0x3525; + case 0x3522: // Bring me the fastest dog! + case 0x3523: // Hurry up and bring me a dog! + if (this->stateFlags & ENAOB01_FLAG_TALKING_TO_PLAYER_HOLDING_DOG) { + this->textId = 0x3525; // Is that dog okay? break; } - this->unk_210 = 0x3523; - this->unk_2D2 |= 0x40; - this->unk_2D2 |= 0x10; - this->unk_43C = 1; - Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, 1); + this->textId = 0x3523; // Hurry up and bring me a dog! + this->stateFlags |= ENAOB01_FLAG_LAUGH; + this->stateFlags |= ENAOB01_FLAG_CONVERSATION_OVER; + this->animIndex = EN_AOB01_ANIM_LAUGH_START; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, EN_AOB01_ANIM_LAUGH_START); break; - case 0x3525: - case 0x3526: - if (this->unk_2D2 & 4) { - if (this->unk_2D2 & 8) { - this->unk_210 = 0x3525; + case 0x3525: // Is that dog okay? + case 0x3526: // Don't wait! Hurry up and choose! + if (this->stateFlags & ENAOB01_FLAG_PLAYER_TOLD_TO_PICK_A_DOG) { + if (this->stateFlags & ENAOB01_FLAG_TALKING_TO_PLAYER_HOLDING_DOG) { + this->textId = 0x3525; // Is that dog okay? break; } - this->unk_210 = 0x3523; - this->unk_2D2 |= 0x40; - this->unk_2D2 |= 0x10; - this->unk_43C = 1; - Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, 1); + this->textId = 0x3523; // Hurry up and bring me a dog! + this->stateFlags |= ENAOB01_FLAG_LAUGH; + this->stateFlags |= ENAOB01_FLAG_CONVERSATION_OVER; + this->animIndex = EN_AOB01_ANIM_LAUGH_START; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, EN_AOB01_ANIM_LAUGH_START); break; } - if (this->unk_2D2 & 2) { - this->unk_2D2 &= ~2; - this->unk_210 = 0x3527; + if (this->stateFlags & ENAOB01_FLAG_PLAYER_CONFIRMED_CHOICE) { + this->stateFlags &= ~ENAOB01_FLAG_PLAYER_CONFIRMED_CHOICE; + this->textId = 0x3527; // If you win, you'll get more than you bet. break; } - this->unk_210 = 0x3526; - this->unk_2D2 |= 0x40; - this->unk_2D2 |= 4; - this->unk_2D2 |= 0x10; - this->unk_43C = 1; - Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, 1); + this->textId = 0x3526; // Don't wait! Hurry up and choose! + this->stateFlags |= ENAOB01_FLAG_LAUGH; + this->stateFlags |= ENAOB01_FLAG_PLAYER_TOLD_TO_PICK_A_DOG; + this->stateFlags |= ENAOB01_FLAG_CONVERSATION_OVER; + this->animIndex = EN_AOB01_ANIM_LAUGH_START; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, EN_AOB01_ANIM_LAUGH_START); break; - case 0x3527: - this->unk_210 = 0x3528; + case 0x3527: // If you win, you'll get more than you bet. + this->textId = 0x3528; // How much will you bet? break; - case 0x3528: - if (gSaveContext.save.saveInfo.playerData.rupees < this->unk_434) { - this->unk_210 = 0x3536; - this->unk_2D2 |= 0x40; - this->unk_43C = 1; - Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, 1); + case 0x3528: // How much will you bet? + if (gSaveContext.save.saveInfo.playerData.rupees < this->rupeesBet) { + this->textId = 0x3536; // You don't have enough rupees for that bet. + this->stateFlags |= ENAOB01_FLAG_LAUGH; + this->animIndex = EN_AOB01_ANIM_LAUGH_START; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, EN_AOB01_ANIM_LAUGH_START); break; } - if (this->unk_434 == 0) { - this->unk_210 = 0x3537; - this->unk_2D2 |= 0x40; - this->unk_43C = 1; - Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, 1); + if (this->rupeesBet == 0) { + this->textId = 0x3537; // You can't race if you don't bet. + this->stateFlags |= ENAOB01_FLAG_LAUGH; + this->animIndex = EN_AOB01_ANIM_LAUGH_START; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, EN_AOB01_ANIM_LAUGH_START); break; } - gSaveContext.unk_3F5C = this->unk_434; - play->msgCtx.bankRupees = this->unk_434; - this->unk_210 = 0x3529; + gSaveContext.unk_3F5C = this->rupeesBet; + play->msgCtx.bankRupees = this->rupeesBet; + this->textId = 0x3529; // Is that bet okay? break; - case 0x3529: - if (this->unk_2D2 & 2) { - this->unk_2D2 &= ~2; - Rupees_ChangeBy(-this->unk_434); + case 0x3529: // Is that bet okay? + if (this->stateFlags & ENAOB01_FLAG_PLAYER_CONFIRMED_CHOICE) { + this->stateFlags &= ~ENAOB01_FLAG_PLAYER_CONFIRMED_CHOICE; + Rupees_ChangeBy(-this->rupeesBet); func_800B7298(play, NULL, PLAYER_CSMODE_WAIT); play->msgCtx.msgMode = 0x43; play->msgCtx.stateTimer = 4; - this->actionFunc = func_809C1C9C; + this->actionFunc = EnAob01_BeforeRace_StartRace; return; } - this->unk_210 = 0x3528; + this->textId = 0x3528; // How much will you bet? break; - case 0x3536: - case 0x3537: - this->unk_210 = 0x3528; + case 0x3536: // You don't have enough rupees for that bet. + case 0x3537: // You can't race if you don't bet. + this->textId = 0x3528; // How much will you bet? break; } - Message_StartTextbox(play, this->unk_210, &this->actor); + Message_StartTextbox(play, this->textId, &this->actor); } -void func_809C1C9C(EnAob01* this, PlayState* play) { +/** + * Once the player's rupees are done counting down, this function will + * reload the racetrack to start the race. + */ +void EnAob01_BeforeRace_StartRace(EnAob01* this, PlayState* play) { if (gSaveContext.rupeeAccumulator == 0) { SET_WEEKEVENTREG(WEEKEVENTREG_KICKOUT_WAIT); CLEAR_WEEKEVENTREG(WEEKEVENTREG_KICKOUT_TIME_PASSED); - this->unk_2D2 |= 0x20; - func_800FD750(0x40); + this->stateFlags |= ENAOB01_FLAG_STARTED_RACE; + func_800FD750(NA_BGM_HORSE); play->nextEntrance = ENTRANCE(DOGGY_RACETRACK, 1); play->transitionType = TRANS_TYPE_64; gSaveContext.nextTransitionType = TRANS_TYPE_64; - gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & (u8)~7) | 2; - gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & 7) | (this->unk_432 * 8); + SET_EVENTINF_DOG_RACE_STATE(EVENTINF_DOG_RACE_STATE_STARTED); + SET_EVENTINF_DOG_RACE_SELECTED_DOG_INDEX(this->selectedDogIndex); play->transitionTrigger = TRANS_TRIGGER_START; } } -void func_809C1D64(EnAob01* this, PlayState* play) { +/** + * Handles the player's response to the question of whether or not they want to play again. + * Once the textbox closes, the racetrack owner will go back to being idle. + */ +void EnAob01_BeforeRace_RespondToPlayAgainQuestion(EnAob01* this, PlayState* play) { u8 talkState = Message_GetState(&play->msgCtx); if (talkState == TEXT_STATE_CHOICE) { @@ -436,34 +497,38 @@ void func_809C1D64(EnAob01* this, PlayState* play) { case 0: if (gSaveContext.save.saveInfo.playerData.rupees < 10) { play_sound(NA_SE_SY_ERROR); - this->unk_210 = 0x3524; - Message_StartTextbox(play, this->unk_210, &this->actor); + this->textId = 0x3524; // You can't play if you can't pay! + Message_StartTextbox(play, this->textId, &this->actor); } else { func_8019F208(); - this->unk_2D2 |= 4; - this->unk_2D2 |= 0x10; - this->unk_210 = 0x3522; - Message_StartTextbox(play, this->unk_210, &this->actor); - this->actionFunc = func_809C21E0; + this->stateFlags |= ENAOB01_FLAG_PLAYER_TOLD_TO_PICK_A_DOG; + this->stateFlags |= ENAOB01_FLAG_CONVERSATION_OVER; + this->textId = 0x3522; // Bring me the fastest dog! + Message_StartTextbox(play, this->textId, &this->actor); + this->actionFunc = EnAob01_BeforeRace_Talk; } break; case 1: func_8019F230(); - this->unk_210 = 0x3535; - Message_StartTextbox(play, this->unk_210, &this->actor); + this->textId = 0x3535; // Really? + Message_StartTextbox(play, this->textId, &this->actor); break; } } } else if ((talkState == TEXT_STATE_5) && Message_ShouldAdvance(play)) { play->msgCtx.msgMode = 0x43; play->msgCtx.stateTimer = 4; - this->unk_210 = 0; - this->actionFunc = func_809C2060; + this->textId = 0; + this->actionFunc = EnAob01_BeforeRace_Idle; } } -void func_809C1EC8(EnAob01* this, PlayState* play) { +/** + * Handles various things that are common to all action functions, like tracking the + * player, blinking, handling collision, etc. + */ +void EnAob01_UpdateCommon(EnAob01* this, PlayState* play) { static TrackOptionsSet sTrackOptions = { { 0xFA0, 4, 1, 3 }, { 0x1770, 4, 1, 6 }, @@ -474,6 +539,7 @@ void func_809C1EC8(EnAob01* this, PlayState* play) { Vec3f point; SkelAnime_Update(&this->skelAnime); + if (SubS_AngleDiffLessEqual(this->actor.shape.rot.y, 0x36B0, this->actor.yawTowardsPlayer)) { point.x = player->actor.world.pos.x; point.y = player->bodyPartsPos[PLAYER_BODYPART_HEAD].y + 3.0f; @@ -488,124 +554,152 @@ void func_809C1EC8(EnAob01* this, PlayState* play) { Math_SmoothStepToS(&this->torsoRot.x, 0, 4, 0x3E8, 1); Math_SmoothStepToS(&this->torsoRot.y, 0, 4, 0x3E8, 1); } - func_809C10B0(this, 3); - SubS_FillLimbRotTables(play, this->unk_2F8, this->unk_318, ARRAY_COUNT(this->unk_2F8)); - func_809C165C(this, play); + + EnAob01_Blink(this, EN_AOB01_EYE_MAX); + SubS_FillLimbRotTables(play, this->limbRotTableY, this->limbRotTableZ, ARRAY_COUNT(this->limbRotTableY)); + EnAob01_UpdateCollision(this, play); + + // This specific code ensures that in-game time passes during the race. if (player->stateFlags1 & PLAYER_STATE1_20) { - func_809C1124(); + EnAob01_AdvanceTime(); } } -void func_809C2060(EnAob01* this, PlayState* play) { - if (func_809C15BC(this)) { - if (func_809C2EC4(this, play) && !(this->unk_2D2 & 0x100)) { +/** + * Stand around and wait until either the player talks to the racetrack owner or until + * the player bumps into them while holding a dog. In either case, the racetrack owner + * will then start talking with the player. + */ +void EnAob01_BeforeRace_Idle(EnAob01* this, PlayState* play) { + if (EnAob01_ProcessIdleAnim(this)) { + if (EnAob01_PlayerIsHoldingDog(this, play) && !(this->stateFlags & ENAOB01_FLAG_PLAYER_CAN_TALK)) { if (this->collider.base.ocFlags2 & OC2_HIT_PLAYER) { this->actor.flags |= ACTOR_FLAG_10000; func_800B8614(&this->actor, play, 100.0f); - this->unk_2D2 |= 8; - this->actionFunc = func_809C21E0; + this->stateFlags |= ENAOB01_FLAG_TALKING_TO_PLAYER_HOLDING_DOG; + this->actionFunc = EnAob01_BeforeRace_Talk; } - } else if (Actor_ProcessTalkRequest(&this->actor, &play->state) && (this->unk_2D2 & 0x100)) { - this->unk_2D2 &= ~0x100; - this->unk_2E6 = this->trackTarget; - this->unk_2EC = this->headRot; - this->unk_2F2 = this->torsoRot; - func_809C16DC(this, play); - this->actionFunc = func_809C21E0; + } else if (Actor_ProcessTalkRequest(&this->actor, &play->state) && + (this->stateFlags & ENAOB01_FLAG_PLAYER_CAN_TALK)) { + this->stateFlags &= ~ENAOB01_FLAG_PLAYER_CAN_TALK; + this->prevTrackTarget = this->trackTarget; + this->prevHeadRot = this->headRot; + this->prevTorsoRot = this->torsoRot; + EnAob01_BeforeRace_HandleConversation(this, play); + this->actionFunc = EnAob01_BeforeRace_Talk; } else { - this->unk_2D2 &= ~0x100; + this->stateFlags &= ~ENAOB01_FLAG_PLAYER_CAN_TALK; if ((this->actor.xzDistToPlayer < 100.0f) && !(this->collider.base.ocFlags2 & OC2_HIT_PLAYER)) { - this->unk_2D2 |= 0x100; + this->stateFlags |= ENAOB01_FLAG_PLAYER_CAN_TALK; func_800B8614(&this->actor, play, 100.0f); } } } } -void func_809C21E0(EnAob01* this, PlayState* play) { +/** + * Handles the actual action of talking with the player before the race begins. + */ +void EnAob01_BeforeRace_Talk(EnAob01* this, PlayState* play) { u8 talkState = Message_GetState(&play->msgCtx); Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 4, 4000, 1); - if ((this->unk_2D2 & 8) && !func_809C2EC4(this, play)) { - if ((this->unk_210 != 0) && (this->unk_210 != 0x3535) && (this->unk_210 != 0x3524) && - (this->unk_210 != 0x3548) && (this->unk_210 != 0x3549) && (this->unk_210 != 0x354A)) { - this->unk_210 = 0x3523; + //! @bug: This block of code acts as a failsafe for when the player triggered this conversation by + //! bumping into the racetrack owner while holding the dog and, at the same time, threw or dropped + //! the dog frame-perfectly by pressing A. In this case, the code successfully returns the racetrack + //! owner to her idle state. Unfortunately, the player can also drop the dog by shielding. If this + //! shield drop is done frame-perfectly, then the below code will not function properly and will + //! instead softlock the game. + if ((this->stateFlags & ENAOB01_FLAG_TALKING_TO_PLAYER_HOLDING_DOG) && !EnAob01_PlayerIsHoldingDog(this, play)) { + if ((this->textId != 0) && (this->textId != 0x3535) && (this->textId != 0x3524) && (this->textId != 0x3548) && + (this->textId != 0x3549) && (this->textId != 0x354A)) { + this->textId = 0x3523; // Hurry up and bring me a dog! } + this->actor.textId = 0; - this->unk_2D2 &= ~8; + this->stateFlags &= ~ENAOB01_FLAG_TALKING_TO_PLAYER_HOLDING_DOG; this->actor.flags &= ~ACTOR_FLAG_10000; - this->actionFunc = func_809C2060; + this->actionFunc = EnAob01_BeforeRace_Idle; return; } - if (this->unk_2D2 & 0x40) { - if (!func_809C1424(this)) { + if (this->stateFlags & ENAOB01_FLAG_LAUGH) { + if (!EnAob01_ProcessLaughAnim(this)) { return; } - } else if (!func_809C15BC(this)) { + } else if (!EnAob01_ProcessIdleAnim(this)) { return; } - if (this->unk_2D2 & 8) { + if (this->stateFlags & ENAOB01_FLAG_TALKING_TO_PLAYER_HOLDING_DOG) { if (Actor_ProcessTalkRequest(&this->actor, &play->state)) { this->actor.flags &= ~ACTOR_FLAG_10000; func_80123E90(play, &this->actor); - if (this->unk_2D2 & 4) { - func_809C16DC(this, play); - this->unk_2D2 &= ~4; + if (this->stateFlags & ENAOB01_FLAG_PLAYER_TOLD_TO_PICK_A_DOG) { + EnAob01_BeforeRace_HandleConversation(this, play); + this->stateFlags &= ~ENAOB01_FLAG_PLAYER_TOLD_TO_PICK_A_DOG; } else { - this->unk_2D2 |= 0x10; - this->unk_2D2 |= 0x40; - this->unk_43C = 1; - Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, 1); + this->stateFlags |= ENAOB01_FLAG_CONVERSATION_OVER; + this->stateFlags |= ENAOB01_FLAG_LAUGH; + this->animIndex = EN_AOB01_ANIM_LAUGH_START; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, EN_AOB01_ANIM_LAUGH_START); + // Put my dog down! Message_StartTextbox(play, 0x354B, &this->actor); } - this->unk_2D2 &= ~8; + + this->stateFlags &= ~ENAOB01_FLAG_TALKING_TO_PLAYER_HOLDING_DOG; } } else if (talkState == TEXT_STATE_CHOICE) { if (Message_ShouldAdvance(play)) { - this->unk_2D2 &= ~0x40; + this->stateFlags &= ~ENAOB01_FLAG_LAUGH; switch (play->msgCtx.choiceIndex) { case 0: func_8019F208(); - this->unk_2D2 |= 2; - func_809C16DC(this, play); + this->stateFlags |= ENAOB01_FLAG_PLAYER_CONFIRMED_CHOICE; + EnAob01_BeforeRace_HandleConversation(this, play); break; case 1: func_8019F230(); - func_809C16DC(this, play); + EnAob01_BeforeRace_HandleConversation(this, play); break; } } } else if (talkState == TEXT_STATE_5) { if (Message_ShouldAdvance(play)) { - this->unk_2D2 &= ~0x40; - if (this->unk_2D2 & 0x10) { - this->unk_2D2 &= ~0x10; + this->stateFlags &= ~ENAOB01_FLAG_LAUGH; + if (this->stateFlags & ENAOB01_FLAG_CONVERSATION_OVER) { + this->stateFlags &= ~ENAOB01_FLAG_CONVERSATION_OVER; play->msgCtx.msgMode = 0x43; play->msgCtx.stateTimer = 4; - this->actionFunc = func_809C2060; + this->actionFunc = EnAob01_BeforeRace_Idle; } else { - func_809C16DC(this, play); + EnAob01_BeforeRace_HandleConversation(this, play); } } } else if ((talkState == TEXT_STATE_14) && Message_ShouldAdvance(play)) { - this->unk_2D2 &= ~0x40; - this->unk_434 = play->msgCtx.bankRupeesSelected; - func_809C16DC(this, play); + this->stateFlags &= ~ENAOB01_FLAG_LAUGH; + this->rupeesBet = play->msgCtx.bankRupeesSelected; + EnAob01_BeforeRace_HandleConversation(this, play); } } -s32 func_809C2504(EnAob01* this, PlayState* play) { +/** + * Checks all dog instances to see if any of them have reached a certain point along the racetrack, + * as specified by the cutscene's custom value. Once one of them has reached that point, this function + * will switch to following that dog and set the csId to correspond to the next cutscene in the race + * sequence; this usually appears to the user as a cut to a different camera angle. Returns true if any + * dog has reached the specified point, false otherwise. + */ +s32 EnAob01_Race_DogHasReachedNextCutsceneTrigger(EnAob01* this, PlayState* play) { Actor* npc = play->actorCtx.actorLists[ACTORCAT_NPC].first; while (npc != NULL) { if ((npc->id == ACTOR_EN_RACEDOG) && (CutsceneManager_GetCutsceneCustomValue(this->csId) == ((EnRacedog*)npc)->currentPoint)) { CutsceneManager_Stop(this->csId); - this->unk_3F4 = npc; + this->dogToFollow = npc; this->csId = CutsceneManager_GetAdditionalCsId(this->csId); return true; } @@ -615,12 +709,17 @@ s32 func_809C2504(EnAob01* this, PlayState* play) { return false; } -s32 func_809C2594(EnAob01* this, PlayState* play) { +/** + * Finds the dog that the player selected and starts following it. Returns true if it finds the player's + * selected dog and false otherwise, though nothing actually cares about this return value, and it should + * always be true in normal function (it is impossible to start a race without selecting a dog). + */ +s32 EnAob01_Race_FollowSelectedDog(EnAob01* this, PlayState* play) { Actor* npc = play->actorCtx.actorLists[ACTORCAT_NPC].first; while (npc != NULL) { if ((npc->id == ACTOR_EN_RACEDOG) && (((EnRacedog*)npc)->index == ((EnRacedog*)npc)->selectedDogIndex)) { - this->unk_3F4 = npc; + this->dogToFollow = npc; return true; } npc = npc->next; @@ -629,28 +728,41 @@ s32 func_809C2594(EnAob01* this, PlayState* play) { return false; } -s32 func_809C25E4(EnAob01* this, PlayState* play) { +/** + * Returns true if the race should be ended, which can happen in either of the following circumstances: + * - All `RACEDOG_COUNT` dogs have finished the race. + * - At least 10 dogs have finished the race, and at least 500 frames have passed since the 10th place + * dog finished. This is controlled by the forceRaceEndTimer, which is set in EnAob01_Init. + */ +s32 EnAob01_Race_IsRaceOver(EnAob01* this, PlayState* play) { Actor* npc = play->actorCtx.actorLists[ACTORCAT_NPC].first; - s16 count = 0; + s16 finishedCount = 0; while (npc != NULL) { if ((npc->id == ACTOR_EN_RACEDOG) && (((EnRacedog*)npc)->raceStatus == RACEDOG_RACE_STATUS_FINISHED)) { - count++; + finishedCount++; } npc = npc->next; } - if (count >= 14) { + if (finishedCount >= RACEDOG_COUNT) { return true; } - if ((count >= 10) && (DECR(this->unk_440) == 0)) { + if ((finishedCount >= 10) && (DECR(this->forceRaceEndTimer) == 0)) { return true; } + return false; } -s32 func_809C2680(EnAob01* this) { +/** + * If the current cutscene has a positive length, and if the current cutscene is over (in other words, + * if the length has elapsed), this function will set the csId to the next cutscene in the race sequence + * and return true. In all other cases, it will return false. Note that *all* of the race cutscenes have + * a length of -1, so in practice, this function never does anything and always returns false. + */ +s32 EnAob01_Race_CurrentCutsceneHasEnded(EnAob01* this) { if ((CutsceneManager_GetLength(this->csId) > 0) && (CutsceneManager_GetCurrentCsId() != this->csId)) { this->csId = CutsceneManager_GetAdditionalCsId(this->csId); return true; @@ -658,25 +770,40 @@ s32 func_809C2680(EnAob01* this) { return false; } -void func_809C26E4(EnAob01* this, PlayState* play) { +/** + * The only way we end up inside this function is if we tried to start a cutscene with a custom + * value of 255. This does not correspond to a point on the racetrack, nor is it the special value + * of 99, which is used to signal the race ending cutscene. Thus, whatever cutscene we're trying + * to play here is almost certainly not a race cutscene, so this function just skips it and tries + * to play the next cutscene. + */ +void EnAob01_Race_SkipNonRaceCutscene(EnAob01* this, PlayState* play) { CutsceneManager_Stop(this->csId); this->csId = CutsceneManager_GetAdditionalCsId(this->csId); - this->actionFunc = func_809C2824; + this->actionFunc = EnAob01_Race_StartCutscene; } -void func_809C2730(EnAob01* this, PlayState* play) { - if (func_809C2504(this, play) || func_809C2680(this)) { +/** + * Wait around doing nothing until the next cutscene is triggered (in practice, this only happens + * when a dog reaches the next cutscene trigger), at which point we queue up the next cutscene. + */ +void EnAob01_Race_HandleRaceCutscene(EnAob01* this, PlayState* play) { + if (EnAob01_Race_DogHasReachedNextCutsceneTrigger(this, play) || EnAob01_Race_CurrentCutsceneHasEnded(this)) { CutsceneManager_Queue(this->csId); - this->actionFunc = func_809C2824; + this->actionFunc = EnAob01_Race_StartCutscene; } } -void func_809C2788(EnAob01* this, PlayState* play) { - this->unk_2D2 |= 0x20; - if (func_809C25E4(this, play)) { +/** + * Waits until the race is over, then reloads the racetrack to return it + * to its regular playable state. + */ +void EnAob01_Race_HandleRaceEndCutscene(EnAob01* this, PlayState* play) { + this->stateFlags |= ENAOB01_FLAG_STARTED_RACE; + if (EnAob01_Race_IsRaceOver(this, play)) { if (AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) != NA_BGM_HORSE_GOAL) { play->nextEntrance = ENTRANCE(DOGGY_RACETRACK, 1); - gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & (u8)~7) | 3; + SET_EVENTINF_DOG_RACE_STATE(EVENTINF_DOG_RACE_STATE_ENDED); play->transitionType = TRANS_TYPE_64; gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE; play->transitionTrigger = TRANS_TRIGGER_START; @@ -684,93 +811,109 @@ void func_809C2788(EnAob01* this, PlayState* play) { } } -void func_809C2824(EnAob01* this, PlayState* play) { +/** + * Starts the cutscene specified by the csId and switches to an appropriate + * action function based on the cutscene's custom value. + */ +void EnAob01_Race_StartCutscene(EnAob01* this, PlayState* play) { if (CutsceneManager_IsNext(this->csId)) { - CutsceneManager_Start(this->csId, this->unk_3F4); + CutsceneManager_Start(this->csId, this->dogToFollow); switch (CutsceneManager_GetCutsceneCustomValue(this->csId)) { case 255: - this->actionFunc = func_809C26E4; + this->actionFunc = EnAob01_Race_SkipNonRaceCutscene; break; case 99: - this->actionFunc = func_809C2788; + this->actionFunc = EnAob01_Race_HandleRaceEndCutscene; break; default: - this->actionFunc = func_809C2730; + this->actionFunc = EnAob01_Race_HandleRaceCutscene; } } else { CutsceneManager_Queue(this->csId); } } -void func_809C28B8(EnAob01* this, PlayState* play) { +/** + * Tells the player how their selected dog did in the race and gives the player + * rupees depending on their performance. If their dog placed 1st, they will + * receive triple the rupees they bet. If their dog places 2nd, they will receive + * double the rupees they bet. If their dog places 3rd through 5th, they will + * receive the same number of rupees they bet. + */ +void EnAob01_AfterRace_GiveRaceResult(EnAob01* this, PlayState* play) { if (Actor_ProcessTalkRequest(&this->actor, &play->state)) { this->actor.flags &= ~ACTOR_FLAG_10000; func_80123E90(play, &this->actor); - this->unk_434 = gSaveContext.unk_3F5C; - switch ((gSaveContext.eventInf[0] & 0xF8) >> 3) { + this->rupeesBet = gSaveContext.unk_3F5C; + switch (GET_EVENTINF_DOG_RACE_RACE_STANDING) { case 1: - this->unk_210 = 0x352A; - this->unk_2D2 |= 0x80; - this->unk_434 *= 3; - Rupees_ChangeBy(this->unk_434); - play->msgCtx.bankRupees = this->unk_434; + this->textId = 0x352A; // You took 1st place! + this->stateFlags |= ENAOB01_FLAG_SURPRISE; + this->rupeesBet *= 3; + Rupees_ChangeBy(this->rupeesBet); + play->msgCtx.bankRupees = this->rupeesBet; break; case 2: - this->unk_210 = 0x352B; - this->unk_2D2 |= 0x80; - this->unk_434 *= 2; - Rupees_ChangeBy(this->unk_434); - play->msgCtx.bankRupees = this->unk_434; + this->textId = 0x352B; // You took 2nd place! + this->stateFlags |= ENAOB01_FLAG_SURPRISE; + this->rupeesBet *= 2; + Rupees_ChangeBy(this->rupeesBet); + play->msgCtx.bankRupees = this->rupeesBet; break; case 3: case 4: case 5: - this->unk_210 = 0x352C; - Rupees_ChangeBy(this->unk_434); + this->textId = 0x352C; // I'll give you back what you bet. + Rupees_ChangeBy(this->rupeesBet); break; default: - this->unk_210 = 0x352D; - this->unk_2D2 |= 0x40; - this->unk_43C = 1; - Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, 1); + this->textId = 0x352D; // Bad choice! + this->stateFlags |= ENAOB01_FLAG_LAUGH; + this->animIndex = EN_AOB01_ANIM_LAUGH_START; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, EN_AOB01_ANIM_LAUGH_START); break; } - Message_StartTextbox(play, this->unk_210, &this->actor); - this->actionFunc = func_809C2D0C; + Message_StartTextbox(play, this->textId, &this->actor); + this->actionFunc = EnAob01_AfterRace_Talk; } else if (this->actor.xzDistToPlayer < 100.0f) { func_800B8614(&this->actor, play, 100.0f); } } -void func_809C2A64(EnAob01* this, PlayState* play) { +/** + * Gives the player the reward for winning 150 or more rupees from the dog race. The first + * time this happens, the player will receive a Heart Piece; any other time, they will + * instead receive a Red Rupee. + */ +void EnAob01_AfterRace_GiveReward(EnAob01* this, PlayState* play) { u8 talkState = Message_GetState(&play->msgCtx); - if (func_809C15BC(this)) { + if (EnAob01_ProcessIdleAnim(this)) { if ((talkState == TEXT_STATE_5) && Message_ShouldAdvance(play)) { - this->unk_434 = 0; + this->rupeesBet = 0; play->msgCtx.msgMode = 0x43; play->msgCtx.stateTimer = 4; } if (Actor_HasParent(&this->actor, play)) { - this->trackTarget = this->unk_2E6; - this->headRot = this->unk_2EC; - this->torsoRot = this->unk_2F2; + this->trackTarget = this->prevTrackTarget; + this->headRot = this->prevHeadRot; + this->torsoRot = this->prevTorsoRot; this->actor.parent = NULL; this->actor.shape.rot.y = this->actor.world.rot.y; - if (CHECK_WEEKEVENTREG(WEEKEVENTREG_08_20)) { - this->actionFunc = func_809C2BE4; + if (CHECK_WEEKEVENTREG(WEEKEVENTREG_RECEIVED_DOGGY_RACETRACK_HEART_PIECE)) { + this->actionFunc = EnAob01_AfterRace_AfterGivingReward; } else { - SET_WEEKEVENTREG(WEEKEVENTREG_08_20); - this->actionFunc = func_809C2BE4; + SET_WEEKEVENTREG(WEEKEVENTREG_RECEIVED_DOGGY_RACETRACK_HEART_PIECE); + this->actionFunc = EnAob01_AfterRace_AfterGivingReward; } - } else if (CHECK_WEEKEVENTREG(WEEKEVENTREG_08_20)) { + } else if (CHECK_WEEKEVENTREG(WEEKEVENTREG_RECEIVED_DOGGY_RACETRACK_HEART_PIECE)) { Actor_OfferGetItem(&this->actor, play, GI_RUPEE_RED, 300.0f, 300.0f); } else { Actor_OfferGetItem(&this->actor, play, GI_HEART_PIECE, 300.0f, 300.0f); @@ -778,7 +921,12 @@ void func_809C2A64(EnAob01* this, PlayState* play) { } } -void func_809C2BE4(EnAob01* this, PlayState* play) { +/** + * If the current time is after the racetrack closes, kick the player out. + * Otherwise, ask the player if they want to play again. This function is + * only used when the player has won the 150 rupee reward. + */ +void EnAob01_AfterRace_AfterGivingReward(EnAob01* this, PlayState* play) { u8 talkState = Message_GetState(&play->msgCtx); if (((talkState == TEXT_STATE_5) || (talkState == TEXT_STATE_DONE)) && Message_ShouldAdvance(play)) { @@ -790,51 +938,63 @@ void func_809C2BE4(EnAob01* this, PlayState* play) { CLEAR_WEEKEVENTREG(WEEKEVENTREG_KICKOUT_WAIT); } - this->unk_210 = 0; + this->textId = 0; func_800B85E0(&this->actor, play, 400.0f, PLAYER_IA_MINUS1); - gSaveContext.eventInf[0] &= (u8)~7; - this->actionFunc = func_809C2C9C; + SET_EVENTINF_DOG_RACE_STATE(EVENTINF_DOG_RACE_STATE_NOT_STARTED); + this->actionFunc = EnAob01_AfterRace_AskToPlayAgain; } } -void func_809C2C9C(EnAob01* this, PlayState* play) { +/** + * Ask if the player wants to play again. This function is only used when + * the player has won the 150 rupee reward. + */ +void EnAob01_AfterRace_AskToPlayAgain(EnAob01* this, PlayState* play) { if (Actor_ProcessTalkRequest(&this->actor, &play->state)) { - this->unk_210 = 0x354C; - Message_ContinueTextbox(play, this->unk_210); - this->actionFunc = func_809C1D64; + this->textId = 0x354C; // Want to play again? + Message_ContinueTextbox(play, this->textId); + this->actionFunc = EnAob01_BeforeRace_RespondToPlayAgainQuestion; } else { func_800B85E0(&this->actor, play, 400.0f, PLAYER_IA_MINUS1); } } -void func_809C2D0C(EnAob01* this, PlayState* play) { +/** + * Handles the conversation the racetrack owner has with the player after the race + * is over. If the player won 150 or more rupees, this function will transition to + * the action function that gives them the reward. If the player did *not* win 150 + * or more rupees, then if the current time is after the racetrack closes, this + * kicks the player out. Otherwise, this asks the player if they want to play again. + * Much of the logic here is duplicated in the above two functions. + */ +void EnAob01_AfterRace_Talk(EnAob01* this, PlayState* play) { u8 talkState = Message_GetState(&play->msgCtx); Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 4, 4000, 1); - if (this->unk_2D2 & 0x40) { - if (!func_809C1424(this)) { + if (this->stateFlags & ENAOB01_FLAG_LAUGH) { + if (!EnAob01_ProcessLaughAnim(this)) { return; } - } else if (this->unk_2D2 & 0x80) { - if (!func_809C14D0(this)) { + } else if (this->stateFlags & ENAOB01_FLAG_SURPRISE) { + if (!EnAob01_ProcessSurpriseAnim(this)) { return; } } if ((talkState == TEXT_STATE_5) && Message_ShouldAdvance(play)) { - this->unk_2D2 &= ~0x40; - this->unk_2D2 &= ~0x80; - if (this->unk_434 >= 150) { - this->unk_210 = 0x352E; - Message_StartTextbox(play, this->unk_210, &this->actor); - this->actionFunc = func_809C2A64; + this->stateFlags &= ~ENAOB01_FLAG_LAUGH; + this->stateFlags &= ~ENAOB01_FLAG_SURPRISE; + if (this->rupeesBet >= 150) { + this->textId = 0x352E; // You won over 150 rupees! + Message_StartTextbox(play, this->textId, &this->actor); + this->actionFunc = EnAob01_AfterRace_GiveReward; } else { - this->trackTarget = this->unk_2E6; - this->headRot = this->unk_2EC; - this->torsoRot = this->unk_2F2; + this->trackTarget = this->prevTrackTarget; + this->headRot = this->prevHeadRot; + this->torsoRot = this->prevTorsoRot; - this->unk_434 = 0; + this->rupeesBet = 0; this->actor.shape.rot.y = this->actor.world.rot.y; if (CHECK_WEEKEVENTREG(WEEKEVENTREG_KICKOUT_TIME_PASSED)) { CLEAR_WEEKEVENTREG(WEEKEVENTREG_KICKOUT_TIME_PASSED); @@ -844,35 +1004,40 @@ void func_809C2D0C(EnAob01* this, PlayState* play) { CLEAR_WEEKEVENTREG(WEEKEVENTREG_KICKOUT_WAIT); } - this->unk_210 = 0x354C; - Message_StartTextbox(play, this->unk_210, &this->actor); - this->actionFunc = func_809C1D64; - gSaveContext.eventInf[0] &= (u8)~7; + this->textId = 0x354C; // Want to play again? + Message_StartTextbox(play, this->textId, &this->actor); + this->actionFunc = EnAob01_BeforeRace_RespondToPlayAgainQuestion; + SET_EVENTINF_DOG_RACE_STATE(EVENTINF_DOG_RACE_STATE_NOT_STARTED); } } } -s32 func_809C2EC4(EnAob01* this, PlayState* play) { +s32 EnAob01_PlayerIsHoldingDog(EnAob01* this, PlayState* play) { Actor* dog = play->actorCtx.actorLists[ACTORCAT_ENEMY].first; while (dog != NULL) { if (dog->id == ACTOR_EN_DG) { - this->unk_432 = ((EnDg*)dog)->selectedDogIndex; - if (this->unk_432 == -1) { + this->selectedDogIndex = ((EnDg*)dog)->selectedDogIndex; + if (this->selectedDogIndex == -1) { return false; } - if (this->unk_432 == ENDG_GET_INDEX(dog)) { + if (this->selectedDogIndex == ENDG_GET_INDEX(dog)) { return true; } } + dog = dog->next; } return false; } -void func_809C2F34(EnAob01* this, PlayState* play) { +/** + * Moves the player and racetrack owner to the center of the racetrack + * (out of the way of the dogs) and stops drawing the player. + */ +void EnAob01_Race_HidePlayer(EnAob01* this, PlayState* play) { Player* player = GET_PLAYER(play); player->actor.world.pos.x = -4134.0f; @@ -885,40 +1050,48 @@ void func_809C2F34(EnAob01* this, PlayState* play) { this->actor.prevPos = this->actor.world.pos; } -void func_809C2FA0(void) { +/** + * Generates a randomized list of dog text offsets and stores them in weekEventRegs. + * EnDg uses these text offsets to determine what text to show when the player picks + * the dog up while equipped with the Mask of Truth, and EnRacedog uses them to + * determine what condition the dog is in. + */ +void EnAob01_InitializeDogTextOffsets(void) { u8 i; u8 rand; - u8 index; - u8 orig; - u8 orig2; - u8 sp44[7]; - u8 sp34[] = { + u8 dogTextOffsetsTemp; + u8 packedDogTextOffsets[(RACEDOG_COUNT + 1) / 2]; + u8 dogTextOffsets[RACEDOG_COUNT] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, }; - for (i = 0; i < ARRAY_COUNT(sp34); i++) { - rand = Rand_ZeroFloat(14.0f); - orig = sp34[i]; + // Swap around the dog text offsets randomly 14 times. + for (i = 0; i < RACEDOG_COUNT; i++) { + rand = Rand_ZeroFloat(RACEDOG_COUNT); - sp34[i] = sp34[rand]; - sp34[rand] = orig; + dogTextOffsetsTemp = dogTextOffsets[i]; + dogTextOffsets[i] = dogTextOffsets[rand]; + dogTextOffsets[rand] = dogTextOffsetsTemp; } - for (i = 0; i < ARRAY_COUNT(sp44); i++) { - gSaveContext.save.saveInfo.weekEventReg[42 + i] = 0; - sp44[i] = 0; + // Clear out all weekEventRegs related to the dog text offsets. + for (i = 0; i < ARRAY_COUNT(packedDogTextOffsets); i++) { + CLEAR_WEEKEVENTREG_DOG_RACE_TEXT_OFFSETS(i); + packedDogTextOffsets[i] = 0; } - for (i = 0; i < ARRAY_COUNT(sp34); i++) { - orig2 = sp34[i]; - index = i / 2; + // Go through all the dog text offsets and pack them into weekEventRegs. + for (i = 0; i < RACEDOG_COUNT; i++) { + u8 dogTextOffsetsTemp = dogTextOffsets[i]; + u8 j = i / 2; if (i % 2) { - sp44[index] |= orig2 << 0x4; - gSaveContext.save.saveInfo.weekEventReg[42 + index] = - ((void)0, gSaveContext.save.saveInfo.weekEventReg[42 + index]) | sp44[index]; + //! @note sets text offsets for both even and odd entry. + //! Requires `RACEDOG_COUNT` to be even to work properly. + packedDogTextOffsets[j] |= dogTextOffsetsTemp << 4; + SET_WEEKEVENTREG_DOG_RACE_TEXT_OFFSETS(j, packedDogTextOffsets[j]); } else { - sp44[index] |= orig2; + packedDogTextOffsets[j] |= dogTextOffsetsTemp; } } } @@ -932,36 +1105,36 @@ void EnAob01_Init(Actor* thisx, PlayState* play) { MAMAMU_YAN_LIMB_MAX); Collider_InitCylinder(play, &this->collider); Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit); - this->unk_43C = 0; - Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, 0); + this->animIndex = EN_AOB01_ANIM_IDLE_1; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, EN_AOB01_ANIM_IDLE_1); Actor_SetScale(&this->actor, 0.01f); - switch (gSaveContext.eventInf[0] & 7) { - case 0: - func_809C2FA0(); - func_809C11EC(this, play); + switch (GET_EVENTINF_DOG_RACE_STATE) { + case EVENTINF_DOG_RACE_STATE_NOT_STARTED: + EnAob01_InitializeDogTextOffsets(); + EnAob01_SpawnDogs(this, play); this->actor.flags |= ACTOR_FLAG_1; - this->actionFunc = func_809C2060; + this->actionFunc = EnAob01_BeforeRace_Idle; break; - case 2: - this->unk_440 = 500; - func_809C1304(this, play); + case EVENTINF_DOG_RACE_STATE_STARTED: + this->forceRaceEndTimer = 500; + EnAob01_SpawnRacedogs(this, play); this->actor.draw = NULL; this->csId = this->actor.csId; - func_809C2594(this, play); + EnAob01_Race_FollowSelectedDog(this, play); CutsceneManager_Queue(this->csId); this->actor.flags &= ~ACTOR_FLAG_1; - func_809C2F34(this, play); - this->actionFunc = func_809C2824; + EnAob01_Race_HidePlayer(this, play); + this->actionFunc = EnAob01_Race_StartCutscene; break; - case 3: - func_809C2FA0(); - func_809C11EC(this, play); + case EVENTINF_DOG_RACE_STATE_ENDED: + EnAob01_InitializeDogTextOffsets(); + EnAob01_SpawnDogs(this, play); this->actor.flags |= ACTOR_FLAG_1; this->actor.flags |= ACTOR_FLAG_10000; - this->actionFunc = func_809C28B8; + this->actionFunc = EnAob01_AfterRace_GiveRaceResult; break; } } @@ -969,9 +1142,10 @@ void EnAob01_Init(Actor* thisx, PlayState* play) { void EnAob01_Destroy(Actor* thisx, PlayState* play) { EnAob01* this = THIS; - if (!(this->unk_2D2 & 0x20)) { + if (!(this->stateFlags & ENAOB01_FLAG_STARTED_RACE)) { CLEAR_WEEKEVENTREG(WEEKEVENTREG_KICKOUT_WAIT); } + Collider_DestroyCylinder(play, &this->collider); } @@ -979,7 +1153,7 @@ void EnAob01_Update(Actor* thisx, PlayState* play) { EnAob01* this = THIS; this->actionFunc(this, play); - func_809C1EC8(this, play); + EnAob01_UpdateCommon(this, play); } s32 EnAob01_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { @@ -1014,18 +1188,19 @@ s32 EnAob01_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* if ((limbIndex == MAMAMU_YAN_LIMB_TORSO) || (limbIndex == MAMAMU_YAN_LIMB_LEFT_UPPER_ARM) || (limbIndex == MAMAMU_YAN_LIMB_RIGHT_UPPER_ARM)) { - rot->y += (s16)Math_SinS(this->unk_2F8[limbIndex]) * 200; - rot->z += (s16)Math_CosS(this->unk_318[limbIndex]) * 200; + rot->y += (s16)Math_SinS(this->limbRotTableY[limbIndex]) * 200; + rot->z += (s16)Math_CosS(this->limbRotTableZ[limbIndex]) * 200; } + return false; } void EnAob01_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { - static Vec3f D_809C3968 = { 0.0f, 0.0f, 0.0f }; + static Vec3f sFocusOffset = { 0.0f, 0.0f, 0.0f }; EnAob01* this = THIS; if (limbIndex == MAMAMU_YAN_LIMB_HEAD) { - Matrix_MultVec3f(&D_809C3968, &this->actor.focus.pos); + Matrix_MultVec3f(&sFocusOffset, &this->actor.focus.pos); } } diff --git a/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.h b/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.h index 5432f74ae4..a550fd0d35 100644 --- a/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.h +++ b/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.h @@ -8,38 +8,56 @@ struct EnAob01; typedef void (*EnAob01ActionFunc)(struct EnAob01*, PlayState*); -#define ENAOB01_GET_7E00_1(thisx) ((thisx)->params & 0x7E00) -#define ENAOB01_GET_7E00_2(thisx) (((thisx)->params & 0x7E00) >> 9) +// This needs to be kept in sync with the number of weekEventRegs used to store the text ID offsets for +// the race dogs. In particular, there needs to be one weekEventReg for every two dogs. This needs to be +// an even number to ensure that all text ID offsets are created (see EnAob01_InitializeDogTextOffsets). +#define RACEDOG_COUNT 14 + +#define ENAOB01_GET_STARTING_DOG_PATH_INDEX(thisx) (((thisx)->params & 0x7E00) >> 9) + +//! @bug This should be shifted up by 1 to match how EnRacedog expects the path index to be supplied. +//! It doesn't cause any problems in the final game because every time EnAob01 is spawned, all the +//! bits here are zero. +#define ENAOB01_GET_RACEDOG_PATH_INDEX(thisx) ((thisx)->params & 0x7E00) + +#define ENAOB01_FLAG_PLAYER_CONFIRMED_CHOICE (1 << 1) +#define ENAOB01_FLAG_PLAYER_TOLD_TO_PICK_A_DOG (1 << 2) +#define ENAOB01_FLAG_TALKING_TO_PLAYER_HOLDING_DOG (1 << 3) +#define ENAOB01_FLAG_CONVERSATION_OVER (1 << 4) +#define ENAOB01_FLAG_STARTED_RACE (1 << 5) +#define ENAOB01_FLAG_LAUGH (1 << 6) +#define ENAOB01_FLAG_SURPRISE (1 << 7) +#define ENAOB01_FLAG_PLAYER_CAN_TALK (1 << 8) typedef struct EnAob01 { /* 0x000 */ Actor actor; /* 0x144 */ EnAob01ActionFunc actionFunc; /* 0x148 */ SkelAnime skelAnime; /* 0x18C */ ColliderCylinder collider; - /* 0x1D8 */ Path* unk_1D8[14]; - /* 0x210 */ u16 unk_210; + /* 0x1D8 */ Path* dogPaths[RACEDOG_COUNT]; + /* 0x210 */ u16 textId; /* 0x212 */ Vec3s jointTable[MAMAMU_YAN_LIMB_MAX]; /* 0x272 */ Vec3s morphTable[MAMAMU_YAN_LIMB_MAX]; - /* 0x2D2 */ u16 unk_2D2; + /* 0x2D2 */ u16 stateFlags; /* 0x2D4 */ Vec3s trackTarget; /* 0x2DA */ Vec3s headRot; /* 0x2E0 */ Vec3s torsoRot; - /* 0x2E6 */ Vec3s unk_2E6; - /* 0x2EC */ Vec3s unk_2EC; - /* 0x2F2 */ Vec3s unk_2F2; - /* 0x2F8 */ s16 unk_2F8[MAMAMU_YAN_LIMB_MAX]; - /* 0x318 */ s16 unk_318[MAMAMU_YAN_LIMB_MAX]; + /* 0x2E6 */ Vec3s prevTrackTarget; + /* 0x2EC */ Vec3s prevHeadRot; + /* 0x2F2 */ Vec3s prevTorsoRot; + /* 0x2F8 */ s16 limbRotTableY[MAMAMU_YAN_LIMB_MAX]; + /* 0x318 */ s16 limbRotTableZ[MAMAMU_YAN_LIMB_MAX]; /* 0x338 */ UNK_TYPE1 unk338[0xB6]; /* 0x3EE */ s16 eyeIndex; /* 0x3F0 */ s16 blinkTimer; - /* 0x3F4 */ Actor* unk_3F4; - /* 0x3F8 */ Actor* unk_3F8[14]; + /* 0x3F4 */ Actor* dogToFollow; + /* 0x3F8 */ Actor* dogs[RACEDOG_COUNT]; /* 0x430 */ s16 csId; - /* 0x432 */ s16 unk_432; - /* 0x434 */ s32 unk_434; + /* 0x432 */ s16 selectedDogIndex; + /* 0x434 */ s32 rupeesBet; // Also used for determining how many rupees to give to the player if they place 1st-5th in the race. /* 0x438 */ UNK_TYPE1 unk438[4]; - /* 0x43C */ s32 unk_43C; - /* 0x440 */ s16 unk_440; + /* 0x43C */ s32 animIndex; + /* 0x440 */ s16 forceRaceEndTimer; } EnAob01; // size = 0x444 #endif // Z_EN_AOB_01_H diff --git a/src/overlays/actors/ovl_En_Bat/z_en_bat.c b/src/overlays/actors/ovl_En_Bat/z_en_bat.c index 963bc41046..702e07f32e 100644 --- a/src/overlays/actors/ovl_En_Bat/z_en_bat.c +++ b/src/overlays/actors/ovl_En_Bat/z_en_bat.c @@ -4,7 +4,6 @@ * Description: Bad Bat */ -#include "prevent_bss_reordering.h" #include "z_en_bat.h" #include "objects/object_bat/object_bat.h" diff --git a/src/overlays/actors/ovl_En_Dg/z_en_dg.c b/src/overlays/actors/ovl_En_Dg/z_en_dg.c index 360cf2c494..8a6ae63e8b 100644 --- a/src/overlays/actors/ovl_En_Dg/z_en_dg.c +++ b/src/overlays/actors/ovl_En_Dg/z_en_dg.c @@ -5,13 +5,12 @@ */ #include "z_en_dg.h" +#include "overlays/actors/ovl_En_Aob_01/z_en_aob_01.h" #define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_800000) #define THIS ((EnDg*)thisx) -//! TODO: this file require macros for its uses of weekEventReg - void EnDg_Init(Actor* thisx, PlayState* play); void EnDg_Destroy(Actor* thisx, PlayState* play); void EnDg_Update(Actor* thisx, PlayState* play); @@ -417,20 +416,13 @@ void EnDg_SetupIdleMove(EnDg* this, PlayState* play) { /** * Updates the text ID in sRacetrackDogInfo based on what was set in the weekEventRegs by - * En_Aob_01. This makes it sp the proper message can be displayed when the player picks up + * En_Aob_01. This makes it so the proper message can be displayed when the player picks up * the dog with the Mask of Truth equipped. */ void EnDg_UpdateTextId(EnDg* this) { - if (this->index < 14) { - // Assuming that the weekEventRegs haven't been tampered with, then this will produce a text ID in - // the range of 0x3538 to 0x3545. - if (this->index % 2) { - sRacetrackDogInfo[this->index].textId = - 0x3538 + ((gSaveContext.save.saveInfo.weekEventReg[42 + (this->index / 2)] & 0xF0) >> 4); - } else { - sRacetrackDogInfo[this->index].textId = - 0x3538 + (gSaveContext.save.saveInfo.weekEventReg[42 + (this->index / 2)] & 0x0F); - } + if (this->index < RACEDOG_COUNT) { + // This will produce a text ID in the range of 0x3538 to 0x3545. + sRacetrackDogInfo[this->index].textId = GET_WEEKEVENTREG_DOG_RACE_TEXT(this->index, 0x3538); } else { Actor_Kill(&this->actor); } diff --git a/src/overlays/actors/ovl_En_Horse/z_en_horse.c b/src/overlays/actors/ovl_En_Horse/z_en_horse.c index df4f17d4c3..f12599df72 100644 --- a/src/overlays/actors/ovl_En_Horse/z_en_horse.c +++ b/src/overlays/actors/ovl_En_Horse/z_en_horse.c @@ -792,7 +792,8 @@ void EnHorse_Init(Actor* thisx, PlayState* play2) { this->stateFlags = 0; } - if (((play->sceneId == SCENE_KOEPONARACE) && (GET_WEEKEVENTREG_RACE_FLAGS == WEEKEVENTREG_RACE_FLAG_START)) || + if (((play->sceneId == SCENE_KOEPONARACE) && + (GET_WEEKEVENTREG_HORSE_RACE_STATE == WEEKEVENTREG_HORSE_RACE_STATE_START)) || ((gSaveContext.save.entrance == ENTRANCE(ROMANI_RANCH, 0)) && (Cutscene_GetSceneLayer(play) != 0))) { this->stateFlags |= ENHORSE_FLAG_25; } @@ -2471,7 +2472,7 @@ void func_808819D8(EnHorse* this, PlayState* play) { func_8088168C(this); } - if (GET_WEEKEVENTREG_RACE_FLAGS == WEEKEVENTREG_RACE_FLAG_3) { + if (GET_WEEKEVENTREG_HORSE_RACE_STATE == WEEKEVENTREG_HORSE_RACE_STATE_3) { this->rider->unk488 = 7; } else { EnHorse_SetIngoAnimation(this->animIndex, this->skin.skelAnime.curFrame, this->unk_394 & 1, diff --git a/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c b/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c index 5e7619cd24..d37fb8f23e 100644 --- a/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c +++ b/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c @@ -59,7 +59,7 @@ s32 func_808F8AA0(EnHorseGameCheck* this, PlayState* play) { DynaPolyActor_Init(&this->dyna, 0); - if (GET_WEEKEVENTREG_RACE_FLAGS != WEEKEVENTREG_RACE_FLAG_START) { + if (GET_WEEKEVENTREG_HORSE_RACE_STATE != WEEKEVENTREG_HORSE_RACE_STATE_START) { Actor_Kill(&this->dyna.actor); return false; } @@ -116,7 +116,7 @@ s32 func_808F8CCC(EnHorseGameCheck* this, PlayState* play2) { this->unk_168 = 0; this->unk_174 = 0; - if (GET_WEEKEVENTREG_RACE_FLAGS != WEEKEVENTREG_RACE_FLAG_START) { + if (GET_WEEKEVENTREG_HORSE_RACE_STATE != WEEKEVENTREG_HORSE_RACE_STATE_START) { Actor_Kill(&this->dyna.actor); return false; } @@ -156,14 +156,14 @@ s32 func_808F8EB0(EnHorseGameCheck* this, PlayState* play) { return false; } - if (GET_WEEKEVENTREG_RACE_FLAGS == WEEKEVENTREG_RACE_FLAG_3) { + if (GET_WEEKEVENTREG_HORSE_RACE_STATE == WEEKEVENTREG_HORSE_RACE_STATE_3) { play->transitionType = TRANS_TYPE_64; gSaveContext.nextTransitionType = TRANS_TYPE_FADE_BLACK; - } else if (GET_WEEKEVENTREG_RACE_FLAGS == WEEKEVENTREG_RACE_FLAG_2) { + } else if (GET_WEEKEVENTREG_HORSE_RACE_STATE == WEEKEVENTREG_HORSE_RACE_STATE_2) { play->transitionType = TRANS_TYPE_80; gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE; - } else if (GET_WEEKEVENTREG_RACE_FLAGS == WEEKEVENTREG_RACE_FLAG_4) { - SET_WEEKEVENTREG_RACE_FLAGS(WEEKEVENTREG_RACE_FLAG_3); + } else if (GET_WEEKEVENTREG_HORSE_RACE_STATE == WEEKEVENTREG_HORSE_RACE_STATE_4) { + SET_WEEKEVENTREG_HORSE_RACE_STATE(WEEKEVENTREG_HORSE_RACE_STATE_3); play->transitionType = TRANS_TYPE_FADE_BLACK; gSaveContext.nextTransitionType = TRANS_TYPE_FADE_BLACK; } @@ -252,7 +252,7 @@ s32 func_808F8FAC(EnHorseGameCheck* this, PlayState* play) { play_sound(NA_SE_SY_START_SHOT); this->unk_164 |= 0x40000; gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_6; - SET_WEEKEVENTREG_RACE_FLAGS(WEEKEVENTREG_RACE_FLAG_4); + SET_WEEKEVENTREG_HORSE_RACE_STATE(WEEKEVENTREG_HORSE_RACE_STATE_4); this->unk_174 = 60; } @@ -285,7 +285,7 @@ s32 func_808F8FAC(EnHorseGameCheck* this, PlayState* play) { play_sound(NA_SE_SY_START_SHOT); this->unk_164 |= 0x40000; gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_6; - SET_WEEKEVENTREG_RACE_FLAGS(WEEKEVENTREG_RACE_FLAG_3); + SET_WEEKEVENTREG_HORSE_RACE_STATE(WEEKEVENTREG_HORSE_RACE_STATE_3); this->unk_174 = 60; } @@ -318,7 +318,7 @@ s32 func_808F8FAC(EnHorseGameCheck* this, PlayState* play) { play_sound(NA_SE_SY_START_SHOT); this->unk_164 |= 0x02000000; gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_6; - SET_WEEKEVENTREG_RACE_FLAGS(WEEKEVENTREG_RACE_FLAG_3); + SET_WEEKEVENTREG_HORSE_RACE_STATE(WEEKEVENTREG_HORSE_RACE_STATE_3); this->unk_174 = 60; } @@ -347,7 +347,7 @@ s32 func_808F8FAC(EnHorseGameCheck* this, PlayState* play) { play_sound(NA_SE_SY_START_SHOT); this->unk_164 |= 0x800; gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_6; - SET_WEEKEVENTREG_RACE_FLAGS(WEEKEVENTREG_RACE_FLAG_2); + SET_WEEKEVENTREG_HORSE_RACE_STATE(WEEKEVENTREG_HORSE_RACE_STATE_2); this->unk_174 = 60; } return true; diff --git a/src/overlays/actors/ovl_En_In/z_en_in.c b/src/overlays/actors/ovl_En_In/z_en_in.c index 8bedd48cfa..71c5124189 100644 --- a/src/overlays/actors/ovl_En_In/z_en_in.c +++ b/src/overlays/actors/ovl_En_In/z_en_in.c @@ -336,7 +336,7 @@ void func_808F38F8(EnIn* this, PlayState* play) { } void func_808F395C(EnIn* this, PlayState* play) { - if (this->unk4B0 == WEEKEVENTREG_RACE_FLAG_END) { + if (this->unk4B0 == WEEKEVENTREG_HORSE_RACE_STATE_END) { this->actionFunc = func_808F5A94; } if (Actor_ProcessTalkRequest(&this->actor, &play->state)) { @@ -352,30 +352,30 @@ void func_808F39DC(EnIn* this, PlayState* play) { u16 textId = 0; if (gSaveContext.save.day != 3) { - switch (GET_WEEKEVENTREG_RACE_FLAGS) { - case WEEKEVENTREG_RACE_FLAG_2: + switch (GET_WEEKEVENTREG_HORSE_RACE_STATE) { + case WEEKEVENTREG_HORSE_RACE_STATE_2: textId = 0x347A; break; - case WEEKEVENTREG_RACE_FLAG_3: + case WEEKEVENTREG_HORSE_RACE_STATE_3: textId = 0x3476; break; } - SET_WEEKEVENTREG_RACE_FLAGS(WEEKEVENTREG_RACE_FLAG_END); + SET_WEEKEVENTREG_HORSE_RACE_STATE(WEEKEVENTREG_HORSE_RACE_STATE_END); } else { - switch (GET_WEEKEVENTREG_RACE_FLAGS) { - case WEEKEVENTREG_RACE_FLAG_2: + switch (GET_WEEKEVENTREG_HORSE_RACE_STATE) { + case WEEKEVENTREG_HORSE_RACE_STATE_2: textId = 0x349D; break; - case WEEKEVENTREG_RACE_FLAG_3: + case WEEKEVENTREG_HORSE_RACE_STATE_3: textId = 0x3499; break; } - SET_WEEKEVENTREG_RACE_FLAGS(WEEKEVENTREG_RACE_FLAG_END); + SET_WEEKEVENTREG_HORSE_RACE_STATE(WEEKEVENTREG_HORSE_RACE_STATE_END); } this->actor.flags |= ACTOR_FLAG_10000; this->actor.textId = textId; this->actionFunc = func_808F395C; - if (this->unk4B0 == WEEKEVENTREG_RACE_FLAG_2) { + if (this->unk4B0 == WEEKEVENTREG_HORSE_RACE_STATE_2) { Actor_PlaySfx(&this->actor, NA_SE_VO_IN_LOST); } else { Actor_PlaySfx(&this->actor, NA_SE_VO_IN_JOY0); @@ -635,7 +635,7 @@ s32 func_808F4270(PlayState* play, EnIn* this, s32 arg2, MessageContext* msgCtx, s32 func_808F43E0(EnIn* this) { this->unk48C = 0; this->actor.textId = 0; - SET_WEEKEVENTREG_RACE_FLAGS(WEEKEVENTREG_RACE_FLAG_END); + SET_WEEKEVENTREG_HORSE_RACE_STATE(WEEKEVENTREG_HORSE_RACE_STATE_END); return 0; } @@ -817,7 +817,7 @@ s32 func_808F4414(PlayState* play, EnIn* this, s32 arg2) { func_80151BB4(play, 0x11); break; case 0x3475: - SET_WEEKEVENTREG_RACE_FLAGS(WEEKEVENTREG_RACE_FLAG_START); + SET_WEEKEVENTREG_HORSE_RACE_STATE(WEEKEVENTREG_HORSE_RACE_STATE_START); func_800FD750(NA_BGM_HORSE); play->nextEntrance = ENTRANCE(GORMAN_TRACK, 5); play->transitionType = TRANS_TYPE_FADE_WHITE_FAST; @@ -1064,7 +1064,7 @@ s32 func_808F4414(PlayState* play, EnIn* this, s32 arg2) { ret = false; break; case 0x3475: - SET_WEEKEVENTREG_RACE_FLAGS(WEEKEVENTREG_RACE_FLAG_START); + SET_WEEKEVENTREG_HORSE_RACE_STATE(WEEKEVENTREG_HORSE_RACE_STATE_START); func_800FD750(NA_BGM_HORSE); play->nextEntrance = ENTRANCE(GORMAN_TRACK, 5); play->transitionType = TRANS_TYPE_FADE_WHITE_FAST; @@ -1322,7 +1322,7 @@ void func_808F5B58(EnIn* this, PlayState* play) { } void func_808F5C98(EnIn* this, PlayState* play) { - if (this->unk4B0 == WEEKEVENTREG_RACE_FLAG_END) { + if (this->unk4B0 == WEEKEVENTREG_HORSE_RACE_STATE_END) { this->actionFunc = func_808F5B58; } if ((Player_GetMask(play) == PLAYER_MASK_CIRCUS_LEADER && CHECK_WEEKEVENTREG(WEEKEVENTREG_63_40)) || @@ -1334,7 +1334,7 @@ void func_808F5C98(EnIn* this, PlayState* play) { } } if (this->unk4A8 == 2) { - if (this->unk4B0 == WEEKEVENTREG_RACE_FLAG_2) { + if (this->unk4B0 == WEEKEVENTREG_HORSE_RACE_STATE_2) { Actor_PlaySfx(&this->actor, NA_SE_VO_IN_LOST); } else { Actor_PlaySfx(&this->actor, NA_SE_VO_IN_JOY0); @@ -1366,7 +1366,7 @@ void EnIn_Init(Actor* thisx, PlayState* play) { this->unk48C = 0; this->unk4AC = 0; type = ENIN_GET_TYPE(thisx); - this->unk4B0 = GET_WEEKEVENTREG_RACE_FLAGS; + this->unk4B0 = GET_WEEKEVENTREG_HORSE_RACE_STATE; if (type == ENIN_HORSE_RIDER_BLUE_SHIRT || type == ENIN_BLUE_SHIRT) { this->unk4AC |= 8; } @@ -1387,8 +1387,8 @@ void EnIn_Init(Actor* thisx, PlayState* play) { this->path = SubS_GetPathByIndex(play, ENIN_GET_PATH(&this->actor), 0x3F); this->unk23D = 0; if (type == ENIN_YELLOW_SHIRT || type == ENIN_BLUE_SHIRT) { - if ((GET_WEEKEVENTREG_RACE_FLAGS == WEEKEVENTREG_RACE_FLAG_2) || - (GET_WEEKEVENTREG_RACE_FLAGS == WEEKEVENTREG_RACE_FLAG_3)) { + if ((GET_WEEKEVENTREG_HORSE_RACE_STATE == WEEKEVENTREG_HORSE_RACE_STATE_2) || + (GET_WEEKEVENTREG_HORSE_RACE_STATE == WEEKEVENTREG_HORSE_RACE_STATE_3)) { CLEAR_WEEKEVENTREG(WEEKEVENTREG_56_08); this->unk4A8 = 0; this->unk4AC |= 2; @@ -1396,12 +1396,12 @@ void EnIn_Init(Actor* thisx, PlayState* play) { this->unk23C = 0; D_801BDAA0 = 0; - if (GET_WEEKEVENTREG_RACE_FLAGS == WEEKEVENTREG_RACE_FLAG_2) { + if (GET_WEEKEVENTREG_HORSE_RACE_STATE == WEEKEVENTREG_HORSE_RACE_STATE_2) { EnIn_ChangeAnim(&this->skelAnime, ENIN_ANIM_6); } else { EnIn_ChangeAnim(&this->skelAnime, ENIN_ANIM_4); } - if (GET_WEEKEVENTREG_RACE_FLAGS == WEEKEVENTREG_RACE_FLAG_2) { + if (GET_WEEKEVENTREG_HORSE_RACE_STATE == WEEKEVENTREG_HORSE_RACE_STATE_2) { this->skelAnime.curFrame = ((Rand_ZeroOne() * 0.6f) + 0.2f) * this->skelAnime.endFrame; } if (this->unk4AC & 8) { @@ -1410,7 +1410,7 @@ void EnIn_Init(Actor* thisx, PlayState* play) { this->actionFunc = func_808F5C98; } } else { - if (GET_WEEKEVENTREG_RACE_FLAGS != WEEKEVENTREG_RACE_FLAG_START) { + if (GET_WEEKEVENTREG_HORSE_RACE_STATE != WEEKEVENTREG_HORSE_RACE_STATE_START) { CLEAR_WEEKEVENTREG(WEEKEVENTREG_56_08); this->unk23C = 0; this->unk4AC |= 2; diff --git a/src/overlays/actors/ovl_En_Racedog/z_en_racedog.c b/src/overlays/actors/ovl_En_Racedog/z_en_racedog.c index 3ffde38cd7..a8e222bec3 100644 --- a/src/overlays/actors/ovl_En_Racedog/z_en_racedog.c +++ b/src/overlays/actors/ovl_En_Racedog/z_en_racedog.c @@ -9,14 +9,13 @@ */ #include "z_en_racedog.h" +#include "overlays/actors/ovl_En_Aob_01/z_en_aob_01.h" #include "overlays/actors/ovl_En_Dg/z_en_dg.h" #define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_80000000) #define THIS ((EnRacedog*)thisx) -//! TODO: this file require macros for its uses of weekEventReg - void EnRacedog_Init(Actor* thisx, PlayState* play); void EnRacedog_Destroy(Actor* thisx, PlayState* play); void EnRacedog_Update(Actor* thisx, PlayState* play); @@ -317,7 +316,7 @@ void EnRacedog_Init(Actor* thisx, PlayState* play) { this->path = SubS_GetPathByIndex(play, ENRACEDOG_GET_PATH(&this->actor), 0x3F); Actor_SetScale(&this->actor, 0.0075f); this->actor.gravity = -3.0f; - if (ENRACEDOG_GET_INDEX(&this->actor) < 14) { + if (ENRACEDOG_GET_INDEX(&this->actor) < RACEDOG_COUNT) { this->index = ENRACEDOG_GET_INDEX(&this->actor); } else { Actor_Kill(&this->actor); @@ -353,7 +352,7 @@ void EnRacedog_Init(Actor* thisx, PlayState* play) { this->actor.flags |= ACTOR_FLAG_10; this->actor.flags |= ACTOR_FLAG_20; - sSelectedDogInfo = sDogInfo[(s16)((gSaveContext.eventInf[0] & 0xF8) >> 3)]; + sSelectedDogInfo = sDogInfo[(s16)GET_EVENTINF_DOG_RACE_SELECTED_DOG_INDEX]; this->selectedDogIndex = sSelectedDogInfo.index; EnRacedog_ChangeAnim(&this->skelAnime, sAnimationInfo, RACEDOG_ANIM_IDLE); @@ -439,15 +438,8 @@ void EnRacedog_Race(EnRacedog* this, PlayState* play) { * or an intentional choice to introduce a bit of extra variance to the race. */ void EnRacedog_UpdateTextId(EnRacedog* this) { - // Assuming that the weekEventRegs haven't been tampered with, then this will produce a text ID in the - // range of 0x3539 to 0x3546. - if (this->index % 2) { - sDogInfo[this->index].textId = - (((gSaveContext.save.saveInfo.weekEventReg[42 + (this->index / 2)]) & 0xF0) >> 4) + 0x3539; - } else { - sDogInfo[this->index].textId = - ((gSaveContext.save.saveInfo.weekEventReg[42 + (this->index / 2)]) & 0x0F) + 0x3539; - } + // This will produce a text ID in the range of 0x3539 to 0x3546. + sDogInfo[this->index].textId = GET_WEEKEVENTREG_DOG_RACE_TEXT(this->index, 0x3539); // As a sanity check, this makes sure the text ID is something in the expected range of 0x3539 to 0x3546. if ((sDogInfo[this->index].textId > 0x3546) || (sDogInfo[this->index].textId < 0x3539)) { @@ -593,7 +585,7 @@ void EnRacedog_CheckForFinish(EnRacedog* this) { this->raceStatus = RACEDOG_RACE_STATUS_FINISHED; if (this->index == this->selectedDogIndex) { - gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & 7) | (sNumberOfDogsFinished * 8); + SET_EVENTINF_DOG_RACE_RACE_STANDING(sNumberOfDogsFinished); } } } diff --git a/src/overlays/actors/ovl_En_Racedog/z_en_racedog.h b/src/overlays/actors/ovl_En_Racedog/z_en_racedog.h index 9d49ea4c26..a8cf2a9f9a 100644 --- a/src/overlays/actors/ovl_En_Racedog/z_en_racedog.h +++ b/src/overlays/actors/ovl_En_Racedog/z_en_racedog.h @@ -6,6 +6,7 @@ #define ENRACEDOG_GET_INDEX(thisx) (((thisx)->params & 0x3E0) >> 5) #define ENRACEDOG_GET_PATH(thisx) (((thisx)->params & 0xFC00) >> 10) +#define ENRACEDOG_PARAMS(index, path) ((index << 5) | (path)) /** * The main point of this seems to be some very light anti-cheat detection. The dog diff --git a/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c b/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c index 71eade542f..60846fda88 100644 --- a/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c +++ b/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c @@ -708,11 +708,11 @@ void EnSsh_Talk(EnSsh* this, PlayState* play) { void func_809756D0(EnSsh* this, PlayState* play) { u16 nextTextId; - if (CHECK_WEEKEVENTREG(WEEKEVENTREG_SWAMP_SPIDER_HOUSE_TALKED)) { + if (CHECK_WEEKEVENTREG(WEEKEVENTREG_TALKED_SWAMP_SPIDER_HOUSE_MAN)) { nextTextId = 0x914; // In here, cursed spiders, defeat them to make me normal } else { nextTextId = 0x910; // Help me! I am not a monster, I was cursed this way - SET_WEEKEVENTREG(WEEKEVENTREG_SWAMP_SPIDER_HOUSE_TALKED); + SET_WEEKEVENTREG(WEEKEVENTREG_TALKED_SWAMP_SPIDER_HOUSE_MAN); } Message_StartTextbox(play, nextTextId, &this->actor); } diff --git a/src/overlays/actors/ovl_En_Sth/z_en_sth.c b/src/overlays/actors/ovl_En_Sth/z_en_sth.c index f10d387d19..215845341f 100644 --- a/src/overlays/actors/ovl_En_Sth/z_en_sth.c +++ b/src/overlays/actors/ovl_En_Sth/z_en_sth.c @@ -148,7 +148,7 @@ void EnSth_Init(Actor* thisx, PlayState* play) { } this->actor.textId = 0; if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_RECEIVED_MASK_OF_TRUTH) || - !CHECK_WEEKEVENTREG(WEEKEVENTREG_SWAMP_SPIDER_HOUSE_TALKED)) { + !CHECK_WEEKEVENTREG(WEEKEVENTREG_TALKED_SWAMP_SPIDER_HOUSE_MAN)) { this->sthFlags |= STH_FLAG_DRAW_MASK_OF_TRUTH; } break; @@ -479,7 +479,7 @@ void EnSth_GetInitialSwampSpiderHouseText(EnSth* this, PlayState* play) { nextTextId = 0x90F; // (does not exist) EnSth_ChangeAnim(this, STH_ANIM_TALK); } else if (CHECK_WEEKEVENTREG(WEEKEVENTREG_RECEIVED_MASK_OF_TRUTH)) { - if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_SWAMP_SPIDER_HOUSE_TALKED)) { + if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_TALKED_SWAMP_SPIDER_HOUSE_MAN)) { nextTextId = 0x91B; // As soon as I calm down, getting rid of it } else { nextTextId = 0x918; // I've had enough of this, going home @@ -525,7 +525,7 @@ void EnSth_SwampSpiderHouseGiveMask(EnSth* this, PlayState* play) { } else { this->sthFlags &= ~STH_FLAG_DRAW_MASK_OF_TRUTH; // This flag is used to keep track if the player has already spoken to the actor, triggering secondary dialogue. - SET_WEEKEVENTREG(WEEKEVENTREG_SWAMP_SPIDER_HOUSE_TALKED); + SET_WEEKEVENTREG(WEEKEVENTREG_TALKED_SWAMP_SPIDER_HOUSE_MAN); Actor_OfferGetItem(&this->actor, play, GI_MASK_TRUTH, 10000.0f, 50.0f); } } @@ -566,7 +566,7 @@ void EnSth_HandleSwampSpiderHouseConversation(EnSth* this, PlayState* play) { case 0x91A: // Someone gave me this mask and said it would make me rich, getting rid of it SET_WEEKEVENTREG(WEEKEVENTREG_RECEIVED_MASK_OF_TRUTH); - CLEAR_WEEKEVENTREG(WEEKEVENTREG_SWAMP_SPIDER_HOUSE_TALKED); + CLEAR_WEEKEVENTREG(WEEKEVENTREG_TALKED_SWAMP_SPIDER_HOUSE_MAN); case 0x902: // (does not exist) case 0x903: // (does not exist) 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 a7cd6617a0..196b292635 100644 --- a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c +++ b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c @@ -230,7 +230,7 @@ void EnSuttari_TriggerTransition(PlayState* play, u16 entrance) { play->transitionTrigger = TRANS_TRIGGER_START; } -void EnSuttari_UpdateTime(void) { +void EnSuttari_AdvanceTime(void) { gSaveContext.save.time = ((void)0, gSaveContext.save.time) + (u16)R_TIME_SPEED; gSaveContext.save.time = ((void)0, gSaveContext.save.time) + (u16)((void)0, gSaveContext.save.timeSpeedOffset); } @@ -1483,7 +1483,7 @@ void EnSuttari_Update(Actor* thisx, PlayState* play) { func_80BAB4F0(this, play); } if (this->flags2 & 2) { - EnSuttari_UpdateTime(); + EnSuttari_AdvanceTime(); } if (this->unk428 != 0) { if (this->animIndex == 2 || this->animIndex == 6) { diff --git a/src/overlays/actors/ovl_Obj_Nozoki/z_obj_nozoki.c b/src/overlays/actors/ovl_Obj_Nozoki/z_obj_nozoki.c index 7f7f9550af..d5dfed84d1 100644 --- a/src/overlays/actors/ovl_Obj_Nozoki/z_obj_nozoki.c +++ b/src/overlays/actors/ovl_Obj_Nozoki/z_obj_nozoki.c @@ -4,6 +4,7 @@ * Description: Sakon's Hideout Objects (Sun's Mask, doors, etc) */ +#include "prevent_bss_reordering.h" #include "z_obj_nozoki.h" #include "objects/object_secom_obj/object_secom_obj.h" diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 8cbc8f13f6..157036d0c5 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -8997,37 +8997,37 @@ 0x809C0E30:("EnWarpTag_GrottoReturn",), 0x809C0F18:("EnWarptag_Update",), 0x809C0F3C:("EnWarpTag_Draw",), - 0x809C10B0:("func_809C10B0",), - 0x809C1124:("func_809C1124",), - 0x809C1158:("func_809C1158",), - 0x809C11EC:("func_809C11EC",), - 0x809C1304:("func_809C1304",), - 0x809C1424:("func_809C1424",), - 0x809C14D0:("func_809C14D0",), - 0x809C15BC:("func_809C15BC",), - 0x809C165C:("func_809C165C",), - 0x809C16DC:("func_809C16DC",), - 0x809C1C9C:("func_809C1C9C",), - 0x809C1D64:("func_809C1D64",), - 0x809C1EC8:("func_809C1EC8",), - 0x809C2060:("func_809C2060",), - 0x809C21E0:("func_809C21E0",), - 0x809C2504:("func_809C2504",), - 0x809C2594:("func_809C2594",), - 0x809C25E4:("func_809C25E4",), - 0x809C2680:("func_809C2680",), - 0x809C26E4:("func_809C26E4",), - 0x809C2730:("func_809C2730",), - 0x809C2788:("func_809C2788",), - 0x809C2824:("func_809C2824",), - 0x809C28B8:("func_809C28B8",), - 0x809C2A64:("func_809C2A64",), - 0x809C2BE4:("func_809C2BE4",), - 0x809C2C9C:("func_809C2C9C",), - 0x809C2D0C:("func_809C2D0C",), - 0x809C2EC4:("func_809C2EC4",), - 0x809C2F34:("func_809C2F34",), - 0x809C2FA0:("func_809C2FA0",), + 0x809C10B0:("EnAob01_Blink",), + 0x809C1124:("EnAob01_AdvanceTime",), + 0x809C1158:("EnAob01_InitializeDogPaths",), + 0x809C11EC:("EnAob01_SpawnDogs",), + 0x809C1304:("EnAob01_SpawnRacedogs",), + 0x809C1424:("EnAob01_ProcessLaughAnim",), + 0x809C14D0:("EnAob01_ProcessSurpriseAnim",), + 0x809C15BC:("EnAob01_ProcessIdleAnim",), + 0x809C165C:("EnAob01_UpdateCollision",), + 0x809C16DC:("EnAob01_BeforeRace_HandleConversation",), + 0x809C1C9C:("EnAob01_BeforeRace_StartRace",), + 0x809C1D64:("EnAob01_BeforeRace_RespondToPlayAgainQuestion",), + 0x809C1EC8:("EnAob01_UpdateCommon",), + 0x809C2060:("EnAob01_BeforeRace_Idle",), + 0x809C21E0:("EnAob01_BeforeRace_Talk",), + 0x809C2504:("EnAob01_Race_DogHasReachedNextCutsceneTrigger",), + 0x809C2594:("EnAob01_Race_FollowSelectedDog",), + 0x809C25E4:("EnAob01_Race_IsRaceOver",), + 0x809C2680:("EnAob01_Race_CurrentCutsceneHasEnded",), + 0x809C26E4:("EnAob01_Race_SkipNonRaceCutscene",), + 0x809C2730:("EnAob01_Race_HandleRaceCutscene",), + 0x809C2788:("EnAob01_Race_HandleRaceEndCutscene",), + 0x809C2824:("EnAob01_Race_StartCutscene",), + 0x809C28B8:("EnAob01_AfterRace_GiveRaceResult",), + 0x809C2A64:("EnAob01_AfterRace_GiveReward",), + 0x809C2BE4:("EnAob01_AfterRace_AfterGivingReward",), + 0x809C2C9C:("EnAob01_AfterRace_AskToPlayAgain",), + 0x809C2D0C:("EnAob01_AfterRace_Talk",), + 0x809C2EC4:("EnAob01_PlayerIsHoldingDog",), + 0x809C2F34:("EnAob01_Race_HidePlayer",), + 0x809C2FA0:("EnAob01_InitializeDogTextOffsets",), 0x809C3190:("EnAob01_Init",), 0x809C3350:("EnAob01_Destroy",), 0x809C339C:("EnAob01_Update",), @@ -15199,7 +15199,7 @@ 0x80BAA6D0:("EnSuttari_UpdateCollider",), 0x80BAA848:("EnSuttari_GetActorById",), 0x80BAA88C:("EnSuttari_TriggerTransition",), - 0x80BAA8D0:("EnSuttari_UpdateTime",), + 0x80BAA8D0:("EnSuttari_AdvanceTime",), 0x80BAA904:("func_80BAA904",), 0x80BAA9B4:("func_80BAA9B4",), 0x80BAAA94:("func_80BAAA94",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index ffd045d44e..6abc9a1a84 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -9860,11 +9860,11 @@ 0x809C3770:("En_Aob_01_InitVars","UNK_TYPE1","",0x1), 0x809C3790:("sAnimationInfo","UNK_TYPE4","",0x4), 0x809C3820:("D_809C3820","UNK_TYPE1","",0x1), - 0x809C384C:("D_809C384C","UNK_TYPE4","",0x4), + 0x809C384C:("sDogInfo","UNK_TYPE4","",0x4), 0x809C392C:("D_809C392C","UNK_TYPE1","",0x1), 0x809C394C:("D_809C394C","UNK_TYPE4","",0x4), 0x809C395C:("D_809C395C","UNK_PTR","",0x4), - 0x809C3968:("D_809C3968","UNK_TYPE1","",0x1), + 0x809C3968:("sFocusOffset","UNK_TYPE1","",0x1), 0x809C3980:("D_809C3980","f32","",0x4), 0x809C3984:("D_809C3984","f32","",0x4), 0x809C3988:("D_809C3988","f32","",0x4), diff --git a/tools/weekeventregconvert.py b/tools/weekeventregconvert.py index 34b3ddc46d..b96696b46d 100755 --- a/tools/weekeventregconvert.py +++ b/tools/weekeventregconvert.py @@ -73,7 +73,7 @@ weekEventReg = { ( 8 << 8) | 0x04: "WEEKEVENTREG_08_04", ( 8 << 8) | 0x08: "WEEKEVENTREG_08_08", ( 8 << 8) | 0x10: "WEEKEVENTREG_08_10", - ( 8 << 8) | 0x20: "WEEKEVENTREG_08_20", + ( 8 << 8) | 0x20: "WEEKEVENTREG_RECEIVED_DOGGY_RACETRACK_HEART_PIECE", ( 8 << 8) | 0x40: "WEEKEVENTREG_08_40", ( 8 << 8) | 0x80: "WEEKEVENTREG_08_80", ( 9 << 8) | 0x01: "WEEKEVENTREG_09_01", @@ -279,7 +279,7 @@ weekEventReg = { (34 << 8) | 0x01: "WEEKEVENTREG_34_01", (34 << 8) | 0x02: "WEEKEVENTREG_34_02", (34 << 8) | 0x04: "WEEKEVENTREG_34_04", - (34 << 8) | 0x08: "WEEKEVENTREG_SWAMP_SPIDER_HOUSE_TALKED", + (34 << 8) | 0x08: "WEEKEVENTREG_TALKED_SWAMP_SPIDER_HOUSE_MAN", (34 << 8) | 0x10: "WEEKEVENTREG_34_10", (34 << 8) | 0x20: "WEEKEVENTREG_34_20", (34 << 8) | 0x40: "WEEKEVENTREG_RECEIVED_MASK_OF_TRUTH", @@ -523,12 +523,12 @@ weekEventReg = { (64 << 8) | 0x10: "WEEKEVENTREG_64_10", (64 << 8) | 0x20: "WEEKEVENTREG_64_20", (64 << 8) | 0x40: "WEEKEVENTREG_64_40", - (64 << 8) | 0x80: "WEEKEVENTREG_64_80", - (65 << 8) | 0x01: "WEEKEVENTREG_65_01", - (65 << 8) | 0x02: "WEEKEVENTREG_65_02", - (65 << 8) | 0x04: "WEEKEVENTREG_65_04", - (65 << 8) | 0x08: "WEEKEVENTREG_65_08", - (65 << 8) | 0x10: "WEEKEVENTREG_65_10", + (64 << 8) | 0x80: "WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_DAY_1", + (65 << 8) | 0x01: "WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_NIGHT_1", + (65 << 8) | 0x02: "WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_DAY_2", + (65 << 8) | 0x04: "WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_NIGHT_2", + (65 << 8) | 0x08: "WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_DAY_3", + (65 << 8) | 0x10: "WEEKEVENTREG_TALKED_DOGGY_RACETRACK_OWNER_NIGHT_3", (65 << 8) | 0x20: "WEEKEVENTREG_65_20", (65 << 8) | 0x40: "WEEKEVENTREG_65_40", (65 << 8) | 0x80: "WEEKEVENTREG_65_80",