From 588980ca2bc110e5fc36e38114e3e0febe027667 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Wed, 10 Jan 2024 03:38:42 -0500 Subject: [PATCH] Implement & link ac_go_home_npc --- config/rel_slices.yml | 4 ++ include/ac_go_home_npc.h | 7 +++ src/ac_go_home_npc.c | 117 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 src/ac_go_home_npc.c diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 0505256f..6f171442 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -582,6 +582,10 @@ ac_ev_soncho.c: .text: [0x8052400C, 0x8052475C] .rodata: [0x80649270, 0x80649278] .data: [0x806A0D38, 0x806A0D88] +ac_go_home_npc.c: + .text: [0x80526F48, 0x805272D8] + .rodata: [0x806492B8, 0x806492C0] + .data: [0x806A0FB8, 0x806A0FF8] ac_npc_curator.c: .text: [0x8054B06C, 0x8054CF28] .rodata: [0x806495B0, 0x806495B8] diff --git a/include/ac_go_home_npc.h b/include/ac_go_home_npc.h index ecb1b0c1..13d404e0 100644 --- a/include/ac_go_home_npc.h +++ b/include/ac_go_home_npc.h @@ -3,11 +3,18 @@ #include "types.h" #include "m_actor.h" +#include "ac_npc.h" #ifdef __cplusplus extern "C" { #endif +typedef struct go_home_npc_s GO_HOME_NPC_ACTOR; + +struct go_home_npc_s { + NPC_ACTOR npc_class; +}; + extern ACTOR_PROFILE Go_Home_Npc_Profile; #ifdef __cplusplus diff --git a/src/ac_go_home_npc.c b/src/ac_go_home_npc.c new file mode 100644 index 00000000..136242c0 --- /dev/null +++ b/src/ac_go_home_npc.c @@ -0,0 +1,117 @@ +#include "ac_go_home_npc.h" + +#include "m_common_data.h" +#include "m_font.h" +#include "m_msg.h" + +static void aGHN_actor_ct(ACTOR* actorx, GAME* game); +static void aGHN_actor_dt(ACTOR* actorx, GAME* game); +static void aGHN_actor_init(ACTOR* actorx, GAME* game); +static void aGHN_actor_move(ACTOR* actorx, GAME* game); +static void aGHN_actor_draw(ACTOR* actorx, GAME* game); +static void aGHN_actor_save(ACTOR* actorx, GAME* game); + +ACTOR_PROFILE Go_Home_Npc_Profile = { + mAc_PROFILE_GO_HOME_NPC, + ACTOR_PART_NPC, + ACTOR_STATE_NONE, + EMPTY_NO, + ACTOR_OBJ_BANK_KEEP, + sizeof(GO_HOME_NPC_ACTOR), + &aGHN_actor_ct, + &aGHN_actor_dt, + &aGHN_actor_init, + mActor_NONE_PROC1, + &aGHN_actor_save +}; + +static void aGHN_talk_request(ACTOR* actorx, GAME* game); +static int aGHN_talk_init(ACTOR* actorx, GAME* game); +static int aGHN_talk_end_chk(ACTOR* actorx, GAME* game); + +static void aGHN_actor_ct(ACTOR* actorx, GAME* game) { + static aNPC_ct_data_c ct_data = { + &aGHN_actor_move, + &aGHN_actor_draw, + 3, + &aGHN_talk_request, + &aGHN_talk_init, + &aGHN_talk_end_chk, + 0 + }; + + if ((*Common_Get(clip).npc_clip->birth_check_proc)(actorx, game) == TRUE) { + (*Common_Get(clip).npc_clip->ct_proc)(actorx, game, &ct_data); + + /* If the player has already spoken to the NPC, despawn them */ + if ((Common_Get(spnpc_first_talk_flags) & (1 << aNPC_SPNPC_BIT_GOHOME_NPC)) != 0) { + Actor_delete(actorx); + } + } +} + +static void aGHN_actor_dt(ACTOR* actorx, GAME* game) { + (*Common_Get(clip).npc_clip->dt_proc)(actorx, game); + mEv_actor_dying_message(mEv_EVENT_MASK_NPC, actorx); +} + +static void aGHN_actor_save(ACTOR* actorx, GAME* game) { + (*Common_Get(clip).npc_clip->save_proc)(actorx, game); +} + +static void aGHN_actor_init(ACTOR* actorx, GAME* game) { + (*Common_Get(clip).npc_clip->init_proc)(actorx, game); +} + +static void aGHN_actor_draw(ACTOR* actorx, GAME* game) { + (*Common_Get(clip).npc_clip->draw_proc)(actorx, game); +} + +static void aGHN_set_free_str() { + u8 str[2]; + int fig_start = 2; + int num = lbRTC_GetIntervalDays(&Save_Get(return_animal).renew_time, Common_GetPointer(time.rtc_time)); // days since animal left + + if (num < 10) { + fig_start = 1; + } + + mFont_UnintToString(str, sizeof(str), num, fig_start, TRUE, FALSE, FALSE); + mMsg_Set_free_str(mMsg_Get_base_window_p(), mMsg_FREE_STR0, str, fig_start); +} + +static void aGHN_set_talk_info(ACTOR* actorx) { + int msg_no = 0x321B + mNpc_GetNpcLooks(actorx) * 4; + + if ((Common_Get(spnpc_first_talk_flags) & (1 << aNPC_SPNPC_BIT_GOHOME_NPC)) != 0) { + msg_no += 1 + RANDOM(3); + } + + mDemo_Set_msg_num(msg_no); +} + +static void aGHN_talk_request(ACTOR* actorx, GAME* game) { + mDemo_Request(mDemo_TYPE_TALK, actorx, &aGHN_set_talk_info); +} + +static int aGHN_talk_init(ACTOR* actorx, GAME* game) { + aNPC_SPNPC_BIT_SET(Common_Get(spnpc_first_talk_flags), aNPC_SPNPC_BIT_GOHOME_NPC); // record that the npc has been spoken to before + Save_Get(return_animal).talk_bit |= (1 << Common_Get(player_no)); // record this player has spoken to the npc + aGHN_set_free_str(); + mDemo_Set_ListenAble(); + return TRUE; +} + +static int aGHN_talk_end_chk(ACTOR* actorx, GAME* game) { + int res = FALSE; + + if (mDemo_Check(mDemo_TYPE_TALK, actorx) == FALSE) { + res = TRUE; + } + + return res; +} + +static void aGHN_actor_move(ACTOR* actorx, GAME* game) { + (*Common_Get(clip).npc_clip->move_proc)(actorx, game); +}