diff options
| author | Jordan Longstaff <JordanLongstaff@users.noreply.github.com> | 2026-07-18 15:20:31 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-07-18 12:20:31 -0700 |
| commit | 5fd95d51f9ca06194a88c37362461e661c2e9ab6 (patch) | |
| tree | 1f8a88559448ca8d9a2cb0369969d6639e11451e /src/overlays/actors/ovl_En_Test3/z_en_test3.c | |
| parent | ae6e93fcf91830ba5e3dd28e7bf1623ee006002e (diff) | |
Document `EnTest3` (#1881)
* Document `EnTest3`
* Add comments for enum-type fields
* Add scheduled action index comments
Co-authored-by: Copilot <copilot@github.com>
* Use enums in comparisons
* Rename `sp3C`
* Rewrite comments on speak data
Co-authored-by: Copilot <copilot@github.com>
* Reformat
* Missed a text comment
* Missed another text comment
---------
Co-authored-by: Copilot <copilot@github.com>
Diffstat (limited to 'src/overlays/actors/ovl_En_Test3/z_en_test3.c')
| -rw-r--r-- | src/overlays/actors/ovl_En_Test3/z_en_test3.c | 846 |
1 files changed, 516 insertions, 330 deletions
diff --git a/src/overlays/actors/ovl_En_Test3/z_en_test3.c b/src/overlays/actors/ovl_En_Test3/z_en_test3.c index c3abb7379..910729b65 100644 --- a/src/overlays/actors/ovl_En_Test3/z_en_test3.c +++ b/src/overlays/actors/ovl_En_Test3/z_en_test3.c @@ -18,68 +18,135 @@ #define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED | ACTOR_FLAG_CAN_PRESS_SWITCHES) typedef struct { - /* 0x0 */ s8 unk_0; - /* 0x1 */ s8 unk_1_0 : 4; - /* 0x1 */ s8 unk_1_4 : 4; -} struct_80A41828; // size = 0x2 - -typedef s32 (*EnTest3UnkFunc2)(EnTest3* this, PlayState* play, struct_80A41828* arg2, ScheduleOutput* scheduleOutput); -typedef s32 (*EnTest3UnkFunc)(EnTest3* this, PlayState* play); - + /* 0x0 */ s8 schActionIndex; // KafeiScheduledActionIndex + /* 0x1 */ s8 pathIndexAndDirection : 4; + /* 0x1 */ s8 speakDataIndex : 4; +} EnTest3ScheduleResultData; // size = 0x2 + +typedef s32 (*EnTest3ProcessScheduleFunc)(EnTest3* this, PlayState* play, EnTest3ScheduleResultData* schResultData, + ScheduleOutput* scheduleOutput); +typedef s32 (*EnTest3HandlerFunc)(EnTest3* this, PlayState* play); typedef struct { - /* 0x0 */ EnTest3UnkFunc2 unk_0; - /* 0x4 */ EnTest3UnkFunc unk_4; -} struct_80A40678; // size = 0x8 + /* 0x0 */ EnTest3ProcessScheduleFunc processSchFunc; + /* 0x4 */ EnTest3HandlerFunc handleSchFunc; +} EnTest3ScheduledAction; // size = 0x8 typedef struct { - /* 0x0 */ EnTest3ActionFunc unk_0; // might not actually be an action function - /* 0x4 */ EnTest3ActionFunc actionFunc; -} struct_80A4168C; // size = 0x8 + /* 0x0 */ EnTest3ActionFunc effect; // might not actually be an action function + /* 0x4 */ EnTest3ActionFunc nextMainAction; // always NULL +} EnTest3PostTalkEffect; // size = 0x8 + +typedef enum EnTest3RunToTownPhase { + /* 0 */ ENTEST3_RUN_TO_TOWN_WAITING, + /* 1 */ ENTEST3_RUN_TO_TOWN_RUNNING, + /* 2 */ ENTEST3_RUN_TO_TOWN_END, + /* 3 */ ENTEST3_RUN_TO_TOWN_CLEARED, +} EnTest3RunToTownPhase; + +typedef enum EnTest3CoupleCsPhase { + /* 0 */ ENTEST3_COUPLE_CS_ENTERING, + /* 1 */ ENTEST3_COUPLE_CS_STARTING, + /* 2 */ ENTEST3_COUPLE_CS_PLAYING, +} EnTest3CoupleCsPhase; void EnTest3_Init(Actor* thisx, PlayState* play2); void EnTest3_Destroy(Actor* thisx, PlayState* play2); void EnTest3_Update(Actor* thisx, PlayState* play2); void EnTest3_Draw(Actor* thisx, PlayState* play2); -// Functions used in D_80A4169C and D_80A416C0. Purpose unclear, but related to Schedule -s32 func_80A3E870(EnTest3* this, PlayState* play); -s32 func_80A3E884(EnTest3* this, PlayState* play); -s32 func_80A3E898(EnTest3* this, PlayState* play); -s32 func_80A3E960(EnTest3* this, PlayState* play); -s32 func_80A3E97C(EnTest3* this, PlayState* play); -s32 func_80A3E9DC(EnTest3* this, PlayState* play); -s32 func_80A3EA30(EnTest3* this, PlayState* play); -s32 func_80A3EAC4(EnTest3* this, PlayState* play); -s32 func_80A3EAF8(EnTest3* this, PlayState* play); -s32 func_80A3EB8C(EnTest3* this, PlayState* play); -s32 func_80A3EBFC(EnTest3* this, PlayState* play); -s32 func_80A3EC30(EnTest3* this, PlayState* play); -s32 func_80A3EC44(EnTest3* this, PlayState* play); - -// Functions used in D_80A417E8. Purpose unclear, but related to Schedule -s32 func_80A3F080(EnTest3* this, PlayState* play, struct_80A41828* arg2, ScheduleOutput* scheduleOutput); -s32 func_80A3F09C(EnTest3* this, PlayState* play); -s32 func_80A3F62C(EnTest3* this, PlayState* play, struct_80A41828* arg2, ScheduleOutput* scheduleOutput); -s32 func_80A3F73C(EnTest3* this, PlayState* play); -s32 func_80A3F8D4(EnTest3* this, PlayState* play, struct_80A41828* arg2, ScheduleOutput* scheduleOutput); -s32 func_80A3F9A4(EnTest3* this, PlayState* play); -s32 func_80A3F9E4(EnTest3* this, PlayState* play, struct_80A41828* arg2, ScheduleOutput* scheduleOutput); -s32 func_80A3FA58(EnTest3* this, PlayState* play); -s32 func_80A3FBCC(EnTest3* this, PlayState* play, struct_80A41828* arg2, ScheduleOutput* scheduleOutput); -s32 func_80A3FBE8(EnTest3* this, PlayState* play); -s32 func_80A3FDE4(EnTest3* this, PlayState* play, struct_80A41828* arg2, ScheduleOutput* scheduleOutput); -s32 func_80A3FE20(EnTest3* this, PlayState* play); -s32 func_80A3FF10(EnTest3* this, PlayState* play, struct_80A41828* arg2, ScheduleOutput* scheduleOutput); -s32 func_80A3FFD0(EnTest3* this, PlayState* play2); -s32 func_80A40098(EnTest3* this, PlayState* play, struct_80A41828* arg2, ScheduleOutput* scheduleOutput); -s32 func_80A40230(EnTest3* this, PlayState* play); +// Functions used to process and advance phases in Kafei's talk state machine +s32 EnTest3_SetupTalk_TriggerFaceRevealCs(EnTest3* this, PlayState* play); +s32 EnTest3_SetupTalk_DoNothing(EnTest3* this, PlayState* play); +s32 EnTest3_SetupTalk_NextMessage(EnTest3* this, PlayState* play); +s32 EnTest3_SetupTalk_SetNextMessageTimer(EnTest3* this, PlayState* play); +s32 EnTest3_HandleTalk_Wait(EnTest3* this, PlayState* play); +s32 EnTest3_StartCutscene(EnTest3* this, PlayState* play); +s32 EnTest3_SetupTalk_CutsceneCheck(EnTest3* this, PlayState* play); +s32 EnTest3_HandleTalk_Done(EnTest3* this, PlayState* play); +s32 EnTest3_HandleTalk_Event(EnTest3* this, PlayState* play); +s32 EnTest3_HandleTalk_LookAtPeephole(EnTest3* this, PlayState* play); +s32 EnTest3_HandleTalk_Closing(EnTest3* this, PlayState* play); +s32 EnTest3_HandleTalk_EndOfMessage(EnTest3* this, PlayState* play); +s32 EnTest3_HandleTalk_Choice(EnTest3* this, PlayState* play); + +// Process and handle functions for all parts of Kafei's schedule +s32 EnTest3_ProcessSchedule_StopDrawing(EnTest3* this, PlayState* play, EnTest3ScheduleResultData* schResultData, + ScheduleOutput* scheduleOutput); +s32 EnTest3_HandleSchedule_StopDrawing(EnTest3* this, PlayState* play); +s32 EnTest3_ProcessSchedule_CanTalk(EnTest3* this, PlayState* play, EnTest3ScheduleResultData* schResultData, + ScheduleOutput* scheduleOutput); +s32 EnTest3_HandleSchedule_CanTalk(EnTest3* this, PlayState* play); +s32 EnTest3_ProcessSchedule_FindMailCarrier(EnTest3* this, PlayState* play, EnTest3ScheduleResultData* schResultData, + ScheduleOutput* scheduleOutput); +s32 EnTest3_HandleSchedule_TurnToMailCarrier(EnTest3* this, PlayState* play); +s32 EnTest3_ProcessSchedule_BellRung(EnTest3* this, PlayState* play, EnTest3ScheduleResultData* schResultData, + ScheduleOutput* scheduleOutput); +s32 EnTest3_HandleSchedule_BellRung(EnTest3* this, PlayState* play); +s32 EnTest3_ProcessSchedule_SakonHideout(EnTest3* this, PlayState* play, EnTest3ScheduleResultData* schResultData, + ScheduleOutput* scheduleOutput); +s32 EnTest3_HandleSchedule_SakonHideout(EnTest3* this, PlayState* play); +s32 EnTest3_ProcessSchedule_RunToTownCs(EnTest3* this, PlayState* play, EnTest3ScheduleResultData* schResultData, + ScheduleOutput* scheduleOutput); +s32 EnTest3_HandleSchedule_RunToTownCs(EnTest3* this, PlayState* play); +s32 EnTest3_ProcessSchedule_CouplesMaskCs(EnTest3* this, PlayState* play, EnTest3ScheduleResultData* schResultData, + ScheduleOutput* scheduleOutput); +s32 EnTest3_HandleSchedule_CouplesMaskCs(EnTest3* this, PlayState* play2); +s32 EnTest3_ProcessSchedule_ComputeWaypoint(EnTest3* this, PlayState* play, EnTest3ScheduleResultData* schResultData, + ScheduleOutput* scheduleOutput); +s32 EnTest3_HandleSchedule_MoveToWaypoint(EnTest3* this, PlayState* play); // Action functions -void func_80A40678(EnTest3* this, PlayState* play); -void func_80A40824(EnTest3* this, PlayState* play); -void func_80A4084C(EnTest3* this, PlayState* play); -void func_80A40908(EnTest3* this, PlayState* play); -void EnTest3_EnablePeephole(EnTest3* this, PlayState* play); +void EnTest3_Action_FollowSchedule(EnTest3* this, PlayState* play); +void EnTest3_Action_Unused(EnTest3* this, PlayState* play); +void EnTest3_Action_HandleTalk(EnTest3* this, PlayState* play); +void EnTest3_Action_GivePendant(EnTest3* this, PlayState* play); +void EnTest3_PostTalk_EnablePeephole(EnTest3* this, PlayState* play); + +typedef enum KafeiScheduleResult { + /* 0 */ KAFEI_SCH_NONE, + // Kafei either puts a letter in the postbox or receives one from the Postman + /* 1 */ KAFEI_SCH_HANDLING_LETTER, + // Unused + /* 2 */ KAFEI_SCH_2, + // Kafei is ready to speak with Link for the first time (and gives him the Pendant of Memories) + /* 3 */ KAFEI_SCH_MEETING_LINK_IN_CURIOSITY_SHOP, + // Kafei waits to spy on Sakon, but he didn't come because you stopped him stealing the Bomb Bag + /* 4 */ KAFEI_SCH_WAITING_AT_CURIOSITY_SHOP, + // Kafei waits outside Sakon's Hideout + /* 5 */ KAFEI_SCH_WAITING_OUTSIDE_SAKONS_HIDEOUT, + // Kafei laments that he couldn't keep his promise to Anju, though her bridal dress is lovely + /* 6 */ KAFEI_SCH_COULDNT_KEEP_PROMISE, + // Sakon's Hideout mission - Link helps Kafei retrieve the Sun's Mask + /* 7 */ KAFEI_SCH_INSIDE_SAKONS_HIDEOUT, + // Kafei reunites with Anju and they give Link the Couple's Mask + /* 8 */ KAFEI_SCH_BECOMING_A_COUPLE, + // Kafei runs back to Clock Town after retrieving the Sun's Mask + /* 9 */ KAFEI_SCH_RUNNING_TO_TOWN, + // Kafei heard Link ring the bell and steps outside briefly to look around + /* 10 */ KAFEI_SCH_HEARD_BELL_RING, + // Kafei enters Clock Town through the east gate on his way to reunite with Anju + /* 11 */ KAFEI_SCH_ENTERING_CLOCK_TOWN_EAST, + // Kafei has entered the Curiosity Shop with Anju's letter and is returning to his hiding spot + /* 12 */ KAFEI_SCH_RETURNING_TO_CURIOSITY_SHOP_DAY_2, + // Kafei goes to the postbox outside the Laundry Pool to deposit his letter + /* 13 */ KAFEI_SCH_GOING_TO_POSTBOX, + // Kafei returns to the Laundry Pool after dropping his letter in the postbox + /* 14 */ KAFEI_SCH_RETURNING_TO_LAUNDRY_POOL, + // Kafei runs to the Curiosity Shop backdoor after depositing his letter + /* 15 */ KAFEI_SCH_RETURNING_TO_CURIOSITY_SHOP_DAY_1, + // Kafei runs to the Postman to receive Anju's letter + /* 16 */ KAFEI_SCH_RUNNING_TO_POSTMAN, + // Kafei has the letter from Anju and is bringing it back to the Curiosity Shop + /* 17 */ KAFEI_SCH_RUNNING_BACK_TO_DOOR_WITH_LETTER, + // Kafei enters the Stock Pot Inn and heads upstairs to where Anju is waiting for him + /* 18 */ KAFEI_SCH_ENTERING_STOCK_POT_INN, + // Kafei slowly walks over to Anju's bridal dress + /* 19 */ KAFEI_SCH_WALKING_TO_BRIDAL_DRESS, + // Kafei sneaks inside Sakon's Hideout when the door opens + /* 20 */ KAFEI_SCH_ENTERING_SAKONS_HIDEOUT, + // Unused + /* 21 */ KAFEI_SCH_21, +} KafeiScheduleResult; #include "src/overlays/actors/ovl_En_Test3/scheduleScripts.schl.inc" @@ -95,19 +162,46 @@ ActorProfile En_Test3_Profile = { /**/ NULL, }; -static struct_80A4168C D_80A4168C[] = { - { EnTest3_EnablePeephole, NULL }, +static EnTest3PostTalkEffect sPostTalkEffects[] = { + { EnTest3_PostTalk_EnablePeephole, NULL }, { NULL, NULL }, }; -static EnTest3UnkFunc D_80A4169C[] = { - func_80A3E898, func_80A3E898, func_80A3E884, func_80A3E898, func_80A3E898, - func_80A3EA30, func_80A3E898, func_80A3E960, func_80A3E870, +typedef enum EnTest3TalkState { + /* 0 */ ENTEST3_TALK_DONE, + /* 1 */ ENTEST3_TALK_EVENT, + /* 2 */ ENTEST3_TALK_CLOSING, + /* 3 */ ENTEST3_TALK_CHOICE, + /* 4 */ ENTEST3_TALK_END, + /* 5 */ ENTEST3_TALK_START_CUTSCENE, + /* 6 */ ENTEST3_TALK_LOOK_AT_PEEPHOLE, + /* 7 */ ENTEST3_TALK_WAIT, + /* 8 */ ENTEST3_TALK_FACE_REVEAL, +} EnTest3TalkState; + +static EnTest3HandlerFunc sTalkStateSetupFuncs[] = { + EnTest3_SetupTalk_NextMessage, // ENTEST3_TALK_DONE + EnTest3_SetupTalk_NextMessage, // ENTEST3_TALK_EVENT + EnTest3_SetupTalk_DoNothing, // ENTEST3_TALK_CLOSING + EnTest3_SetupTalk_NextMessage, // ENTEST3_TALK_CHOICE + EnTest3_SetupTalk_NextMessage, // ENTEST3_TALK_END + EnTest3_SetupTalk_CutsceneCheck, // ENTEST3_TALK_START_CUTSCENE + EnTest3_SetupTalk_NextMessage, // ENTEST3_TALK_LOOK_AT_PEEPHOLE + EnTest3_SetupTalk_SetNextMessageTimer, // ENTEST3_TALK_WAIT + EnTest3_SetupTalk_TriggerFaceRevealCs, // ENTEST3_TALK_FACE_REVEAL }; -static EnTest3UnkFunc D_80A416C0[] = { - func_80A3EAC4, func_80A3EAF8, func_80A3EBFC, func_80A3EC44, - func_80A3EC30, func_80A3E9DC, func_80A3EB8C, func_80A3E97C, +static EnTest3HandlerFunc sTalkStateHandlerFuncs[] = { + EnTest3_HandleTalk_Done, // ENTEST3_TALK_DONE + EnTest3_HandleTalk_Event, // ENTEST3_TALK_EVENT + EnTest3_HandleTalk_Closing, // ENTEST3_TALK_CLOSING + EnTest3_HandleTalk_Choice, // ENTEST3_TALK_CHOICE + EnTest3_HandleTalk_EndOfMessage, // ENTEST3_TALK_END + EnTest3_StartCutscene, // ENTEST3_TALK_START_CUTSCENE + EnTest3_HandleTalk_LookAtPeephole, // ENTEST3_TALK_LOOK_AT_PEEPHOLE + EnTest3_HandleTalk_Wait, // ENTEST3_TALK_WAIT + // ENTEST3_TALK_FACE_REVEAL has no entry here, so possibly an index out of bounds; thankfully, we've left the talk + // state machine at this point because the GivePendant action has been set up }; static PlayerAgeProperties sAgeProperties = { @@ -214,78 +308,141 @@ static EffectTireMarkInit sTireMarkInit = { { 0, 0, 15, 100 }, }; -static struct_80A40678 D_80A417E8[] = { - { func_80A3F080, func_80A3F09C }, { func_80A40098, func_80A40230 }, { func_80A3F62C, func_80A3F73C }, - { func_80A3F8D4, func_80A3F9A4 }, { func_80A3F9E4, func_80A3FA58 }, { func_80A3FBCC, func_80A3FBE8 }, - { func_80A3FDE4, func_80A3FE20 }, { func_80A3FF10, func_80A3FFD0 }, +typedef enum KafeiScheduledActionIndex { + /* 0 */ KAFEI_SCH_ACTION_STOP_DRAWING, + /* 1 */ KAFEI_SCH_ACTION_COMPUTE_WAYPOINT, + /* 2 */ KAFEI_SCH_ACTION_CAN_TALK, + /* 3 */ KAFEI_SCH_ACTION_FIND_MAIL_CARRIER, + /* 4 */ KAFEI_SCH_ACTION_BELL_RUNG, + /* 5 */ KAFEI_SCH_ACTION_SAKON_HIDEOUT, + /* 6 */ KAFEI_SCH_ACTION_RUN_TO_TOWN_CS, + /* 7 */ KAFEI_SCH_ACTION_COUPLE_CS, +} KafeiScheduledActionIndex; + +static EnTest3ScheduledAction sScheduledActions[] = { + // KAFEI_SCH_ACTION_STOP_DRAWING + { EnTest3_ProcessSchedule_StopDrawing, EnTest3_HandleSchedule_StopDrawing }, + // KAFEI_SCH_ACTION_COMPUTE_WAYPOINT + { EnTest3_ProcessSchedule_ComputeWaypoint, EnTest3_HandleSchedule_MoveToWaypoint }, + // KAFEI_SCH_ACTION_CAN_TALK + { EnTest3_ProcessSchedule_CanTalk, EnTest3_HandleSchedule_CanTalk }, + // KAFEI_SCH_ACTION_FIND_MAIL_CARRIER + { EnTest3_ProcessSchedule_FindMailCarrier, EnTest3_HandleSchedule_TurnToMailCarrier }, + // KAFEI_SCH_ACTION_BELL_RUNG + { EnTest3_ProcessSchedule_BellRung, EnTest3_HandleSchedule_BellRung }, + // KAFEI_SCH_ACTION_SAKON_HIDEOUT + { EnTest3_ProcessSchedule_SakonHideout, EnTest3_HandleSchedule_SakonHideout }, + // KAFEI_SCH_ACTION_RUN_TO_TOWN_CS + { EnTest3_ProcessSchedule_RunToTownCs, EnTest3_HandleSchedule_RunToTownCs }, + // KAFEI_SCH_ACTION_COUPLE_CS + { EnTest3_ProcessSchedule_CouplesMaskCs, EnTest3_HandleSchedule_CouplesMaskCs }, }; -static struct_80A41828 D_80A41828[] = { - { 0, 0, 0 }, { 3, -2, 0 }, { 2, -1, 0 }, { 2, -1, 1 }, { 2, -1, 2 }, { 2, 1, 3 }, { 2, -2, 4 }, { 5, 1, 0 }, - { 7, -1, 0 }, { 6, 2, 0 }, { 4, 4, 0 }, { 1, 1, 0 }, { 1, 1, 0 }, { 1, 2, 0 }, { 1, 1, 0 }, { 1, 1, 0 }, - { 1, 2, 0 }, { 1, 3, 0 }, { 1, 1, 0 }, { 1, 2, 0 }, { 1, 1, 0 }, { 0, 0, 0 }, +static EnTest3ScheduleResultData sKafeiScheduledResultData[] = { + { KAFEI_SCH_ACTION_STOP_DRAWING, 0, 0 }, // KAFEI_SCH_NONE + { KAFEI_SCH_ACTION_FIND_MAIL_CARRIER, -2, 0 }, // KAFEI_SCH_HANDLING_LETTER + { KAFEI_SCH_ACTION_CAN_TALK, -1, 0 }, // KAFEI_SCH_2 + { KAFEI_SCH_ACTION_CAN_TALK, -1, 1 }, // KAFEI_SCH_MEETING_LINK_IN_CURIOSITY_SHOP + { KAFEI_SCH_ACTION_CAN_TALK, -1, 2 }, // KAFEI_SCH_WAITING_AT_CURIOSITY_SHOP + { KAFEI_SCH_ACTION_CAN_TALK, 1, 3 }, // KAFEI_SCH_WAITING_OUTSIDE_SAKONS_HIDEOUT + { KAFEI_SCH_ACTION_CAN_TALK, -2, 4 }, // KAFEI_SCH_COULDNT_KEEP_PROMISE + { KAFEI_SCH_ACTION_SAKON_HIDEOUT, 1, 0 }, // KAFEI_SCH_INSIDE_SAKONS_HIDEOUT + { KAFEI_SCH_ACTION_COUPLE_CS, -1, 0 }, // KAFEI_SCH_BECOMING_A_COUPLE + { KAFEI_SCH_ACTION_RUN_TO_TOWN_CS, 2, 0 }, // KAFEI_SCH_RUNNING_TO_TOWN + { KAFEI_SCH_ACTION_BELL_RUNG, 4, 0 }, // KAFEI_SCH_HEARD_BELL_RING + { KAFEI_SCH_ACTION_COMPUTE_WAYPOINT, 1, 0 }, // KAFEI_SCH_ENTERING_CLOCK_TOWN_EAST + { KAFEI_SCH_ACTION_COMPUTE_WAYPOINT, 1, 0 }, // KAFEI_SCH_RETURNING_TO_CURIOSITY_SHOP_DAY_2 + { KAFEI_SCH_ACTION_COMPUTE_WAYPOINT, 2, 0 }, // KAFEI_SCH_GOING_TO_POSTBOX + { KAFEI_SCH_ACTION_COMPUTE_WAYPOINT, 1, 0 }, // KAFEI_SCH_RETURNING_TO_LAUNDRY_POOL + { KAFEI_SCH_ACTION_COMPUTE_WAYPOINT, 1, 0 }, // KAFEI_SCH_RETURNING_TO_CURIOSITY_SHOP_DAY_1 + { KAFEI_SCH_ACTION_COMPUTE_WAYPOINT, 2, 0 }, // KAFEI_SCH_RUNNING_TO_POSTMAN + { KAFEI_SCH_ACTION_COMPUTE_WAYPOINT, 3, 0 }, // KAFEI_SCH_RUNNING_BACK_TO_DOOR_WITH_LETTER + { KAFEI_SCH_ACTION_COMPUTE_WAYPOINT, 1, 0 }, // KAFEI_SCH_ENTERING_STOCK_POT_INN + { KAFEI_SCH_ACTION_COMPUTE_WAYPOINT, 2, 0 }, // KAFEI_SCH_WALKING_TO_BRIDAL_DRESS + { KAFEI_SCH_ACTION_COMPUTE_WAYPOINT, 1, 0 }, // KAFEI_SCH_ENTERING_SAKONS_HIDEOUT + { KAFEI_SCH_ACTION_STOP_DRAWING, 0, 0 }, // KAFEI_SCH_21 }; -static EnTest3_struct_D78 D_80A41854[] = { - { 4, 0, 0x2B25 }, { 1, 0, 0x2969 }, { 3, 1, 0x296A }, { 1, 0, 0x296B }, { 5, 1, 0x0000 }, { 8, 0, 0x0000 }, - { 4, 0, 0x2976 }, { 6, 0, 0x2977 }, { 7, 10, 0x2978 }, { 4, 1, 0x0000 }, { 4, 0, 0x2968 }, { 4, 0, 0x297A }, - { 1, 0, 0x145D }, { 1, 0, 0x145E }, { 5, 1, 0x145F }, { 1, 0, 0x145F }, { 5, 0, 0x0000 }, { 4, 0, 0x1460 }, - { 4, 0, 0x145C }, { 4, 0, 0x2913 }, { 4, 0, 0x1465 }, +static EnTest3SpeakData sSpeakData[] = { + { 4, 0, 0x2B25 }, // Unused? NTSC message: "Oh, that's too bad." + { 1, 0, 0x2969 }, // First thing Kafei says when he meets Link + { 3, 1, 0x296A }, // Asking Link to keep a secret + { 1, 0, 0x296B }, // If Link said no + { 5, 1, 0x0000 }, // Starts the face reveal cutscene, regardless of what Link chose + { 8, 0, 0x0000 }, // Sets Kafei's next action as GivePendant + { 4, 0, 0x2976 }, // Last message after giving Link the pendant + { 6, 0, 0x2977 }, // Talking to Kafei after he gave Link the pendant + { 7, 10, 0x2978 }, // 10-frame delay as Kafei turns to look at the peephole on the wall + { 4, 1, 0x0000 }, // Displays the previous message once 10 frames have passed + { 4, 0, 0x2968 }, // Kafei doesn't recognize Link in Curiosity Shop; long silence + { 4, 0, 0x297A }, // Kafei says Sakon will definitely appear + { 1, 0, 0x145D }, // Talking to Kafei outside Sakon's Hideout; first message + { 1, 0, 0x145E }, // Talking to Kafei outside Sakon's Hideout; second message + { 5, 1, 0x145F }, // Starts cutscene where Kafei looks at the hideout door. The text ID is necessary to tell Kafei + // to look at it. + { 1, 0, 0x145F }, // Third message, spoken while looking at the hideout door + { 5, 0, 0x0000 }, // Ends cutscene where Kafei looks at the hideout door + { 4, 0, 0x1460 }, // Last message in this conversation; in subsequent talks, he only says this + { 4, 0, 0x145C }, // Kafei doesn't recognize Link at Ikana Canyon; medium silence + { 4, 0, 0x2913 }, // Talking to Kafei at inn with Anju absent (Link didn't give her the pendant) + { 4, 0, 0x1465 }, // Kafei tells Link to step on the switch }; -s32 D_80A41D20; -s32 D_80A41D24; +s32 sSakonHideoutPhase; +s32 sExists; Input sKafeiControlInput; f32 sKafeiControlStickMagnitude; s16 sKafeiControlStickAngle; -s32 D_80A41D48; -Vec3f D_80A41D50; -s32 D_80A41D5C; -s32 D_80A41D60; -s32 D_80A41D64; -s32 D_80A41D68; +s32 sKafeiIsFollowingPath; +Vec3f sKafeiCurrentPathTargetPos; +s32 sMetAtIkana; +s32 sKafeiGavePendantToLink; +EnTest3RunToTownPhase sKafeiRunToTownPhase; +EnTest3CoupleCsPhase sKafeiCoupleCsPhase; Vec3f* sKafeiCurBodyPartPos; -s32 func_80A3E7E0(EnTest3* this, EnTest3ActionFunc actionFunc) { - if (actionFunc == this->unk_D94) { +s32 EnTest3_SetMainAction(EnTest3* this, EnTest3ActionFunc actionFunc) { + if (actionFunc == this->mainActionFunc) { return false; } else { - this->unk_D94 = actionFunc; - this->unk_D8A = 0; - this->scheduleResult = 0; + this->mainActionFunc = actionFunc; + this->bellTimer = 0; + this->scheduleResult = KAFEI_SCH_NONE; return true; } } -s32 func_80A3E80C(EnTest3* this, PlayState* play, s32 arg2) { +s32 EnTest3_TalkTriggersAction(EnTest3* this, PlayState* play, s32 index) { s32 pad; - D_80A4168C[arg2].unk_0(this, play); + sPostTalkEffects[index].effect(this, play); - if (D_80A4168C[arg2].actionFunc == NULL) { - // D_80A4168C[arg2].actionFunc is always NULL + if (sPostTalkEffects[index].nextMainAction == NULL) { + // sPostTalkEffects[index].nextMainAction is always NULL return false; } else { - func_80A3E7E0(this, D_80A4168C[arg2].actionFunc); + EnTest3_SetMainAction(this, sPostTalkEffects[index].nextMainAction); return true; } } -s32 func_80A3E870(EnTest3* this, PlayState* play) { +s32 EnTest3_SetupTalk_TriggerFaceRevealCs(EnTest3* this, PlayState* play) { return true; } -s32 func_80A3E884(EnTest3* this, PlayState* play) { +s32 EnTest3_SetupTalk_DoNothing(EnTest3* this, PlayState* play) { return false; } -s32 func_80A3E898(EnTest3* this, PlayState* play) { - u16 textId = this->unk_D78->textId; +s32 EnTest3_SetupTalk_NextMessage(EnTest3* this, PlayState* play) { + u16 textId = this->speakData->textId; - if ((this->unk_D78->unk_0 == 4) && CHECK_WEEKEVENTREG(WEEKEVENTREG_51_08)) { + if ((this->speakData->talkActionIndex == ENTEST3_TALK_END) && + CHECK_WEEKEVENTREG(WEEKEVENTREG_KAFEI_ENTRUSTED_LINK)) { Message_BombersNotebookQueueEvent(play, BOMBERS_NOTEBOOK_EVENT_MET_KAFEI); } if (textId == 0xFFFF) { + // Never happens Message_CloseTextbox(play); } else if ((u32)textId != 0) { Message_ContinueTextbox(play, textId); @@ -297,20 +454,20 @@ s32 func_80A3E898(EnTest3* this, PlayState* play) { return false; } -s32 func_80A3E960(EnTest3* this, PlayState* play) { - this->unk_D8C = this->unk_D78->unk_1; +s32 EnTest3_SetupTalk_SetNextMessageTimer(EnTest3* this, PlayState* play) { + this->nextMsgTimer = this->speakData->argument; return false; } -s32 func_80A3E97C(EnTest3* this, PlayState* play) { - if (DECR(this->unk_D8C) == 0) { - Message_StartTextbox(play, this->unk_D78->textId, NULL); +s32 EnTest3_HandleTalk_Wait(EnTest3* this, PlayState* play) { + if (DECR(this->nextMsgTimer) == 0) { + Message_StartTextbox(play, this->speakData->textId, NULL); return true; } return false; } -s32 func_80A3E9DC(EnTest3* this, PlayState* play) { +s32 EnTest3_StartCutscene(EnTest3* this, PlayState* play) { if (CutsceneManager_IsNext(this->csId)) { CutsceneManager_StartWithPlayerCs(this->csId, &this->player.actor); return true; @@ -320,15 +477,15 @@ s32 func_80A3E9DC(EnTest3* this, PlayState* play) { } } -s32 func_80A3EA30(EnTest3* this, PlayState* play) { - if (this->unk_D78->textId == 0x145F) { +s32 EnTest3_SetupTalk_CutsceneCheck(EnTest3* this, PlayState* play) { + if (this->speakData->textId == 0x145F) { Actor* hideoutDoor = SubS_FindActor(play, NULL, ACTORCAT_BG, ACTOR_BG_IKNV_OBJ); if (hideoutDoor != NULL) { this->player.focusActor = hideoutDoor; } } - if (this->unk_D78->unk_1 != 0) { + if (this->speakData->argument != 0) { CutsceneManager_Stop(CS_ID_GLOBAL_TALK); CutsceneManager_Queue(this->csId); play->msgCtx.msgMode = MSGMODE_PAUSED; @@ -336,16 +493,16 @@ s32 func_80A3EA30(EnTest3* this, PlayState* play) { return false; } -s32 func_80A3EAC4(EnTest3* this, PlayState* play) { +s32 EnTest3_HandleTalk_Done(EnTest3* this, PlayState* play) { if (Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) { return 1; } return 0; } -s32 func_80A3EAF8(EnTest3* this, PlayState* play) { +s32 EnTest3_HandleTalk_Event(EnTest3* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) { - if (this->unk_D78->textId == 0x145F) { + if (this->speakData->textId == 0x145F) { CutsceneManager_Stop(this->csId); this->csId = CS_ID_GLOBAL_TALK; CutsceneManager_Queue(this->csId); @@ -356,8 +513,8 @@ s32 func_80A3EAF8(EnTest3* this, PlayState* play) { return 0; } -s32 func_80A3EB8C(EnTest3* this, PlayState* play) { - if (func_80A3EAF8(this, play)) { +s32 EnTest3_HandleTalk_LookAtPeephole(EnTest3* this, PlayState* play) { + if (EnTest3_HandleTalk_Event(this, play)) { Actor* hideoutObject = SubS_FindActor(play, NULL, ACTORCAT_ITEMACTION, ACTOR_OBJ_NOZOKI); if (hideoutObject != NULL) { @@ -369,18 +526,18 @@ s32 func_80A3EB8C(EnTest3* this, PlayState* play) { return 0; } -s32 func_80A3EBFC(EnTest3* this, PlayState* play) { +s32 EnTest3_HandleTalk_Closing(EnTest3* this, PlayState* play) { if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { return 1; } return 0; } -s32 func_80A3EC30(EnTest3* this, PlayState* play) { +s32 EnTest3_HandleTalk_EndOfMessage(EnTest3* this, PlayState* play) { return 0; } -s32 func_80A3EC44(EnTest3* this, PlayState* play) { +s32 EnTest3_HandleTalk_Choice(EnTest3* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_CHOICE) && Message_ShouldAdvance(play)) { if (play->msgCtx.choiceIndex != 0) { Audio_PlaySfx_MessageCancel(); @@ -390,24 +547,24 @@ s32 func_80A3EC44(EnTest3* this, PlayState* play) { if (play->msgCtx.choiceIndex != 0) { return 1; } else { - s32 ret = this->unk_D78->unk_1 + 1; + s32 nextOffset = this->speakData->argument + 1; - return ret; + return nextOffset; } } return 0; } -s32 func_80A3ECEC(EnTest3* this, PlayState* play) { - return D_80A4169C[this->unk_D78->unk_0](this, play); +s32 EnTest3_ShouldTriggerCutscene(EnTest3* this, PlayState* play) { + return sTalkStateSetupFuncs[this->speakData->talkActionIndex](this, play); } -s32 func_80A3ED24(EnTest3* this, PlayState* play) { - s32 temp = D_80A416C0[this->unk_D78->unk_0](this, play); +s32 EnTest3_NextTalkStateTriggersCutscene(EnTest3* this, PlayState* play) { + s32 nextOffset = sTalkStateHandlerFuncs[this->speakData->talkActionIndex](this, play); - if (temp != 0) { - this->unk_D78 = &this->unk_D78[temp]; - return func_80A3ECEC(this, play); + if (nextOffset != 0) { + this->speakData = &this->speakData[nextOffset]; + return EnTest3_ShouldTriggerCutscene(this, play); } return false; } @@ -417,11 +574,11 @@ void EnTest3_Init(Actor* thisx, PlayState* play2) { EnTest3* this = (EnTest3*)thisx; Camera* subCam; - if (D_80A41D24) { + if (sExists) { Actor_Kill(&this->player.actor); return; } - D_80A41D24 = true; + sExists = true; this->player.actor.room = -1; this->player.csId = CS_ID_NONE; @@ -439,12 +596,12 @@ void EnTest3_Init(Actor* thisx, PlayState* play2) { this->player.maskObjectSegment = ZeldaArena_Malloc(0x3800); play->func_18780(&this->player, play); - this->unk_D90 = GET_PLAYER(play); - this->player.giObjectSegment = this->unk_D90->giObjectSegment; - this->player.tatlActor = this->unk_D90->tatlActor; + this->link = GET_PLAYER(play); + this->player.giObjectSegment = this->link->giObjectSegment; + this->player.tatlActor = this->link->tatlActor; if ((CURRENT_DAY != 3) || CHECK_WEEKEVENTREG(WEEKEVENTREG_RECOVERED_STOLEN_BOMB_BAG) || - !CHECK_WEEKEVENTREG(WEEKEVENTREG_51_08)) { + !CHECK_WEEKEVENTREG(WEEKEVENTREG_KAFEI_ENTRUSTED_LINK)) { this->player.currentMask = PLAYER_MASK_KEATON; } this->player.prevMask = this->player.currentMask; @@ -462,9 +619,9 @@ void EnTest3_Init(Actor* thisx, PlayState* play2) { this->player.actor.colChkInfo.health = 255; if (KAFEI_GET_PARAM_1E0(&this->player.actor) == 0) { - func_80A3E7E0(this, func_80A40824); + EnTest3_SetMainAction(this, EnTest3_Action_Unused); } else { - func_80A3E7E0(this, func_80A40678); + EnTest3_SetMainAction(this, EnTest3_Action_FollowSchedule); } } @@ -484,28 +641,29 @@ void EnTest3_Destroy(Actor* thisx, PlayState* play2) { Environment_StartTime(); } -s32 func_80A3F080(EnTest3* this, PlayState* play, struct_80A41828* arg2, ScheduleOutput* scheduleOutput) { +s32 EnTest3_ProcessSchedule_StopDrawing(EnTest3* this, PlayState* play, EnTest3ScheduleResultData* schResultData, + ScheduleOutput* scheduleOutput) { return true; } -s32 func_80A3F09C(EnTest3* this, PlayState* play) { +s32 EnTest3_HandleSchedule_StopDrawing(EnTest3* this, PlayState* play) { this->player.actor.draw = NULL; return true; } -void func_80A3F0B0(EnTest3* this, PlayState* play) { - Actor_ChangeCategory(play, &play->actorCtx, &this->unk_D90->actor, ACTORCAT_PLAYER); +void EnTest3_ReturnControlToLink(EnTest3* this, PlayState* play) { + Actor_ChangeCategory(play, &play->actorCtx, &this->link->actor, ACTORCAT_PLAYER); Actor_ChangeCategory(play, &play->actorCtx, &this->player.actor, ACTORCAT_NPC); - this->unk_D90->stateFlags1 &= ~PLAYER_STATE1_20; + this->link->stateFlags1 &= ~PLAYER_STATE1_20; } -void func_80A3F114(EnTest3* this, PlayState* play) { +void EnTest3_EndCsAction(EnTest3* this, PlayState* play) { if (this->player.csAction != PLAYER_CSACTION_NONE) { play->tryPlayerCsAction(play, &this->player, PLAYER_CSACTION_END); } } -s32 func_80A3F15C(EnTest3* this, PlayState* play, struct_80A41828* arg2) { +s32 EnTest3_MoveTowardNextPoint(EnTest3* this, PlayState* play, EnTest3ScheduleResultData* schResultData) { s32 limit; Path* path; Vec3s* curPathPoint; @@ -513,13 +671,13 @@ s32 func_80A3F15C(EnTest3* this, PlayState* play, struct_80A41828* arg2) { Vec3f curPathPos; Vec3f nextPathPos; - limit = ABS_ALT(arg2->unk_1_0) - 1; + limit = ABS_ALT(schResultData->pathIndexAndDirection) - 1; if (limit >= 0) { path = SubS_GetAdditionalPath(play, KAFEI_GET_PATH_INDEX(&this->player.actor), limit); curPathPoint = Lib_SegmentedToVirtual(path->points); - if (arg2->unk_1_0 > 0) { + if (schResultData->pathIndexAndDirection > 0) { nextPathPoint = curPathPoint + 1; } else { curPathPoint += path->count - 1; @@ -532,7 +690,7 @@ s32 func_80A3F15C(EnTest3* this, PlayState* play, struct_80A41828* arg2) { Math_Vec3f_Copy(&this->player.actor.home.pos, &curPathPos); Math_Vec3f_Copy(&this->player.actor.prevPos, &curPathPos); this->player.yaw = Math_Vec3f_Yaw(&this->player.actor.world.pos, &nextPathPos); - if (arg2->unk_1_0 < 0) { + if (schResultData->pathIndexAndDirection < 0) { this->player.yaw += 0x8000; } this->player.actor.shape.rot.y = this->player.yaw; @@ -542,14 +700,14 @@ s32 func_80A3F15C(EnTest3* this, PlayState* play, struct_80A41828* arg2) { return false; } -Actor* func_80A3F2BC(PlayState* play, EnTest3* this, s32 actorId, s32 category, f32 arg4, f32 arg5) { +Actor* EnTest3_FindNearbyActor(PlayState* play, EnTest3* this, s32 actorId, s32 category, f32 radiusXZ, f32 distY) { Actor* actor = play->actorCtx.actorLists[category].first; while (actor != NULL) { if (actorId == actor->id) { f32 dy = this->player.actor.world.pos.y - actor->world.pos.y; - if ((fabsf(dy) < arg5) && (Actor_WorldDistXZToActor(&this->player.actor, actor) < arg4)) { + if ((fabsf(dy) < distY) && (Actor_WorldDistXZToActor(&this->player.actor, actor) < radiusXZ)) { return actor; } } @@ -558,9 +716,9 @@ Actor* func_80A3F2BC(PlayState* play, EnTest3* this, s32 actorId, s32 category, return NULL; } -s32 func_80A3F384(EnTest3* this, PlayState* play) { +s32 EnTest3_IsOpeningDoor(EnTest3* this, PlayState* play) { Player* player = GET_PLAYER(play); - EnDoor* door = (EnDoor*)func_80A3F2BC(play, this, ACTOR_EN_DOOR, ACTORCAT_DOOR, 55.0f, 20.0f); + EnDoor* door = (EnDoor*)EnTest3_FindNearbyActor(play, this, ACTOR_EN_DOOR, ACTORCAT_DOOR, 55.0f, 20.0f); Vec3f offset; if ((door != NULL) && !door->knobDoor.requestOpen && @@ -576,44 +734,54 @@ s32 func_80A3F384(EnTest3* this, PlayState* play) { return false; } -bool func_80A3F4A4(PlayState* play) { +// Checks if Kafei can recognize Link. He won't unless Link is wearing one of: +// - No mask +// - Bunny Hood +// - Postman's Hat +// - Keaton Mask +// - Kafei's Mask +bool EnTest3_RecognizesLink(PlayState* play) { return (Player_GetMask(play) == PLAYER_MASK_NONE) || (Player_GetMask(play) == PLAYER_MASK_BUNNY) || (Player_GetMask(play) == PLAYER_MASK_POSTMAN) || (Player_GetMask(play) == PLAYER_MASK_KEATON) || (Player_GetMask(play) == PLAYER_MASK_KAFEIS_MASK); } -void func_80A3F534(EnTest3* this, PlayState* play) { - if (!func_80A3F4A4(play)) { - this->unk_D78 = &D_80A41854[10]; - } else if (CHECK_WEEKEVENTREG(WEEKEVENTREG_51_08)) { - this->unk_D78 = &D_80A41854[7]; +void EnTest3_GetSpeakDataAtShop(EnTest3* this, PlayState* play) { + if (!EnTest3_RecognizesLink(play)) { + this->speakData = &sSpeakData[10]; + } else if (CHECK_WEEKEVENTREG(WEEKEVENTREG_KAFEI_ENTRUSTED_LINK)) { + this->speakData = &sSpeakData[7]; } else { - this->unk_D78 = &D_80A41854[1]; + this->speakData = &sSpeakData[1]; } this->csId = this->player.actor.csId; } -void func_80A3F5A4(EnTest3* this, PlayState* play) { - if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_51_08) || !func_80A3F4A4(play)) { - this->unk_D78 = &D_80A41854[18]; - D_80A41D5C = false; - } else if (D_80A41D5C) { - this->unk_D78 = &D_80A41854[17]; +void EnTest3_GetSpeakDataAtIkana(EnTest3* this, PlayState* play) { + if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_KAFEI_ENTRUSTED_LINK) || !EnTest3_RecognizesLink(play)) { + this->speakData = &sSpeakData[18]; + sMetAtIkana = false; + } else if (sMetAtIkana) { + this->speakData = &sSpeakData[17]; } else { - this->unk_D78 = &D_80A41854[12]; + this->speakData = &sSpeakData[12]; } this->csId = this->player.actor.csId; } -s32 func_80A3F62C(EnTest3* this, PlayState* play, struct_80A41828* arg2, ScheduleOutput* scheduleOutput) { - static EnTest3_struct_D78* D_80A418A8[] = { - &D_80A41854[0], &D_80A41854[1], &D_80A41854[11], &D_80A41854[12], &D_80A41854[19], +s32 EnTest3_ProcessSchedule_CanTalk(EnTest3* this, PlayState* play, EnTest3ScheduleResultData* schResultData, + ScheduleOutput* scheduleOutput) { + // This speak data array is separate from the normal one, containing only a few of its entries. The only ones + // that actually matter are 11 and 19; the rest get overridden by the above functions. + static EnTest3SpeakData* sNpcSpeakData[] = { + &sSpeakData[0], &sSpeakData[1], &sSpeakData[11], &sSpeakData[12], &sSpeakData[19], }; - if (((func_80A3F15C(this, play, arg2) || (this->scheduleResult >= 8)) && - ((arg2->unk_1_4 == 1) || (arg2->unk_1_4 == 2))) || - (arg2->unk_1_4 == 4)) { - if (arg2->unk_1_4 == 4) { + if (((EnTest3_MoveTowardNextPoint(this, play, schResultData) || + (this->scheduleResult >= KAFEI_SCH_BECOMING_A_COUPLE)) && + ((schResultData->speakDataIndex == 1) || (schResultData->speakDataIndex == 2))) || + (schResultData->speakDataIndex == 4)) { + if (schResultData->speakDataIndex == 4) { this->player.actor.home.rot.y = 0x7FFF; } else { this->player.actor.home.rot.y = this->player.actor.shape.rot.y + 0x8000; @@ -621,123 +789,127 @@ s32 func_80A3F62C(EnTest3* this, PlayState* play, struct_80A41828* arg2, Schedul this->player.stateFlags2 |= PLAYER_STATE2_40000; play->tryPlayerCsAction(play, &this->player, PLAYER_CSACTION_NEG1); } - this->unk_D78 = D_80A418A8[arg2->unk_1_4]; + this->speakData = sNpcSpeakData[schResultData->speakDataIndex]; return true; } -s32 func_80A3F73C(EnTest3* this, PlayState* play) { +s32 EnTest3_HandleSchedule_CanTalk(EnTest3* this, PlayState* play) { if (Actor_TalkOfferAccepted(&this->player.actor, &play->state)) { - func_80A3E7E0(this, func_80A4084C); + EnTest3_SetMainAction(this, EnTest3_Action_HandleTalk); this->player.focusActor = &GET_PLAYER(play)->actor; this->player.stateFlags2 &= ~PLAYER_STATE2_40000; - D_80A41D5C = true; - if ((this->unk_D78->unk_0 == 4) && CHECK_WEEKEVENTREG(WEEKEVENTREG_51_08)) { + sMetAtIkana = true; + if ((this->speakData->talkActionIndex == ENTEST3_TALK_END) && + CHECK_WEEKEVENTREG(WEEKEVENTREG_KAFEI_ENTRUSTED_LINK)) { Message_BombersNotebookQueueEvent(play, BOMBERS_NOTEBOOK_EVENT_MET_KAFEI); } } else { if (play->actorCtx.flags & ACTORCTX_FLAG_4) { play->actorCtx.flags &= ~ACTORCTX_FLAG_4; this->player.stateFlags2 &= ~PLAYER_STATE2_40000; - this->unk_D90->stateFlags1 |= PLAYER_STATE1_20; - Actor_ChangeCategory(play, &play->actorCtx, &this->unk_D90->actor, ACTORCAT_NPC); + this->link->stateFlags1 |= PLAYER_STATE1_20; + Actor_ChangeCategory(play, &play->actorCtx, &this->link->actor, ACTORCAT_NPC); Actor_ChangeCategory(play, &play->actorCtx, &this->player.actor, ACTORCAT_PLAYER); CutsceneManager_SetReturnCamera(this->subCamId); play->tryPlayerCsAction(play, &this->player, PLAYER_CSACTION_WAIT); } Actor_OfferTalkNearColChkInfoCylinder(&this->player.actor, play); - if (this->scheduleResult == 3) { - func_80A3F534(this, play); - } else if (this->scheduleResult == 5) { - func_80A3F5A4(this, play); + if (this->scheduleResult == KAFEI_SCH_MEETING_LINK_IN_CURIOSITY_SHOP) { + EnTest3_GetSpeakDataAtShop(this, play); + } else if (this->scheduleResult == KAFEI_SCH_WAITING_OUTSIDE_SAKONS_HIDEOUT) { + EnTest3_GetSpeakDataAtIkana(this, play); } - this->player.actor.textId = this->unk_D78->textId; + this->player.actor.textId = this->speakData->textId; this->player.actor.flags |= (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY); } return false; } -s32 func_80A3F8D4(EnTest3* this, PlayState* play, struct_80A41828* arg2, ScheduleOutput* scheduleOutput) { +s32 EnTest3_ProcessSchedule_FindMailCarrier(EnTest3* this, PlayState* play, EnTest3ScheduleResultData* schResultData, + ScheduleOutput* scheduleOutput) { Actor* postActor; - func_80A3F15C(this, play, arg2); - if (((postActor = func_80A3F2BC(play, this, ACTOR_EN_PST, ACTORCAT_PROP, 100.0f, 20.0f)) != NULL) || - ((postActor = func_80A3F2BC(play, this, ACTOR_EN_PM, ACTORCAT_NPC, 100.0f, 20.0f)) != NULL)) { + EnTest3_MoveTowardNextPoint(this, play, schResultData); + if (((postActor = EnTest3_FindNearbyActor(play, this, ACTOR_EN_PST, ACTORCAT_PROP, 100.0f, 20.0f)) != NULL) || + ((postActor = EnTest3_FindNearbyActor(play, this, ACTOR_EN_PM, ACTORCAT_NPC, 100.0f, 20.0f)) != NULL)) { this->player.actor.home.rot.y = Actor_WorldYawTowardActor(&this->player.actor, postActor); } play->tryPlayerCsAction(play, &this->player, PLAYER_CSACTION_97); return true; } -s32 func_80A3F9A4(EnTest3* this, PlayState* play) { +s32 EnTest3_HandleSchedule_TurnToMailCarrier(EnTest3* this, PlayState* play) { Math_ScaledStepToS(&this->player.actor.shape.rot.y, this->player.actor.home.rot.y, 0x320); this->player.yaw = this->player.actor.shape.rot.y; return false; } -s32 func_80A3F9E4(EnTest3* this, PlayState* play, struct_80A41828* arg2, ScheduleOutput* scheduleOutput) { +s32 EnTest3_ProcessSchedule_BellRung(EnTest3* this, PlayState* play, EnTest3ScheduleResultData* schResultData, + ScheduleOutput* scheduleOutput) { scheduleOutput->time0 = (u16)SCRIPT_TIME_NOW; scheduleOutput->time1 = (u16)(scheduleOutput->time0 + 70); - func_80A40098(this, play, arg2, scheduleOutput); + EnTest3_ProcessSchedule_ComputeWaypoint(this, play, schResultData, scheduleOutput); if (this->player.actor.xzDistToPlayer < 300.0f) { - this->unk_D8A = -1; + this->bellTimer = -1; } else { - this->unk_D8A = 120; + this->bellTimer = 120; } return true; } -s32 func_80A3FA58(EnTest3* this, PlayState* play) { +s32 EnTest3_HandleSchedule_BellRung(EnTest3* this, PlayState* play) { s32 pad; Player* player = GET_PLAYER(play); u32 cond; - struct_80A41828 sp40; + EnTest3ScheduleResultData backToDoor; ScheduleOutput scheduleOutput; if (player->stateFlags1 & PLAYER_STATE1_TALKING) { return false; } - cond = func_80A40230(this, play); - if (this->unk_D8A > 0) { - this->unk_D8A--; + cond = EnTest3_HandleSchedule_MoveToWaypoint(this, play); + if (this->bellTimer > 0) { + this->bellTimer--; cond = cond && (this->player.actor.xzDistToPlayer < 200.0f); - if (cond || this->unk_D8A <= 0) { - func_80A3F114(this, play); - sp40.unk_1_0 = 5; + if (cond || this->bellTimer <= 0) { + EnTest3_EndCsAction(this, play); + backToDoor.pathIndexAndDirection = 5; scheduleOutput.time0 = (u16)SCRIPT_TIME_NOW; scheduleOutput.time1 = (u16)(scheduleOutput.time0 + (cond ? 80 : 140)); - func_80A40098(this, play, &sp40, &scheduleOutput); - this->unk_D8A = -40; + EnTest3_ProcessSchedule_ComputeWaypoint(this, play, &backToDoor, &scheduleOutput); + this->bellTimer = -40; return false; } - if (this->unk_D8A == 90) { + if (this->bellTimer == 90) { play->tryPlayerCsAction(play, &this->player, PLAYER_CSACTION_21); } } else { - this->unk_D8A++; - if (this->unk_D8A == 0) { - CLEAR_WEEKEVENTREG(WEEKEVENTREG_51_04); - this->scheduleResult = 0; + this->bellTimer++; + if (this->bellTimer == 0) { + CLEAR_WEEKEVENTREG(WEEKEVENTREG_HIT_LAUNDRY_POOL_BELL); + this->scheduleResult = KAFEI_SCH_NONE; } } return false; } -s32 func_80A3FBCC(EnTest3* this, PlayState* play, struct_80A41828* arg2, ScheduleOutput* scheduleOutput) { +s32 EnTest3_ProcessSchedule_SakonHideout(EnTest3* this, PlayState* play, EnTest3ScheduleResultData* schResultData, + ScheduleOutput* scheduleOutput) { return true; } -s32 func_80A3FBE8(EnTest3* this, PlayState* play) { - if (D_80A41D20 == 0) { +s32 EnTest3_HandleSchedule_SakonHideout(EnTest3* this, PlayState* play) { + if (sSakonHideoutPhase == 0) { if (!Play_InCsMode(play)) { - D_80A41D20 = 1; - this->unk_D78 = &D_80A41854[20]; + sSakonHideoutPhase = 1; + this->speakData = &sSpeakData[20]; this->csId = this->player.actor.csId; - this->player.actor.textId = this->unk_D78->textId; + this->player.actor.textId = this->speakData->textId; } - } else if (D_80A41D20 == 1) { + } else if (sSakonHideoutPhase == 1) { if (this->csId > CS_ID_NONE) { - if (func_80A3E9DC(this, play)) { + if (EnTest3_StartCutscene(this, play)) { this->csId = CS_ID_NONE; Environment_StopTime(); } @@ -748,11 +920,11 @@ s32 func_80A3FBE8(EnTest3* this, PlayState* play) { this->csId = CutsceneManager_GetAdditionalCsId(this->csId); } SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 1); - D_80A41D20 = 2; + sSakonHideoutPhase = 2; } else { - func_80A3F73C(this, play); + EnTest3_HandleSchedule_CanTalk(this, play); } - } else if ((D_80A41D20 == 2) && func_80A3E9DC(this, play)) { + } else if ((sSakonHideoutPhase == 2) && EnTest3_StartCutscene(this, play)) { CutsceneManager_SetReturnCamera(CAM_ID_MAIN); Environment_StartTime(); if (CURRENT_TIME > CLOCK_TIME(6, 0)) { @@ -762,46 +934,48 @@ s32 func_80A3FBE8(EnTest3* this, PlayState* play) { SET_WEEKEVENTREG(WEEKEVENTREG_ESCAPED_SAKONS_HIDEOUT); CLEAR_WEEKEVENTREG(WEEKEVENTREG_90_02); } - D_80A41D20 = 3; + sSakonHideoutPhase = 3; } return false; } -s32 func_80A3FDE4(EnTest3* this, PlayState* play, struct_80A41828* arg2, ScheduleOutput* scheduleOutput) { +s32 EnTest3_ProcessSchedule_RunToTownCs(EnTest3* this, PlayState* play, EnTest3ScheduleResultData* schResultData, + ScheduleOutput* scheduleOutput) { this->csId = CutsceneManager_GetAdditionalCsId(this->player.actor.csId); return true; } -s32 func_80A3FE20(EnTest3* this, PlayState* play) { - struct_80A41828 sp2C; +s32 EnTest3_HandleSchedule_RunToTownCs(EnTest3* this, PlayState* play) { + EnTest3ScheduleResultData endPoint; ScheduleOutput scheduleOutput; - if (D_80A41D64 == 0) { - if (func_80A3E9DC(this, play)) { - sp2C.unk_1_0 = 2; + if (sKafeiRunToTownPhase == ENTEST3_RUN_TO_TOWN_WAITING) { + if (EnTest3_StartCutscene(this, play)) { + endPoint.pathIndexAndDirection = 2; scheduleOutput.time0 = (u16)SCRIPT_TIME_NOW; scheduleOutput.time1 = (u16)(scheduleOutput.time0 + 1000); - func_80A40098(this, play, &sp2C, &scheduleOutput); - D_80A41D64 = 1; + EnTest3_ProcessSchedule_ComputeWaypoint(this, play, &endPoint, &scheduleOutput); + sKafeiRunToTownPhase = ENTEST3_RUN_TO_TOWN_RUNNING; return false; } - } else if (D_80A41D64 == 1) { - func_80A40230(this, play); - } else if (D_80A41D64 == 2) { + } else if (sKafeiRunToTownPhase == ENTEST3_RUN_TO_TOWN_RUNNING) { + EnTest3_HandleSchedule_MoveToWaypoint(this, play); + } else if (sKafeiRunToTownPhase == ENTEST3_RUN_TO_TOWN_END) { CutsceneManager_Stop(this->csId); SET_WEEKEVENTREG(WEEKEVENTREG_90_02); - D_80A41D64 = 3; + sKafeiRunToTownPhase = ENTEST3_RUN_TO_TOWN_CLEARED; } return false; } -s32 func_80A3FF10(EnTest3* this, PlayState* play, struct_80A41828* arg2, ScheduleOutput* scheduleOutput) { - static Vec3f D_80A418BC = { -420.0f, 210.0f, -162.0f }; +s32 EnTest3_ProcessSchedule_CouplesMaskCs(EnTest3* this, PlayState* play, EnTest3ScheduleResultData* schResultData, + ScheduleOutput* scheduleOutput) { + static Vec3f holdHandsPos = { -420.0f, 210.0f, -162.0f }; if (CHECK_WEEKEVENTREG(WEEKEVENTREG_COUPLES_MASK_CUTSCENE_FINISHED)) { - D_80A41D68 = 2; - Math_Vec3f_Copy(&this->player.actor.world.pos, &D_80A418BC); - Math_Vec3f_Copy(&this->player.actor.home.pos, &D_80A418BC); + sKafeiCoupleCsPhase = ENTEST3_COUPLE_CS_PLAYING; + Math_Vec3f_Copy(&this->player.actor.world.pos, &holdHandsPos); + Math_Vec3f_Copy(&this->player.actor.home.pos, &holdHandsPos); this->player.actor.home.rot.y = -0x2AAB; this->player.actor.shape.rot.y = -0x2AAB; @@ -810,7 +984,7 @@ s32 func_80A3FF10(EnTest3* this, PlayState* play, struct_80A41828* arg2, Schedul if (1) {} return true; } else { - func_80A3F15C(this, play, arg2); + EnTest3_MoveTowardNextPoint(this, play, schResultData); this->csId = this->player.actor.csId; if (play->roomCtx.curRoom.num == 2) { this->csId = CutsceneManager_GetAdditionalCsId(this->csId); @@ -819,16 +993,16 @@ s32 func_80A3FF10(EnTest3* this, PlayState* play, struct_80A41828* arg2, Schedul } } -s32 func_80A3FFD0(EnTest3* this, PlayState* play2) { +s32 EnTest3_HandleSchedule_CouplesMaskCs(EnTest3* this, PlayState* play2) { PlayState* play = play2; - if (D_80A41D68 == 0) { + if (sKafeiCoupleCsPhase == ENTEST3_COUPLE_CS_ENTERING) { if (!Play_InCsMode(play) && (play->roomCtx.curRoom.num == 2)) { - D_80A41D68 = 1; + sKafeiCoupleCsPhase = ENTEST3_COUPLE_CS_STARTING; } - } else if (D_80A41D68 == 1) { - if (func_80A3E9DC(this, play)) { - D_80A41D68 = 2; + } else if (sKafeiCoupleCsPhase == ENTEST3_COUPLE_CS_STARTING) { + if (EnTest3_StartCutscene(this, play)) { + sKafeiCoupleCsPhase = ENTEST3_COUPLE_CS_PLAYING; } } else { SET_WEEKEVENTREG(WEEKEVENTREG_COUPLES_MASK_CUTSCENE_FINISHED); @@ -837,91 +1011,96 @@ s32 func_80A3FFD0(EnTest3* this, PlayState* play2) { return false; } -s32 func_80A40098(EnTest3* this, PlayState* play, struct_80A41828* arg2, ScheduleOutput* scheduleOutput) { +s32 EnTest3_ProcessSchedule_ComputeWaypoint(EnTest3* this, PlayState* play, EnTest3ScheduleResultData* schResultData, + ScheduleOutput* scheduleOutput) { u16 now = SCRIPT_TIME_NOW; u16 startTime; u16 numWaypoints; - func_80A3F15C(this, play, arg2); - this->unk_D7C = SubS_GetAdditionalPath(play, KAFEI_GET_PATH_INDEX(&this->player.actor), ABS_ALT(arg2->unk_1_0) - 1); - if ((this->scheduleResult < 7) && (this->scheduleResult != 0) && (this->unk_D80 >= 0)) { + EnTest3_MoveTowardNextPoint(this, play, schResultData); + this->currentPath = SubS_GetAdditionalPath(play, KAFEI_GET_PATH_INDEX(&this->player.actor), + ABS_ALT(schResultData->pathIndexAndDirection) - 1); + if ((this->scheduleResult < KAFEI_SCH_INSIDE_SAKONS_HIDEOUT) && (this->scheduleResult != KAFEI_SCH_NONE) && + (this->timeSpeed >= 0)) { startTime = now; } else { startTime = scheduleOutput->time0; } if (scheduleOutput->time1 < startTime) { - this->unk_DA8 = (startTime - scheduleOutput->time1) + (DAY_LENGTH - 1); + this->schPathRemainingTime = (startTime - scheduleOutput->time1) + (DAY_LENGTH - 1); } else { - this->unk_DA8 = scheduleOutput->time1 - startTime; + this->schPathRemainingTime = scheduleOutput->time1 - startTime; } - this->unk_DB4 = now - startTime; - numWaypoints = startTime = this->unk_D7C->count - (SUBS_TIME_PATHING_ORDER - 1); - this->unk_DAC = this->unk_DA8 / numWaypoints; - this->unk_DB0 = (this->unk_DB4 / this->unk_DAC) + (SUBS_TIME_PATHING_ORDER - 1); - this->unk_D89 &= ~1; - this->unk_D84 = 1.0f; + this->schPathElapsedTime = now - startTime; + numWaypoints = startTime = this->currentPath->count - (SUBS_TIME_PATHING_ORDER - 1); + this->waypointRemainingTime = this->schPathRemainingTime / numWaypoints; + this->waypointIndex = (this->schPathElapsedTime / this->waypointRemainingTime) + (SUBS_TIME_PATHING_ORDER - 1); + this->isTimePathStarted &= ~1; + this->waypointProgress = 1.0f; return true; } -s32 func_80A40230(EnTest3* this, PlayState* play) { +s32 EnTest3_HandleSchedule_MoveToWaypoint(EnTest3* this, PlayState* play) { f32 knots[265]; Vec3f worldPos; - Vec3f sp7C; - Vec3f sp70; - s32 sp6C = 0; - s32 sp68 = 0; + Vec3f nextTargetPos; + Vec3f currentTargetPos; + s32 tempElapsedTime = 0; + s32 tempWaypointIndex = 0; s32 pad1; f32 dx; f32 dy; s32 ret = false; - SubS_TimePathing_FillKnots(knots, 3, this->unk_D7C->count + 3); - if (!(this->unk_D89 & 1)) { - sp70 = gZeroVec3f; - SubS_TimePathing_Update(this->unk_D7C, &this->unk_DA4, &this->unk_DB4, this->unk_DAC, this->unk_DA8, - &this->unk_DB0, knots, &sp70, this->unk_D80); - SubS_TimePathing_ComputeInitialY(play, this->unk_D7C, this->unk_DB0, &sp70); - Math_Vec3f_Copy(&this->player.actor.home.pos, &sp70); - Math_Vec3f_Copy(&this->player.actor.prevPos, &sp70); - this->player.actor.world.pos.y = sp70.y; - this->unk_D89 |= 1; + SubS_TimePathing_FillKnots(knots, 3, this->currentPath->count + 3); + if (!(this->isTimePathStarted & 1)) { + currentTargetPos = gZeroVec3f; + SubS_TimePathing_Update(this->currentPath, &this->schPathProgress, &this->schPathElapsedTime, + this->waypointRemainingTime, this->schPathRemainingTime, &this->waypointIndex, knots, + ¤tTargetPos, this->timeSpeed); + SubS_TimePathing_ComputeInitialY(play, this->currentPath, this->waypointIndex, ¤tTargetPos); + Math_Vec3f_Copy(&this->player.actor.home.pos, ¤tTargetPos); + Math_Vec3f_Copy(&this->player.actor.prevPos, ¤tTargetPos); + this->player.actor.world.pos.y = currentTargetPos.y; + this->isTimePathStarted |= 1; } else { - sp70 = this->unk_D98; + currentTargetPos = this->targetPos; } - this->player.actor.world.pos.x = sp70.x; - this->player.actor.world.pos.z = sp70.z; + this->player.actor.world.pos.x = currentTargetPos.x; + this->player.actor.world.pos.z = currentTargetPos.z; if (play->transitionMode != TRANS_MODE_OFF) { - sp6C = this->unk_DB4; - sp68 = this->unk_DB0; - sp70 = this->player.actor.world.pos; + tempElapsedTime = this->schPathElapsedTime; + tempWaypointIndex = this->waypointIndex; + currentTargetPos = this->player.actor.world.pos; } - this->unk_D98 = gZeroVec3f; - if (SubS_TimePathing_Update(this->unk_D7C, &this->unk_DA4, &this->unk_DB4, this->unk_DAC, this->unk_DA8, - &this->unk_DB0, knots, &this->unk_D98, this->unk_D80)) { - if (this->scheduleResult == 0x14) { + this->targetPos = gZeroVec3f; + if (SubS_TimePathing_Update(this->currentPath, &this->schPathProgress, &this->schPathElapsedTime, + this->waypointRemainingTime, this->schPathRemainingTime, &this->waypointIndex, knots, + &this->targetPos, this->timeSpeed)) { + if (this->scheduleResult == KAFEI_SCH_ENTERING_SAKONS_HIDEOUT) { CLEAR_WEEKEVENTREG(WEEKEVENTREG_58_80); this->player.actor.draw = NULL; - } else if (this->scheduleResult == 9) { - D_80A41D64 = 2; + } else if (this->scheduleResult == KAFEI_SCH_RUNNING_TO_TOWN) { + sKafeiRunToTownPhase = ENTEST3_RUN_TO_TOWN_END; } ret = true; } else { worldPos = this->player.actor.world.pos; - sp7C = this->unk_D98; - this->player.actor.world.rot.y = Math_Vec3f_Yaw(&worldPos, &sp7C); + nextTargetPos = this->targetPos; + this->player.actor.world.rot.y = Math_Vec3f_Yaw(&worldPos, &nextTargetPos); } if (play->transitionMode != TRANS_MODE_OFF) { - this->unk_DB4 = sp6C; - this->unk_DB0 = sp68; - this->unk_D98 = sp70; + this->schPathElapsedTime = tempElapsedTime; + this->waypointIndex = tempWaypointIndex; + this->targetPos = currentTargetPos; } dx = this->player.actor.world.pos.x - this->player.actor.prevPos.x; dy = this->player.actor.world.pos.z - this->player.actor.prevPos.z; - if (!Math_StepToF(&this->unk_D84, 1.0f, 0.1f)) { - this->player.actor.world.pos.x = this->player.actor.prevPos.x + (dx * this->unk_D84); - this->player.actor.world.pos.z = this->player.actor.prevPos.z + (dy * this->unk_D84); + if (!Math_StepToF(&this->waypointProgress, 1.0f, 0.1f)) { + this->player.actor.world.pos.x = this->player.actor.prevPos.x + (dx * this->waypointProgress); + this->player.actor.world.pos.z = this->player.actor.prevPos.z + (dy * this->waypointProgress); } - Math_Vec3f_Copy(&D_80A41D50, &this->player.actor.world.pos); + Math_Vec3f_Copy(&sKafeiCurrentPathTargetPos, &this->player.actor.world.pos); dx = this->player.actor.world.pos.x - this->player.actor.prevPos.x; dy = this->player.actor.world.pos.z - this->player.actor.prevPos.z; this->player.speedXZ = sqrtf(SQ(dx) + SQ(dy)); @@ -931,28 +1110,32 @@ s32 func_80A40230(EnTest3* this, PlayState* play) { sKafeiControlStickAngle = this->player.actor.world.rot.y; this->player.actor.world.pos.x = this->player.actor.prevPos.x; this->player.actor.world.pos.z = this->player.actor.prevPos.z; - if (!func_80A3F384(this, play)) { - D_80A41D48 = true; + if (!EnTest3_IsOpeningDoor(this, play)) { + sKafeiIsFollowingPath = true; } return ret; } -void func_80A40678(EnTest3* this, PlayState* play) { - struct_80A41828* sp3C; +void EnTest3_Action_FollowSchedule(EnTest3* this, PlayState* play) { + EnTest3ScheduleResultData* schResultData; ScheduleOutput scheduleOutput; - this->unk_D80 = ((this->scheduleResult == 20) || (this->scheduleResult == 10) || (this->scheduleResult == 9)) ? 3 - : Play_InCsMode(play) ? 0 - : R_TIME_SPEED + ((void)0, gSaveContext.save.timeSpeedOffset); + this->timeSpeed = + ((this->scheduleResult == KAFEI_SCH_ENTERING_SAKONS_HIDEOUT) || + (this->scheduleResult == KAFEI_SCH_HEARD_BELL_RING) || (this->scheduleResult == KAFEI_SCH_RUNNING_TO_TOWN)) + ? 3 + : Play_InCsMode(play) ? 0 + : R_TIME_SPEED + ((void)0, gSaveContext.save.timeSpeedOffset); if (Schedule_RunScript(play, sScheduleScript, &scheduleOutput)) { if (this->scheduleResult != scheduleOutput.result) { - sp3C = &D_80A41828[scheduleOutput.result]; - func_80A3F114(this, play); - if (sp3C->unk_0 != 4) { - CLEAR_WEEKEVENTREG(WEEKEVENTREG_51_04); + schResultData = &sKafeiScheduledResultData[scheduleOutput.result]; + EnTest3_EndCsAction(this, play); + if (schResultData->schActionIndex != KAFEI_SCH_ACTION_BELL_RUNG) { + CLEAR_WEEKEVENTREG(WEEKEVENTREG_HIT_LAUNDRY_POOL_BELL); } - if (!D_80A417E8[sp3C->unk_0].unk_0(this, play, sp3C, &scheduleOutput)) { + if (!sScheduledActions[schResultData->schActionIndex].processSchFunc(this, play, schResultData, + &scheduleOutput)) { return; } if (scheduleOutput.result == 6) { @@ -965,56 +1148,59 @@ void func_80A40678(EnTest3* this, PlayState* play) { scheduleOutput.result = 0; } this->scheduleResult = scheduleOutput.result; - sp3C = &D_80A41828[this->scheduleResult]; - D_80A417E8[sp3C->unk_0].unk_4(this, play); + schResultData = &sKafeiScheduledResultData[this->scheduleResult]; + sScheduledActions[schResultData->schActionIndex].handleSchFunc(this, play); } -void func_80A40824(EnTest3* this, PlayState* play) { - this->unk_D78 = &D_80A41854[0]; - func_80A3F73C(this, play); +// Apparently unused as Kafei normally follows a schedule, but this function sets him up as a generic speakable NPC +// with one line of dialogue. +void EnTest3_Action_Unused(EnTest3* this, PlayState* play) { + this->speakData = &sSpeakData[0]; + EnTest3_HandleSchedule_CanTalk(this, play); } -void func_80A4084C(EnTest3* this, PlayState* play) { +void EnTest3_Action_HandleTalk(EnTest3* this, PlayState* play) { if (Actor_TextboxIsClosing(&this->player.actor, play)) { - if ((this->unk_D78->unk_1 == 0) || !func_80A3E80C(this, play, this->unk_D78->unk_1 - 1)) { + if ((this->speakData->argument == 0) || + !EnTest3_TalkTriggersAction(this, play, this->speakData->argument - 1)) { if (KAFEI_GET_PARAM_1E0(&this->player.actor) == 0) { - func_80A3E7E0(this, func_80A40824); + EnTest3_SetMainAction(this, EnTest3_Action_Unused); } else { - func_80A3E7E0(this, func_80A40678); + EnTest3_SetMainAction(this, EnTest3_Action_FollowSchedule); } this->player.focusActor = NULL; } - } else if (func_80A3ED24(this, play)) { - func_80A3E7E0(this, func_80A40908); + } else if (EnTest3_NextTalkStateTriggersCutscene(this, play)) { + EnTest3_SetMainAction(this, EnTest3_Action_GivePendant); } } -void func_80A40908(EnTest3* this, PlayState* play) { +void EnTest3_Action_GivePendant(EnTest3* this, PlayState* play) { if (Actor_TalkOfferAccepted(&this->player.actor, &play->state)) { - func_80A3E7E0(this, func_80A4084C); + EnTest3_SetMainAction(this, EnTest3_Action_HandleTalk); this->player.focusActor = &GET_PLAYER(play)->actor; - SET_WEEKEVENTREG(WEEKEVENTREG_51_08); + SET_WEEKEVENTREG(WEEKEVENTREG_KAFEI_ENTRUSTED_LINK); Message_BombersNotebookQueueEvent(play, BOMBERS_NOTEBOOK_EVENT_RECEIVED_PENDANT_OF_MEMORIES); Message_BombersNotebookQueueEvent(play, BOMBERS_NOTEBOOK_EVENT_MET_KAFEI); } else { Actor_OfferTalkExchange(&this->player.actor, play, 9999.9f, 9999.9f, PLAYER_IA_MINUS1); - this->unk_D78 = &D_80A41854[6]; - this->player.actor.textId = this->unk_D78->textId; + this->speakData = &sSpeakData[6]; + this->player.actor.textId = this->speakData->textId; this->player.actor.flags |= (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY); } } -void func_80A409D4(EnTest3* this, PlayState* play) { +void EnTest3_UpdateControl(EnTest3* this, PlayState* play) { if ((play->actorCtx.flags & ACTORCTX_FLAG_5) || (play->actorCtx.flags & ACTORCTX_FLAG_4)) { play->actorCtx.flags &= ~ACTORCTX_FLAG_4; - func_80A3F0B0(this, play); + EnTest3_ReturnControlToLink(this, play); CutsceneManager_SetReturnCamera(CAM_ID_MAIN); } else { sKafeiControlInput = *CONTROLLER1(&play->state); } } -void EnTest3_EnablePeephole(EnTest3* this, PlayState* play) { +void EnTest3_PostTalk_EnablePeephole(EnTest3* this, PlayState* play) { SET_WEEKEVENTREG(WEEKEVENTREG_CAN_USE_CURIOSITY_SHOP_PEEPHOLE); } @@ -1029,7 +1215,7 @@ void EnTest3_Update(Actor* thisx, PlayState* play2) { play->actorCtx.flags &= ~ACTORCTX_FLAG_7; this->player.actor.draw = EnTest3_Draw; - D_80A41D48 = false; + sKafeiIsFollowingPath = false; this->player.actor.flags &= ~(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY); if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_506) && @@ -1040,22 +1226,22 @@ void EnTest3_Update(Actor* thisx, PlayState* play2) { } play->actorCtx.flags &= ~ACTORCTX_FLAG_4; } else if (this->player.actor.category == ACTORCAT_PLAYER) { - func_80A409D4(this, play); + EnTest3_UpdateControl(this, play); } else if (play->tryPlayerCsAction(play, &this->player, PLAYER_CSACTION_NONE)) { - if (this->scheduleResult >= 7) { + if (this->scheduleResult >= KAFEI_SCH_INSIDE_SAKONS_HIDEOUT) { Vec3f worldPos; Math_Vec3f_Copy(&worldPos, &this->player.actor.world.pos); - this->unk_D80 = 4; - func_80A40230(this, play); + this->timeSpeed = 4; + EnTest3_HandleSchedule_MoveToWaypoint(this, play); Math_Vec3f_Copy(&this->player.actor.world.pos, &worldPos); - D_80A41D48 = false; - this->unk_D84 = 0.0f; + sKafeiIsFollowingPath = false; + this->waypointProgress = 0.0f; } } else { sKafeiControlStickMagnitude = 0.0f; sKafeiControlStickAngle = this->player.actor.shape.rot.y; - this->unk_D94(this, play); + this->mainActionFunc(this, play); sKafeiControlInput.press.button = (sKafeiControlInput.rel.button ^ sKafeiControlInput.cur.button) & sKafeiControlInput.cur.button; @@ -1064,9 +1250,9 @@ void EnTest3_Update(Actor* thisx, PlayState* play2) { play->playerUpdate(&this->player, play, &sKafeiControlInput); - if (D_80A41D48) { - this->player.actor.world.pos.x = D_80A41D50.x; - this->player.actor.world.pos.z = D_80A41D50.z; + if (sKafeiIsFollowingPath) { + this->player.actor.world.pos.x = sKafeiCurrentPathTargetPos.x; + this->player.actor.world.pos.z = sKafeiCurrentPathTargetPos.z; this->player.speedXZ = 0.0f; } } @@ -1195,15 +1381,15 @@ void EnTest3_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList1, Gfx** dL if ((focusActor != NULL) && (focusActor->id == ACTOR_BG_IKNV_OBJ)) { Math_Vec3f_Copy(&this->player.actor.focus.pos, &focusActor->focus.pos); } else { - static Vec3f D_80A418CC = { 1100.0f, -700.0f, 0.0f }; + static Vec3f focusOffset = { 1100.0f, -700.0f, 0.0f }; - Matrix_MultVec3f(&D_80A418CC, &this->player.actor.focus.pos); + Matrix_MultVec3f(&focusOffset, &this->player.actor.focus.pos); } } else if (limbIndex == KAFEI_LIMB_TORSO) { - if (D_80A41D60 || CHECK_WEEKEVENTREG(WEEKEVENTREG_RECEIVED_PENDANT_OF_MEMORIES) || + if (sKafeiGavePendantToLink || CHECK_WEEKEVENTREG(WEEKEVENTREG_RECEIVED_PENDANT_OF_MEMORIES) || (INV_CONTENT(ITEM_PENDANT_OF_MEMORIES) == ITEM_PENDANT_OF_MEMORIES) || (this->player.getItemDrawIdPlusOne - 1 == GID_PENDANT_OF_MEMORIES)) { - D_80A41D60 = true; + sKafeiGavePendantToLink = true; } else { OPEN_DISPS(play->state.gfxCtx); |
