From 4c4140af99ec43d6b015bb6473a5a788d4a5444b Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Wed, 20 Dec 2023 16:07:18 -0500 Subject: [PATCH] Implement most of NPC_ACTOR class --- include/ac_npc.h | 257 ++++++++++++++++++++++++++++++++++++++++++--- src/ac_ev_soncho.c | 4 +- src/m_actor.c | 2 +- src/m_melody.c | 4 +- src/m_soncho.c | 4 +- 5 files changed, 249 insertions(+), 22 deletions(-) diff --git a/include/ac_npc.h b/include/ac_npc.h index cfdcb31e..990f8a90 100644 --- a/include/ac_npc.h +++ b/include/ac_npc.h @@ -100,6 +100,210 @@ typedef struct npc_info_s { mActor_name_t npc_name; } NpcActorInfo_c; +/* TODO: draw data */ +typedef struct npc_draw_info_s { + /* 0x000 */ u8 _000[0x584 - 0x000]; + /* 0x584 */ int texture_bank_idx; + /* 0x588 */ u8 _588[0x5BD - 0x588]; + /* 0x5BD */ u8 _5BD; + /* 0x5BE */ u8 _5BE[0x630 - 0x5BE]; +} 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) + +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; +} 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; +} 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_NUM +}; + +typedef void (*aNPC_ACTION_PROC)(NPC_ACTOR*, GAME_PLAY*, int); + +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; +} 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; +} aNPC_request_c; + +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; +} aNPC_condition_info_c; + +typedef struct npc_uzai_s { + 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; +} 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; +} aNPC_head_c; + +enum { + aNPC_FOOT_LEFT, + aNPC_FOOT_RIGHT, + + 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; +} 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; +} 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; +} 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; +} aNPC_accessory_c; + /* Used for think, schedule, action, & talk */ typedef void (*aNPC_PROC)(NPC_ACTOR* npc_actorx, GAME_PLAY* play, int schedule_idx); typedef void (*aNPC_SUB_PROC)(NPC_ACTOR* npc_actorx, GAME_PLAY* play); @@ -109,23 +313,46 @@ struct npc_actor_s { int _174; int _178; NpcActorInfo_c npc_info; - u8 _194[0x718 - 0x194]; - int texture_bank_idx; // TEMP: this is part of draw struct - u8 _71C[0x751 - 0x71C]; - u8 _751; - u8 _752[0x8F4 - 0x752]; - int _8F4; - u8 _8F8[0x974 - 0x8F8]; - s16 talk_base_anim_id; - s16 _976; - s16 melody_inst; - u8 _97A[0x994 - 0x97A]; /* TODO: 0x994 may be too big. Verify size. Seen in ac_normal_npc, ac_npc_engineer */ + 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 animal_npc_actor_s { - NPC_ACTOR npc_actor_class; - u8 _994[0x9D8 - 0x994]; -} ANIMAL_NPC_ACTOR; +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; +} aNPC_cloth_c; + +typedef struct npc_control_actor_s { + ACTOR* actor_class; + aNPC_cloth_c cloth[10]; + u8 _8F4[0x9D8 - 0x8F4]; // TODO +} NPC_CONTROL_ACTOR; extern ACTOR_PROFILE Npc_Profile; diff --git a/src/ac_ev_soncho.c b/src/ac_ev_soncho.c index 72286a63..80cdeb6a 100644 --- a/src/ac_ev_soncho.c +++ b/src/ac_ev_soncho.c @@ -48,8 +48,8 @@ static void aESC_actor_ct(ACTOR* actorx, GAME* game) { if ((*Common_Get(clip).npc_clip->birth_check_proc)(actorx, game) == TRUE) { (*Common_Get(clip).npc_clip->ct_proc)(actorx, game, &ct_data); - soncho_actor->npc_class._8F4 = -1; - soncho_actor->npc_class._751 = 3; + soncho_actor->npc_class.palActorIgnoreTimer = -1; + soncho_actor->npc_class.draw._5BD = 3; if (soncho_event == NULL) { soncho_event = (aESC_event_save_c*)mEv_reserve_save_area(mEv_EVENT_SONCHO_BRIDGE_MAKE, 34); diff --git a/src/m_actor.c b/src/m_actor.c index bbaf6544..81ca1099 100644 --- a/src/m_actor.c +++ b/src/m_actor.c @@ -136,7 +136,7 @@ static void Actor_ct(ACTOR* actor, GAME* game) { (*Common_Get(clip).npc_clip->dma_draw_data_proc)(&draw_data, actor->npc_id); tex_bank_id = mSc_bank_regist_check(exchange, draw_data.texture_bank); - npc_actor->texture_bank_idx = tex_bank_id; + npc_actor->draw.texture_bank_idx = tex_bank_id; bank = &exchange->banks[tex_bank_id]; bank->num_exist++; diff --git a/src/m_melody.c b/src/m_melody.c index 5c0a4700..7fd883e9 100644 --- a/src/m_melody.c +++ b/src/m_melody.c @@ -49,7 +49,7 @@ extern void mMld_MakeMelody(u16 inst) { extern void mMld_ActorMakeThisMelody(u8* melody, ACTOR* actor) { if (actor != NULL && actor->part == ACTOR_PART_NPC) { NPC_ACTOR* npc_actor = (NPC_ACTOR*)actor; - int melody_inst = npc_actor->melody_inst; + int melody_inst = npc_actor->talk_info.melody_inst; if (melody_inst != 0) { sAdo_Inst(melody_inst, melody); @@ -60,7 +60,7 @@ extern void mMld_ActorMakeThisMelody(u8* melody, ACTOR* actor) { extern void mMld_ActorMakeMelody(ACTOR* actor) { if (actor != NULL && actor->part == ACTOR_PART_NPC) { NPC_ACTOR* npc_actor = (NPC_ACTOR*)actor; - int melody_inst = npc_actor->melody_inst; + int melody_inst = npc_actor->talk_info.melody_inst; if (melody_inst != 0) { mMld_MakeMelody(melody_inst); diff --git a/src/m_soncho.c b/src/m_soncho.c index ae96492a..8eae2593 100644 --- a/src/m_soncho.c +++ b/src/m_soncho.c @@ -787,7 +787,7 @@ static void mSCR_talk_inspection(TAISOU_NPC0_ACTOR* taisou_actor, GAME_PLAY* pla Common_Get(clip).handOverItem_clip->player_after_mode = 8; mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 3); mMsg_Unset_LockContinue(msg_win); - taisou_actor->npc_actor_class.talk_base_anim_id = 30; + taisou_actor->npc_actor_class.talk_info.default_animation = 30; } break; } @@ -805,7 +805,7 @@ static void mSCR_talk_inspection(TAISOU_NPC0_ACTOR* taisou_actor, GAME_PLAY* pla case 4: { if (Common_Get(clip).handOverItem_clip->master_actor == NULL) { - taisou_actor->npc_actor_class.talk_base_anim_id = -1; + taisou_actor->npc_actor_class.talk_info.default_animation = -1; mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0); if (radiocard->days >= mSC_RADIO_DAYS) {