From 7612466fe1fa0ba4101098a845a52e9f4475a16f Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Sat, 8 Jul 2023 03:07:20 -0400 Subject: [PATCH] Implement & link m_post_office.c --- config/rel_slices.yml | 3 + include/ac_npc.h | 10 + include/ac_train0.h | 10 +- include/m_clip.h | 4 +- include/m_common_data.h | 5 +- include/m_event.h | 4 + include/m_field_info.h | 1 + include/m_mail.h | 5 + include/m_museum.h | 2 + include/m_name_table.h | 2 + include/m_npc.h | 2 + include/m_post_office.h | 1 + rel/ac_train0.c | 2 +- rel/m_post_office.c | 539 ++++++++++++++++++++++++++++++++++++++++ 14 files changed, 578 insertions(+), 12 deletions(-) create mode 100644 rel/m_post_office.c diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 2a6ae8e7..fc44611e 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -83,6 +83,9 @@ m_police_box.c: .text: [0x803DE8A0, 0x803DEE38] .rodata: [0x806431C8, 0x806431D8] .data: [0x8065BE98, 0x8065BEF0] +m_post_office.c: + .text: [0x803DEE38, 0x803DFF7C] + .data: [0x8065BEF0, 0x8065BF00] m_private.c: .text: [0x803DFF7C, 0x803E2990] .rodata: [0x806431D8, 0x80643208] diff --git a/include/ac_npc.h b/include/ac_npc.h index a2710a7b..13bb6ea5 100644 --- a/include/ac_npc.h +++ b/include/ac_npc.h @@ -3,11 +3,21 @@ #include "types.h" #include "m_actor.h" +#include "m_play.h" #ifdef __cplusplus extern "C" { #endif +typedef struct ac_npc_clip_s aNPC_Clip_c; + +typedef int (*aNPC_SETUP_ACTOR_PROC)(GAME_PLAY*, mActor_name_t, s8, int, s16, int, int, int, int); + +struct ac_npc_clip_s { + aNPC_SETUP_ACTOR_PROC setupActor_proc; + void* _004[(0x12C - 0x004) / sizeof(void*)]; +}; + extern ACTOR_PROFILE Npc_Profile; #ifdef __cplusplus diff --git a/include/ac_train0.h b/include/ac_train0.h index eec0107f..662e8ac8 100644 --- a/include/ac_train0.h +++ b/include/ac_train0.h @@ -10,13 +10,7 @@ extern "C" { #endif -typedef int (*aTR0_SETUP_ACTOR_PROC)(GAME_PLAY*, mActor_name_t,int,int,int,int,int,int,int); - -typedef struct ac_train0_clip_s{ - aTR0_SETUP_ACTOR_PROC setup_actor_proc; -}aTR0_Clip_c; - -typedef struct train0_s{ +typedef struct train0_s { ACTOR actor_class; int steam_available; cKF_SkeletonInfo_R_c keyframe; @@ -32,7 +26,7 @@ typedef struct train0_s{ f32 tr1_pos; f32 tr_speed; u8 pad6[0x2D8 - 0x2CC]; -}TRAIN0_ACTOR; +} TRAIN0_ACTOR; extern ACTOR_PROFILE Train0_Profile; diff --git a/include/m_clip.h b/include/m_clip.h index 1a4566d6..86ecbb71 100644 --- a/include/m_clip.h +++ b/include/m_clip.h @@ -2,7 +2,6 @@ #define M_CLIP_H #include "types.h" -#include "ac_train0.h" #include "ac_gyoei_h.h" #include "ac_insect_h.h" #include "ac_structure.h" @@ -10,6 +9,7 @@ #include "ef_effect_control.h" #include "m_demo.h" #include "bg_item_h.h" +#include "ac_npc.h" #ifdef __cplusplus extern "C" { @@ -18,7 +18,7 @@ extern "C" { /* sizeof(Clip_c) == 0x104 */ typedef struct clip_s { /* 0x000 */ void* _000[(0x040 - 0x000) / sizeof(void*)]; - /* 0x040 */ aTR0_Clip_c* train0_clip; + /* 0x040 */ aNPC_Clip_c* npc_clip; /* 0x044 */ void* _044[(0x074 - 0x044) / sizeof(void*)]; /* 0x074 */ bIT_Clip_c* bg_item_clip; /* 0x078 */ void* _078; diff --git a/include/m_common_data.h b/include/m_common_data.h index c466fdec..ce8d483c 100644 --- a/include/m_common_data.h +++ b/include/m_common_data.h @@ -202,7 +202,10 @@ typedef struct common_data_s { /* 0x028866 */ u16 unused_028866; /* 0x028868 */ u8 reset_flag; /* 0x028869 */ u8 reset_type; - /* 0x02886A */ u8 _02886A[0x028879 - 0x02886A]; + /* 0x02886A */ u8 force_mail_delivery_flag; + /* 0x02886B */ u8 post_girl_npc_type; + /* 0x02886C */ xyz_t ball_pos; + /* 0x028878 */ u8 ball_type; /* 0x028879 */ u8 auto_nwrite_count; /* 0x02887A */ lbRTC_year_t auto_nwrite_year; /* 0x02887C */ u8 save_error_type; /* set to one of the mFRm_ERROR_* states when save is invalid */ diff --git a/include/m_event.h b/include/m_event.h index d85d86d8..44f6e462 100644 --- a/include/m_event.h +++ b/include/m_event.h @@ -115,6 +115,8 @@ enum event_table { mEv_EVENT_MUSHROOM_SEASON = 47, mEv_EVENT_FISHING_TOURNEY_2 = 54, mEv_EVENT_GHOST = 64, + mEv_EVENT_BROKER_SALE = 75, + mEv_EVENT_SHOP_SALE = 78, }; #define mEv_STATUS_ACTIVE (1 << 0) /* event is active */ @@ -144,6 +146,8 @@ extern int mEv_CheckArbeit(); extern int mEv_CheckTitleDemo(); extern int mEv_check_status(int event, s16 status); extern s8* mEv_get_common_area(int type, s8 id); +extern int mEv_ArbeitPlayer(u32 player_no); +extern u16 mEv_get_special_event_type(); extern int mEv_weekday2day(lbRTC_month_t month, int week_type, lbRTC_weekday_t weekday); extern void mEv_ClearEventInfo(); diff --git a/include/m_field_info.h b/include/m_field_info.h index ba0348ff..ccc46162 100644 --- a/include/m_field_info.h +++ b/include/m_field_info.h @@ -143,6 +143,7 @@ extern int mFI_SetFG_common(mActor_name_t item, xyz_t wpos, int update); extern mActor_name_t* mFI_GetUnitFG(xyz_t wpos); extern void mFI_Wpos2DepositOFF(xyz_t wpos); extern mActor_name_t mFI_GetOtherFruit(); +extern int mFI_Wpos2UtNum_inBlock(int* ut_x, int* ut_z, xyz_t wpos); extern void mFI_PrintNowBGNum(gfxprint_t* gfxprint); extern void mFI_PrintFgAttr(gfxprint_t* gfxprint); diff --git a/include/m_mail.h b/include/m_mail.h index d70d7251..71dabf14 100644 --- a/include/m_mail.h +++ b/include/m_mail.h @@ -37,6 +37,11 @@ enum { mMl_FONT_NUM }; +enum { + mMl_TYPE_SHOP_SALE_LEAFLET = 2, + mMl_TYPE_BROKER_SALE_LEAFLET = 3 +}; + /* sizeof(Mail_nm_c) == 0x16 */ typedef struct mail_nm_s { /* 0x00 */ PersonalID_c personalID; diff --git a/include/m_museum.h b/include/m_museum.h index b4cb5db3..f6ca12fe 100644 --- a/include/m_museum.h +++ b/include/m_museum.h @@ -32,6 +32,8 @@ typedef struct museum_mail_info_s { mMsm_remail_info_c remail_info; /* remail info */ } mMsm_mail_info_c; +extern void mMsm_SendMuseumMail(Mail_c* mail); + #ifdef __cplusplus } #endif diff --git a/include/m_name_table.h b/include/m_name_table.h index 4a2007d1..332e1f92 100644 --- a/include/m_name_table.h +++ b/include/m_name_table.h @@ -865,6 +865,8 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define ITM_CALLIGRAPHY_PAD 0x2B0F #define ITM_DIARY_END 0x2B10 +#define ITM_TICKET_START 0x2C00 + #define ITM_KABU_10 0x2F00 #define ITM_KABU_50 0x2F01 #define ITM_KABU_100 0x2F02 diff --git a/include/m_npc.h b/include/m_npc.h index e2872f98..cd68597f 100644 --- a/include/m_npc.h +++ b/include/m_npc.h @@ -205,6 +205,8 @@ extern int mNpc_GetLooks(mActor_name_t npc_name); extern void mNpc_LoadNpcNameString(u8* buf, u8 idx); extern u8 mNpc_GetPaperType(); extern void mMl_set_mail_name_npcinfo(Mail_nm_c* mail_name, AnmPersonalID_c* anm_pid); +extern int mNpc_ReceiveHPMail(Mail_c* hp_mail); +extern void mNpc_SendMailtoNpc(Mail_c* mail); extern void mNpc_PrintRemoveInfo(gfxprint_t* gfxprint); extern void mNpc_PrintFriendship_fdebug(gfxprint_t* gfxprint); diff --git a/include/m_post_office.h b/include/m_post_office.h index 675ffe30..91be0cda 100644 --- a/include/m_post_office.h +++ b/include/m_post_office.h @@ -10,6 +10,7 @@ extern "C" { #endif #define mPO_MAIL_STORAGE_SIZE 5 +#define mPO_DELIVER_ALL_HOUSES -1 enum { mPO_SENDTYPE_MAIL, diff --git a/rel/ac_train0.c b/rel/ac_train0.c index 5810785c..3a151378 100644 --- a/rel/ac_train0.c +++ b/rel/ac_train0.c @@ -72,7 +72,7 @@ static void aTR0_ctrl_engineer(ACTOR* actor, GAME* game){ if(ac_p == NULL){ - if((*Common_Get(clip.train0_clip)->setup_actor_proc)(play, SP_NPC_ENGINEER, -1,-1,-1,-1,-1,0,0) == 1){ + if((*Common_Get(clip.npc_clip)->setupActor_proc)(play, SP_NPC_ENGINEER, -1,-1,-1,-1,-1,0,0) == 1){ train0->tr_actor_p = Actor_info_fgName_search(&play->actor_info, SP_NPC_ENGINEER, ACTOR_PART_4); } } diff --git a/rel/m_post_office.c b/rel/m_post_office.c new file mode 100644 index 00000000..87ea8da7 --- /dev/null +++ b/rel/m_post_office.c @@ -0,0 +1,539 @@ +#include "m_post_office.h" + +#include "m_mail.h" +#include "m_npc.h" +#include "m_handbill.h" +#include "m_museum.h" +#include "m_name_table.h" +#include "m_item_name.h" +#include "m_private.h" +#include "m_string.h" +#include "m_house.h" +#include "m_event.h" +#include "m_field_info.h" +#include "m_play.h" +#include "libultra/libultra.h" +#include "m_common_data.h" + +static int mPO_keep_contents(Mail_c* mail) { + int res = FALSE; + + int free_idx = mMl_chk_mail_free_space(Save_Get(post_office).mail, mPO_MAIL_STORAGE_SIZE); + if (free_idx >= 0) { + mMl_copy_mail(Save_Get(post_office).mail + free_idx, mail); + mMl_clear_mail(mail); + res = TRUE; + } + + return res; +} + +extern int mPO_count_mail(int house_no) { + int used = mMl_count_use_mail_space(Save_Get(homes[house_no]).mailbox, HOME_MAILBOX_SIZE); + Mail_c* mail = Save_Get(post_office).mail; + int i; + + for (i = 0; i < mPO_MAIL_STORAGE_SIZE; i++) { + if (house_no == mMl_hunt_for_send_address(mail)) { + used++; + } + + mail++; + } + + return used; +} + +extern int mPO_get_keep_mail_sum() { + PostOffice_c* post_office = Save_GetPointer(post_office); + + return post_office->keep_mail_sum_players + post_office->keep_mail_sum_npcs; +} + +static void mPO_adjust_keep_mail() { + Mail_c* mail = Save_Get(post_office).mail; + int i; + s16 recipient_flags = 0; + s16 keep_mail_player_num = 0; + + for (i = 0; i < mPO_MAIL_STORAGE_SIZE; i++) { + if (mMl_check_not_used_mail(mail) == FALSE) { + int house_idx = mMl_hunt_for_send_address(mail); + if (house_idx != -1) { + keep_mail_player_num++; + recipient_flags |= (1 << house_idx); + } + else { + mMl_clear_mail(mail); + } + } + mail++; + } + + Save_Set(post_office.mail_recipient_flags, recipient_flags); + Save_Set(post_office.keep_mail_sum_players, keep_mail_player_num); + Save_Set(post_office.keep_mail_sum_npcs, 0); +} + +static int mPO_receipt_check_mail(Mail_c* mail) { + int res = FALSE; + + switch (mail->header.recipient.type) { + case mMl_NAME_TYPE_PLAYER: + { + int house_idx = mMl_hunt_for_send_address(mail); + if (house_idx != -1 && mPO_count_mail(house_idx) < HOME_MAILBOX_SIZE) { + res = mPO_keep_contents(mail); + if (res == TRUE) { + Save_Get(post_office.mail_recipient_flags) |= (1 << house_idx); + Save_Get(post_office.keep_mail_sum_players)++; + } + } + + break; + } + + case mMl_NAME_TYPE_NPC: + { + if (mNpc_ReceiveHPMail(mail) == FALSE) { + mNpc_SendMailtoNpc(mail); + } + + res = mPO_keep_contents(mail); + if (res == TRUE) { + Save_Get(post_office).keep_mail_sum_npcs++; + } + + break; + } + + case mMl_NAME_TYPE_MUSEUM: + { + mMsm_SendMuseumMail(mail); + mMl_clear_mail(mail); + + Save_Get(post_office).keep_mail_sum_npcs++; + res = TRUE; + + break; + } + } + + return res; +} + +extern int mPO_receipt_proc(Mail_c* mail, int send_type) { + int res = FALSE; + + switch (send_type) { + case mPO_SENDTYPE_MAIL: + { + res = mPO_receipt_check_mail(mail); + break; + } + + case mPO_SENDTYPE_LEAFLET: + { + mMl_copy_mail(&Save_Get(post_office).leaflet, mail); + Save_Set(post_office.leaflet_recipient_flags.leaflet_flags, 0); + res = TRUE; + break; + } + + case mPO_SENDTYPE_EVENT_LEAFLET: + { + mMl_copy_mail(&Save_Get(post_office).event_leaflet, mail); + Save_Set(post_office.leaflet_recipient_flags.event_flags, 0); + res = TRUE; + break; + } + } + + return res; +} + +static int mPO_copy_contents(int house_no, Mail_c* mail) { + int res = FALSE; + int free_slot = mMl_chk_mail_free_space(Save_Get(homes[house_no]).mailbox, HOME_MAILBOX_SIZE); + + if (free_slot >= 0) { + mMl_copy_mail(Save_Get(homes[house_no]).mailbox + free_slot, mail); + res = TRUE; + } + + return res; +} + +static void mPO_delivery_mail_with_item(Mail_c* mail, int mail_no, mActor_name_t present, PersonalID_c* pid) { + int header_back_start; + + mHandbill_Load_HandbillFromRom(mail->content.header, &header_back_start, mail->content.footer, mail->content.body, mail_no); + + mail->content.font = mMl_FONT_0; + mail->content.header_back_start = header_back_start; + mail->content.mail_type = 7; + mail->content.paper_type = ITM_PAPER55; + mail->present = present; + + mMl_set_to_plname(mail, pid); +} + +static int mPO_delivery_mail_with_order_ftr_sub(int house_no, PersonalID_c* pid, mPr_catalog_order_c* order) { + Mail_c mail; + u8 item_name[mIN_ITEM_NAME_LEN]; + + mMl_clear_mail(&mail); + mIN_copy_name_str(item_name, order->item); + mHandbill_Set_free_str(0, item_name, mIN_ITEM_NAME_LEN); + mPO_delivery_mail_with_item(&mail, 0x049 + order->shop_level, order->item, pid); + return mPO_copy_contents(house_no, &mail); +} + +static void mPO_delivery_mail_with_order_ftr(int house_no, int player_no) { + Private_c* priv = Save_GetPointer(private[player_no]); + + if (priv->exists == TRUE) { + mPr_catalog_order_c* order = priv->catalog_orders; + int i; + + for (i = 0; i < mPr_CATALOG_ORDER_NUM; i++) { + if (order->item != EMPTY_NO) { + if (mPO_delivery_mail_with_order_ftr_sub(house_no, &priv->player_ID, order) == FALSE) { + return; + } + + order->item = EMPTY_NO; + } + + order++; + } + } +} + +static void mPO_delivery_mail_with_ticket_set_free_str(lbRTC_month_t month) { + u8 month_str[9]; + u8 day_str[4]; + + int days = lbRTC_GetDaysByMonth(Common_Get(time.rtc_time.year), month); + mString_Load_MonthStringFromRom(month_str, month); + mString_Load_DayStringFromRom(day_str, days); + mHandbill_Set_free_str(4, month_str, 9); + mHandbill_Set_free_str(5, day_str, 4); +} + +static int mPO_delivery_mail_with_ticket_sub(int house_no, PersonalID_c* pid, mActor_name_t present) { + Mail_c mail; + + mMl_clear_mail(&mail); + mPO_delivery_mail_with_item(&mail, 0x057, present, pid); + return mPO_copy_contents(house_no, &mail); +} + +static void mPO_delivery_mail_with_ticket(int house_no, int player_no) { + mActor_name_t ticket; + Private_c* priv = Save_GetPointer(private[player_no]); + + if (priv->exists == TRUE) { + int ticket_num = priv->inventory.lotto_ticket_mail_storage; + + if (ticket_num != 0) { + int minus_ticket; + mActor_name_t ticket_id; + lbRTC_month_t ticket_month = priv->inventory.lotto_ticket_expiry_month; + + mPO_delivery_mail_with_ticket_set_free_str(ticket_month); + ticket = ITM_TICKET_START + (ticket_month - 1) * 8; + + for (ticket_num; ticket_num != 0; ticket_num -= minus_ticket) { + minus_ticket = ticket_num < 5 ? ticket_num : 5; + ticket_id = ticket + minus_ticket - 1; + if (mPO_delivery_mail_with_ticket_sub(house_no, &priv->player_ID, ticket_id) == FALSE) { + break; + } + } + } + + priv->inventory.lotto_ticket_mail_storage = ticket_num; + } +} + +static int mPO_delivery_mail_sub(int house_no) { + PostOffice_c* post_office; + Mail_c* po_mail; + int i; + int res = TRUE; + + po_mail = Save_Get(post_office).mail; + post_office = Save_GetPointer(post_office); + + for (i = 0; i < mPO_MAIL_STORAGE_SIZE; i++, po_mail++) { + if (mMl_check_not_used_mail(po_mail) == FALSE) { + int dst_house_no = mMl_hunt_for_send_address(po_mail); + if (dst_house_no != -1) { + if (house_no == mPO_DELIVER_ALL_HOUSES || dst_house_no == house_no) { + if (mPO_copy_contents(dst_house_no, po_mail) == TRUE) { + post_office->keep_mail_sum_players--; + mMl_clear_mail(po_mail); + } + else { + res = FALSE; // failed to deliver the mail, house mailbox is likely full + } + } + } + else { + switch (po_mail->header.recipient.type) { + case mMl_NAME_TYPE_PLAYER: + post_office->keep_mail_sum_players--; + break; + } + + mMl_clear_mail(po_mail); + } + } + } + + Save_Set(post_office.keep_mail_sum_npcs, 0); + return res; +} + +static void mPO_delivery_one_address_mail(int house_no) { + if (mPO_delivery_mail_sub(house_no) == TRUE) { + s16 mask = (1 << house_no) ^ 0b1111; + Save_Get(post_office.mail_recipient_flags) &= mask; // clear out delivered houses + } +} + +static void mPO_delivery_one_address_special_mail(int house_no) { + int player_no = mHS_get_pl_no(house_no); + + mPO_delivery_mail_with_ticket(house_no, player_no); + mPO_delivery_mail_with_order_ftr(house_no, player_no); +} + +static void mPO_delivery_one_address_leaflet(s16* leaflet_received_flags, Mail_c* leaflet, int house_no) { + if ((((*leaflet_received_flags) >> house_no) & 1) == FALSE) { + mHm_hs_c* house = Save_GetPointer(homes[house_no]); + + if (house->ownerID.land_id == 0xFFFF) { + *leaflet_received_flags |= (1 << house_no); // unclaimed houses are marked "received" + } + else { + int player_no = mHS_get_pl_no(house_no); + if (player_no < mPr_FOREIGNER && mEv_ArbeitPlayer(player_no) == FALSE) { + mMl_set_to_plname(leaflet, &house->ownerID); + if (mPO_copy_contents(house_no, leaflet) == TRUE) { + *leaflet_received_flags |= (1 << house_no); + } + } + } + } +} + +static void mPO_delivery_one_address_event_leaflet(int house_no) { + Mail_c* ev_leaflet = &Save_Get(post_office).event_leaflet; + int special_type = mEv_get_special_event_type(); + int leaflet_event_type; + + switch (ev_leaflet->content.mail_type) { + case mMl_TYPE_SHOP_SALE_LEAFLET: + leaflet_event_type = mEv_EVENT_SHOP_SALE; + break; + + case mMl_TYPE_BROKER_SALE_LEAFLET: + leaflet_event_type = mEv_EVENT_BROKER_SALE; + break; + + default: + leaflet_event_type = -1; + break; + } + + if (leaflet_event_type == special_type) { + mPO_delivery_one_address_leaflet(&Save_Get(post_office).leaflet_recipient_flags.event_flags, ev_leaflet, house_no); + } +} + +extern int mPO_delivery_one_address(int house_no) { + mPO_delivery_one_address_mail(house_no); + mPO_delivery_one_address_leaflet(&Save_Get(post_office).leaflet_recipient_flags.leaflet_flags, &Save_Get(post_office).leaflet, house_no); + mPO_delivery_one_address_event_leaflet(house_no); +} + +static void mPO_delivery_mail() { + mPO_delivery_mail_sub(mPO_DELIVER_ALL_HOUSES); + mPO_adjust_keep_mail(); +} + +static void mPO_delivery_leaflet() { + int house_no; + + for (house_no = 0; house_no < mHS_HOUSE_NUM; house_no++) { + mPO_delivery_one_address_leaflet(&Save_Get(post_office).leaflet_recipient_flags.leaflet_flags, &Save_Get(post_office).leaflet, house_no); + mPO_delivery_one_address_event_leaflet(house_no); + } +} + +extern void mPO_delivery_all_address_proc() { + mPO_delivery_mail(); + mPO_delivery_leaflet(); +} + +static int mPO_make_post_man(GAME_PLAY* play) { + static int bx_add[2] = { -1, 1 }; + static int ux_table[2] = { UT_X_NUM - 1, 0 }; + + int pl_block_x; + int pl_block_z; + u32 block_kind; + + int po_block_x; + int po_block_z; + int res = FALSE; + + if (Save_Get(scene_no) == SCENE_FG) { + mFI_BlockKind2BkNum(&pl_block_x, &pl_block_z, mRF_BLOCKKIND_PLAYER); + block_kind = mFI_BkNum2BlockKind(play->block_table.block_x, play->block_table.block_z); + + if (block_kind != mRF_BLOCKKIND_NONE) { + if ((block_kind & mRF_BLOCKKIND_PLAYER) != 0) { + int bx_add_idx; + int spawned_postman; + + mFI_BlockKind2BkNum(&po_block_x, &po_block_z, mRF_BLOCKKIND_POSTOFFICE); + bx_add_idx = pl_block_x >= po_block_x ? 0 : 1; + spawned_postman = (*Common_Get(clip).npc_clip->setupActor_proc)(play, SP_NPC_POST_MAN, -1, -1, 0, play->block_table.block_x + bx_add[bx_add_idx], play->block_table.block_z, ux_table[bx_add_idx], 7); + + if (spawned_postman == TRUE) { + res = TRUE; + } + } + else if ((block_kind & mRF_BLOCKKIND_POSTOFFICE) != 0) { + if (Common_Get(force_mail_delivery_flag) == TRUE) { + int post_utx; + int post_utz; + int spawned_postman; + ACTOR* post_office_structure = Actor_info_fgName_search(&play->actor_info, POST_OFFICE, ACTOR_PART_ITEM); + + if (post_office_structure != NULL) { + mFI_Wpos2UtNum_inBlock(&post_utx, &post_utz, post_office_structure->world_position); + spawned_postman = (*Common_Get(clip).npc_clip->setupActor_proc)(play, SP_NPC_POST_MAN, -1, -1, 1, play->block_table.block_x, play->block_table.block_z, post_utx - 3, post_utz); + + if (spawned_postman == TRUE) { + res = TRUE; + } + } + } + } + else { + mPO_delivery_all_address_proc(); + res = TRUE; + } + } + else { + mPO_delivery_all_address_proc(); + res = TRUE; + } + } + else { + mPO_delivery_all_address_proc(); + res = TRUE; + } + + return res; +} + +static void mPO_set_next_delivery_time(lbRTC_time_c* time) { + if (time->hour < 9) { + time->hour = 9; + } + else if (time->hour < 17) { + time->hour = 17; + } + else { + lbRTC_Add_DD(time, 1); + time->hour = 9; + } + + time->min = 0; + time->sec = 0; + lbRTC_TimeCopy(&Save_Get(post_office).delivery_time, time); +} + +static void mPO_delivery_proc(GAME_PLAY* play) { + lbRTC_time_c time; + + lbRTC_TimeCopy(&time, Common_GetPointer(time.rtc_time)); + + if ((lbRTC_IsOverTime(&Save_Get(post_office).delivery_time, &time) == lbRTC_OVER || Common_Get(force_mail_delivery_flag) == TRUE) && + (mPO_make_post_man(play) == TRUE) + ) { + mPO_set_next_delivery_time(&time); + Common_Set(force_mail_delivery_flag, FALSE); + } +} + +static void mPO_first_delivery_proc() { + int deliver = FALSE; + lbRTC_time_c time; + + lbRTC_TimeCopy(&time, Common_GetPointer(time.rtc_time)); + + if (lbRTC_IsOverTime(&Save_Get(post_office).delivery_time, &time) == lbRTC_OVER || Common_Get(force_mail_delivery_flag) == TRUE) { + deliver = TRUE; + mPO_set_next_delivery_time(&time); + Common_Set(force_mail_delivery_flag, FALSE); + } + + if (deliver == TRUE) { + mPO_delivery_mail(); + } + + if (mLd_PlayerManKindCheck() == FALSE) { + int house_no = mHS_get_arrange_idx(Common_Get(player_no)); + mPO_delivery_one_address_special_mail(house_no); + } + + if (deliver == TRUE) { + mPO_delivery_leaflet(); + } +} + +extern void mPO_business_proc(GAME_PLAY* play) { + if ((Common_Get(clip).demo_clip == NULL && Common_Get(clip).demo_clip2 == NULL) || + (Common_Get(clip).demo_clip != NULL && Common_Get(clip).demo_clip->type == mDemo_CLIP_TYPE_INTRO_DEMO) + ) { + int scene = Save_Get(scene_no); + + switch (scene) { + default: + mPO_delivery_proc(play); + break; + + case SCENE_PLAYERSELECT: + case SCENE_PLAYERSELECT_2: + case SCENE_PLAYERSELECT_3: + case SCENE_PLAYERSELECT_SAVE: + case SCENE_TITLE_DEMO: + return; + } + } +} + +extern void mPO_first_work() { + lbRTC_time_c* time = &Save_Get(save_check).time; + if (mTM_AreTimesEqual(time, &mTM_rtcTime_clear_code) == FALSE && lbRTC_IsOverRTC(time) == FALSE) { + Common_Set(force_mail_delivery_flag, TRUE); + } + + mPO_first_delivery_proc(); + mPO_adjust_keep_mail(); +} + +extern void mPO_post_office_init() { + bzero(Save_GetPointer(post_office), sizeof(PostOffice_c)); + mMl_clear_mail_box(Save_Get(post_office).mail, mPO_MAIL_STORAGE_SIZE); + mMl_clear_mail(&Save_Get(post_office).leaflet); + mMl_clear_mail(&Save_Get(post_office).event_leaflet); + Save_Get(post_office).leaflet_recipient_flags.raw = 0x000F000F; + lbRTC_TimeCopy(&Save_Get(post_office).delivery_time, Common_GetPointer(time.rtc_time)); +}