From b945bca1cf72af5ca4981a42aaf139a3111d6bc0 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Thu, 2 Nov 2023 01:20:31 -0400 Subject: [PATCH] Implement & link ac_ev_soncho.c --- config/rel_slices.yml | 4 + include/ac_ev_soncho.h | 15 ++++ include/ac_npc.h | 8 +- rel/ac_ev_soncho.c | 83 +++++++++++++++++ rel/ac_ev_soncho_talk.c_inc | 174 ++++++++++++++++++++++++++++++++++++ 5 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 rel/ac_ev_soncho.c create mode 100644 rel/ac_ev_soncho_talk.c_inc diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 0a98e7f0..79a6865c 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -495,6 +495,10 @@ ac_groundhog_control.c: ac_ev_dokutu.c: .text: [0x8051DFF4, 0x8051E228] .data: [0x806A05C8, 0x806A0608] +ac_ev_soncho.c: + .text: [0x8052400C, 0x8052475C] + .rodata: [0x80649270, 0x80649278] + .data: [0x806A0D38, 0x806A0D88] ac_douzou.c: .text: [0x805AD6D8, 0x805AE704] .rodata: [0x8064A7C0, 0x8064A7E8] diff --git a/include/ac_ev_soncho.h b/include/ac_ev_soncho.h index 0355f852..b84aded3 100644 --- a/include/ac_ev_soncho.h +++ b/include/ac_ev_soncho.h @@ -3,11 +3,26 @@ #include "types.h" #include "m_actor.h" +#include "ac_npc.h" #ifdef __cplusplus extern "C" { #endif +enum { + aESC_TALK_OWARI, + aESC_TALK_SELECT, + aESC_TALK_SECAND, + + aESC_TALK_NUM +}; + +typedef struct npc_event_soncho_s { + NPC_ACTOR npc_class; + u8 talk_state; + u8 first_talk; +} EVENT_SONCHO_ACTOR; + extern ACTOR_PROFILE Ev_Soncho_Profile; #ifdef __cplusplus diff --git a/include/ac_npc.h b/include/ac_npc.h index bf0776ca..9c58652f 100644 --- a/include/ac_npc.h +++ b/include/ac_npc.h @@ -13,6 +13,8 @@ extern "C" { #endif +#define aNPC_SPNPC_BIT_EV_SONCHO 5 + typedef struct ac_npc_clip_s aNPC_Clip_c; typedef struct npc_draw_data_s { @@ -105,7 +107,11 @@ struct npc_actor_s { NpcActorInfo_c npc_info; u8 _194[0x718 - 0x194]; int texture_bank_idx; // TEMP: this is part of draw struct - u8 _71C[0x974 - 0x71C]; + 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; diff --git a/rel/ac_ev_soncho.c b/rel/ac_ev_soncho.c new file mode 100644 index 00000000..2af85dcb --- /dev/null +++ b/rel/ac_ev_soncho.c @@ -0,0 +1,83 @@ +#include "ac_ev_soncho.h" + +#include "m_common_data.h" + +typedef struct soncho_event_save_s { + u16 _00; + u8 msg_no; +} aESC_event_save_c; + +static void aESC_actor_ct(ACTOR* actorx, GAME* game); +static void aESC_actor_dt(ACTOR* actorx, GAME* game); +static void aESC_actor_init(ACTOR* actorx, GAME* game); +static void aESC_actor_draw(ACTOR* actorx, GAME* game); +static void aESC_actor_save(ACTOR* actorx, GAME* game); +static void aESC_actor_move(ACTOR* actorx, GAME* game); + +static void aESC_talk_request(ACTOR* actorx, GAME* game); +static int aESC_talk_init(ACTOR* actorx, GAME* game); +static int aESC_talk_end_chk(ACTOR* actorx, GAME* game); + +ACTOR_PROFILE Ev_Soncho_Profile = { + mAc_PROFILE_EV_SONCHO, + ACTOR_PART_NPC, + 0, + SP_NPC_EV_SONCHO, + ACTOR_OBJ_BANK_KEEP, + sizeof(EVENT_SONCHO_ACTOR), + &aESC_actor_ct, + &aESC_actor_dt, + &aESC_actor_init, + mActor_NONE_PROC1, + &aESC_actor_save +}; + +static aNPC_ct_data_c ct_data = { + &aESC_actor_move, + &aESC_actor_draw, + 4, + &aESC_talk_request, + &aESC_talk_init, + &aESC_talk_end_chk, + 1 +}; + +static void aESC_actor_ct(ACTOR* actorx, GAME* game) { + EVENT_SONCHO_ACTOR* soncho_actor = (EVENT_SONCHO_ACTOR*)actorx; + aESC_event_save_c* soncho_event = (aESC_event_save_c*)mEv_get_save_area(mEv_EVENT_SONCHO_BRIDGE_MAKE, 34); + + 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; + + if (soncho_event == NULL) { + soncho_event = (aESC_event_save_c*)mEv_reserve_save_area(mEv_EVENT_SONCHO_BRIDGE_MAKE, 34); + soncho_event->_00 = 0; + soncho_event->msg_no = RANDOM(5); + } + + if (Save_Get(bridge).pending) { + Actor_delete(actorx); + } + } +} + +static void aESC_actor_save(ACTOR* actorx, GAME* game) { + (*Common_Get(clip).npc_clip->save_proc)(actorx, game); +} + +static void aESC_actor_dt(ACTOR* actorx, GAME* game) { + mEv_actor_dying_message(mEv_EVENT_SONCHO_BRIDGE_MAKE, actorx); + (*Common_Get(clip).npc_clip->dt_proc)(actorx, game); +} + +static void aESC_actor_init(ACTOR* actorx, GAME* game) { + (*Common_Get(clip).npc_clip->init_proc)(actorx, game); +} + +static void aESC_actor_draw(ACTOR* actorx, GAME* game) { + (*Common_Get(clip).npc_clip->draw_proc)(actorx, game); +} + +#include "../rel/ac_ev_soncho_talk.c_inc" diff --git a/rel/ac_ev_soncho_talk.c_inc b/rel/ac_ev_soncho_talk.c_inc new file mode 100644 index 00000000..dd8bce11 --- /dev/null +++ b/rel/ac_ev_soncho_talk.c_inc @@ -0,0 +1,174 @@ +#include "m_msg.h" +#include "m_font.h" + +static int aESC_bitset_func() { + u8 flags = Common_Get(spnpc_first_talk_flags); + if (Common_Get(player_no) == mPr_FOREIGNER) { + return FALSE; + } + + Common_Get(spnpc_first_talk_flags) = flags | (1 << aNPC_SPNPC_BIT_EV_SONCHO); + return TRUE; +} + +static u16 aESC_bitcheck_func() { + u8 flags = Common_Get(spnpc_first_talk_flags); + + if (Common_Get(player_no) == mPr_FOREIGNER) { + return FALSE; + } + + return (Common_Get(spnpc_first_talk_flags) >> aNPC_SPNPC_BIT_EV_SONCHO) & 1; +} + +static void aESC_owari_message() { + mMsg_Window_c* win_p = mMsg_Get_base_window_p(); + aESC_event_save_c* ev_save = (aESC_event_save_c*)mEv_get_save_area(mEv_EVENT_SONCHO_BRIDGE_MAKE, 34); + + if ((*(u8*)&Save_Get(event_save_common).bridge_flags) & 0x80) { + mMsg_Set_continue_msg_num(win_p, 0x2F47 + ev_save->msg_no); + } + else { + mMsg_Set_continue_msg_num(win_p, 0x2F39 + ev_save->msg_no); + } + + ev_save->msg_no++; + + if (ev_save->msg_no >= 5) { + ev_save->msg_no = 0; + } +} + +static void aESC_set_day() { + u8 day_str[16]; + + int len = mFont_UnintToString(day_str, 16, Save_Get(bridge).build_date.day, 16, TRUE, FALSE, TRUE); + mMsg_Set_free_str(mMsg_Get_base_window_p(), mMsg_FREE_STR0, day_str, len); +} + +/* They forgot to change the prefix on this copy-paste */ +static int aEGH_change_talk_proc(EVENT_SONCHO_ACTOR* soncho, u8 state) { + soncho->talk_state = state; + return TRUE; +} + +static void aESC_talk_select(EVENT_SONCHO_ACTOR* soncho, GAME* game) { + lbRTC_time_c rtc_time = Common_Get(time.rtc_time); + + if ((int)mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9) == 1 && mMsg_Check_MainNormalContinue(mMsg_Get_base_window_p())) { + mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0); + aEGH_change_talk_proc(soncho, aESC_TALK_OWARI); + + switch (mChoice_Get_ChoseNum(mChoice_Get_base_window_p())) { + case 1: + { + Save_Get(bridge).pending = TRUE; + lbRTC_Add_DD(&rtc_time, 1); + Save_Get(bridge).build_date.year = rtc_time.year; + Save_Get(bridge).build_date.month = rtc_time.month; + Save_Get(bridge).build_date.day = rtc_time.day; + Save_Get(bridge).block_x = soncho->npc_class.actor_class.block_x; + Save_Get(bridge).block_z = soncho->npc_class.actor_class.block_z; + aESC_set_day(); + + break; + } + + case 0: + { + if (soncho->first_talk != FALSE) { + aESC_owari_message(); + } + else { + aEGH_change_talk_proc(soncho, aESC_TALK_SECAND); + } + + break; + } + } + + } +} + +static void aESC_talk_secand(EVENT_SONCHO_ACTOR* soncho, GAME* game) { + if ((int)mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9) == 1 && mMsg_Check_MainNormalContinue(mMsg_Get_base_window_p())) { + mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0); + aEGH_change_talk_proc(soncho, aESC_TALK_OWARI); + aESC_owari_message(); + } +} + +static int aESC_time_talk() { + lbRTC_time_c rtc_time = Common_Get(time.rtc_time); + + if (rtc_time.hour < 6 || rtc_time.hour >= 23) { + return 0x2F36; + } + else if (rtc_time.hour < 10) { + return 0x2F33; + } + else if (rtc_time.hour < 17) { + return 0x2F34; + } + else { + return 0x2F35; + } +} + +static void aESC_set_talk_info_talk_request(ACTOR* actorx) { + int msg_no; + EVENT_SONCHO_ACTOR* soncho = (EVENT_SONCHO_ACTOR*)actorx; + + aEGH_change_talk_proc(soncho, 0); + if (Save_Get(bridge).pending) { + msg_no = 0x2F44 + RANDOM(3); + aESC_set_day(); + } + else if (aESC_bitcheck_func()) { + msg_no = 0x2F3E; + aEGH_change_talk_proc(soncho, aESC_TALK_SELECT); + soncho->first_talk = FALSE; + } + else { + msg_no = aESC_time_talk(); + aEGH_change_talk_proc(soncho, aESC_TALK_SELECT); + soncho->first_talk = TRUE; + } + + mDemo_Set_msg_num(msg_no); +} + +static void aESC_talk_request(ACTOR* actorx, GAME* game) { + mDemo_Request(mDemo_TYPE_TALK, actorx, &aESC_set_talk_info_talk_request); +} + +static int aESC_talk_init(ACTOR* actorx, GAME* game) { + aESC_bitset_func(); + mDemo_Set_ListenAble(); + return TRUE; +} + +typedef void (*aESC_TALK_PROC)(EVENT_SONCHO_ACTOR*, GAME*); + +static int aESC_talk_end_chk(ACTOR* actorx, GAME* game) { + static aESC_TALK_PROC proc[aESC_TALK_NUM] = { + (aESC_TALK_PROC)&none_proc1, + &aESC_talk_select, + &aESC_talk_secand + }; + + EVENT_SONCHO_ACTOR* soncho = (EVENT_SONCHO_ACTOR*)actorx; + int res = FALSE; + + (*proc[soncho->talk_state])(soncho, game); + + if (mDemo_Check(mDemo_TYPE_TALK, actorx) == FALSE) { + res = TRUE; + } + + return res; +} + +static void aESC_actor_move(ACTOR* actorx, GAME* game) { + (*Common_Get(clip).npc_clip->move_proc)(actorx, game); +}