#include "m_mail.h" #include "m_private.h" #include "m_font.h" #include "m_land.h" #include "m_name_table.h" #include "m_common_data.h" #include "m_house.h" #include "m_handbill.h" #include "libultra/libultra.h" /* TODO: fix bss ordering*/ static u8 free_str[16]; static Mail_c l_ml_mail; static u8 footer[MAIL_FOOTER2_LEN]; static u8 header[MAIL_HEADER2_LEN]; extern int mMl_strlen(u8* str, int size, u8 end_char) { u32 end_p = size + (u32)str; int i; end_p--; for (size; size != 0; size--) { if (*(u8*)end_p != end_char) { return size; } end_p--; } return 0; } extern int mMl_strlen2(int* found, u8* str, int size, u8 end_char) { int len = 0; if (found != NULL) { *found = FALSE; } for (size; size != 0; size--) { len++; if (*str == end_char) { if (found != NULL) { *found = TRUE; } break; } str++; } return len; } extern void mMl_clear_mail_header(Mail_hdr_c* header) { mPr_ClearPersonalID(&header->recipient.personalID); header->recipient.type = mMl_TYPE_CLEAR; mPr_ClearPersonalID(&header->sender.personalID); header->sender.type = mMl_TYPE_CLEAR; } extern void mMl_clear_mail(Mail_c* mail) { bzero(mail, sizeof(Mail_c)); mMl_clear_mail_header(&mail->header); mem_clear(mail->content.header, MAIL_HEADER_LEN + MAIL_BODY_LEN + MAIL_FOOTER_LEN, CHAR_SPACE); mail->content.font = -1; } extern void mMl_clear_mail_box(Mail_c* mail, int num) { while (num != 0) { num--; mMl_clear_mail(mail); mail++; } } extern int mMl_check_not_used_mail(Mail_c* mail) { int res = FALSE; if (mail->content.font == 0xFF) { res = TRUE; } return res; } extern void mMl_copy_header_name(Mail_c* dst, Mail_c* src) { dst->header.recipient.type = src->header.recipient.type; mPr_CopyPersonalID(&dst->header.recipient.personalID, &src->header.recipient.personalID); } extern void mMl_set_to_plname(Mail_c* mail, PersonalID_c* pid) { mPr_CopyPersonalID(&mail->header.recipient.personalID, pid); mail->header.recipient.type = mMl_NAME_TYPE_PLAYER; } extern void mMl_set_playername(Mail_c* mail, PersonalID_c* pid) { mPr_CopyPersonalID(&mail->header.sender.personalID, pid); mail->header.sender.type = mMl_NAME_TYPE_PLAYER; } extern void mMl_init_mail(Mail_c* mail, PersonalID_c* pid) { mMl_clear_mail(mail); mMl_set_playername(mail, pid); mail->content.font = mMl_FONT_SEND; mail->content.mail_type = 0; mail->content.paper_type = 0; } extern int mMl_chk_mail_free_space(Mail_c* mail, int num) { int free_idx; for (free_idx = 0; free_idx < num; free_idx++) { if (mMl_check_not_used_mail(mail) == TRUE) { return free_idx; } mail++; } return -1; } extern int mMl_count_use_mail_space(Mail_c* mail, int num) { int used = 0; int i; for (i = 0; i < num; i++) { if (mMl_check_not_used_mail(mail) != TRUE) { used++; } mail++; } return used; } extern void mMl_copy_mail(Mail_c* dst, Mail_c* src) { mem_copy((u8*)dst, (u8*)src, sizeof(Mail_c)); } extern void mMl_clear_mail_header_common(Mail_hs_c* header) { header->header_back_start = -1; header->unknown = 0; mem_clear(header->header, MAIL_HEADER_LEN, CHAR_SPACE); mem_clear(header->footer, MAIL_FOOTER_LEN, CHAR_SPACE); } extern void mMl_set_mail_name_npcinfo(Mail_nm_c* name, AnmPersonalID_c* anm_pid) { u8 animal_name[PLAYER_NAME_LEN]; name->type = mMl_NAME_TYPE_NPC; mNpc_GetNpcWorldNameAnm(animal_name, anm_pid); mPr_CopyPlayerName(name->personalID.player_name, animal_name); name->personalID.land_id = anm_pid->land_id; mLd_CopyLandName(name->personalID.land_name, anm_pid->land_name); name->personalID.player_id = (((anm_pid->npc_id & 0xFF) << 8) | anm_pid->name_id); } extern int mMl_get_npcinfo_from_mail_name(AnmPersonalID_c* anm_pid, Mail_nm_c* name) { int res = FALSE; if (name->type == mMl_NAME_TYPE_NPC) { anm_pid->npc_id = ((name->personalID.player_id & 0xFF00) >> 8) | NPC_START; anm_pid->land_id = name->personalID.land_id; mLd_CopyLandName(anm_pid->land_name, name->personalID.land_name); anm_pid->name_id = name->personalID.player_id; anm_pid->looks = mNpc_GetLooks(anm_pid->npc_id); res = TRUE; } return res; } extern int mMl_hunt_for_send_address(Mail_c* mail) { int i; if (mail->header.recipient.type != mMl_NAME_TYPE_PLAYER) { return -1; } for (i = 0; i < mHS_HOUSE_NUM; i++) { if (mPr_CheckCmpPersonalID(&Save_Get(homes[i]).ownerID, &mail->header.recipient.personalID) == TRUE) { return i; } } return -1; } extern int mMl_check_send_mail(Mail_c* mail) { return mail->content.font == mMl_FONT_SEND; } extern int mMl_check_set_present_myself(Mail_c* mail) { u8 font = mail->content.font; if (font == mMl_FONT_SEND || font == mMl_FONT_3 || font == mMl_FONT_4) { return TRUE; } return FALSE; } static void mMl_load_mail_data(Mail_c* mail, int mail_no) { int header_back_start; mHandbill_Load_HandbillFromRom(mail->content.header, &header_back_start, mail->content.footer, mail->content.body, mail_no); mail->content.header_back_start = header_back_start; } /* TODO: fix bss ordering */ static void mMl_load_mail_data2(Mail_c* mail, int mail_no) { //static u8 header[MAIL_HEADER2_LEN]; //static u8 footer[MAIL_FOOTER2_LEN]; int header_back_start; mHandbill_Load_HandbillFromRom2(header, MAIL_HEADER2_LEN, &header_back_start, footer, MAIL_FOOTER2_LEN, mail->content.body, mail_no); bcopy(header, mail->content.header, MAIL_HEADER_LEN); bcopy(footer, mail->content.footer, MAIL_FOOTER_LEN); mail->content.header_back_start = header_back_start; } static void mMl_get_mail_to_player_com(Mail_c* mail, PersonalID_c* recipient_pid, mActor_name_t present, mActor_name_t paper, u8* sender_name, int mail_no, u32 proc_type, u8 mail_type) { static void (*get_proc[2])(Mail_c*, int) = { &mMl_load_mail_data, &mMl_load_mail_data2 }; proc_type %= 2; mMl_clear_mail(mail); (*get_proc[proc_type])(mail, mail_no); mail->content.font = mMl_FONT_0; mail->content.mail_type = mail_type; mPr_CopyPersonalID(&mail->header.recipient.personalID, recipient_pid); mail->header.recipient.type = mMl_NAME_TYPE_PLAYER; mPr_ClearPersonalID(&mail->header.sender.personalID); mPr_CopyPlayerName(mail->header.sender.personalID.player_name, sender_name); mail->header.sender.type = mMl_NAME_TYPE_MUSEUM; mail->present = present; mail->content.paper_type = (paper - ITM_PAPER_START) % 64; } static int mMl_send_mail_box_com(PersonalID_c* recipient_pid, int player_no, Mail_c* mail, mActor_name_t present, mActor_name_t paper, int mail_no, u8* sender_name, u32 proc_type, u8 mail_type) { mHm_hs_c* house; int res = FALSE; house = Save_GetPointer(homes[mHS_get_arrange_idx(player_no)]); if (mPr_CheckCmpPersonalID(recipient_pid, &house->ownerID) == TRUE) { int free_idx = mMl_chk_mail_free_space(house->mailbox, HOME_MAILBOX_SIZE); if (free_idx != -1) { mMl_get_mail_to_player_com(mail, recipient_pid, present, paper, sender_name, mail_no, proc_type, mail_type); mMl_copy_mail(house->mailbox + free_idx, mail); res = TRUE; } } return res; } extern int mMl_send_mail_box(PersonalID_c* recipient_pid, int player_no, Mail_c* mail, mActor_name_t present, mActor_name_t paper, int mail_no, u8* sender_name, u32 proc_type) { return mMl_send_mail_box_com(recipient_pid, player_no, mail, present, paper, mail_no, sender_name, proc_type, 0); } static int mMl_send_mail_postoffice_com(Mail_c* mail, PersonalID_c* recipient_pid, int player_no, mActor_name_t present, mActor_name_t paper, int mail_no, u8* sender_name, u32 proc_type, u8 mail_type) { int res = FALSE; if (mPO_get_keep_mail_sum() < mPO_MAIL_STORAGE_SIZE) { mMl_get_mail_to_player_com(mail, recipient_pid, present, paper, sender_name, mail_no, proc_type, mail_type); res = mPO_receipt_proc(mail, mPO_SENDTYPE_MAIL); } return res; } extern int mMl_send_mail_postoffice(PersonalID_c* recipient_pid, int player_no, mActor_name_t present, mActor_name_t paper, int mail_no, u8* sender_name, u32 proc_type, u8 mail_type) { return mMl_send_mail_postoffice_com(&l_ml_mail, recipient_pid, player_no, present, paper, mail_no, sender_name, proc_type, mail_type); } static int mMl_send_mail_com(PersonalID_c* recipient_pid, int player_no, mActor_name_t present, mActor_name_t paper, int mail_no, u8* sender_name, u32 proc_type, u8 mail_type) { Mail_c* mail = &l_ml_mail; int res = mMl_send_mail_box_com(recipient_pid, player_no, mail, present, paper, mail_no, sender_name, proc_type, mail_type); if (res != TRUE) { res = mMl_send_mail_postoffice_com(mail, recipient_pid, player_no, present, paper, mail_no, sender_name, proc_type, mail_type); } return res; } extern int mMl_send_mail(PersonalID_c* recipient_pid, int player_no, mActor_name_t present, mActor_name_t paper, int mail_no, u8* sender_name, u32 proc_type) { return mMl_send_mail_com(recipient_pid, player_no, present, paper, mail_no, sender_name, proc_type, 0); } typedef struct post_office_gift_info_s { int mail_no; mActor_name_t present; mActor_name_t paper; int player_received_flag; u32 required_balance; } mMl_PostOffice_Info_c; static mMl_PostOffice_Info_c l_mml_postoffice_info[mMl_POSTOFFICE_GIFT_NUM] = { { 0x0246, FTR_TISSUE, ITM_PAPER00, mPr_FLAG_POSTOFFICE_GIFT0, 1000000 }, { 0x0247, FTR_PIGGY_BANK, ITM_PAPER00, mPr_FLAG_POSTOFFICE_GIFT1, 10000000 }, { 0x0248, FTR_MAILBOX, ITM_PAPER00, mPr_FLAG_POSTOFFICE_GIFT2, 100000000 }, { 0x0249, FTR_POST_MODEL, ITM_PAPER00, mPr_FLAG_POSTOFFICE_GIFT3, 999999999 } }; static void mMl_send_postoffice_mail() { //static u8 free_str[16]; // TODO: fix bss ordering static u8 debug_name[PLAYER_NAME_LEN] = { 0x91, 0x92, 0x93, 0x94, 0x95, 0x91, 0x00, 0x00 }; Private_c* priv = Save_Get(private); mMl_PostOffice_Info_c* po_info; int town_name_len; int i; town_name_len = mLd_GetLandNameStringAddMura(free_str); mHandbill_Set_free_str(0, free_str, town_name_len); for (i = 0; i < PLAYER_NUM; i++) { if (mPr_NullCheckPersonalID(&priv->player_ID) == FALSE) { int j; mHandbill_Set_free_str(1, priv->player_ID.player_name, PLAYER_NAME_LEN); po_info = l_mml_postoffice_info; for (j = 0; j < mMl_POSTOFFICE_GIFT_NUM; j++) { if ((priv->bank_account >= po_info->required_balance) && (priv->state_flags & po_info->player_received_flag) == FALSE ) { int res = mMl_send_mail_com(&priv->player_ID, i, po_info->present, po_info->paper, po_info->mail_no, debug_name, 0, 10); if (res == TRUE) { priv->state_flags |= po_info->player_received_flag; } break; } po_info++; } } priv++; } } extern void mMl_start_send_mail() { mMl_send_postoffice_mail(); }