diff --git a/config/rel_slices.yml b/config/rel_slices.yml index ed713397..ca0fa774 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -757,6 +757,10 @@ ac_npc_curator.c: ac_npc_engineer.c: .text: [0x80552984, 0x80552B5C] .data: [0x806A61C8, 0x806A6208] +ac_npc_rcn_guide.c: + .text: [0x8056EED0, 0x8056FFF0] + .rodata: [0x806499C0, 0x806499E8] + .data: [0x806BEE20, 0x806BF028] ac_npc_rtc.c: .text: [0x80573044, 0x80574134] .rodata: [0x80649A08, 0x80649A40] diff --git a/include/ac_intro_demo.h b/include/ac_intro_demo.h index da49acbf..42a71c8a 100644 --- a/include/ac_intro_demo.h +++ b/include/ac_intro_demo.h @@ -40,7 +40,7 @@ struct actor_intro_demo_s { TRAIN1_ACTOR* train1_actor_p; ACTOR* station_master_actor_p; // TODO: correct type ACTOR* rcn_guide_actor_p; // TODO: correct type - int player_in_intro_demo; + int player_in_house; int player_intro_demo_state; int house_idx; int talk_flag; diff --git a/include/ac_npc.h b/include/ac_npc.h index 039bed33..7b1534b4 100644 --- a/include/ac_npc.h +++ b/include/ac_npc.h @@ -27,40 +27,40 @@ extern "C" { typedef struct ac_npc_clip_s aNPC_Clip_c; typedef struct npc_draw_data_s { - s16 model_bank; - s16 texture_bank; - u8 _04[0x68]; // TODO + s16 model_bank; + s16 texture_bank; + u8 _04[0x68]; // TODO } aNPC_draw_data_c; enum { - aNPC_ATTENTION_TYPE_NONE, - aNPC_ATTENTION_TYPE_ACTOR, - aNPC_ATTENTION_TYPE_POSITION, + aNPC_ATTENTION_TYPE_NONE, + aNPC_ATTENTION_TYPE_ACTOR, + aNPC_ATTENTION_TYPE_POSITION, - aNPC_ATTENTION_TYPE_NUM -}; - -enum { - aNPC_THINK_WAIT, - aNPC_THINK_WANDER, - aNPC_THINK_WANDER2, - aNPC_THINK_GO_HOME, - aNPC_THINK_INTO_HOUSE, - aNPC_THINK_LEAVE_HOUSE, - aNPC_THINK_IN_BLOCK, - aNPC_THINK_PITFALL, - aNPC_THINK_SLEEP, - aNPC_THINK_SPECIAL, - - aNPC_THINK_NUM + aNPC_ATTENTION_TYPE_NUM }; enum { - aNPC_THINK_TYPE_INIT, - aNPC_THINK_TYPE_CHK_INTERRUPT, - aNPC_THINK_TYPE_MAIN, + aNPC_THINK_WAIT, + aNPC_THINK_WANDER, + aNPC_THINK_WANDER2, + aNPC_THINK_GO_HOME, + aNPC_THINK_INTO_HOUSE, + aNPC_THINK_LEAVE_HOUSE, + aNPC_THINK_IN_BLOCK, + aNPC_THINK_PITFALL, + aNPC_THINK_SLEEP, + aNPC_THINK_SPECIAL, - aNPC_THINK_TYPE_NUM + aNPC_THINK_NUM +}; + +enum { + aNPC_THINK_TYPE_INIT, + aNPC_THINK_TYPE_CHK_INTERRUPT, + aNPC_THINK_TYPE_MAIN, + + aNPC_THINK_TYPE_NUM }; typedef void (*aNPC_TALK_REQUEST_PROC)(ACTOR*, GAME*); @@ -68,13 +68,13 @@ typedef int (*aNPC_TALK_INIT_PROC)(ACTOR*, GAME*); typedef int (*aNPC_TALK_END_CHECK_PROC)(ACTOR*, GAME*); typedef struct npc_ct_data_s { - mActor_proc move_proc; - mActor_proc draw_proc; - int _08; - aNPC_TALK_REQUEST_PROC talk_request_proc; - aNPC_TALK_INIT_PROC talk_init_proc; - aNPC_TALK_END_CHECK_PROC talk_end_check_proc; - int _18; + mActor_proc move_proc; + mActor_proc draw_proc; + int _08; + aNPC_TALK_REQUEST_PROC talk_request_proc; + aNPC_TALK_INIT_PROC talk_init_proc; + aNPC_TALK_END_CHECK_PROC talk_end_check_proc; + int _18; } aNPC_ct_data_c; typedef int (*aNPC_SETUP_ACTOR_PROC)(GAME_PLAY*, mActor_name_t, s8, int, s16, int, int, int, int); @@ -101,115 +101,152 @@ typedef int (*aNPC_CLIP_THINK_PROC)(NPC_ACTOR*, GAME_PLAY*, int, int); typedef int (*aNPC_FORCE_CALL_REQ_PROC)(NPC_ACTOR*, int); struct ac_npc_clip_s { - /* 0x000 */ aNPC_SETUP_ACTOR_PROC setupActor_proc; - /* 0x004 */ void* _004; - /* 0x008 */ aNPC_FREE_OVERLAY_AREA_PROC free_overlay_area_proc; - /* 0x00C */ aNPC_GET_ACTOR_AREA_PROC get_actor_area_proc; - /* 0x010 */ aNPC_FREE_ACTOR_AREA_PROC free_actor_area_proc; - /* 0x014 */ aNPC_DMA_DRAW_DATA_PROC dma_draw_data_proc; - /* 0x018 */ aNPC_SET_ATTENTION_REQUEST_PROC set_attention_request_proc; - /* 0x01C */ void* _01C[(0x0CC - 0x01C) / sizeof(void*)]; - /* 0x0CC */ aNPC_BIRTH_CHECK_PROC birth_check_proc; - /* 0x0D0 */ aNPC_CT_PROC ct_proc; - /* 0x0D4 */ aNPC_DT_PROC dt_proc; - /* 0x0D8 */ aNPC_SAVE_PROC save_proc; - /* 0x0DC */ aNPC_INIT_PROC init_proc; - /* 0x0E0 */ aNPC_MOVE_PROC move_proc; - /* 0x0E4 */ aNPC_MOVE_BEFORE_PROC move_before_proc; - /* 0x0E8 */ aNPC_MOVE_AFTER_PROC move_after_proc; - /* 0x0EC */ void* _0EC; - /* 0x0F0 */ void* _0F0; - /* 0x0F4 */ aNPC_DRAW_PROC draw_proc; - /* 0x0F8 */ aNPC_REBUILD_DMA_PROC rebuild_dma_proc; - /* 0x0FC */ void* _0FC[(0x114 - 0x0FC) / sizeof(void*)]; - /* 0x114 */ aNPC_ANIMATION_INIT_PROC animation_init_proc; - /* 0x118 */ aNPC_CHG_SCHEDULE_PROC chg_schedule_proc; - /* 0x11C */ void* _11C; - /* 0x120 */ aNPC_CLIP_THINK_PROC think_proc; - /* 0x124 */ aNPC_FORCE_CALL_REQ_PROC force_call_req_proc; - /* 0x128 */ void* _128; + /* 0x000 */ aNPC_SETUP_ACTOR_PROC setupActor_proc; + /* 0x004 */ void* _004; + /* 0x008 */ aNPC_FREE_OVERLAY_AREA_PROC free_overlay_area_proc; + /* 0x00C */ aNPC_GET_ACTOR_AREA_PROC get_actor_area_proc; + /* 0x010 */ aNPC_FREE_ACTOR_AREA_PROC free_actor_area_proc; + /* 0x014 */ aNPC_DMA_DRAW_DATA_PROC dma_draw_data_proc; + /* 0x018 */ aNPC_SET_ATTENTION_REQUEST_PROC set_attention_request_proc; + /* 0x01C */ void* _01C[(0x0CC - 0x01C) / sizeof(void*)]; + /* 0x0CC */ aNPC_BIRTH_CHECK_PROC birth_check_proc; + /* 0x0D0 */ aNPC_CT_PROC ct_proc; + /* 0x0D4 */ aNPC_DT_PROC dt_proc; + /* 0x0D8 */ aNPC_SAVE_PROC save_proc; + /* 0x0DC */ aNPC_INIT_PROC init_proc; + /* 0x0E0 */ aNPC_MOVE_PROC move_proc; + /* 0x0E4 */ aNPC_MOVE_BEFORE_PROC move_before_proc; + /* 0x0E8 */ aNPC_MOVE_AFTER_PROC move_after_proc; + /* 0x0EC */ void* _0EC; + /* 0x0F0 */ void* _0F0; + /* 0x0F4 */ aNPC_DRAW_PROC draw_proc; + /* 0x0F8 */ aNPC_REBUILD_DMA_PROC rebuild_dma_proc; + /* 0x0FC */ void* _0FC[(0x114 - 0x0FC) / sizeof(void*)]; + /* 0x114 */ aNPC_ANIMATION_INIT_PROC animation_init_proc; + /* 0x118 */ aNPC_CHG_SCHEDULE_PROC chg_schedule_proc; + /* 0x11C */ void* _11C; + /* 0x120 */ aNPC_CLIP_THINK_PROC think_proc; + /* 0x124 */ aNPC_FORCE_CALL_REQ_PROC force_call_req_proc; + /* 0x128 */ void* _128; }; typedef struct npc_info_s { - Animal_c* animal; - mNpc_NpcList_c* list; - mNPS_schedule_c* schedule; - mNpc_EventNpc_c* event; - mNpc_MaskNpc_c* mask; - mActor_name_t npc_name; + Animal_c* animal; + mNpc_NpcList_c* list; + mNPS_schedule_c* schedule; + mNpc_EventNpc_c* event; + mNpc_MaskNpc_c* mask; + mActor_name_t npc_name; } NpcActorInfo_c; typedef struct npc_animation_s { - cKF_SkeletonInfo_R_c keyframe; - s_xyz work[27]; - s_xyz morph[27]; - int _1B4; - s8 animation_id; + cKF_SkeletonInfo_R_c keyframe; + s_xyz work[27]; + s_xyz morph[27]; + int _1B4; + s8 animation_id; } aNPC_ANIMATION_c; /* TODO: draw data */ typedef struct npc_draw_info_s { - /* 0x000 */ int main_animation_frame; - /* 0x004 */ int _04; // TODO: figure out where this is set - /* 0x008 */ int main_animation_frame_changed; - /* 0x00C */ int _08; // TODO: figure out where this is set - /* 0x010 */ int _0C; // TODO: figure out where this is set - /* 0x014 */ aNPC_ANIMATION_c main_animation; - /* 0x1D0 */ aNPC_ANIMATION_c sub_animation0; - /* 0x38C */ aNPC_ANIMATION_c sub_animation1; - /* 0x548 */ u8 _548[0x580 - 0x548]; - /* 0x580 */ int animation_id; - /* 0x584 */ int texture_bank_idx; - /* 0x588 */ u8 _588[0x5B9 - 0x588]; - /* 0x5B9 */ u8 _5B9; - /* 0x5BA */ u8 _5BA; - /* 0x5BB */ u8 _5BB; - /* 0x5BC */ u8 _5BC; - /* 0x5BD */ u8 _5BD; - /* 0x5BE */ u8 _5BE; - /* 0x5BE */ u8 _5BF[0x5D0 - 0x5BF]; - /* 0x5D0 */ f32 animation_speed; - /* 0x5D4 */ u8 _5D4[0x630 - 0x5D4]; + /* 0x000 */ int main_animation_frame; + /* 0x004 */ int _04; // TODO: figure out where this is set + /* 0x008 */ int main_animation_frame_changed; + /* 0x00C */ int _08; // TODO: figure out where this is set + /* 0x010 */ int _0C; // TODO: figure out where this is set + /* 0x014 */ aNPC_ANIMATION_c main_animation; + /* 0x1D0 */ aNPC_ANIMATION_c sub_animation0; + /* 0x38C */ aNPC_ANIMATION_c sub_animation1; + /* 0x548 */ u8 _548[0x580 - 0x548]; + /* 0x580 */ int animation_id; + /* 0x584 */ int texture_bank_idx; + /* 0x588 */ u8 _588[0x5B9 - 0x588]; + /* 0x5B9 */ u8 _5B9; + /* 0x5BA */ u8 _5BA; + /* 0x5BB */ u8 _5BB; + /* 0x5BC */ u8 _5BC; + /* 0x5BD */ u8 _5BD; + /* 0x5BE */ u8 _5BE; + /* 0x5BE */ u8 _5BF[0x5D0 - 0x5BF]; + /* 0x5D0 */ f32 animation_speed; + /* 0x5D4 */ u8 _5D4[0x630 - 0x5D4]; } aNPC_draw_info_c; typedef void (*aNPC_THINK_PROC)(NPC_ACTOR*, GAME_PLAY*, int); #define aNPC_THINK_INTERRUPT_FRIENDSHIP (1 << 0) -#define aNPC_THINK_INTERRUPT_FATIGUE (1 << 1) -#define aNPC_THINK_INTERRUPT_OBSTANCE (1 << 2) -#define aNPC_THINK_INTERRUPT_ENTRANCE (1 << 3) +#define aNPC_THINK_INTERRUPT_FATIGUE (1 << 1) +#define aNPC_THINK_INTERRUPT_OBSTANCE (1 << 2) +#define aNPC_THINK_INTERRUPT_ENTRANCE (1 << 3) typedef struct npc_think_info_s { - int idx; - u8 end_flag; - u8 force_call_flag; - u16 force_call_timer; - int force_call_msg_no; - u8 force_call_camera_type; - aNPC_THINK_PROC think_proc; - u32 interrupt_flags; + int idx; + u8 end_flag; + u8 force_call_flag; + u16 force_call_timer; + int force_call_msg_no; + u8 force_call_camera_type; + aNPC_THINK_PROC think_proc; + u32 interrupt_flags; } aNPC_think_info_c; typedef void (*aNPC_SCHEDULE_PROC)(NPC_ACTOR*, GAME_PLAY*, int); typedef struct npc_schedule_info_s { - u8 type; - u8 state; - mNPS_schedule_c schedule; - aNPC_SCHEDULE_PROC schedule_proc; + u8 type; + u8 state; + mNPS_schedule_c schedule; + aNPC_SCHEDULE_PROC schedule_proc; } aNPC_schedule_info_c; enum { - aNPC_ACT_OBJ_NONE, - aNPC_ACT_OBJ_PLAYER, - aNPC_ACT_OBJ_ANY_NPC, - aNPC_ACT_OBJ_TARGET_NPC, - aNPC_ACT_OBJ_4, - aNPC_ACT_OBJ_5, - aNPC_ACT_OBJ_INSECT, - aNPC_ACT_OBJ_FISH, + aNPC_ACT_OBJ_DEFAULT, + aNPC_ACT_OBJ_PLAYER, + aNPC_ACT_OBJ_ANY_NPC, + aNPC_ACT_OBJ_TARGET_NPC, + aNPC_ACT_OBJ_4, + aNPC_ACT_OBJ_5, + aNPC_ACT_OBJ_INSECT, + aNPC_ACT_OBJ_FISH, - aNPC_ACT_OBJ_NUM + aNPC_ACT_OBJ_NUM +}; + +enum { + aNPC_ACT_TYPE_DEFAULT, + aNPC_ACT_TYPE_AVOID, + aNPC_ACT_TYPE_SEARCH, + aNPC_ACT_TYPE_TO_POINT, + + aNPC_ACT_TYPE_NUM +}; + +enum { + aNPC_ACT_WAIT, + aNPC_ACT_WALK, + aNPC_ACT_WALK2, + aNPC_ACT_TURN, + aNPC_ACT_TURN2, + aNPC_ACT_CHASE_INSECT, + aNPC_ACT_CHASE_INSECT2, + aNPC_ACT_GREETING, + aNPC_ACT_TALK, + aNPC_ACT_INTO_HOUSE, + aNPC_ACT_LEAVE_HOUSE, + aNPC_ACT_UMB_OPEN, + aNPC_ACT_UMB_CLOSE, + aNPC_ACT_ENSOU, + aNPC_ACT_TALK2, + aNPC_ACT_REACT_TOOL, + aNPC_ACT_CLAP, + aNPC_ACT_TRANS, + aNPC_ACT_GET, + aNPC_ACT_GET2, + aNPC_ACT_PITFALL, + aNPC_ACT_REVIVE, + aNPC_ACT_SPECIAL, + + aNPC_ACT_NUM }; typedef void (*aNPC_ACTION_PROC)(NPC_ACTOR*, GAME_PLAY*, int); @@ -217,174 +254,174 @@ typedef void (*aNPC_ACTION_PROC)(NPC_ACTOR*, GAME_PLAY*, int); #define aNPC_ACTION_END_STEP 0xFF typedef struct npc_action_s { - u8 priority; - u8 idx; - u8 step; - u8 type; - u8 prev_priority; - u8 prev_step; - s16 act_timer; - u8 feel; - u8 act_obj; - u16 act_obj_id; - s16 move_x; - s16 move_z; - aNPC_ACTION_PROC act_proc; + u8 priority; + u8 idx; + u8 step; + u8 type; + u8 prev_priority; + u8 prev_step; + s16 act_timer; + u8 feel; + u8 act_obj; + u16 act_obj_id; + s16 move_x; + s16 move_z; + aNPC_ACTION_PROC act_proc; } aNPC_action_c; typedef struct npc_request_s { - u8 act_priority; - u8 act_idx; - u8 act_type; - u16 act_args[6]; - u8 umb_flag; - u8 _11; - u8 head_priority; - u8 head_type; - ACTOR* head_target; - xyz_t head_pos; + u8 act_priority; + u8 act_idx; + u8 act_type; + u16 act_args[6]; + u8 umb_flag; + u8 _11; + u8 head_priority; + u8 head_type; + ACTOR* head_target; + xyz_t head_pos; } aNPC_request_c; -#define aNPC_COND_DEMO_SKIP_MOVE_RANGE_CHECK (1 << 0) /* 0x0001 */ -#define aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV (1 << 1) /* 0x0002 */ -#define aNPC_COND_DEMO_SKIP_MOVE_Y (1 << 2) /* 0x0004 */ -#define aNPC_COND_DEMO_SKIP_OBJ_COL_CHECK (1 << 3) /* 0x0008 */ -#define aNPC_COND_DEMO_SKIP_BGCHECK (1 << 4) /* 0x0010 */ -#define aNPC_COND_DEMO_SKIP_FORWARD_CHECK (1 << 5) /* 0x0020 */ -#define aNPC_COND_DEMO_SKIP_ITEM (1 << 6) /* 0x0040 */ -#define aNPC_COND_DEMO_SKIP_TALK_CHECK (1 << 7) /* 0x0080 */ -#define aNPC_COND_DEMO_SKIP_HEAD_LOOKAT (1 << 8) /* 0x0100 */ -#define aNPC_COND_DEMO_SKIP_ENTRANCE_CHECK (1 << 9) /* 0x0200 */ -#define aNPC_COND_DEMO_SKIP_KUTIPAKU (1 << 10) /* 0x0400 */ -#define aNPC_COND_DEMO_SKIP_FOOTSTEPS (1 << 11) /* 0x0800 */ -#define aNPC_COND_DEMO_SKIP_FEEL_CHECK (1 << 12) /* 0x1000 */ -#define aNPC_COND_DEMO_SKIP_LOVE_CHECK (1 << 13) /* 0x2000 */ -#define aNPC_COND_DEMO_SKIP_FOOTSTEPS_VFX (1 << 14) /* 0x4000 */ -#define aNPC_COND_DEMO_SKIP_UZAI_CHECK (1 << 15) /* 0x8000 */ +#define aNPC_COND_DEMO_SKIP_MOVE_RANGE_CHECK (1 << 0) /* 0x0001 */ +#define aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV (1 << 1) /* 0x0002 */ +#define aNPC_COND_DEMO_SKIP_MOVE_Y (1 << 2) /* 0x0004 */ +#define aNPC_COND_DEMO_SKIP_OBJ_COL_CHECK (1 << 3) /* 0x0008 */ +#define aNPC_COND_DEMO_SKIP_BGCHECK (1 << 4) /* 0x0010 */ +#define aNPC_COND_DEMO_SKIP_FORWARD_CHECK (1 << 5) /* 0x0020 */ +#define aNPC_COND_DEMO_SKIP_ITEM (1 << 6) /* 0x0040 */ +#define aNPC_COND_DEMO_SKIP_TALK_CHECK (1 << 7) /* 0x0080 */ +#define aNPC_COND_DEMO_SKIP_HEAD_LOOKAT (1 << 8) /* 0x0100 */ +#define aNPC_COND_DEMO_SKIP_ENTRANCE_CHECK (1 << 9) /* 0x0200 */ +#define aNPC_COND_DEMO_SKIP_KUTIPAKU (1 << 10) /* 0x0400 */ +#define aNPC_COND_DEMO_SKIP_FOOTSTEPS (1 << 11) /* 0x0800 */ +#define aNPC_COND_DEMO_SKIP_FEEL_CHECK (1 << 12) /* 0x1000 */ +#define aNPC_COND_DEMO_SKIP_LOVE_CHECK (1 << 13) /* 0x2000 */ +#define aNPC_COND_DEMO_SKIP_FOOTSTEPS_VFX (1 << 14) /* 0x4000 */ +#define aNPC_COND_DEMO_SKIP_UZAI_CHECK (1 << 15) /* 0x8000 */ typedef struct npc_condition_s { - u8 hide_flg; - u8 hide_request; - u8 action; - u8 talk_condition; - u8 greeting_flag; - u8 entrance_flag; - u16 fatigue; - int feel_tim; - int _0C; - u32 demo_flg; - u32 talk_demo_flg_save; - u32 trans_demo_flg_save; - u8 appear_flag; - u8 appear_rotation; - u8 pitfall_flag; - u32 actor_state_save; - int _24; - int _28; - int _2C; - s8* friendship; - int over_friendship; - mActor_name_t* under_fg_p; - int ut_x; - int ut_z; + u8 hide_flg; + u8 hide_request; + u8 action; + u8 talk_condition; + u8 greeting_flag; + u8 entrance_flag; + u16 fatigue; + int feel_tim; + int _0C; + u32 demo_flg; + u32 talk_demo_flg_save; + u32 trans_demo_flg_save; + u8 appear_flag; + u8 appear_rotation; + u8 pitfall_flag; + u32 actor_state_save; + int _24; + int _28; + int _2C; + s8* friendship; + int over_friendship; + mActor_name_t* under_fg_p; + int ut_x; + int ut_z; } aNPC_condition_info_c; typedef struct npc_uzai_s { - int step; - u8 tool; - u8 flag; - u8 cross; + int step; + u8 tool; + u8 flag; + u8 cross; } aNPC_uzai_c; typedef struct npc_hand_s { - u8 item_type; - u8 requested_item_type; - mActor_name_t item; - u8 after_mode; - u8 present_flag; - u8 umbrella_disabled_flag; - u8 umbrella_type; - ACTOR* item_actor_p; - ACTOR* prev_item_actor_p; - xyz_t pos; + u8 item_type; + u8 requested_item_type; + mActor_name_t item; + u8 after_mode; + u8 present_flag; + u8 umbrella_disabled_flag; + u8 umbrella_type; + ACTOR* item_actor_p; + ACTOR* prev_item_actor_p; + xyz_t pos; } aNPC_hand_c; typedef struct npc_head_s { - s16 angle_x; - s16 angle_y; - s16 angle_add_x; - s16 angle_add_y; - s16 _08; - u8 lock_flag; - u8 target_type; - ACTOR* target; - xyz_t pos; + s16 angle_x; + s16 angle_y; + s16 angle_add_x; + s16 angle_add_y; + s16 _08; + u8 lock_flag; + u8 target_type; + ACTOR* target; + xyz_t pos; } aNPC_head_c; enum { - aNPC_FOOT_LEFT, - aNPC_FOOT_RIGHT, + aNPC_FOOT_LEFT, + aNPC_FOOT_RIGHT, - aNPC_FOOT_NUM + aNPC_FOOT_NUM }; typedef struct npc_movement_s { - f32 max_speed; - f32 acceleration; - f32 deceleration; - f32 target_pos_x; - f32 target_pos_z; - f32 avoid_pos_x; - f32 avoid_pos_z; - s16 move_timer; - u8 avoid_direction; - u8 range_type; - f32 range_center_x; - f32 range_center_z; - f32 range_radius; - s16 mv_angl; - s16 mv_add_angl; - f32 arrival_area_radius; - ACTOR* target; - s8 movement_ut_x; - s8 movement_ut_z; - s16 body_angle; - u8 override_body_angle_flag; - u8 demo_move_timer; + f32 max_speed; + f32 acceleration; + f32 deceleration; + f32 target_pos_x; + f32 target_pos_z; + f32 avoid_pos_x; + f32 avoid_pos_z; + s16 move_timer; + u8 avoid_direction; + u8 range_type; + f32 range_center_x; + f32 range_center_z; + f32 range_radius; + s16 mv_angl; + s16 mv_add_angl; + f32 arrival_area_radius; + ACTOR* target; + s8 movement_ut_x; + s8 movement_ut_z; + s16 body_angle; + u8 override_body_angle_flag; + u8 demo_move_timer; } aNPC_movement_c; typedef struct npc_collision_s { - ClObjPipe_c pipe; - f32 BGcheck_radius; - u8 collision_flag; - u8 priority; - u8 turn_flag; - u16 _24; - s16 turn_angle; - f32 bg_rev_add; + ClObjPipe_c pipe; + f32 BGcheck_radius; + u8 collision_flag; + u8 priority; + u8 turn_flag; + u16 _24; + s16 turn_angle; + f32 bg_rev_add; } aNPC_collision_c; typedef struct npc_actor_talk_info_s { - aNPC_TALK_REQUEST_PROC talk_request_proc; - aNPC_TALK_INIT_PROC talk_init_proc; - aNPC_TALK_END_CHECK_PROC talk_end_check_proc; - u8 type; - u8 default_act; - u8 demo_code; - u8 turn; - s16 default_animation; - s16 default_turn_animation; - s16 melody_inst; - s16 npc_voice_id; - u8 feel; - u8 memory; - u8 kutipaku_timer; // frames of mouth movement animation + aNPC_TALK_REQUEST_PROC talk_request_proc; + aNPC_TALK_INIT_PROC talk_init_proc; + aNPC_TALK_END_CHECK_PROC talk_end_check_proc; + u8 type; + u8 default_act; + u8 demo_code; + u8 turn; + s16 default_animation; + s16 default_turn_animation; + s16 melody_inst; + s16 npc_voice_id; + u8 feel; + u8 memory; + u8 kutipaku_timer; // frames of mouth movement animation } aNPC_talk_info_c; typedef struct npc_accessory_s { - s16 type; - s16 pos_joint_idx; // might be better suited as base_joint_idx? - ACTOR* accessory; + s16 type; + s16 pos_joint_idx; // might be better suited as base_joint_idx? + ACTOR* accessory; } aNPC_accessory_c; /* Used for think, schedule, action, & talk */ @@ -392,66 +429,66 @@ typedef void (*aNPC_PROC)(NPC_ACTOR* npc_actorx, GAME_PLAY* play, int schedule_i typedef void (*aNPC_SUB_PROC)(NPC_ACTOR* npc_actorx, GAME_PLAY* play); enum { - aNPC_SCHEDULE_TYPE_FIELD, - aNPC_SCHEDULE_TYPE_IN_HOUSE, - aNPC_SCHEDULE_TYPE_SLEEP, - aNPC_SCHEDULE_TYPE_STAND, - aNPC_SCHEDULE_TYPE_WANDER, - aNPC_SCHEDULE_TYPE_WALK_WANDER, - aNPC_SCHEDULE_TYPE_SPECIAL, + aNPC_SCHEDULE_TYPE_FIELD, + aNPC_SCHEDULE_TYPE_IN_HOUSE, + aNPC_SCHEDULE_TYPE_SLEEP, + aNPC_SCHEDULE_TYPE_STAND, + aNPC_SCHEDULE_TYPE_WANDER, + aNPC_SCHEDULE_TYPE_WALK_WANDER, + aNPC_SCHEDULE_TYPE_SPECIAL, - aNPC_SCHEDULE_TYPE_NUM + aNPC_SCHEDULE_TYPE_NUM }; struct npc_actor_s { - ACTOR actor_class; - s_xyz _174; - NpcActorInfo_c npc_info; - aNPC_draw_info_c draw; - aNPC_think_info_c think; - aNPC_schedule_info_c schedule; - aNPC_action_c action; - aNPC_request_c request; - f32 eye_y; - aNPC_condition_info_c condition_info; - aNPC_uzai_c uzai; - aNPC_hand_c left_hand; - aNPC_hand_c right_hand; - aNPC_head_c head; - xyz_t feet[aNPC_FOOT_NUM]; - mActor_proc move_proc; - mActor_proc draw_proc; - ACTOR* palActor; - int palActorIgnoreTimer; - aNPC_movement_c movement; - aNPC_collision_c collision; - aNPC_talk_info_c talk_info; - aNPC_accessory_c accessory; - int act_react_tool_timer; - int _98C; - int _990; + ACTOR actor_class; + s_xyz _174; + NpcActorInfo_c npc_info; + aNPC_draw_info_c draw; + aNPC_think_info_c think; + aNPC_schedule_info_c schedule; + aNPC_action_c action; + aNPC_request_c request; + f32 eye_y; + aNPC_condition_info_c condition_info; + aNPC_uzai_c uzai; + aNPC_hand_c left_hand; + aNPC_hand_c right_hand; + aNPC_head_c head; + xyz_t feet[aNPC_FOOT_NUM]; + mActor_proc move_proc; + mActor_proc draw_proc; + ACTOR* palActor; + int palActorIgnoreTimer; + aNPC_movement_c movement; + aNPC_collision_c collision; + aNPC_talk_info_c talk_info; + aNPC_accessory_c accessory; + int act_react_tool_timer; + int _98C; + int _990; }; typedef struct npc_control_cloth_s { - u8 dma_flag; - u8 init_flag; - s16 _02; - mActor_name_t cloth_item; - u8 in_use_count; - Object_Bank_c texture_bank; - Object_Bank_c palette_bank; + u8 dma_flag; + u8 init_flag; + s16 _02; + mActor_name_t cloth_item; + u8 in_use_count; + Object_Bank_c texture_bank; + Object_Bank_c palette_bank; } aNPC_cloth_c; typedef struct npc_control_actor_s { - ACTOR* actor_class; - aNPC_cloth_c cloth[10]; - u8 _8F4[0x9D8 - 0x8F4]; // TODO + ACTOR* actor_class; + aNPC_cloth_c cloth[10]; + u8 _8F4[0x9D8 - 0x8F4]; // TODO } NPC_CONTROL_ACTOR; -typedef struct npc_destruct_table_proc{ +typedef struct npc_destruct_table_proc { aNPC_SUB_PROC unk0; aNPC_SUB_PROC unk4; -}NPC_DT_PROCS; +} NPC_DT_PROCS; extern ACTOR_PROFILE Npc_Profile; @@ -460,4 +497,3 @@ extern ACTOR_PROFILE Npc_Profile; #endif #endif - diff --git a/include/ac_npc_rcn_guide.h b/include/ac_npc_rcn_guide.h index 3cd95614..97d863d7 100644 --- a/include/ac_npc_rcn_guide.h +++ b/include/ac_npc_rcn_guide.h @@ -3,11 +3,32 @@ #include "types.h" #include "m_actor.h" +#include "ac_npc.h" #ifdef __cplusplus extern "C" { #endif +typedef struct npc_rcn_guide_s NPC_RCN_GUIDE_ACTOR; + +typedef void (*aNRG_THINK_PROC)(NPC_RCN_GUIDE_ACTOR*, GAME_PLAY*); +typedef void (*aNRG_TALK_PROC)(NPC_RCN_GUIDE_ACTOR*, GAME_PLAY*); + +/* sizeof(NPC_RCN_GUIDE_ACTOR) == 0x9B4 */ +struct npc_rcn_guide_s { + /* 0x000 */ NPC_ACTOR npc_class; + /* 0x994 */ int think_idx; + /* 0x998 */ int next_think_idx; + /* 0x99C */ aNRG_THINK_PROC think_proc; + /* 0x9A0 */ int talk_idx; + /* 0x9A4 */ aNRG_TALK_PROC talk_proc; + /* 0x9A8 */ u8 talk_proc_idx; + /* 0x9A9 */ u8 path; + /* 0x9AA */ u8 melody_copy; + /* 0x9AC */ int shop_bx; + /* 0x9B0 */ int shop_bz; +}; + extern ACTOR_PROFILE Npc_Rcn_Guide_Profile; #ifdef __cplusplus @@ -15,4 +36,3 @@ extern ACTOR_PROFILE Npc_Rcn_Guide_Profile; #endif #endif - diff --git a/include/m_msg.h b/include/m_msg.h index 0a87615a..8a0b065d 100644 --- a/include/m_msg.h +++ b/include/m_msg.h @@ -362,8 +362,13 @@ extern void mMsg_sound_unset_voice_silent(mMsg_Window_c* msg_p, int update_mode) #define mMsg_CHECK_MAINNORMALCONTINUE() mMsg_Check_MainNormalContinue(mMsg_Get_base_window_p()) #define mMsg_CHECK_MAINDISAPPEAR() mMsg_Check_MainDisappear(mMsg_Get_base_window_p()) #define mMsg_CHECK_MAINHIDE() mMsg_Check_MainHide(mMsg_Get_base_window_p()) +#define mMsg_CHECK_MAIN_WAIT() mMsg_Check_main_wait(mMsg_Get_base_window_p()) #define mMsg_REQUEST_MAIN_DISAPPEAR() mMsg_request_main_disappear(mMsg_Get_base_window_p()) +#define mMsg_REQUEST_MAIN_DISAPPEAR_WAIT_TYPE1() mMsg_request_main_disappear_wait_type1(mMsg_Get_base_window_p()) +#define mMsg_REQUEST_MAIN_APPEAR() mMsg_request_main_appear(mMsg_Get_base_window_p()) +#define mMsg_REQUEST_MAIN_APPEAR_WAIT_TYPE1() mMsg_request_main_appear_wait_type1(mMsg_Get_base_window_p()); +#define mMsg_REQUEST_MAIN_APPEAR_WAIT_TYPE2() mMsg_request_main_appear_wait_type2(mMsg_Get_base_window_p()); #ifdef __cplusplus } diff --git a/include/m_player.h b/include/m_player.h index 1cb16ff9..fe5e86b3 100644 --- a/include/m_player.h +++ b/include/m_player.h @@ -1267,7 +1267,33 @@ struct player_actor_s { /* 0x105C */ xyz_t left_hand_pos; /* 0x1068 */ MtxF right_hand_mtx; /* 0x10A8 */ MtxF left_hand_mtx; - /* 0x10E8 */ u8 _10E8[0x1270 - 0x10E8]; + /* 0x10E8 */ u8 _10E8[0x11FC - 0x10E8]; // TODO + /* 0x11FC */ int crash_snowball_for_wade; + /* 0x1200 */ xyz_t snowball_dist; + /* 0x120C */ int wade_request_flag; + /* 0x1210 */ u16 cancel_wade_timer; + /* 0x1214 */ int cancel_wade_flag; + /* 0x1218 */ f32 geton_boat_wade; + /* 0x121C */ u16 frame_timer; + /* 0x121E */ s8 bee_chase_bgm_flag; + /* 0x121F */ s8 status_for_bee; + /* 0x1220 */ void* angle_force_speak_label; + /* 0x1224 */ int player_sunburn_rankup; + /* 0x1228 */ int player_sunburn_rankdown; + /* 0x122C */ u8 radio_exercise_command_ring_buffer[8]; + /* 0x1234 */ s8 radio_exercise_ring_buffer_cmd_num; + /* 0x1238 */ int radio_exercise_command_ring_buffer_index; + /* 0x123C */ int radio_exercise_continue_cmd_idx; + /* 0x1240 */ f32 radio_exercise_cmd_timer; + /* 0x1244 */ int old_sound_frame_counter; + /* 0x1248 */ s16 boat_angleZ; + /* 0x124C */ int change_color_request; + /* 0x1250 */ int change_color_flag; + /* 0x1254 */ f32 change_color_timer; + /* 0x1258 */ int change_color_rgb[3]; + /* 0x1264 */ int change_color_near; + /* 0x1268 */ int change_color_far; + /* 0x126C */ int refuse_pickup_knife_fork_flag; /* 0x1270 */ int (*request_main_invade_all_proc)(GAME*, int); /* 0x1274 */ int (*request_main_refuse_all_proc)(GAME*, int); /* 0x1278 */ int (*request_main_return_demo_all_proc)(GAME*, int, f32, int); diff --git a/include/m_player_lib.h b/include/m_player_lib.h index 2b884b06..00fe9ebc 100644 --- a/include/m_player_lib.h +++ b/include/m_player_lib.h @@ -63,7 +63,7 @@ extern int mPlib_check_player_outdoor_start(GAME* game); extern void mPlib_Set_change_color_request(); extern int mPlib_check_player_open_umbrella(GAME_PLAY* play); extern int mPlib_Check_UKI_COMEBACK_STATUS(); -extern int mPlib_check_player_actor_main_index_OutDoorMove(GAME_PLAY* play); +extern int mPlib_check_player_actor_main_index_OutDoorMove(GAME* game); extern int mPlib_request_main_close_furniture_type1(GAME* game); extern int mPlib_request_main_shock_type1(GAME* game, f32 time, s16 angle_y, int axe_swing); extern int mPlib_request_main_hold_type1(GAME* game, int ftr_no, int player_direct, const xyz_t* player_pos); @@ -100,6 +100,7 @@ extern int mPlib_Check_scoop_after(GAME* game, xyz_t* pos, mActor_name_t* item, extern int mPlib_request_main_demo_standing_train_type1(GAME* game); extern void mPlib_Set_unable_wade(int unable); extern int mPlib_request_main_demo_getoff_train_type1(GAME* game); +extern int mPlib_check_player_actor_main_index_OutDoorMove2(GAME* game); extern mPlayer_change_data_from_submenu_c* mPlib_Get_change_data_from_submenu_p(); diff --git a/src/ac_br_shop_move.c_inc b/src/ac_br_shop_move.c_inc index 3a21815c..7aa57ac4 100644 --- a/src/ac_br_shop_move.c_inc +++ b/src/ac_br_shop_move.c_inc @@ -37,9 +37,9 @@ static void change_FGUnit(ACTOR* actor, int type) { static void aBRS_set_bgOffset(STRUCTURE_ACTOR* windmill, int idx) { static mCoBG_OffsetTable_c height_table_ct[9] = { - {0x64, 9, 9, 9, 9, 9, 0}, {0x64, 9, 9, 9, 9, 9, 0}, {0x64, 9, 9, 9, 9, 9, 0}, - {0x64, 9, 9, 9, 9, 9, 0}, {0x64, 9, 9, 9, 9, 9, 0}, {0x64, 9, 9, 9, 9, 9, 0}, - {0x64, 9, 9, 9, 9, 9, 0}, {0x64, 9, 9, 9, 9, 9, 0}, {0x64, 9, 9, 9, 9, 9, 0}, + { 0x64, 9, 9, 9, 9, 9, 0 }, { 0x64, 9, 9, 9, 9, 9, 0 }, { 0x64, 9, 9, 9, 9, 9, 0 }, + { 0x64, 9, 9, 9, 9, 9, 0 }, { 0x64, 9, 9, 9, 9, 9, 0 }, { 0x64, 9, 9, 9, 9, 9, 0 }, + { 0x64, 9, 9, 9, 9, 9, 0 }, { 0x64, 9, 9, 9, 9, 9, 0 }, { 0x64, 9, 9, 9, 9, 9, 0 }, }; static mCoBG_OffsetTable_c* height_table[2] = { @@ -182,7 +182,7 @@ static void aBRS_open_wait(STRUCTURE_ACTOR* actor, GAME_PLAY* play) { if (actor == GET_PLAYER_ACTOR_NOW()->get_door_label_proc(gamePT)) { aBRS_rewrite_out_data(&actor->actor_class, play); goto_other_scene(play, &aBRS_br_shop_door_data, 1); - } else if (mPlib_check_player_actor_main_index_OutDoorMove(play) == 0) { + } else if (mPlib_check_player_actor_main_index_OutDoorMove(&play->game) == 0) { if (aBRS_check_player(&actor->actor_class, play) == 0) { if (aBRS_open_check(&actor->actor_class) != 2) { aBRS_setup_action(actor, 2); diff --git a/src/ac_buggy_move.c_inc b/src/ac_buggy_move.c_inc index ad2a442c..150d291e 100644 --- a/src/ac_buggy_move.c_inc +++ b/src/ac_buggy_move.c_inc @@ -132,7 +132,8 @@ static int aBGY_check_player2(GAME_PLAY* play) { y = player->actor_class.world.angle.y; res = 0; - if ((y > DEG2SHORT_ANGLE2(135.0f)) && (y < DEG2SHORT_ANGLE2(225.0f)) && (player->actor_class.speed > 0.0f)) { // 0x6000 && 0xA000 + if ((y > DEG2SHORT_ANGLE2(135.0f)) && (y < DEG2SHORT_ANGLE2(225.0f)) && + (player->actor_class.speed > 0.0f)) { // 0x6000 && 0xA000 res = 1; } @@ -230,7 +231,7 @@ static void aBGY_open_wait(STRUCTURE_ACTOR* buggy, GAME_PLAY* play) { return; } - if (mPlib_check_player_actor_main_index_OutDoorMove(play) != FALSE) { + if (mPlib_check_player_actor_main_index_OutDoorMove(&play->game) != FALSE) { return; } @@ -264,12 +265,7 @@ static void aBGY_open_door(STRUCTURE_ACTOR* buggy, GAME_PLAY* play) { } static void aBGY_setup_action(STRUCTURE_ACTOR* buggy, int action) { - static aSTR_MOVE_PROC process[] = { - &aBGY_close_wait, - &aBGY_open_wait, - &aBGY_close_door, - &aBGY_open_door - }; + static aSTR_MOVE_PROC process[] = { &aBGY_close_wait, &aBGY_open_wait, &aBGY_close_door, &aBGY_open_door }; static cKF_Animation_R_c* animation[] = { &cKF_ba_r_obj_s_uranai, &cKF_ba_r_obj_w_uranai }; static f32 start_idx[] = { 1.0f, 17.0f, 17.0f, 1.0f }; @@ -314,7 +310,7 @@ static void aBGY_actor_move(ACTOR* actor, GAME* game) { (mDemo_Check(mDemo_TYPE_SCROLL3, &player->actor_class) == FALSE) && ((bx1 != bx2) || (bz1 != bz2))) { Actor_delete(actor); } else { - + buggy->keyframe_state = cKF_SkeletonInfo_R_play(&buggy->keyframe); buggy->action_proc(buggy, play); diff --git a/src/ac_my_house_move.c_inc b/src/ac_my_house_move.c_inc index 73d0fded..c72d921e 100644 --- a/src/ac_my_house_move.c_inc +++ b/src/ac_my_house_move.c_inc @@ -205,7 +205,7 @@ static int aMHS_check_player_in_intro_demo(STRUCTURE_ACTOR* my_house, GAME_PLAY* return 0; } - if (my_house->arg3_f == TRUE && intro_demo->player_in_intro_demo == TRUE) { + if (my_house->arg3_f == TRUE && intro_demo->player_in_house == TRUE) { return 1; } @@ -405,7 +405,7 @@ static void aMHS_open_door(STRUCTURE_ACTOR* my_house, GAME_PLAY* play) { if (demo_class != NULL) { intro_demo = (INTRO_DEMO_ACTOR*)demo_class; - intro_demo->player_in_intro_demo = FALSE; + intro_demo->player_in_house = FALSE; } } diff --git a/src/ac_npc_rcn_guide.c b/src/ac_npc_rcn_guide.c new file mode 100644 index 00000000..34f1eaf4 --- /dev/null +++ b/src/ac_npc_rcn_guide.c @@ -0,0 +1,161 @@ +#include "ac_npc_rcn_guide.h" + +#include "m_play.h" +#include "m_name_table.h" +#include "libultra/libultra.h" +#include "m_common_data.h" +#include "m_player_lib.h" +#include "m_bgm.h" +#include "m_msg.h" +#include "m_font.h" +#include "m_house.h" +#include "ac_intro_demo.h" + +/* sizeof(aNRG_talk_data_c) == 0x0C */ +typedef struct rcn_guide_talk_data_s { + /* 0x00 */ int msg_no; + /* 0x04 */ u8 turn_flag; + /* 0x05 */ u8 camera_type; + /* 0x06 */ u8 melody_flag; + /* 0x08 */ aNRG_TALK_PROC talk_proc; +} aNRG_talk_data_c; + +enum { + aNRC_THINK_CALL, + aNRC_THINK_APPROACH, + aNRG_THINK_INTRODUCE, + aNRC_THINK_TURN, + aNRC_THINK_TAKE_WITH, + aNRC_THINK_EXPLAIN, + aNRC_THINK_DECIDE_HOUSE_WAIT, + aNRC_THINK_STOP_WADE, + aNRC_THINK_BEFORE_OPEN_DOOR_TALK, + aNRC_THINK_BEFORE_OPEN_DOOR_TALK2, + aNRC_THINK_ENTER_WAIT, + aNRC_THINK_RESTART_WAIT, + aNRC_THINK_RESTART_TALK, + aNRC_THINK_DECIDE_HOUSE, + aNRC_THINK_EXIT_TURN, + aNRC_THINK_EXIT, + aNRC_THINK_WAIT, + + aNRC_THINK_NUM +}; + +enum { + aNRG_FORCE_TALK_CALL, + aNRG_FORCE_TALK_INTRODUCE, + aNRG_FORCE_TALK_EXPLAIN, + aNRG_FORCE_TALK_STOP_WADE, + aNRG_FORCE_TALK_BEFORE_OPEN_DOOR_TALK, + aNRG_FORCE_TALK_BEFORE_OPEN_DOOR2_TALK, + aNRG_FORCE_TALK_HOUSE_TAKEN, + aNRG_FORCE_TALK_HOUSE_VACANT, + + aNRG_FORCE_TALK_NUM +}; + +enum { + aNRG_NORM_TALK_DECIDE_HOUSE, + + aNRG_NORM_TALK_NUM +}; + +static void aNRG_actor_ct(ACTOR* actorx, GAME* game); +static void aNRG_actor_save(ACTOR* actorx, GAME* game); +static void aNRG_actor_dt(ACTOR* actorx, GAME* game); +static void aNRG_actor_init(ACTOR* actorx, GAME* game); +static void aNRG_actor_draw(ACTOR* actorx, GAME* game); +static void aNRG_actor_move(ACTOR* actorx, GAME* game); + +// clang-format off +ACTOR_PROFILE Npc_Rcn_Guide_Profile = { + mAc_PROFILE_NPC_RCN_GUIDE, + ACTOR_PART_NPC, + ACTOR_STATE_CAN_MOVE_IN_DEMO_SCENES | ACTOR_STATE_NO_MOVE_WHILE_CULLED, + SP_NPC_RCN_GUIDE, + ACTOR_OBJ_BANK_KEEP, + sizeof(NPC_RCN_GUIDE_ACTOR), + &aNRG_actor_ct, + &aNRG_actor_dt, + &aNRG_actor_init, + mActor_NONE_PROC1, + &aNRG_actor_save, +}; +// clang-format on + +static void aNRG_force_talk_request(ACTOR* actorx, GAME* game); +static int aNRG_talk_init(ACTOR* actorx, GAME* game); +static int aNRG_talk_end_chk(ACTOR* actorx, GAME* game); + +static void aNRG_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* game, int sched_idx); +static void aNRG_setup_think_proc(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play, int think_idx); + +static void aNRG_actor_ct(ACTOR* actorx, GAME* game) { + // clang-format off + static aNPC_ct_data_c ct_data = { + &aNRG_actor_move, + &aNRG_actor_draw, + 5, + &aNRG_force_talk_request, + &aNRG_talk_init, + &aNRG_talk_end_chk, + 0, + }; + // clang-format on + + NPC_RCN_GUIDE_ACTOR* rcn_guide = (NPC_RCN_GUIDE_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + PLAYER_ACTOR* player; + s16 angle_y; + + if (Common_Get(clip).npc_clip->birth_check_proc(actorx, &play->game) == TRUE) { + rcn_guide->npc_class.schedule.schedule_proc = &aNRG_schedule_proc; + Common_Get(clip).npc_clip->ct_proc(actorx, &play->game, &ct_data); + rcn_guide->npc_class.collision.priority = 2; + rcn_guide->melody_copy = rcn_guide->npc_class.talk_info.melody_inst; + + /* Set shop acre */ + mFI_BlockKind2BkNum(&rcn_guide->shop_bx, &rcn_guide->shop_bz, mRF_BLOCKKIND_SHOP); + + rcn_guide->npc_class.draw.main_animation.keyframe.morph_counter = 0.0f; + rcn_guide->npc_class.actor_class.status_data.weight = 255; + + player = GET_PLAYER_ACTOR(play); + if (player != NULL) { + angle_y = search_position_angleY(&rcn_guide->npc_class.actor_class.world.position, + &player->actor_class.world.position); + } else { + angle_y = 0; + } + + rcn_guide->npc_class.actor_class.shape_info.rotation.y = angle_y; + rcn_guide->npc_class.actor_class.world.angle.y = angle_y; + } +} + +static void aNRG_actor_save(ACTOR* actorx, GAME* game) { + Common_Get(clip).npc_clip->save_proc(actorx, game); +} + +static void aNRG_actor_dt(ACTOR* actorx, GAME* game) { + NPC_RCN_GUIDE_ACTOR* rcn_guide = (NPC_RCN_GUIDE_ACTOR*)actorx; + + if (rcn_guide->think_idx == 16) { + mBGMPsComp_delete_ps_demo(BGM_INTRO_STATION, 0x168); + } + + Common_Get(clip).npc_clip->dt_proc(actorx, game); +} + +static void aNRG_actor_init(ACTOR* actorx, GAME* game) { + Common_Get(clip).npc_clip->init_proc(actorx, game); +} + +static void aNRG_actor_draw(ACTOR* actorx, GAME* game) { + Common_Get(clip).npc_clip->draw_proc(actorx, game); +} + +#include "../src/ac_npc_rcn_guide_move.c_inc" +#include "../src/ac_npc_rcn_guide_talk.c_inc" +#include "../src/ac_npc_rcn_guide_schedule.c_inc" diff --git a/src/ac_npc_rcn_guide_move.c_inc b/src/ac_npc_rcn_guide_move.c_inc new file mode 100644 index 00000000..06812005 --- /dev/null +++ b/src/ac_npc_rcn_guide_move.c_inc @@ -0,0 +1,39 @@ +static int aNRG_set_request_act(NPC_RCN_GUIDE_ACTOR* rcn_guide, u8 act_prio, u8 act_idx, u8 act_type, u16 obj, int x, + int z) { + u16 args[6]; + int res = FALSE; + + if (act_prio >= rcn_guide->npc_class.request.act_priority) { + bzero(args, sizeof(args)); + args[0] = obj; + args[2] = x; + args[3] = z; + rcn_guide->npc_class.request.act_priority = act_prio; + rcn_guide->npc_class.request.act_idx = act_idx; + rcn_guide->npc_class.request.act_type = act_type; + mem_copy((u8*)rcn_guide->npc_class.request.act_args, (u8*)args, sizeof(args)); + res = TRUE; + } + + return res; +} + +static void aNRG_set_house_master_name(int house_idx) { + mMsg_SET_FREE_STR(mMsg_FREE_STR0, Save_Get(private[mHS_get_pl_no(house_idx)]).player_ID.player_name, + PLAYER_NAME_LEN); +} + +static void aNRG_set_shop_address(NPC_RCN_GUIDE_ACTOR* rcn_guide) { + static u8 choume_str[] = { 'Q', 'A', 'B', 'C', 'D', 'E', 'F' }; + u8 str[1]; + + /* Set the row (Z) string */ + mMsg_SET_FREE_STR(mMsg_FREE_STR1, &choume_str[rcn_guide->shop_bz], 1); + /* Set the column (X) string */ + mFont_UnintToString(str, sizeof(str), rcn_guide->shop_bx, sizeof(str), TRUE, FALSE, TRUE); + mMsg_SET_FREE_STR(mMsg_FREE_STR2, str, sizeof(str)); +} + +static void aNRG_actor_move(ACTOR* actorx, GAME* game) { + Common_Get(clip).npc_clip->move_proc(actorx, game); +} diff --git a/src/ac_npc_rcn_guide_schedule.c_inc b/src/ac_npc_rcn_guide_schedule.c_inc new file mode 100644 index 00000000..fd4963e1 --- /dev/null +++ b/src/ac_npc_rcn_guide_schedule.c_inc @@ -0,0 +1,406 @@ +typedef void (*aNRG_THINK_INIT_PROC)(NPC_RCN_GUIDE_ACTOR*, GAME_PLAY*); + +typedef struct npc_rcn_guide_setup_think_s { + aNRG_THINK_PROC think_proc; + aNRG_THINK_INIT_PROC think_init_proc; + aNPC_TALK_REQUEST_PROC talk_request_proc; + u8 talk_idx; + u8 next_think_idx; +} aNRG_setup_think_c; + +static void aNRG_approach(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) { + if (rcn_guide->npc_class.action.step == aNPC_ACTION_END_STEP && rcn_guide->npc_class.action.idx == 2) { + aNRG_setup_think_proc(rcn_guide, play, aNRG_THINK_INTRODUCE); + } +} + +static void aNRG_turn(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) { + if (rcn_guide->npc_class.action.step == aNPC_ACTION_END_STEP && rcn_guide->npc_class.action.idx == 3) { + aNRG_setup_think_proc(rcn_guide, play, rcn_guide->next_think_idx); + } +} + +static void aNRG_take_with(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) { + if (rcn_guide->npc_class.action.step == aNPC_ACTION_END_STEP && rcn_guide->npc_class.action.idx == 2) { + int path = rcn_guide->path; + + if (path >= 1) { + aNRG_setup_think_proc(rcn_guide, play, aNRC_THINK_EXPLAIN); + } else { + aNRG_set_request_act(rcn_guide, 4, aNPC_ACT_WALK2, aNPC_ACT_TYPE_TO_POINT, aNPC_ACT_OBJ_DEFAULT, 2240, + 1500); + path++; + } + + rcn_guide->path = path; + } +} + +static void aNRG_decide_house_wait(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) { + int next_think_idx = -1; + + if (GET_PLAYER_ACTOR_NOW()->cancel_wade_flag) { + next_think_idx = 7; + } else if (Common_Get(clip).demo_clip != NULL && Common_Get(clip).demo_clip->type == mDemo_CLIP_TYPE_INTRO_DEMO) { + ACTOR* demo_actor = (ACTOR*)Common_Get(clip).demo_clip->demo_class; + + if (demo_actor != NULL) { + INTRO_DEMO_ACTOR* intro_demo = (INTRO_DEMO_ACTOR*)demo_actor; + + switch (intro_demo->player_intro_demo_state) { + case 1: + next_think_idx = aNRC_THINK_BEFORE_OPEN_DOOR_TALK; + break; + case 2: + next_think_idx = aNRC_THINK_BEFORE_OPEN_DOOR_TALK2; + break; + } + } + } + + if (next_think_idx >= 0) { + aNRG_setup_think_proc(rcn_guide, play, next_think_idx); + } +} + +static void aNRG_enter_wait(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) { + if (Common_Get(clip).demo_clip != NULL && Common_Get(clip).demo_clip->type == mDemo_CLIP_TYPE_INTRO_DEMO) { + ACTOR* demo_actor = (ACTOR*)Common_Get(clip).demo_clip->demo_class; + + if (demo_actor != NULL) { + INTRO_DEMO_ACTOR* intro_demo = (INTRO_DEMO_ACTOR*)demo_actor; + + intro_demo->player_in_house = TRUE; + aNRG_setup_think_proc(rcn_guide, play, aNRC_THINK_WAIT); + } + } +} + +static void aNRG_exit(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) { + static s16 moveX[] = { 2240, 2240, 2240, 2240 }; + static s16 moveZ[] = { 1900, 1980, 1300, 1220 }; + + if (rcn_guide->npc_class.action.step == aNPC_ACTION_END_STEP) { + f32 posZ = rcn_guide->npc_class.actor_class.world.position.z; + int idx; + + if (posZ < 1540.0f) { + if (posZ <= 1220.0f) { + idx = -1; + } else if (posZ <= 1300.0f) { + idx = 3; + } else { + idx = 2; + } + } else { + if (posZ >= 1980.0f) { + idx = -1; + } else if (posZ >= 1900.0f) { + idx = 1; + } else { + idx = 0; + } + } + + if (idx == -1) { + if (Common_Get(clip).demo_clip != NULL && Common_Get(clip).demo_clip->type == mDemo_CLIP_TYPE_INTRO_DEMO) { + ACTOR* demo_actor = (ACTOR*)Common_Get(clip).demo_clip->demo_class; + + if (demo_actor != NULL) { + INTRO_DEMO_ACTOR* intro_demo = (INTRO_DEMO_ACTOR*)demo_actor; + + intro_demo->rcn_guide_actor_p = NULL; + Actor_delete(&rcn_guide->npc_class.actor_class); + play->submenu.disable_start_btn_flag = FALSE; + } + } + } else { + aNRG_set_request_act(rcn_guide, 4, aNPC_ACT_WALK2, aNPC_ACT_TYPE_TO_POINT, aNPC_ACT_OBJ_DEFAULT, moveX[idx], + moveZ[idx]); + } + } +} + +static void aNRG_restart_wait(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) { + int think_idx; + + if (mPlib_check_player_actor_main_index_OutDoorMove2(&play->game) == FALSE) { + switch (rcn_guide->npc_class.actor_class.actor_specific) { + case 1: + think_idx = aNRC_THINK_DECIDE_HOUSE; + break; + default: + think_idx = aNRC_THINK_RESTART_TALK; + break; + } + + aNRG_setup_think_proc(rcn_guide, play, think_idx); + } +} + +static void aNRG_think_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) { + NPC_RCN_GUIDE_ACTOR* rcn_guide = (NPC_RCN_GUIDE_ACTOR*)nactorx; + + (*rcn_guide->think_proc)(rcn_guide, play); +} + +static void aNRG_think_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) { + NPC_RCN_GUIDE_ACTOR* rcn_guide = (NPC_RCN_GUIDE_ACTOR*)nactorx; + int think_idx; + + switch (rcn_guide->npc_class.actor_class.actor_specific) { + case 1: + case 2: + think_idx = aNRC_THINK_RESTART_WAIT; + break; + default: + think_idx = aNRC_THINK_CALL; + break; + } + + aNRG_setup_think_proc(rcn_guide, play, think_idx); + rcn_guide->npc_class.condition_info.hide_request = FALSE; +} + +static void aNRG_call_init(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) { + s16 angle_y = atans_table(980.0f - rcn_guide->npc_class.actor_class.world.position.z, + 2320.0f - rcn_guide->npc_class.actor_class.world.position.x); + + rcn_guide->npc_class.actor_class.shape_info.rotation.y = angle_y; + rcn_guide->npc_class.actor_class.world.angle.y = angle_y; +} + +static void aNRG_approach_init(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) { + PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play); + f32 x; + f32 z; + + /* Player cannot open the start menu */ + play->submenu.disable_start_btn_flag = TRUE; + /* Make the player stand around waiting */ + mPlib_request_main_demo_wait_type1(&play->game, 0, NULL); + + if (player != NULL) { + /* Move to a bit below where the player is */ + x = player->actor_class.world.position.x; + z = player->actor_class.world.position.z + 70.0f; + } else { + /* Move to a predefined position -- how would the player even be NULL? */ + x = 2320.0f; + z = 1050.0f; + } + + /* Request action to move to desired location */ + aNRG_set_request_act(rcn_guide, 4, aNPC_ACT_WALK2, aNPC_ACT_TYPE_TO_POINT, aNPC_ACT_OBJ_DEFAULT, x, z); +} + +static void aNRG_introduce_init(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) { + aNRG_set_request_act(rcn_guide, 4, aNPC_ACT_WAIT, aNPC_ACT_TYPE_DEFAULT, aNPC_ACT_OBJ_DEFAULT, 0, 0); +} + +static void aNRG_turn_init(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) { + mPlib_request_main_demo_wait_type1(&play->game, 0, NULL); + aNRG_set_request_act(rcn_guide, 4, aNPC_ACT_TURN, aNPC_ACT_TYPE_TO_POINT, aNPC_ACT_OBJ_DEFAULT, 2240, 1300); +} + +static void aNRG_take_with_init(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) { + if (Common_Get(clip).demo_clip != NULL && Common_Get(clip).demo_clip->type == mDemo_CLIP_TYPE_INTRO_DEMO) { + ACTOR* demo_actor = (ACTOR*)Common_Get(clip).demo_clip->demo_class; + + if (demo_actor != NULL) { + INTRO_DEMO_ACTOR* intro_demo = (INTRO_DEMO_ACTOR*)demo_actor; + + intro_demo->talk_flag = TRUE; + } + } + + aNRG_set_request_act(rcn_guide, 4, aNPC_ACT_WALK2, aNPC_ACT_TYPE_TO_POINT, aNPC_ACT_OBJ_DEFAULT, 2240, 1300); +} + +static void aNRG_before_open_door_talk2_init(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) { + INTRO_DEMO_ACTOR* intro_demo = (INTRO_DEMO_ACTOR*)Common_Get(clip).demo_clip->demo_class; + + aNRG_set_house_master_name(intro_demo->house_idx); +} + +static void aNRG_exit_turn_init(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) { + static s16 moveX[] = { 2240, 2240 }; + static s16 moveZ[] = { 1900, 1300 }; + int idx = 0; + + if (rcn_guide->npc_class.actor_class.world.position.z < 1540.0f) { + idx = 1; + } + + aNRG_set_request_act(rcn_guide, 4, aNPC_ACT_TURN, aNPC_ACT_TYPE_TO_POINT, aNPC_ACT_OBJ_DEFAULT, moveX[idx], + moveZ[idx]); + if (Common_Get(clip).demo_clip != NULL && Common_Get(clip).demo_clip->type == mDemo_CLIP_TYPE_INTRO_DEMO) { + ACTOR* demo_actor = (ACTOR*)Common_Get(clip).demo_clip->demo_class; + + if (demo_actor != NULL) { + INTRO_DEMO_ACTOR* intro_demo = (INTRO_DEMO_ACTOR*)demo_actor; + + intro_demo->talk_flag = TRUE; + } + } + rcn_guide->next_think_idx = 15; +} + +static void aNRG_setup_think_proc(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play, int think_idx) { + // clang-format off + static aNRG_setup_think_c dt_tbl[] = { + { + (aNRG_THINK_PROC)&none_proc1, + &aNRG_call_init, + &aNRG_force_talk_request, + aNRG_FORCE_TALK_CALL, + aNRC_THINK_APPROACH, + }, + { + &aNRG_approach, + &aNRG_approach_init, + (aNPC_TALK_REQUEST_PROC)&none_proc1, + aNRG_FORCE_TALK_CALL, + aNRC_THINK_APPROACH, + }, + { + (aNRG_THINK_PROC)&none_proc1, + &aNRG_introduce_init, + &aNRG_force_talk_request, + aNRG_FORCE_TALK_INTRODUCE, + aNRC_THINK_TURN, + }, + { + &aNRG_turn, + &aNRG_turn_init, + (aNPC_TALK_REQUEST_PROC)&none_proc1, + aNRG_FORCE_TALK_CALL, + aNRC_THINK_TAKE_WITH, + }, + { + &aNRG_take_with, + &aNRG_take_with_init, + (aNPC_TALK_REQUEST_PROC)&none_proc1, + aNRG_FORCE_TALK_CALL, + aNRC_THINK_TAKE_WITH, + }, + { + (aNRG_THINK_PROC)&none_proc1, + (aNRG_THINK_INIT_PROC)&none_proc1, + &aNRG_force_talk_request, + aNRG_FORCE_TALK_EXPLAIN, + aNRC_THINK_DECIDE_HOUSE_WAIT, + }, + { + &aNRG_decide_house_wait, + &aNRG_introduce_init, + &aNRG_norm_talk_request, + aNRG_NORM_TALK_DECIDE_HOUSE, + aNRC_THINK_DECIDE_HOUSE_WAIT, + }, + { + (aNRG_THINK_PROC)&none_proc1, + (aNRG_THINK_INIT_PROC)&none_proc1, + &aNRG_force_talk_request, + aNRG_FORCE_TALK_STOP_WADE, + aNRC_THINK_DECIDE_HOUSE_WAIT, + }, + { + (aNRG_THINK_PROC)&none_proc1, + (aNRG_THINK_INIT_PROC)&none_proc1, + &aNRG_force_talk_request, + aNRG_FORCE_TALK_BEFORE_OPEN_DOOR_TALK, + aNRC_THINK_ENTER_WAIT, + }, + { + (aNRG_THINK_PROC)&none_proc1, + &aNRG_before_open_door_talk2_init, + &aNRG_force_talk_request, + aNRG_FORCE_TALK_BEFORE_OPEN_DOOR2_TALK, + aNRC_THINK_ENTER_WAIT, + }, + { + &aNRG_enter_wait, + (aNRG_THINK_INIT_PROC)&none_proc1, + (aNPC_TALK_REQUEST_PROC)&none_proc1, + aNRG_FORCE_TALK_CALL, + aNRC_THINK_ENTER_WAIT, + }, + { + &aNRG_restart_wait, + (aNRG_THINK_INIT_PROC)&none_proc1, + (aNPC_TALK_REQUEST_PROC)&none_proc1, + aNRG_FORCE_TALK_CALL, + aNRC_THINK_RESTART_WAIT, + }, + { + (aNRG_THINK_PROC)&none_proc1, + (aNRG_THINK_INIT_PROC)&none_proc1, + &aNRG_force_talk_request, + aNRG_FORCE_TALK_HOUSE_TAKEN, + aNRC_THINK_DECIDE_HOUSE_WAIT, + }, + { + (aNRG_THINK_PROC)&none_proc1, + (aNRG_THINK_INIT_PROC)&none_proc1, + &aNRG_force_talk_request, + aNRG_FORCE_TALK_HOUSE_VACANT, + aNRC_THINK_DECIDE_HOUSE_WAIT, + }, + { + &aNRG_turn, + &aNRG_exit_turn_init, + (aNPC_TALK_REQUEST_PROC)&none_proc1, + aNRG_FORCE_TALK_CALL, + aNRC_THINK_EXIT_TURN, + }, + { + &aNRG_exit, + (aNRG_THINK_INIT_PROC)&none_proc1, + (aNPC_TALK_REQUEST_PROC)&none_proc1, + aNRG_FORCE_TALK_CALL, + aNRC_THINK_EXIT, + }, + { + (aNRG_THINK_PROC)&none_proc1, + (aNRG_THINK_INIT_PROC)&none_proc1, + (aNPC_TALK_REQUEST_PROC)&none_proc1, + aNRG_FORCE_TALK_CALL, + aNRC_THINK_WAIT, + }, + }; + // clang-format on + aNRG_setup_think_c* think_data = &dt_tbl[think_idx]; + + rcn_guide->think_idx = think_idx; + rcn_guide->think_proc = think_data->think_proc; + rcn_guide->npc_class.talk_info.talk_request_proc = think_data->talk_request_proc; + rcn_guide->talk_idx = think_data->talk_idx; + rcn_guide->next_think_idx = think_data->next_think_idx; + (*think_data->think_init_proc)(rcn_guide, play); +} + +static void aNRG_think_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int type) { + static aNPC_SUB_PROC think_proc[] = { &aNRG_think_init_proc, &aNRG_think_main_proc }; + + (*think_proc[type])(nactorx, play); +} + +static void aNRG_schedule_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) { + nactorx->think.think_proc = &aNRG_think_proc; + Common_Get(clip).npc_clip->think_proc(nactorx, play, aNPC_THINK_SPECIAL, 0); +} + +static void aNRG_schedule_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) { + int res = Common_Get(clip).npc_clip->think_proc(nactorx, play, -1, 1); + + if (res == 0) { + Common_Get(clip).npc_clip->think_proc(nactorx, play, -1, 2); + } +} + +static void aNRG_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int type) { + static aNPC_SUB_PROC sche_proc[] = { &aNRG_schedule_init_proc, &aNRG_schedule_main_proc }; + + (*sche_proc[type])(nactorx, play); +} diff --git a/src/ac_npc_rcn_guide_talk.c_inc b/src/ac_npc_rcn_guide_talk.c_inc new file mode 100644 index 00000000..45e45bfb --- /dev/null +++ b/src/ac_npc_rcn_guide_talk.c_inc @@ -0,0 +1,170 @@ +enum { + aNRG_TALK_DEMAND_PAYMENT, + aNRG_TALK_MENU_OPEN_WAIT, + aNRG_TALK_MENU_CLOSE_WAIT, + aNRG_TALK_DEMO_START_WAIT, + aNRG_TALK_DEMO_END_WAIT, + aNRG_TALK_FINISHED, + + aNRG_TALK_NUM +}; + +static void aNRG_demand_payment_change_talk_proc(NPC_RCN_GUIDE_ACTOR* rcn_guide, int talk_proc_idx); + +static void aNRG_demand_payment_talk_proc(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) { + u16 order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9); + + if (order != 0) { + mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0); + mMsg_REQUEST_MAIN_DISAPPEAR_WAIT_TYPE1(); + aNRG_demand_payment_change_talk_proc(rcn_guide, aNRG_TALK_MENU_OPEN_WAIT); + } +} + +static void aNRG_menu_open_wait_talk_proc(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) { + if (mMsg_CHECK_MAIN_WAIT() == TRUE) { + Submenu* submenu = &play->submenu; + int idx = mPr_GetPossessionItemIdxWithCond(Now_Private, ITM_MONEY_1000, mPr_ITEM_COND_QUEST); + + mSM_open_submenu(submenu, mSM_OVL_INVENTORY, mSM_IV_OPEN_QUEST, idx); + mMsg_SET_LOCKCONTINUE(); + aNRG_demand_payment_change_talk_proc(rcn_guide, aNRG_TALK_MENU_CLOSE_WAIT); + } +} + +static void aNRG_menu_close_wait_talk_proc(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) { + Submenu* submenu = &play->submenu; + + if (submenu->open_flag == FALSE) { + if (submenu->item_p->item == EMPTY_NO) { + mMsg_Window_c* msg_p = mMsg_Get_base_window_p(); + + mMsg_request_main_appear_wait_type1(msg_p); + mMsg_ChangeMsgData(msg_p, 0x07EB); /* 'You better pay it all back, or I will have to...' */ + mMsg_Set_ForceNext(msg_p); + mMsg_Unset_LockContinue(msg_p); + aNRG_demand_payment_change_talk_proc(rcn_guide, aNRG_TALK_DEMAND_PAYMENT); /* Go back to first state */ + } else { + aNRG_demand_payment_change_talk_proc(rcn_guide, aNRG_TALK_DEMO_START_WAIT); /* Handed over the Bells */ + } + } +} + +static void aNRG_demo_start_wait_talk_proc(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) { + if (Common_Get(clip).handOverItem_clip->request_mode == aHOI_REQUEST_TRANS_WAIT) { + mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 1, 3); + aNRG_demand_payment_change_talk_proc(rcn_guide, aNRG_TALK_DEMO_END_WAIT); + } +} + +static void aNRG_demo_end_wait_talk_proc(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) { + if (Common_Get(clip).handOverItem_clip->master_actor == NULL) { + mMsg_Window_c* msg_p = mMsg_Get_base_window_p(); + + aNRG_set_shop_address(rcn_guide); + rcn_guide->next_think_idx = 14; + mMsg_request_main_appear_wait_type1(msg_p); + mMsg_Set_ForceNext(msg_p); + aNRG_demand_payment_change_talk_proc(rcn_guide, aNRG_TALK_FINISHED); + } +} + +static void aNRG_demand_payment_change_talk_proc(NPC_RCN_GUIDE_ACTOR* rcn_guide, int talk_proc_idx) { + // clang-format off + static aNRG_TALK_PROC talk_proc[] = { + &aNRG_demand_payment_talk_proc, + &aNRG_menu_open_wait_talk_proc, + &aNRG_menu_close_wait_talk_proc, + &aNRG_demo_start_wait_talk_proc, + &aNRG_demo_end_wait_talk_proc, + (aNRG_TALK_PROC)&none_proc1, + }; + // clang-format on + + rcn_guide->talk_proc = talk_proc[talk_proc_idx]; +} + +static void aNRG_set_force_talk_info(ACTOR* actorx) { + // clang-format off + static aNRG_talk_data_c dt_tbl[] = { + { 0x07DE, TRUE, CAMERA2_PROCESS_NORMAL, TRUE, (aNRG_TALK_PROC)&none_proc1 }, /* Step down from train station */ + { 0x07DF, TRUE, CAMERA2_PROCESS_TALK, FALSE, (aNRG_TALK_PROC)&none_proc1 }, /* Ask about call from Rover */ + { 0x07E1, TRUE, CAMERA2_PROCESS_TALK, FALSE, (aNRG_TALK_PROC)&none_proc1 }, /* Show houses */ + { 0x07E2, TRUE, CAMERA2_PROCESS_NORMAL, FALSE, (aNRG_TALK_PROC)&none_proc1 }, /* Player tries leaving acre */ + { 0x07E4, FALSE, CAMERA2_PROCESS_NORMAL, FALSE, (aNRG_TALK_PROC)&none_proc1 }, /* Player enters empty house */ + { 0x07E3, FALSE, CAMERA2_PROCESS_NORMAL, FALSE, (aNRG_TALK_PROC)&none_proc1 }, /* Player enters taken house */ + { 0x07E5, TRUE, CAMERA2_PROCESS_TALK, TRUE, (aNRG_TALK_PROC)&none_proc1 }, /* Player exits taken house */ + { 0x07E6, TRUE, CAMERA2_PROCESS_TALK, TRUE, &aNRG_demand_payment_talk_proc }, /* Player exits empty house */ + }; + // clang-format on + + NPC_RCN_GUIDE_ACTOR* rcn_guide = (NPC_RCN_GUIDE_ACTOR*)actorx; + int talk_idx = rcn_guide->talk_idx; + aNRG_talk_data_c* data = &dt_tbl[talk_idx]; + + mDemo_Set_msg_num(data->msg_no); + mDemo_Set_talk_turn(data->turn_flag); + mDemo_Set_camera(data->camera_type); + rcn_guide->talk_proc_idx = aNRG_TALK_DEMAND_PAYMENT; + rcn_guide->talk_proc = data->talk_proc; + if (data->melody_flag == TRUE) { + rcn_guide->npc_class.talk_info.melody_inst = rcn_guide->melody_copy; + } else { + rcn_guide->npc_class.talk_info.melody_inst = 0; + } + + if (talk_idx == 0) { + mBGMPsComp_make_ps_quiet(0); + } +} + +static void aNRG_force_talk_request(ACTOR* actorx, GAME* game) { + mDemo_Request(mDemo_TYPE_SPEAK, actorx, &aNRG_set_force_talk_info); +} + +static void aNRG_set_norm_talk_info(ACTOR* actorx) { + static aNRG_talk_data_c dt_tbl[] = { + { 0x0820, TRUE, CAMERA2_PROCESS_TALK, FALSE, (aNRG_TALK_PROC)&none_proc1 }, /* Normal talk about houses */ + }; + + NPC_RCN_GUIDE_ACTOR* rcn_guide = (NPC_RCN_GUIDE_ACTOR*)actorx; + aNRG_talk_data_c* data = &dt_tbl[rcn_guide->talk_idx]; + + mDemo_Set_msg_num(data->msg_no); + mDemo_Set_talk_turn(data->turn_flag); + mDemo_Set_camera(data->camera_type); + rcn_guide->talk_proc_idx = aNRG_TALK_DEMAND_PAYMENT; + rcn_guide->talk_proc = data->talk_proc; + if (data->melody_flag == TRUE) { + rcn_guide->npc_class.talk_info.melody_inst = rcn_guide->melody_copy; + } else { + rcn_guide->npc_class.talk_info.melody_inst = 0; + } +} + +static void aNRG_norm_talk_request(ACTOR* actorx, GAME* game) { + mDemo_Request(mDemo_TYPE_TALK, actorx, &aNRG_set_norm_talk_info); +} + +static int aNRG_talk_init(ACTOR* actorx, GAME* game) { + NPC_RCN_GUIDE_ACTOR* rcn_guide = (NPC_RCN_GUIDE_ACTOR*)actorx; + + rcn_guide->npc_class.talk_info.talk_request_proc = (aNPC_TALK_REQUEST_PROC)&none_proc1; + mDemo_Set_ListenAble(); + return TRUE; +} + +static int aNRG_talk_end_chk(ACTOR* actorx, GAME* game) { + NPC_RCN_GUIDE_ACTOR* rcn_guide = (NPC_RCN_GUIDE_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + int res = FALSE; + + (*rcn_guide->talk_proc)(rcn_guide, play); + if (mDemo_Check(mDemo_TYPE_SPEAK, actorx) == FALSE && mDemo_Check(mDemo_TYPE_TALK, actorx) == FALSE) { + /* We're done talking so move onto the next schedule step */ + aNRG_setup_think_proc(rcn_guide, play, rcn_guide->next_think_idx); + res = TRUE; + } + + return res; +} diff --git a/src/ac_shop_move.c_inc b/src/ac_shop_move.c_inc index 67a2669e..1444a046 100644 --- a/src/ac_shop_move.c_inc +++ b/src/ac_shop_move.c_inc @@ -234,7 +234,7 @@ static void aSHOP_open_wait(STRUCTURE_ACTOR* shop, GAME_PLAY* play) { actor = &shop->actor_class; game = &play->game; - if (mPlib_check_player_actor_main_index_OutDoorMove(play) != FALSE) { + if (mPlib_check_player_actor_main_index_OutDoorMove(&play->game) != FALSE) { return; }