diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 6da4390a..184f592d 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -79,6 +79,11 @@ m_police_box.c: .text: [0x803DE8A0, 0x803DEE38] .rodata: [0x806431C8, 0x806431D8] .data: [0x8065BE98, 0x8065BEF0] +m_private.c: + .text: [0x803DFF7C, 0x803E2990] + .rodata: [0x806431D8, 0x80643208] + .data: [0x8065BF00, 0x8065C030] + .bss: [0x8129CD40, 0x8129F2B0] m_random_field.c: .text: [0x803E4B20, 0x803E50E4] .rodata: [0x80643218, 0x80643240] diff --git a/include/m_common_data.h b/include/m_common_data.h index 6a0976fb..c466fdec 100644 --- a/include/m_common_data.h +++ b/include/m_common_data.h @@ -95,7 +95,7 @@ typedef struct Save_s { /* 0x020F1B */ u8 npc_force_go_home; /* when set to 1, forces the 'm_go_home' code to activate */ /* 0x020F1C */ u16 deposit[FG_BLOCK_X_NUM * FG_BLOCK_Z_NUM][UT_Z_NUM]; /* flags for which items are buried around town */ /* 0x0212DC */ lbRTC_time_c last_grow_time; /* last time that a new villager moved into town */ - /* 0x0212E4 */ u8 _tmp4[0x02131C - 0x0212E4]; + /* 0x0212E4 */ mPr_mother_mail_info_c mother_mail[PLAYER_NUM]; /* info on when mom sent player letters and what event was sent */ /* 0x02131C */ mMsr_MushTime_c mushroom_time; /* last time mushroom season info was updated */ /* 0x021322 */ u8 _tmp21322[0x02137E - 0x021322]; /* 0x02137E */ lbRTC_time_c treasure_buried_time; /* last time treasure was actually buried */ diff --git a/include/m_event.h b/include/m_event.h index d6795abf..d85d86d8 100644 --- a/include/m_event.h +++ b/include/m_event.h @@ -109,6 +109,8 @@ enum week_type { }; enum event_table { + mEv_EVENT_MOTHERS_DAY = 23, + mEv_EVENT_FATHERS_DAY = 26, mEv_EVENT_FISHING_TOURNEY_1 = 29, mEv_EVENT_MUSHROOM_SEASON = 47, mEv_EVENT_FISHING_TOURNEY_2 = 54, diff --git a/include/m_field_info.h b/include/m_field_info.h index abf0ac12..ba0348ff 100644 --- a/include/m_field_info.h +++ b/include/m_field_info.h @@ -142,6 +142,7 @@ extern void mFI_ClearFieldData(); 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 void mFI_PrintNowBGNum(gfxprint_t* gfxprint); extern void mFI_PrintFgAttr(gfxprint_t* gfxprint); diff --git a/include/m_handbill.h b/include/m_handbill.h index e56438ea..5b7e1016 100644 --- a/include/m_handbill.h +++ b/include/m_handbill.h @@ -13,6 +13,7 @@ extern "C" { #define mHandbill_BODY_LEN MAIL_BODY_LEN extern void mHandbill_Load_HandbillFromRom(u8* header, int* header_back_pos, u8* footer, u8* body, int handbill_no); +extern void mHandbill_Load_HandbillFromRom2(u8* header, int header_size, int* header_back_pos, u8* footer, int footer_size, u8* body, int handbill_no); extern void mHandbill_Set_free_str(int free_str_no, u8* str, int str_len); extern void mHandbill_Set_free_str_art(int free_str_no, u8* str, int str_len, int article_no); diff --git a/include/m_lib.h b/include/m_lib.h index e36ad015..29e6ca26 100644 --- a/include/m_lib.h +++ b/include/m_lib.h @@ -4,7 +4,7 @@ #include "types.h" #include "m_play_h.h" #include "m_actor_type.h" -#include "MSL_C/math.h" +#include "sys_math.h" #include "libu64/u64types.h" #include "game.h" diff --git a/include/m_mail.h b/include/m_mail.h index 4067987e..7a903026 100644 --- a/include/m_mail.h +++ b/include/m_mail.h @@ -61,6 +61,10 @@ typedef struct mail_s { extern int mMl_strlen(u8* str, int maxlen, u8 check_char); extern void mMl_clear_mail_box(Mail_c* mail_box, int count); +extern void mMl_clear_mail(Mail_c* mail); +extern void mMl_set_to_plname(Mail_c* mail, PersonalID_c* pid); +extern int mMl_chk_mail_free_space(Mail_c* mailbox, int count); +extern void mMl_copy_mail(Mail_c* dst, Mail_c* src); #ifdef __cplusplus } diff --git a/include/m_name_table.h b/include/m_name_table.h index 2a61b686..b0c57f60 100644 --- a/include/m_name_table.h +++ b/include/m_name_table.h @@ -324,6 +324,16 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define FTR0_START 0x1000 +#define FTR_PAPA_BEAR 0x10E8 +#define FTR_PAPA_BEAR_EAST 0x10E9 +#define FTR_PAPA_BEAR_NORTH 0x10EA +#define FTR_PAPA_BEAR_WEST 0x10EB + +#define FTR_DRACAENA 0x13B0 +#define FTR_DRACAENA_EAST 0x13B1 +#define FTR_DRACAENA_NORTH 0x13B2 +#define FTR_DRACAENA_WEST 0x13B3 + #define FTR_CLOTH_MANNIQUIN000_SOUTH 0x17AC #define FTR_REDALOHASHIRT 0x1814 @@ -334,10 +344,29 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define FTR_CLOTH_MANNIQUIN254_WEST 0x1BA7 #define FTR_CLOTH_MANNIQUIN_MY_ORIGINAL0 0x1BA8 +#define FTR_INSECT00 0x1BC8 + +#define FTR_INSECT39 0x1C64 +#define FTR_INSECT39_EAST 0x1C65 +#define FTR_INSECT39_NORTH 0x1C66 +#define FTR_INSECT39_WEST 0x1C67 + +#define FTR_FISH00 0x1C68 + +#define FTR_FISH39 0x1D04 +#define FTR_FISH39_EAST 0x1D05 +#define FTR_FISH39_NORTH 0x1D06 +#define FTR_FISH39_WEST 0x1D07 + #define FTR_UMBRELLA00_SOUTH 0x1D08 #define FTR_UMBRELLA31_WEST 0x1D87 +#define FTR_BIRTHDAY_CAKE 0x11FC +#define FTR_BIRTHDAY_CAKE_EAST 0x11FD +#define FTR_BIRTHDAY_CAKE_NORTH 0x11FE +#define FTR_BIRTHDAY_CAKE_WEST 0x11FF + #define FTR0_END 0x1FFF #define FTR_TAPEDECK 0x1E58 @@ -423,20 +452,329 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define ITM_TOOL_END (ITM_LEAF_FAN + 1) #define ITM_CLOTH_START 0x2400 -#define ITM_CLOTH000 ITM_CLOTH_START -#define ITM_CLOTH001 (ITM_CLOTH_START + 1) -#define ITM_CLOTH_END 0x24FF +#define ITM_CLOTH000 (ITM_CLOTH_START + 0) +#define ITM_CLOTH001 (ITM_CLOTH_START + 1) +#define ITM_CLOTH002 (ITM_CLOTH_START + 2) +#define ITM_CLOTH003 (ITM_CLOTH_START + 3) +#define ITM_CLOTH004 (ITM_CLOTH_START + 4) +#define ITM_CLOTH005 (ITM_CLOTH_START + 5) +#define ITM_CLOTH006 (ITM_CLOTH_START + 6) +#define ITM_CLOTH007 (ITM_CLOTH_START + 7) +#define ITM_CLOTH008 (ITM_CLOTH_START + 8) +#define ITM_CLOTH009 (ITM_CLOTH_START + 9) +#define ITM_CLOTH010 (ITM_CLOTH_START + 10) +#define ITM_CLOTH011 (ITM_CLOTH_START + 11) +#define ITM_CLOTH012 (ITM_CLOTH_START + 12) +#define ITM_CLOTH013 (ITM_CLOTH_START + 13) +#define ITM_CLOTH014 (ITM_CLOTH_START + 14) +#define ITM_CLOTH015 (ITM_CLOTH_START + 15) +#define ITM_CLOTH016 (ITM_CLOTH_START + 16) +#define ITM_CLOTH017 (ITM_CLOTH_START + 17) +#define ITM_CLOTH018 (ITM_CLOTH_START + 18) +#define ITM_CLOTH019 (ITM_CLOTH_START + 19) +#define ITM_CLOTH020 (ITM_CLOTH_START + 20) +#define ITM_CLOTH021 (ITM_CLOTH_START + 21) +#define ITM_CLOTH022 (ITM_CLOTH_START + 22) +#define ITM_CLOTH023 (ITM_CLOTH_START + 23) +#define ITM_CLOTH024 (ITM_CLOTH_START + 24) +#define ITM_CLOTH025 (ITM_CLOTH_START + 25) +#define ITM_CLOTH026 (ITM_CLOTH_START + 26) +#define ITM_CLOTH027 (ITM_CLOTH_START + 27) +#define ITM_CLOTH028 (ITM_CLOTH_START + 28) +#define ITM_CLOTH029 (ITM_CLOTH_START + 29) +#define ITM_CLOTH030 (ITM_CLOTH_START + 30) +#define ITM_CLOTH031 (ITM_CLOTH_START + 31) +#define ITM_CLOTH032 (ITM_CLOTH_START + 32) +#define ITM_CLOTH033 (ITM_CLOTH_START + 33) +#define ITM_CLOTH034 (ITM_CLOTH_START + 34) +#define ITM_CLOTH035 (ITM_CLOTH_START + 35) +#define ITM_CLOTH036 (ITM_CLOTH_START + 36) +#define ITM_CLOTH037 (ITM_CLOTH_START + 37) +#define ITM_CLOTH038 (ITM_CLOTH_START + 38) +#define ITM_CLOTH039 (ITM_CLOTH_START + 39) +#define ITM_CLOTH040 (ITM_CLOTH_START + 40) +#define ITM_CLOTH041 (ITM_CLOTH_START + 41) +#define ITM_CLOTH042 (ITM_CLOTH_START + 42) +#define ITM_CLOTH043 (ITM_CLOTH_START + 43) +#define ITM_CLOTH044 (ITM_CLOTH_START + 44) +#define ITM_CLOTH045 (ITM_CLOTH_START + 45) +#define ITM_CLOTH046 (ITM_CLOTH_START + 46) +#define ITM_CLOTH047 (ITM_CLOTH_START + 47) +#define ITM_CLOTH048 (ITM_CLOTH_START + 48) +#define ITM_CLOTH049 (ITM_CLOTH_START + 49) +#define ITM_CLOTH050 (ITM_CLOTH_START + 50) +#define ITM_CLOTH051 (ITM_CLOTH_START + 51) +#define ITM_CLOTH052 (ITM_CLOTH_START + 52) +#define ITM_CLOTH053 (ITM_CLOTH_START + 53) +#define ITM_CLOTH054 (ITM_CLOTH_START + 54) +#define ITM_CLOTH055 (ITM_CLOTH_START + 55) +#define ITM_CLOTH056 (ITM_CLOTH_START + 56) +#define ITM_CLOTH057 (ITM_CLOTH_START + 57) +#define ITM_CLOTH058 (ITM_CLOTH_START + 58) +#define ITM_CLOTH059 (ITM_CLOTH_START + 59) +#define ITM_CLOTH060 (ITM_CLOTH_START + 60) +#define ITM_CLOTH061 (ITM_CLOTH_START + 61) +#define ITM_CLOTH062 (ITM_CLOTH_START + 62) +#define ITM_CLOTH063 (ITM_CLOTH_START + 63) +#define ITM_CLOTH064 (ITM_CLOTH_START + 64) +#define ITM_CLOTH065 (ITM_CLOTH_START + 65) +#define ITM_CLOTH066 (ITM_CLOTH_START + 66) +#define ITM_CLOTH067 (ITM_CLOTH_START + 67) +#define ITM_CLOTH068 (ITM_CLOTH_START + 68) +#define ITM_CLOTH069 (ITM_CLOTH_START + 69) +#define ITM_CLOTH070 (ITM_CLOTH_START + 70) +#define ITM_CLOTH071 (ITM_CLOTH_START + 71) +#define ITM_CLOTH072 (ITM_CLOTH_START + 72) +#define ITM_CLOTH073 (ITM_CLOTH_START + 73) +#define ITM_CLOTH074 (ITM_CLOTH_START + 74) +#define ITM_CLOTH075 (ITM_CLOTH_START + 75) +#define ITM_CLOTH076 (ITM_CLOTH_START + 76) +#define ITM_CLOTH077 (ITM_CLOTH_START + 77) +#define ITM_CLOTH078 (ITM_CLOTH_START + 78) +#define ITM_CLOTH079 (ITM_CLOTH_START + 79) +#define ITM_CLOTH080 (ITM_CLOTH_START + 80) +#define ITM_CLOTH081 (ITM_CLOTH_START + 81) +#define ITM_CLOTH082 (ITM_CLOTH_START + 82) +#define ITM_CLOTH083 (ITM_CLOTH_START + 83) +#define ITM_CLOTH084 (ITM_CLOTH_START + 84) +#define ITM_CLOTH085 (ITM_CLOTH_START + 85) +#define ITM_CLOTH086 (ITM_CLOTH_START + 86) +#define ITM_CLOTH087 (ITM_CLOTH_START + 87) +#define ITM_CLOTH088 (ITM_CLOTH_START + 88) +#define ITM_CLOTH089 (ITM_CLOTH_START + 89) +#define ITM_CLOTH090 (ITM_CLOTH_START + 90) +#define ITM_CLOTH091 (ITM_CLOTH_START + 91) +#define ITM_CLOTH092 (ITM_CLOTH_START + 92) +#define ITM_CLOTH093 (ITM_CLOTH_START + 93) +#define ITM_CLOTH094 (ITM_CLOTH_START + 94) +#define ITM_CLOTH095 (ITM_CLOTH_START + 95) +#define ITM_CLOTH096 (ITM_CLOTH_START + 96) +#define ITM_CLOTH097 (ITM_CLOTH_START + 97) +#define ITM_CLOTH098 (ITM_CLOTH_START + 98) +#define ITM_CLOTH099 (ITM_CLOTH_START + 99) +#define ITM_CLOTH100 (ITM_CLOTH_START + 100) +#define ITM_CLOTH101 (ITM_CLOTH_START + 101) +#define ITM_CLOTH102 (ITM_CLOTH_START + 102) +#define ITM_CLOTH103 (ITM_CLOTH_START + 103) +#define ITM_CLOTH104 (ITM_CLOTH_START + 104) +#define ITM_CLOTH105 (ITM_CLOTH_START + 105) +#define ITM_CLOTH106 (ITM_CLOTH_START + 106) +#define ITM_CLOTH107 (ITM_CLOTH_START + 107) +#define ITM_CLOTH108 (ITM_CLOTH_START + 108) +#define ITM_CLOTH109 (ITM_CLOTH_START + 109) +#define ITM_CLOTH110 (ITM_CLOTH_START + 110) +#define ITM_CLOTH111 (ITM_CLOTH_START + 111) +#define ITM_CLOTH112 (ITM_CLOTH_START + 112) +#define ITM_CLOTH113 (ITM_CLOTH_START + 113) +#define ITM_CLOTH114 (ITM_CLOTH_START + 114) +#define ITM_CLOTH115 (ITM_CLOTH_START + 115) +#define ITM_CLOTH116 (ITM_CLOTH_START + 116) +#define ITM_CLOTH117 (ITM_CLOTH_START + 117) +#define ITM_CLOTH118 (ITM_CLOTH_START + 118) +#define ITM_CLOTH119 (ITM_CLOTH_START + 119) +#define ITM_CLOTH120 (ITM_CLOTH_START + 120) +#define ITM_CLOTH121 (ITM_CLOTH_START + 121) +#define ITM_CLOTH122 (ITM_CLOTH_START + 122) +#define ITM_CLOTH123 (ITM_CLOTH_START + 123) +#define ITM_CLOTH124 (ITM_CLOTH_START + 124) +#define ITM_CLOTH125 (ITM_CLOTH_START + 125) +#define ITM_CLOTH126 (ITM_CLOTH_START + 126) +#define ITM_CLOTH127 (ITM_CLOTH_START + 127) +#define ITM_CLOTH128 (ITM_CLOTH_START + 128) +#define ITM_CLOTH129 (ITM_CLOTH_START + 129) +#define ITM_CLOTH130 (ITM_CLOTH_START + 130) +#define ITM_CLOTH131 (ITM_CLOTH_START + 131) +#define ITM_CLOTH132 (ITM_CLOTH_START + 132) +#define ITM_CLOTH133 (ITM_CLOTH_START + 133) +#define ITM_CLOTH134 (ITM_CLOTH_START + 134) +#define ITM_CLOTH135 (ITM_CLOTH_START + 135) +#define ITM_CLOTH136 (ITM_CLOTH_START + 136) +#define ITM_CLOTH137 (ITM_CLOTH_START + 137) +#define ITM_CLOTH138 (ITM_CLOTH_START + 138) +#define ITM_CLOTH139 (ITM_CLOTH_START + 139) +#define ITM_CLOTH140 (ITM_CLOTH_START + 140) +#define ITM_CLOTH141 (ITM_CLOTH_START + 141) +#define ITM_CLOTH142 (ITM_CLOTH_START + 142) +#define ITM_CLOTH143 (ITM_CLOTH_START + 143) +#define ITM_CLOTH144 (ITM_CLOTH_START + 144) +#define ITM_CLOTH145 (ITM_CLOTH_START + 145) +#define ITM_CLOTH146 (ITM_CLOTH_START + 146) +#define ITM_CLOTH147 (ITM_CLOTH_START + 147) +#define ITM_CLOTH148 (ITM_CLOTH_START + 148) +#define ITM_CLOTH149 (ITM_CLOTH_START + 149) +#define ITM_CLOTH150 (ITM_CLOTH_START + 150) +#define ITM_CLOTH151 (ITM_CLOTH_START + 151) +#define ITM_CLOTH152 (ITM_CLOTH_START + 152) +#define ITM_CLOTH153 (ITM_CLOTH_START + 153) +#define ITM_CLOTH154 (ITM_CLOTH_START + 154) +#define ITM_CLOTH155 (ITM_CLOTH_START + 155) +#define ITM_CLOTH156 (ITM_CLOTH_START + 156) +#define ITM_CLOTH157 (ITM_CLOTH_START + 157) +#define ITM_CLOTH158 (ITM_CLOTH_START + 158) +#define ITM_CLOTH159 (ITM_CLOTH_START + 159) +#define ITM_CLOTH160 (ITM_CLOTH_START + 160) +#define ITM_CLOTH161 (ITM_CLOTH_START + 161) +#define ITM_CLOTH162 (ITM_CLOTH_START + 162) +#define ITM_CLOTH163 (ITM_CLOTH_START + 163) +#define ITM_CLOTH164 (ITM_CLOTH_START + 164) +#define ITM_CLOTH165 (ITM_CLOTH_START + 165) +#define ITM_CLOTH166 (ITM_CLOTH_START + 166) +#define ITM_CLOTH167 (ITM_CLOTH_START + 167) +#define ITM_CLOTH168 (ITM_CLOTH_START + 168) +#define ITM_CLOTH169 (ITM_CLOTH_START + 169) +#define ITM_CLOTH170 (ITM_CLOTH_START + 170) +#define ITM_CLOTH171 (ITM_CLOTH_START + 171) +#define ITM_CLOTH172 (ITM_CLOTH_START + 172) +#define ITM_CLOTH173 (ITM_CLOTH_START + 173) +#define ITM_CLOTH174 (ITM_CLOTH_START + 174) +#define ITM_CLOTH175 (ITM_CLOTH_START + 175) +#define ITM_CLOTH176 (ITM_CLOTH_START + 176) +#define ITM_CLOTH177 (ITM_CLOTH_START + 177) +#define ITM_CLOTH178 (ITM_CLOTH_START + 178) +#define ITM_CLOTH179 (ITM_CLOTH_START + 179) +#define ITM_CLOTH180 (ITM_CLOTH_START + 180) +#define ITM_CLOTH181 (ITM_CLOTH_START + 181) +#define ITM_CLOTH182 (ITM_CLOTH_START + 182) +#define ITM_CLOTH183 (ITM_CLOTH_START + 183) +#define ITM_CLOTH184 (ITM_CLOTH_START + 184) +#define ITM_CLOTH185 (ITM_CLOTH_START + 185) +#define ITM_CLOTH186 (ITM_CLOTH_START + 186) +#define ITM_CLOTH187 (ITM_CLOTH_START + 187) +#define ITM_CLOTH188 (ITM_CLOTH_START + 188) +#define ITM_CLOTH189 (ITM_CLOTH_START + 189) +#define ITM_CLOTH190 (ITM_CLOTH_START + 190) +#define ITM_CLOTH191 (ITM_CLOTH_START + 191) +#define ITM_CLOTH192 (ITM_CLOTH_START + 192) +#define ITM_CLOTH193 (ITM_CLOTH_START + 193) +#define ITM_CLOTH194 (ITM_CLOTH_START + 194) +#define ITM_CLOTH195 (ITM_CLOTH_START + 195) +#define ITM_CLOTH196 (ITM_CLOTH_START + 196) +#define ITM_CLOTH197 (ITM_CLOTH_START + 197) +#define ITM_CLOTH198 (ITM_CLOTH_START + 198) +#define ITM_CLOTH199 (ITM_CLOTH_START + 199) +#define ITM_CLOTH200 (ITM_CLOTH_START + 200) +#define ITM_CLOTH201 (ITM_CLOTH_START + 201) +#define ITM_CLOTH202 (ITM_CLOTH_START + 202) +#define ITM_CLOTH203 (ITM_CLOTH_START + 203) +#define ITM_CLOTH204 (ITM_CLOTH_START + 204) +#define ITM_CLOTH205 (ITM_CLOTH_START + 205) +#define ITM_CLOTH206 (ITM_CLOTH_START + 206) +#define ITM_CLOTH207 (ITM_CLOTH_START + 207) +#define ITM_CLOTH208 (ITM_CLOTH_START + 208) +#define ITM_CLOTH209 (ITM_CLOTH_START + 209) +#define ITM_CLOTH210 (ITM_CLOTH_START + 210) +#define ITM_CLOTH211 (ITM_CLOTH_START + 211) +#define ITM_CLOTH212 (ITM_CLOTH_START + 212) +#define ITM_CLOTH213 (ITM_CLOTH_START + 213) +#define ITM_CLOTH214 (ITM_CLOTH_START + 214) +#define ITM_CLOTH215 (ITM_CLOTH_START + 215) +#define ITM_CLOTH216 (ITM_CLOTH_START + 216) +#define ITM_CLOTH217 (ITM_CLOTH_START + 217) +#define ITM_CLOTH218 (ITM_CLOTH_START + 218) +#define ITM_CLOTH219 (ITM_CLOTH_START + 219) +#define ITM_CLOTH220 (ITM_CLOTH_START + 220) +#define ITM_CLOTH221 (ITM_CLOTH_START + 221) +#define ITM_CLOTH222 (ITM_CLOTH_START + 222) +#define ITM_CLOTH223 (ITM_CLOTH_START + 223) +#define ITM_CLOTH224 (ITM_CLOTH_START + 224) +#define ITM_CLOTH225 (ITM_CLOTH_START + 225) +#define ITM_CLOTH226 (ITM_CLOTH_START + 226) +#define ITM_CLOTH227 (ITM_CLOTH_START + 227) +#define ITM_CLOTH228 (ITM_CLOTH_START + 228) +#define ITM_CLOTH229 (ITM_CLOTH_START + 229) +#define ITM_CLOTH230 (ITM_CLOTH_START + 230) +#define ITM_CLOTH231 (ITM_CLOTH_START + 231) +#define ITM_CLOTH232 (ITM_CLOTH_START + 232) +#define ITM_CLOTH233 (ITM_CLOTH_START + 233) +#define ITM_CLOTH234 (ITM_CLOTH_START + 234) +#define ITM_CLOTH235 (ITM_CLOTH_START + 235) +#define ITM_CLOTH236 (ITM_CLOTH_START + 236) +#define ITM_CLOTH237 (ITM_CLOTH_START + 237) +#define ITM_CLOTH238 (ITM_CLOTH_START + 238) +#define ITM_CLOTH239 (ITM_CLOTH_START + 239) +#define ITM_CLOTH240 (ITM_CLOTH_START + 240) +#define ITM_CLOTH241 (ITM_CLOTH_START + 241) +#define ITM_CLOTH242 (ITM_CLOTH_START + 242) +#define ITM_CLOTH243 (ITM_CLOTH_START + 243) +#define ITM_CLOTH244 (ITM_CLOTH_START + 244) +#define ITM_CLOTH245 (ITM_CLOTH_START + 245) +#define ITM_CLOTH246 (ITM_CLOTH_START + 246) +#define ITM_CLOTH247 (ITM_CLOTH_START + 247) +#define ITM_CLOTH248 (ITM_CLOTH_START + 248) +#define ITM_CLOTH249 (ITM_CLOTH_START + 249) +#define ITM_CLOTH250 (ITM_CLOTH_START + 250) +#define ITM_CLOTH251 (ITM_CLOTH_START + 251) +#define ITM_CLOTH252 (ITM_CLOTH_START + 252) +#define ITM_CLOTH253 (ITM_CLOTH_START + 253) +#define ITM_CLOTH254 (ITM_CLOTH_START + 254) +#define ITM_CLOTH_END (ITM_CLOTH_START + 255) -#define ITM_DUST0_EMPTY_CAN 0x250E -#define ITM_DUST1_BOOT 0x250F -#define ITM_DUST2_OLD_TIRE 0x2510 -#define ITM_PITFALL 0x2512 -#define ITM_SIGNBOARD 0x251E +#define ITM_ETC_START 0x2500 +#define ITM_QST_LETTER ITM_ETC_START +#define ITM_QST_CLOTH (ITM_QST_LETTER + 1) +#define ITM_QST_MONEY (ITM_QST_CLOTH + 1) +#define ITM_QST_VIDEOTAPE (ITM_QST_MONEY + 1) +#define ITM_QST_ORGANIZER (ITM_QST_VIDEOTAPE + 1) +#define ITM_QST_POKEMON_PIKACHU (ITM_QST_ORGANIZER + 1) +#define ITM_QST_COMIC_BOOK (ITM_QST_POKEMON_PIKACHU + 1) +#define ITM_QST_PICTURE_BOOK (ITM_QST_COMIC_BOOK + 1) +#define ITM_QST_GAME_BOY (ITM_QST_PICTURE_BOOK + 1) +#define ITM_QST_CAMREA (ITM_QST_GAME_BOY + 1) +#define ITM_QST_WATCH (ITM_QST_CAMREA + 1) +#define ITM_QST_HANDKERCHIEF (ITM_QST_WATCH + 1) +#define ITM_QST_GLASSES_CASE (ITM_QST_HANDKERCHIEF + 1) +#define ITM_MONEY1000BELL (ITM_QST_GLASSES_CASE + 1) +#define ITM_DUST0_EMPTY_CAN (ITM_MONEY1000BELL + 1) +#define ITM_DUST1_BOOT (ITM_DUST0_EMPTY_CAN + 1) +#define ITM_DUST2_OLD_TIRE (ITM_DUST1_BOOT + 1) +#define ITM_FOSSIL (ITM_DUST2_OLD_TIRE + 1) +#define ITM_PITFALL (ITM_FOSSIL + 1) +#define ITM_FORTUNE_SLIP (ITM_PITFALL + 1) +#define ITM_SHELL0 (ITM_FORTUNE_SLIP + 1) +#define ITM_SHELL1 (ITM_SHELL0 + 1) +#define ITM_SHELL2 (ITM_SHELL1 + 1) +#define ITM_SHELL3 (ITM_SHELL2 + 1) +#define ITM_SHELL4 (ITM_SHELL3 + 1) +#define ITM_SHELL5 (ITM_SHELL4 + 1) +#define ITM_SHELL6 (ITM_SHELL5 + 1) +#define ITM_SHELL7 (ITM_SHELL6 + 1) +#define ITM_PRESENT (ITM_SHELL7 + 1) +#define ITM_TOWN_MAP (ITM_PRESENT + 1) +#define ITM_SIGNBOARD (ITM_TOWN_MAP + 1) +#define ITM_GOLDEN_NET_PRESENT (ITM_SIGNBOARD + 1) +#define ITM_GOLDEN_AXE_PRESENT (ITM_GOLDEN_NET_PRESENT + 1) +#define ITM_GOLDEN_SHOVEL_PRESENT (ITM_GOLDEN_AXE_PRESENT + 1) +#define ITM_GOLDEN_ROD_PRESENT (ITM_GOLDEN_SHOVEL_PRESENT + 1) +#define ITM_EXCERCISE_CARD00 (ITM_GOLDEN_ROD_PRESENT + 1) +#define ITM_EXCERCISE_CARD01 (ITM_EXCERCISE_CARD00 + 1) +#define ITM_EXCERCISE_CARD02 (ITM_EXCERCISE_CARD01 + 1) +#define ITM_EXCERCISE_CARD03 (ITM_EXCERCISE_CARD02 + 1) +#define ITM_EXCERCISE_CARD04 (ITM_EXCERCISE_CARD03 + 1) +#define ITM_EXCERCISE_CARD05 (ITM_EXCERCISE_CARD04 + 1) +#define ITM_EXCERCISE_CARD06 (ITM_EXCERCISE_CARD05 + 1) +#define ITM_EXCERCISE_CARD07 (ITM_EXCERCISE_CARD06 + 1) +#define ITM_EXCERCISE_CARD08 (ITM_EXCERCISE_CARD07 + 1) +#define ITM_EXCERCISE_CARD09 (ITM_EXCERCISE_CARD08 + 1) +#define ITM_EXCERCISE_CARD10 (ITM_EXCERCISE_CARD09 + 1) +#define ITM_EXCERCISE_CARD11 (ITM_EXCERCISE_CARD10 + 1) +#define ITM_EXCERCISE_CARD12 (ITM_EXCERCISE_CARD11 + 1) +#define ITM_KNIFE_AND_FORK (ITM_EXCERCISE_CARD12 + 1) +#define ITM_ETC_END 0x2531 + +#define ITM_CARPET_START 0x2600 + +#define ITM_WALL_START 0x2700 #define ITM_FOOD_START 0x2800 - -#define ITM_FOOD_MUSHROOM 0x2805 -#define ITM_FOOD_CANDY 0x2806 +#define ITM_FOOD_APPLE ITM_FOOD_START +#define ITM_FOOD_CHERRY (ITM_FOOD_APPLE + 1) +#define ITM_FOOD_PEAR (ITM_FOOD_CHERRY + 1) +#define ITM_FOOD_PEACH (ITM_FOOD_PEAR + 1) +#define ITM_FOOD_ORANGE (ITM_FOOD_PEACH + 1) +#define ITM_FOOD_MUSHROOM (ITM_FOOD_ORANGE + 1) +#define ITM_FOOD_CANDY (ITM_FOOD_MUSHROOM + 1) +#define ITM_FOOD_COCONUT (ITM_FOOD_CANDY + 1) +#define ITM_FOOD_END 0x2808 #define ITM_ENV_START 0x2900 #define ITM_SAPLING ITM_ENV_START @@ -449,7 +787,9 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define ITM_BLUE_COSMOS_BAG 0x2907 #define ITM_RED_TULIP_BAG 0x2908 #define ITM_WHITE_TULIP_BAG 0x2909 -#define ITEM_YELLOW_TULIP_BAG 0x290A +#define ITM_YELLOW_TULIP_BAG 0x290A + +#define ITM_MINIDISK_START 0x2A00 #define ITM_DIARY_START 0x2B00 #define ITM_COLLEGERULE ITM_DIARY_START diff --git a/include/m_npc.h b/include/m_npc.h index dbac37ab..e2872f98 100644 --- a/include/m_npc.h +++ b/include/m_npc.h @@ -201,6 +201,10 @@ extern Animal_c* mNpc_GetInAnimalP(); extern int mNpc_GetLooks2Sex(int looks); extern int mNpc_CheckFreeAnimalInfo(Animal_c* animal); extern int mNpc_GetFriendAnimalNum(Private_c* private_p); +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 void mNpc_PrintRemoveInfo(gfxprint_t* gfxprint); extern void mNpc_PrintFriendship_fdebug(gfxprint_t* gfxprint); diff --git a/include/m_player_lib.h b/include/m_player_lib.h index 799fc064..392f1c45 100644 --- a/include/m_player_lib.h +++ b/include/m_player_lib.h @@ -3,6 +3,7 @@ #include "types.h" #include "m_player.h" +#include "m_private_h.h" #ifdef __cplusplus extern "C" { @@ -20,6 +21,7 @@ extern void mPlib_Set_able_force_speak_label(ACTOR* actor); extern int mPlib_request_main_demo_walk_type1(GAME* game, f32 goal_x, f32 goal_z, f32 speed, int flag); extern void mPlib_Set_goal_player_demo_walk(f32 goal_x, f32 goal_z, f32 speed); extern void mPlib_Set_able_hand_all_item_in_demo(s8 enable); +extern void mPlib_change_player_cloth_info_lv2(Private_c* priv, mActor_name_t cloth_name); #ifdef __cplusplus } diff --git a/include/m_post_office.h b/include/m_post_office.h index 5981e90c..675ffe30 100644 --- a/include/m_post_office.h +++ b/include/m_post_office.h @@ -11,6 +11,14 @@ extern "C" { #define mPO_MAIL_STORAGE_SIZE 5 +enum { + mPO_SENDTYPE_MAIL, + mPO_SENDTYPE_LEAFLET, + mPO_SENDTYPE_EVENT_LEAFLET, + + mPO_SENDTYPE_NUM +}; + /* sizeof(PostOffice_c) == 0x83C */ typedef struct post_office_s { /* 0x000 */ s16 keep_mail_sum_players; /* sum of stored mail from players, see mPO_get_keep_mail_sum */ @@ -33,6 +41,9 @@ typedef struct post_office_s { /* 0x834 */ lbRTC_time_c delivery_time; /* time when Pete should 'deliver' the mail */ } PostOffice_c; +extern int mPO_get_keep_mail_sum(); +extern int mPO_receipt_proc(Mail_c* mail, int type); + #ifdef __cplusplus } #endif diff --git a/include/m_private.h b/include/m_private.h index 44b0c8e3..5de89ad6 100644 --- a/include/m_private.h +++ b/include/m_private.h @@ -70,6 +70,8 @@ enum { #define mPr_FOREIGN_MAP_COUNT 8 #define mPr_ORIGINAL_DESIGN_COUNT 8 +#define mPr_GET_ITEM_COND(all_cond, slot_no) (((all_cond) >> (2 * (slot_no))) & 3) + enum { mPr_SUNBURN_RANK_MIN, @@ -147,6 +149,20 @@ typedef struct player_ecard_data_s { /* 0x04 */ u8 card_letters_sent[mPr_ECARD_LETTER_NUM]; /* bitfield keeping track of which eCard letters have been sent to the player [0, 366] */ } mPr_carde_data_c; +#define mPr_MOTHER_MAIL_NORMAL_NUM 7 +#define mPr_MOTHER_MAIL_MONTHLY_NUM 2 + +typedef struct private_mother_mail_data_s { + u8 normal[mPr_MOTHER_MAIL_NORMAL_NUM]; + u8 monthly[mPr_MOTHER_MAIL_MONTHLY_NUM]; + u8 august; // unique byte for month of august +} mPr_mother_mail_data_c; + +typedef struct private_mother_mail_info_s { + lbRTC_ymd_t date; + mPr_mother_mail_data_c data; +} mPr_mother_mail_info_c; + struct private_s { /* 0x0000 */ PersonalID_c player_ID; /* player's id info */ /* 0x0014 */ s8 gender; /* gender/sex of player */ @@ -217,22 +233,68 @@ struct private_s { /* 0x2412 */ u8 unused_2412[46]; }; -extern s16 mPr_GetGoodsPower(); -extern s16 mPr_GetMoneyPower(); - -extern int mPr_CheckPrivate(Private_c* private_p); -extern void mPr_PrintMapInfo_debug(gfxprint_t* gfxprint); -extern int mPr_NullCheckPersonalID(PersonalID_c* pid); -extern int mPr_CheckCmpPersonalID(PersonalID_c* pid_a, PersonalID_c* pid_b); -extern void mPr_ClearPersonalID(PersonalID_c* pid); -extern void mPr_CopyPersonalID(PersonalID_c* dst, PersonalID_c* src); -extern void mPr_ClearPrivateInfo(Private_c* private_data); -extern int mPr_CheckCmpPlayerName(u8* str0, u8* str1); -extern void mPr_RandomSetPlayerData_title_demo(); -extern int mPr_GetPossessionItemSumWithCond(Private_c* priv, mActor_name_t item_no, u32 cond); -extern int mPr_SetFreePossessionItem(Private_c* priv, mActor_name_t item_no, u32 cond); -extern void mPr_CopyPlayerName(u8* dst, Private_c* private_p); +extern void mPr_ClearPlayerName(u8* buf); +extern void mPr_CopyPlayerName(u8* dst, u8* src); +extern int mPr_NullCheckPlayerName(u8* name_p); +extern int mPr_CheckCmpPlayerName(u8* name0, u8* name1); extern int mPr_GetPlayerName(u8* buf, int player_no); +extern int mPr_NullCheckPersonalID(PersonalID_c* pid); +extern void mPr_ClearPersonalID(PersonalID_c* pid); +extern void mPr_ClearAnyPersonalID(PersonalID_c* pid, int count); +extern void mPr_CopyPersonalID(PersonalID_c* dst, PersonalID_c* src); +extern int mPr_CheckCmpPersonalID(PersonalID_c* pid0, PersonalID_c* pid1); +extern void mPr_ClearPrivateBirthday(mPr_birthday_c* birthday); +extern void mPr_ClearAnimalMemory(mPr_animal_memory_c* memory); +extern void mPr_ClearPrivateInfo(Private_c* private_info); +extern void mPr_SetNowPrivateCloth(); +extern void mPr_InitPrivateInfo(Private_c* priv); +extern void mPr_CopyPrivateInfo(Private_c* dst, Private_c* src); +extern int mPr_CheckPrivate(Private_c* priv); +extern int mPr_CheckCmpPrivate(Private_c* priv0, Private_c* priv1); +extern int mPr_GetPrivateIdx(PersonalID_c* pid); +extern int mPr_GetPossessionItemIdx(Private_c* priv, mActor_name_t item); +extern int mPr_GetPossessionItemIdxWithCond(Private_c* priv, mActor_name_t item, u32 cond); +extern int mPr_GetPossessionItemIdxFGTypeWithCond_cancel(Private_c* priv, mActor_name_t fg_type, u32 cond, mActor_name_t cancel_item); +extern int mPr_GetPossessionItemIdxItem1Category(Private_c* priv, u8 item1_type); +extern int mPr_GetPossessionItemIdxItem1CategoryWithCond_cancel(Private_c* priv, u8 item1_type, u32 cond, mActor_name_t cancel_item); +extern int mPr_GetPossessionItemIdxKindWithCond(Private_c* priv, mActor_name_t kind_start, mActor_name_t kind_end, u32 cond); +extern int mPr_GetPossessionItemSum(Private_c* priv, mActor_name_t item); +extern int mPr_GetPossessionItemSumWithCond(Private_c* priv, mActor_name_t item, u32 cond); +extern int mPr_GetPossessionItemSumFGTypeWithCond_cancel(Private_c* priv, mActor_name_t fg_type, u32 cond, mActor_name_t cancel_item); +extern int mPr_GetPossessionItemSumItemCategoryWithCond_cancel(Private_c* priv, u8 item1_type, u32 cond, mActor_name_t cancel_item); +extern int mPr_GetPossessionItemSumItemCategoryWithCond(Private_c* priv, u8 item1_type, u32 cond); +extern int mPr_GetPossessionItemSumKindWithCond(Private_c* priv, mActor_name_t kind_start, mActor_name_t kind_end, u32 cond); +extern void mPr_SetItemCollectBit(mActor_name_t item); +extern mActor_name_t mPr_DummyPresentToTruePresent(); +extern void mPr_SetPossessionItem(Private_c* priv, int idx, mActor_name_t item, u32 cond); +extern int mPr_SetFreePossessionItem(Private_c* priv, mActor_name_t item, u32 cond); +extern void mPr_AddFirstJobHint(Private_c* priv); +extern int mPr_GetFirstJobHintTime(Private_c* priv); +extern int mPr_CheckFirstJobHint(Private_c* priv); +extern s16 mPr_GetMoneyPower(); +extern s16 mPr_GetGoodsPower(); +extern int mPr_CheckMuseumAddress(Private_c* priv); +extern int mPr_CheckMuseumInfoMail(Private_c* priv); +extern Private_c* mPr_GetForeignerP(); +extern int mPr_LoadPak_and_SetPrivateInfo2(Private_c* unused_private, u8 player_no); +extern void mPr_ClearMotherMailInfo(mPr_mother_mail_info_c* mother_mail); +extern void mPr_SendMailFromMother(); +extern void mPr_SendForeingerAnimalMail(Private_c* priv); +extern void mPr_StartSetCompleteTalkInfo(); +extern void mPr_SetFishCompleteTalk(); +extern int mPr_CheckFishCompleteTalk(u8 player_no); +extern void mPr_SetInsectCompleteTalk(); +extern int mPr_CheckInsectCompleteTalk(u8 player_no); +extern int mPr_GetFishCompTalkPermission(); +extern int mPr_GetInsectCompTalkPermission(); +extern void mPr_ClearMapInfo(mPr_map_info_c* map_info, int max); +extern int mPr_GetThisLandMapIdx(mPr_map_info_c* map_info, int max); +extern void mPr_SetNewMap(mPr_map_info_c* map_info, int max); +extern void mPr_RenewalMapInfo(mPr_map_info_c* map_info, int max, mLd_land_info_c* land_info); +extern void mPr_RandomSetPlayerData_title_demo(); +extern void mPr_PrintMapInfo_debug(gfxprint_t* gfxprint); + +extern Private_c g_foreigner_private; #ifdef __cplusplus } diff --git a/include/m_room_type.h b/include/m_room_type.h index 627beea6..d5c7c077 100644 --- a/include/m_room_type.h +++ b/include/m_room_type.h @@ -108,5 +108,6 @@ extern mActor_name_t mRmTp_FtrIdx2FtrItemNo(int ftr_idx, int rotation); extern int mRmTp_GetFurnitureData(mActor_name_t ftr, int ut_x, int ut_z, mRmTp_FtrPlaceInfo_t* place_info); extern int mRmTp_FurnitureIdx2FurnitureKind(int ftr_idx); extern int mRmTp_PleaseDrawLightSwitch(); +extern mActor_name_t mRmTp_Item1ItemNo2FtrItemNo_AtPlayerRoom(mActor_name_t item_no, int flag); #endif \ No newline at end of file diff --git a/include/m_submenu.h b/include/m_submenu.h index 10fcc3b9..45c639dc 100644 --- a/include/m_submenu.h +++ b/include/m_submenu.h @@ -104,6 +104,8 @@ struct submenu_s { }; extern void mSM_open_submenu(Submenu* submenu, int menu_type, int arg0, int arg1); +extern int mSM_CHECK_ALL_FISH_GET(); +extern int mSM_CHECK_ALL_INSECT_GET(); #ifdef __cplusplus } diff --git a/include/m_time.h b/include/m_time.h index c9e7e716..68b9b1d8 100644 --- a/include/m_time.h +++ b/include/m_time.h @@ -91,6 +91,8 @@ extern const lbRTC_time_c mTM_rtcTime_default_code; #define mTM_IsTimeCleared(time) (lbRTC_IsEqualTime((time), &mTM_rtcTime_clear_code, lbRTC_CHECK_ALL) == TRUE) #define mTM_AreTimesEqual(t0, t1) (lbRTC_IsEqualTime(t0, t1, lbRTC_CHECK_ALL)) +#define mTM_CheckCmpYMDEqual(ymd0, ymd1) ((ymd0)->year == (ymd1)->year && (ymd0)->month == (ymd1)->month && (ymd0)->day == (ymd1)->day) +#define mTM_CheckCmpYMDClear(ymd0) ((ymd0)->year == mTM_rtcTime_ymd_clear_code.year || (ymd0)->month == mTM_rtcTime_ymd_clear_code.month || (ymd0)->day == mTM_rtcTime_ymd_clear_code.day) #ifdef __cplusplus } diff --git a/include/sys_math.h b/include/sys_math.h index 4c4e2c6a..7e3bb4b1 100644 --- a/include/sys_math.h +++ b/include/sys_math.h @@ -3,11 +3,17 @@ #include "types.h" #include "MSL_C/math.h" +#include "libc64/qrand.h" #ifdef __cplusplus extern "C" { #endif +/* Macro to generate a random float in the range of [0, n) */ +#define RANDOM_F(n) (fqrand() * (f32)(n)) + +/* Macro to generate a random integer in the range of [0, n) */ +#define RANDOM(n) ((int)RANDOM_F(n)) extern u16 U_GetAtanTable(f32 y, f32 x); extern s16 atans_table(f32 x, f32 y); diff --git a/rel/m_map_ovl.c b/rel/m_map_ovl.c index 1b91ede2..9eb2d0f1 100644 --- a/rel/m_map_ovl.c +++ b/rel/m_map_ovl.c @@ -416,7 +416,7 @@ static void mMP_set_house_data(mMP_Overlay_c* map_ovl, mSM_MenuInfo_c* menu) { if (mPr_CheckPrivate(priv) == TRUE && (Common_Get(now_private) != priv || mEv_CheckFirstIntro() == FALSE) ) { - mPr_CopyPlayerName(resident_p->name, priv); + mPr_CopyPlayerName(resident_p->name, priv->player_ID.player_name); resident_p->sex = priv->gender; resident_p->house_layer = 0; resident_p->house_idx = 0; diff --git a/rel/m_private.c b/rel/m_private.c new file mode 100644 index 00000000..8fdad98a --- /dev/null +++ b/rel/m_private.c @@ -0,0 +1,1501 @@ +#include "m_private.h" + +#include "m_land.h" +#include "m_font.h" +#include "m_lib.h" +#include "libultra/libultra.h" +#include "m_player_lib.h" +#include "m_name_table.h" +#include "libc64/qrand.h" +#include "m_field_info.h" +#include "m_house.h" +#include "m_mail.h" +#include "m_handbill.h" +#include "m_post_office.h" +#include "m_event.h" +#include "m_npc.h" +#include "m_submenu.h" +#include "m_room_type.h" +#include "m_common_data.h" + +static Mail_c l_mpr_mail; +Private_c g_foreigner_private; + +extern void mPr_ClearPlayerName(u8* buf) { + mem_clear(buf, PLAYER_NAME_LEN, CHAR_SPACE); +} + +extern void mPr_CopyPlayerName(u8* dst, u8* src) { + mem_copy(dst, src, PLAYER_NAME_LEN); +} + +extern int mPr_NullCheckPlayerName(u8* name_p) { + int res = FALSE; + int i; + + for (i = 0; i < PLAYER_NAME_LEN; i++) { + if (name_p[0] != CHAR_SPACE) { + break; + } + name_p++; + } + + if (i == PLAYER_NAME_LEN) { + res = TRUE; + } + + return res; +} + +extern int mPr_CheckCmpPlayerName(u8* name0, u8* name1) { + int res = FALSE; + + if (mPr_NullCheckPlayerName(name0) == FALSE && mPr_NullCheckPlayerName(name1) == FALSE) { + res = mem_cmp(name0, name1, PLAYER_NAME_LEN); + } + + return res; +} + +extern int mPr_GetPlayerName(u8* buf, int player_no) { + PersonalID_c* pid; + int res = FALSE; + + if (mLd_PlayerManKindCheckNo(player_no) == FALSE) { + pid = &Save_Get(private[player_no]).player_ID; + + if (mPr_NullCheckPersonalID(pid) == FALSE) { + mPr_CopyPlayerName(buf, pid->player_name); + res = TRUE; + } + } + else if (mLd_PlayerManKindCheckNo(Common_Get(player_no)) == TRUE) { + mPr_CopyPlayerName(buf, Common_Get(now_private)->player_ID.player_name); + res = TRUE; + } + + return res; +} + +extern int mPr_NullCheckPersonalID(PersonalID_c* pid) { + int res = FALSE; + + if (pid->land_id == 0xFFFF && mPr_NullCheckPlayerName(pid->player_name) == TRUE) { + res = TRUE; + } + + return res; +} + +extern void mPr_ClearPersonalID(PersonalID_c* pid) { + mPr_ClearPlayerName(pid->player_name); + mLd_ClearLandName(pid->land_name); + pid->land_id = 0xFFFF; + pid->player_id = 0xFFFF; +} + +extern void mPr_ClearAnyPersonalID(PersonalID_c* pid, int count) { + for (count; count != 0; count--) { + mPr_ClearPersonalID(pid); + pid++; + } +} + +extern void mPr_CopyPersonalID(PersonalID_c* dst, PersonalID_c* src) { + mem_copy((u8*)dst, (u8*)src, sizeof(PersonalID_c)); +} + +extern int mPr_CheckCmpPersonalID(PersonalID_c* pid0, PersonalID_c* pid1) { + int res = FALSE; + + if ( + pid0->land_id == pid1->land_id && + pid0->player_id == pid1->player_id && + mLd_CheckCmpLandName(pid0->land_name, pid1->land_name) == TRUE && + mPr_CheckCmpPlayerName(pid0->player_name, pid1->player_name) == TRUE + ) { + res = TRUE; + } + + return res; +} + +// TODO: this might actually be file-local but I'm not sure, DnM+ inlined it +extern void mPr_ClearPrivateBirthday(mPr_birthday_c* birthday) { + birthday->year = 0xFFFF; + birthday->month = 0xFF; + birthday->day = 0xFF; +} + +extern void mPr_ClearAnimalMemory(mPr_animal_memory_c* memory) { + memory->npc_id = 0xFFFF; + mLd_ClearLandName(memory->land_name); +} + +extern void mPr_ClearPrivateInfo(Private_c* private_info) { + bzero(private_info, sizeof(Private_c)); + + mPr_ClearPersonalID(&private_info->player_ID); + private_info->gender = mPr_SEX_MALE; + mQst_ClearDelivery(private_info->deliveries, mPr_DELIVERY_QUEST_NUM); + mQst_ClearErrand(private_info->errands, mPr_ERRAND_QUEST_NUM); + mMl_clear_mail_box(private_info->mail, mPr_INVENTORY_MAIL_COUNT); + mMl_clear_mail_header_common(&private_info->saved_mail_header); + mPlib_change_player_cloth_info_lv2(private_info, ITM_CLOTH001); + mNpc_ClearAnimalPersonalID(&private_info->stored_anm_id); + mPr_ClearPrivateBirthday(&private_info->birthday); + private_info->backgound_texture = ITM_CLOTH226; + mNpc_ClearRemail(&private_info->remail); + mPr_ClearAnimalMemory(&private_info->animal_memory); + mPr_ClearMapInfo(private_info->maps, mPr_FOREIGN_MAP_COUNT); + mMsm_ClearRecord(&private_info->museum_mail_info); + private_info->state_flags = 1; +} + +static int mPr_GetRandomFace() { + return (fqrand() * (f32)mPr_FACE_TYPE_NUM); +} + +static int mPr_GetRandomOriginalFace() { + Private_c* priv = Save_Get(private); + Private_c* pr2; + + //Private_c* pr2; + int j; + int player_exist_num = 0; + int face; + int i; + + { + Private_c* pr = priv; + for (i = 0; i < PLAYER_NUM; i++) { + if (pr != NULL && mPr_NullCheckPersonalID(&pr->player_ID) == FALSE) { + player_exist_num++; + } + pr++; + } + } + + face = RANDOM(mPr_FACE_TYPE_NUM - player_exist_num); + for (player_exist_num; player_exist_num > 0; player_exist_num--) { + pr2 = priv; + for (j = 0; j < PLAYER_NUM; j++) { + if (pr2 != NULL && mPr_NullCheckPersonalID(&pr2->player_ID) == FALSE && pr2->face == face) { + face++; + + if (face >= mPr_FACE_TYPE_NUM) { + face = mPr_FACE_TYPE0; + } + break; + } + + pr2++; + } + } + + return face; +} + +static mActor_name_t mPr_boy_cloth_table[8] = { ITM_CLOTH000, ITM_CLOTH001, ITM_CLOTH002, ITM_CLOTH003, ITM_CLOTH004, ITM_CLOTH005, ITM_CLOTH006, ITM_CLOTH007 }; +static mActor_name_t mPr_girl_cloth_table[8] = { ITM_CLOTH008, ITM_CLOTH009, ITM_CLOTH010, ITM_CLOTH011, ITM_CLOTH012, ITM_CLOTH013, ITM_CLOTH014, ITM_CLOTH015 }; + +static mActor_name_t mPr_GetRandomCloth(u8 sex) { + static mActor_name_t* cloth_table[mPr_SEX_NUM] = { mPr_boy_cloth_table, mPr_girl_cloth_table }; + static int cloth_max[mPr_SEX_NUM] = { 8, 8 }; + + u8 s = sex; + int sel_cloth; + mActor_name_t* t; + mActor_name_t cloth; + + if (s >= mPr_SEX_NUM) { + s = mPr_SEX_MALE; + } + + t = cloth_table[s]; + sel_cloth = RANDOM(cloth_max[s]); + cloth = t[sel_cloth]; + return cloth; +} + +extern void mPr_SetNowPrivateCloth() { + Private_c* priv = Common_Get(now_private); + + if (priv != NULL) { + mPlib_change_player_cloth_info_lv2(priv, mPr_GetRandomCloth(priv->gender)); + } +} + +extern void mPr_InitPrivateInfo(Private_c* priv) { + mLd_land_info_c* land_info = Save_GetPointer(land_info); + Private_c* o_priv = Save_Get(private); + int id_existed = FALSE; + int face = mPr_GetRandomOriginalFace(); + int pid; + int i; + + priv->player_ID.land_id = land_info->id; + mLd_CopyLandName(priv->player_ID.land_name, land_info->name); + + pid = fqrand() * 253.0f; + + for (i = 0; i < PLAYER_NUM - 1; i++) { + int j; + + for (j = 0; j < PLAYER_NUM; j++) { + if ((u16)pid == o_priv[j].player_ID.player_id) { + id_existed = TRUE; + pid++; // move to next PID + break; + } + } + + if (id_existed == FALSE) { + break; + } + + id_existed = FALSE; + } + + priv->player_ID.player_id = 0xF000 | pid; + priv->exists = TRUE; + mPlib_change_player_cloth_info_lv2(priv, mPr_GetRandomCloth(mPr_SEX_MALE)); + priv->gender = mPr_SEX_MALE; + priv->inventory.loan = 100; + priv->face = face; + + for (i = 0; i < mPr_ORIGINAL_DESIGN_COUNT; i++) { + priv->my_org_no_table[i] = i; + } +} + +extern void mPr_CopyPrivateInfo(Private_c* dst, Private_c* src) { + bcopy(src, dst, sizeof(Private_c)); +} + +extern int mPr_CheckPrivate(Private_c* priv) { + int res = FALSE; + + if (mLd_CHECK_LAND_ID(priv->player_ID.land_id)) { + res = TRUE; + } + + return res; +} + +extern int mPr_CheckCmpPrivate(Private_c* priv0, Private_c* priv1) { + int res = FALSE; + + if (mPr_CheckCmpPersonalID(&priv0->player_ID, &priv1->player_ID) == TRUE) { + res = TRUE; + } + + return res; +} + +extern int mPr_GetPrivateIdx(PersonalID_c* pid) { + Private_c* priv = Save_Get(private); + int res = -1; + + if (mPr_NullCheckPersonalID(pid) == FALSE) { + int i; + + for (i = 0; i < PLAYER_NUM; i++) { + if (mPr_CheckCmpPersonalID(pid, &priv->player_ID) == TRUE) { + res = i; + break; + } + + priv++; + } + } + + return res; +} + +extern int mPr_GetPossessionItemIdx(Private_c* priv, mActor_name_t item) { + int idx = -1; + + if (priv != NULL) { + mActor_name_t* pockets = priv->inventory.pockets; + int i; + + for (i = 0; i < mPr_POCKETS_SLOT_COUNT; i++) { + mActor_name_t it = *pockets; + if (it == item) { + idx = i; + break; + } + + pockets++; + } + } + + return idx; +} + +extern int mPr_GetPossessionItemIdxWithCond(Private_c* priv, mActor_name_t item, u32 cond) { + int idx = -1; + + if (priv != NULL) { + mActor_name_t* pockets = priv->inventory.pockets; + int i; + + for (i = 0; i < mPr_POCKETS_SLOT_COUNT; i++) { + mActor_name_t it = *pockets; + if (it == item && cond == mPr_GET_ITEM_COND(priv->inventory.item_conditions, i)) { + idx = i; + break; + } + + pockets++; + } + } + + return idx; +} + +extern int mPr_GetPossessionItemIdxFGTypeWithCond_cancel(Private_c* priv, mActor_name_t fg_type, u32 cond, mActor_name_t cancel_item) { + int idx = -1; + + if (priv != NULL) { + mActor_name_t* pockets = priv->inventory.pockets; + int i; + + for (i = 0; i < mPr_POCKETS_SLOT_COUNT; i++) { + if (ITEM_NAME_GET_TYPE(*pockets) == fg_type && cond == mPr_GET_ITEM_COND(priv->inventory.item_conditions, i) && *pockets != cancel_item) { + idx = i; + break; + } + + pockets++; + } + } + + return idx; +} + +extern int mPr_GetPossessionItemIdxItem1Category(Private_c* priv, u8 item1_type) { + int idx = -1; + + if (priv != NULL) { + mActor_name_t* pockets = priv->inventory.pockets; + int i; + + for (i = 0; i < mPr_POCKETS_SLOT_COUNT; i++) { + if (ITEM_NAME_GET_TYPE(*pockets) == NAME_TYPE_ITEM1 && GET_NAME_ITEM1_CATEGORY(*pockets) == item1_type) { + idx = i; + break; + } + pockets++; + } + } + + return idx; +} + +extern int mPr_GetPossessionItemIdxItem1CategoryWithCond_cancel(Private_c* priv, u8 item1_type, u32 cond, mActor_name_t cancel_item) { + int idx = -1; + + if (priv != NULL) { + mActor_name_t* pockets = priv->inventory.pockets; + int i; + + for (i = 0; i < mPr_POCKETS_SLOT_COUNT; i++) { + if (ITEM_NAME_GET_TYPE(*pockets) == NAME_TYPE_ITEM1 && GET_NAME_ITEM1_CATEGORY(*pockets) == item1_type && cond == mPr_GET_ITEM_COND(priv->inventory.item_conditions, i) && *pockets != cancel_item) { + idx = i; + break; + } + pockets++; + } + } + + return idx; +} + +extern int mPr_GetPossessionItemIdxKindWithCond(Private_c* priv, mActor_name_t kind_start, mActor_name_t kind_end, u32 cond) { + int idx = -1; + + if (priv != NULL) { + mActor_name_t* pockets = priv->inventory.pockets; + int i; + + for (i = 0; i < mPr_POCKETS_SLOT_COUNT; i++) { + if (*pockets >= kind_start && *pockets < kind_end && cond == mPr_GET_ITEM_COND(priv->inventory.item_conditions, i)) { + idx = i; + break; + } + pockets++; + } + } + + return idx; +} + +extern int mPr_GetPossessionItemSum(Private_c* priv, mActor_name_t item) { + int sum = 0; + + if (priv != NULL) { + mActor_name_t* pockets = priv->inventory.pockets; + int i; + + for (i = 0; i < mPr_POCKETS_SLOT_COUNT; i++) { + if (*pockets == item) { + sum++; + } + pockets++; + } + } + + return sum; +} + +extern int mPr_GetPossessionItemSumWithCond(Private_c* priv, mActor_name_t item, u32 cond) { + int sum = 0; + + if (priv != NULL) { + mActor_name_t* pockets = priv->inventory.pockets; + int i; + + for (i = 0; i < mPr_POCKETS_SLOT_COUNT; i++) { + if (*pockets == item && cond == mPr_GET_ITEM_COND(priv->inventory.item_conditions, i)) { + sum++; + } + pockets++; + } + } + + return sum; +} + +extern int mPr_GetPossessionItemSumFGTypeWithCond_cancel(Private_c* priv, mActor_name_t fg_type, u32 cond, mActor_name_t cancel_item) { + int sum = 0; + + if (priv != NULL) { + mActor_name_t* pockets = priv->inventory.pockets; + int i; + + for (i = 0; i < mPr_POCKETS_SLOT_COUNT; i++) { + if (ITEM_NAME_GET_TYPE(*pockets) == fg_type && cond == mPr_GET_ITEM_COND(priv->inventory.item_conditions, i) && *pockets != cancel_item) { + sum++; + } + pockets++; + } + } + + return sum; +} + +extern int mPr_GetPossessionItemSumItemCategoryWithCond_cancel(Private_c* priv, u8 item1_type, u32 cond, mActor_name_t cancel_item) { + int sum = 0; + + if (priv != NULL) { + mActor_name_t* pockets = priv->inventory.pockets; + int i; + + for (i = 0; i < mPr_POCKETS_SLOT_COUNT; i++) { + if (ITEM_NAME_GET_TYPE(*pockets) == NAME_TYPE_ITEM1 && GET_NAME_ITEM1_CATEGORY(*pockets) == item1_type && cond == mPr_GET_ITEM_COND(priv->inventory.item_conditions, i) && *pockets != cancel_item) { + sum++; + } + pockets++; + } + } + + return sum; +} + +extern int mPr_GetPossessionItemSumItemCategoryWithCond(Private_c* priv, u8 item1_type, u32 cond) { + int sum = 0; + + if (priv != NULL) { + mActor_name_t* pockets = priv->inventory.pockets; + int i; + + for (i = 0; i < mPr_POCKETS_SLOT_COUNT; i++) { + if (ITEM_NAME_GET_TYPE(*pockets) == NAME_TYPE_ITEM1 && GET_NAME_ITEM1_CATEGORY(*pockets) == item1_type && cond == mPr_GET_ITEM_COND(priv->inventory.item_conditions, i)) { + sum++; + } + pockets++; + } + } + + return sum; +} + +extern int mPr_GetPossessionItemSumKindWithCond(Private_c* priv, mActor_name_t kind_start, mActor_name_t kind_end, u32 cond) { + int sum = 0; + + if (priv != NULL) { + mActor_name_t* pockets = priv->inventory.pockets; + int i; + + for (i = 0; i < mPr_POCKETS_SLOT_COUNT; i++) { + if (*pockets >= kind_start && *pockets < kind_end && cond == mPr_GET_ITEM_COND(priv->inventory.item_conditions, i)) { + sum++; + } + pockets++; + } + } + + return sum; +} + +extern void mPr_SetItemCollectBit(mActor_name_t item) { + mActor_name_t ftr_item_no = mRmTp_Item1ItemNo2FtrItemNo_AtPlayerRoom(item, 0); + int item_type; + + if ((ftr_item_no >= FTR_FISH00 && ftr_item_no <= FTR_FISH39_WEST) || (ftr_item_no >= FTR_INSECT00 && ftr_item_no <= FTR_INSECT39_WEST)) { + return; + } + + item_type = ITEM_NAME_GET_TYPE(ftr_item_no); + + if (item_type == NAME_TYPE_FTR0 || item_type == NAME_TYPE_FTR1) { + int ftr_idx = mRmTp_FtrItemNo2FtrIdx(ftr_item_no); + + if (ftr_idx >= 0 && ftr_idx < FTR_NUM) { + Common_Get(now_private)->furniture_collected_bitfield[ftr_idx >> 5] |= (1 << (ftr_idx & 31)); + } + + } + else if (item_type == NAME_TYPE_ITEM1) { + int category = ITEM_NAME_GET_CAT(ftr_item_no); + + if (category == ITEM1_CAT_PAPER) { + int idx = (ftr_item_no - ITM_PAPER_START) % 64; // 64 unique stationery + Common_Get(now_private)->paper_collected_bitfield[idx >> 5] |= (1 << (idx & 31)); + } + else if (category == ITEM1_CAT_CARPET) { + int idx = ftr_item_no - ITM_CARPET_START; + Common_Get(now_private)->carpet_collected_bitfield[idx >> 5] |= (1 << (idx & 31)); + } + else if (category == ITEM1_CAT_WALL) { + int idx = ftr_item_no - ITM_WALL_START; + Common_Get(now_private)->wall_collected_bitfield[idx >> 5] |= (1 << (idx & 31)); + } + else if (category == ITEM1_CAT_MINIDISK) { + mActor_name_t idx = ftr_item_no - ITM_MINIDISK_START; // why is this one u16, probably mActor_name_t type or something? + Common_Get(now_private)->music_collected_bitfield[idx >> 5] |= (1 << (idx & 31)); + } + } +} + +extern mActor_name_t mPr_DummyPresentToTruePresent() { + mActor_name_t true_present = EMPTY_NO; + + /* 80% chance of rolling furniture from town's rare list */ + if (RANDOM(5) != 0) { + mSP_SelectRandomItem_New(NULL, &true_present, 1, NULL, 0, mSP_KIND_FURNITURE, mSP_LISTTYPE_RARE, FALSE); + } + + /* 20% (and default case) to get random non-native fruit */ + if (true_present == EMPTY_NO) { + true_present = mFI_GetOtherFruit(); + } + + return true_present; +} + +extern void mPr_SetPossessionItem(Private_c* priv, int idx, mActor_name_t item, u32 cond) { + switch (item) { + case ITM_PRESENT: + { + item = mPr_DummyPresentToTruePresent(); + cond = mPr_ITEM_COND_PRESENT; + break; + } + + case ITM_GOLDEN_NET_PRESENT: + { + item = ITM_GOLDEN_NET; + cond = mPr_ITEM_COND_PRESENT; + break; + } + + case ITM_GOLDEN_AXE_PRESENT: + { + item = ITM_GOLDEN_AXE; + cond = mPr_ITEM_COND_PRESENT; + break; + } + + case ITM_GOLDEN_SHOVEL_PRESENT: + { + item = ITM_GOLDEN_SHOVEL; + cond = mPr_ITEM_COND_PRESENT; + break; + } + + case ITM_GOLDEN_ROD_PRESENT: + { + item = ITM_GOLDEN_ROD; + cond = mPr_ITEM_COND_PRESENT; + break; + } + } + + priv->inventory.pockets[idx] = item; + priv->inventory.item_conditions = ((priv->inventory.item_conditions & (~(u32)(mPr_ITEM_COND_NUM << (idx * 2)))) | (cond << (idx * 2))); + + if (cond == mPr_ITEM_COND_NORMAL) { + mPr_SetItemCollectBit(item); + } +} + +extern int mPr_SetFreePossessionItem(Private_c* priv, mActor_name_t item, u32 cond) { + int idx = mPr_GetPossessionItemIdx(priv, EMPTY_NO); + int res; + + if (idx == -1) { + res = FALSE; + } + else { + mPr_SetPossessionItem(priv, idx, item, cond); + res = TRUE; + } + + return res; +} + +extern void mPr_AddFirstJobHint(Private_c* priv) { + int hints = priv->hint_count + 1; + if ((hints & 0x7F) >= 10) { + hints = 0x80; // signal all hints have been given + } + + priv->hint_count = hints; +} + +extern int mPr_GetFirstJobHintTime(Private_c* priv) { + return priv->hint_count & 0x7F; +} + +extern int mPr_CheckFirstJobHint(Private_c* priv) { + return (priv->hint_count & 0x80) >> 7; +} + +extern s16 mPr_GetMoneyPower() { + s16 money_power = Common_Get(money_power); + Private_c* priv = Common_Get(now_private); + + if (priv != NULL) { + switch (priv->destiny.type) { + case mPr_DESTINY_MONEY_LUCK: + { + money_power += 100; + break; + } + + case mPr_DESTINY_BAD_LUCK: + { + money_power -= 50; + break; + } + } + } + + if (money_power < -80) { + money_power = -80; + } + + return money_power; +} + +extern s16 mPr_GetGoodsPower() { + s16 goods_power = Common_Get(goods_power); + Private_c* priv = Common_Get(now_private); + + if (priv != NULL) { + switch (priv->destiny.type) { + case mPr_DESTINY_GOODS_LUCK: + { + goods_power += 30; + break; + } + + case mPr_DESTINY_BAD_LUCK: + { + goods_power -= 30; + break; + } + } + } + + if (goods_power > 50) { + return 50; + } + + if (goods_power < -30) { + goods_power = -30; + } + + return goods_power; +} + +extern int mPr_CheckMuseumAddress(Private_c* priv) { + int res = FALSE; + + if (priv != NULL && priv->museum_mail_info.contacted) { + res = TRUE; + } + + return res; +} + +extern int mPr_CheckMuseumInfoMail(Private_c* priv) { + int res = FALSE; + + if (priv != NULL && priv->museum_mail_info.send_info_mail) { + res = TRUE; + } + + return res; +} + +extern Private_c* mPr_GetForeignerP() { + return &g_foreigner_private; +} + +extern int mPr_LoadPak_and_SetPrivateInfo2(Private_c* unused_private, u8 player_no) { + Private_c* priv; + int res = FALSE; + + if (player_no < mPr_FOREIGNER) { + u32 loan; + mHm_hs_c* house; + Private_c* priv = Save_Get(private + player_no); + if (mPr_CheckCmpPrivate(priv, &g_foreigner_private) == TRUE) { + house = Save_GetPointer(homes[mHS_get_arrange_idx(player_no)]); + loan = priv->inventory.loan; + mPr_CopyPrivateInfo(priv, &g_foreigner_private); + if (mHm_CheckKeepHouseSize(player_no) == FALSE || house->size_info.next_size == mHm_HOMESIZE_STATUE) { + priv->inventory.loan = loan; + } + + res = TRUE; + Common_Set(now_private, priv); + Common_Set(player_no, player_no); + } + } + else { + mHm_hs_c* house; + int exist_player; + u32 loan; + int i; + + priv = Save_Get(private); + for (i = 0; i < PLAYER_NUM; i++) { + exist_player = mPr_CheckCmpPrivate(priv, &g_foreigner_private); + if (exist_player == TRUE) { + house = Save_GetPointer(homes[mHS_get_arrange_idx(i)]); + loan = priv->inventory.loan; + + g_foreigner_private.museum_mail_info.contacted = priv->museum_mail_info.contacted; + mPr_CopyPrivateInfo(priv, &g_foreigner_private); + + if (mHm_CheckKeepHouseSize(i) == FALSE || house->size_info.next_size == mHm_HOMESIZE_STATUE) { + priv->inventory.loan = loan; + } + + res = TRUE; + Common_Set(now_private, priv); + Common_Set(player_no, i); + break; + } + + priv++; + } + + if (exist_player == FALSE) { + res = TRUE; + Common_Set(now_private, &g_foreigner_private); + Common_Set(player_no, mPr_FOREIGNER); + } + } + + return res; +} + +extern void mPr_ClearMotherMailInfo(mPr_mother_mail_info_c* mother_mail) { + mother_mail->date = mTM_rtcTime_ymd_clear_code; + bzero(&mother_mail->data, sizeof(mPr_mother_mail_data_c)); +} + +static int mPr_GetMotherMailPaperType(int month, int day) { + static u8 paper_table[lbRTC_MONTHS_MAX] = { + 13, 49, 32, 12, 62, 14, 19, 11, 59, 46, 47, 17 + }; + + Private_c* priv = Common_Get(now_private); + int paper; + + /* TODO: should paper be enums? */ + if (priv->birthday.month == month && priv->birthday.day == day) { + paper = 1; + } + else if (month == lbRTC_JANUARY && day == 1) { + paper = 63; + } + else if (month == lbRTC_AUGUST && day == 8) { + paper = 48; + } + else if (month == lbRTC_DECEMBER && day == 24) { + paper = 23; + } + else { + int idx = month - 1; + paper = paper_table[idx]; + } + + return paper - 1; +} + +static void mPr_GetMotherMail(Mail_c* mail, PersonalID_c* pid, mActor_name_t present, int stationery, int mail_no) { + int header_back_pos; + + mMl_clear_mail(mail); + mHandbill_Load_HandbillFromRom(mail->content.header, &header_back_pos, mail->content.footer, mail->content.body, mail_no); + mail->content.header_back_start = header_back_pos; + mail->content.font = 0; // TODO: enum + mail->content.mail_type = 4; // TODO: enum, this is "from mom" + mMl_set_to_plname(mail, pid); + mail->present = present; + mail->content.paper_type = stationery; +} + +static int mPr_SendMotherMailPost(PersonalID_c* pid, int player_no, mActor_name_t present, int stationery, int mail_no) { + Mail_c* mail; + mHm_hs_c* home; + int res = FALSE; + + mail = &l_mpr_mail; + home = Save_GetPointer(homes[mHS_get_arrange_idx(player_no)]); + + if (mPr_CheckCmpPersonalID(pid, &home->ownerID) == TRUE) { + int mailbox_idx = mMl_chk_mail_free_space(home->mailbox, HOME_MAILBOX_SIZE); + if (mailbox_idx != -1) { + mPr_GetMotherMail(mail, pid, present, stationery, mail_no); + mMl_copy_mail(&home->mailbox[mailbox_idx], mail); + res = TRUE; + } + else if (mPO_get_keep_mail_sum() < mPO_MAIL_STORAGE_SIZE) { + mPr_GetMotherMail(mail, pid, present, stationery, mail_no); + res = mPO_receipt_proc(mail, mPO_SENDTYPE_MAIL); + } + } + + return res; +} + +static int mPr_SendMotherMailDate(mPr_mother_mail_info_c* mother_mail, lbRTC_time_c* send_time) { + mActor_name_t present = EMPTY_NO; + int mail_no = -1; + int res = FALSE; + + if (Common_Get(now_private)->birthday.month == send_time->month && Common_Get(now_private)->birthday.day == send_time->day) { + mail_no = 0x184 + RANDOM(mPr_MOTHER_MAIL_MONTHLY_NUM); + present = FTR_BIRTHDAY_CAKE; + } + else if (send_time->month == send_time->day) { + int letter_num = (send_time->month - 1) * mPr_MOTHER_MAIL_MONTHLY_NUM + RANDOM(mPr_MOTHER_MAIL_MONTHLY_NUM); + mail_no = 0x164 + letter_num; + + if (send_time->month == lbRTC_JANUARY) { + present = ITM_MONEY_10000; + } + else if (letter_num == 18) { // TODO: these probably have enums... + present = ITM_FOOD_MUSHROOM; + } + } + else { + if (send_time->month == lbRTC_APRIL && send_time->day == 1) { + mail_no = 0x180; // April Fools + } + else if (mEv_check_status(mEv_EVENT_MOTHERS_DAY, mEv_STATUS_ACTIVE) == TRUE) { + mail_no = 0x17C; + } + else if (mEv_check_status(mEv_EVENT_FATHERS_DAY, mEv_STATUS_ACTIVE) == TRUE) { + mail_no = 0x17E; + } + else if (send_time->month == lbRTC_DECEMBER && send_time->day == 24) { + mail_no = 0x182; // Toy Day (Christmas) + mSP_SelectRandomItem_New(NULL, &present, 1, NULL, 0, mSP_KIND_FURNITURE, mSP_LISTTYPE_ABC, FALSE); + } + + if (mail_no != -1) { + /* Randomize between two letter variants */ + mail_no += RANDOM(mPr_MOTHER_MAIL_MONTHLY_NUM); + } + } + + if (mail_no != -1) { + if (mPr_SendMotherMailPost(&Common_Get(now_private)->player_ID, Common_Get(player_no), present, mPr_GetMotherMailPaperType(send_time->month, send_time->day), mail_no) == TRUE) { + mTM_set_renew_time(&mother_mail->date, send_time); + } + + res = TRUE; + } + + return res; +} + +static int mPr_CheckMotherMailMonthly(mPr_mother_mail_data_c* send_data, int month, int idx) { + if (month == lbRTC_AUGUST) { + return (send_data->august >> (idx)) & 1; // August gets its own byte because it has more than two event letters + } + else { + int shift = (month - 1) * 2; + int slot = shift / 8; + shift -= slot * 8; + idx += shift; + + return (send_data->monthly[slot] >> idx) & 1; + } +} + +static int mPr_GetMotherMailMonthlyNotSendNum(mPr_mother_mail_data_c* send_data, int month) { + int slot; + int not_send_num = 0; + int i; + + if (month == lbRTC_AUGUST) { + for (i = 0; i < 8; i++) { + if (((send_data->august >> i) & 1) == 0) { + not_send_num++; + } + } + } + else { + u8 byte; + int shift = (month - 1) * 2; + slot = shift / 8; + shift -= slot * 8; + byte = send_data->monthly[slot]; + + for (i = 0; i < 2; i++) { + if (((byte >> shift) & 1) == 0) { + not_send_num++; + shift++; + } + } + } + + return not_send_num; +} + +static void mPr_SetMotherMailMonthly(mPr_mother_mail_data_c* send_data, int month, int idx) { + if (month == lbRTC_AUGUST) { + send_data->august |= 1 << idx; + } + else { + /* TODO: almost certainly a fake match */ + u8* s; + int slot; + int shift; + + shift = (month - 1) * 2; + slot = ((month - 1) * 2) / 8; + shift -= slot * 8; + idx += shift; + + s = send_data->monthly + slot; + *s |= 1 << idx; + } +} + +#pragma pool_data on +static void mPr_GetMotherMailMonthlyData(mPr_mother_mail_data_c* send_data, int* mail_no, mActor_name_t* present, int* event_no, int month, int not_send_num) { + static int mail_start_no_table[mTM_SEASON_NUM] = { 0x18C, 0x192, 0x186, 0x19E }; + static mActor_name_t may_2_item_table[1] = { ITM_CLOTH105 }; // fortune shirt + static mActor_name_t december_2_item_table[6] = { + ITM_CLOTH108, // aurora knit + ITM_CLOTH109, // winter sweater + ITM_CLOTH110, // go-go shirt + ITM_CLOTH144, // deer shirt + ITM_CLOTH145, // blue check shirt + ITM_CLOTH156 // fish knit + }; + + int max; + int mail_start_idx; + int selected_event; + int i; + + *present = EMPTY_NO; + mail_start_idx = 3; + + if (month <= lbRTC_FEBRUARY) { + mail_start_idx = 3; + } + else if (month <= lbRTC_MAY) { + mail_start_idx = 0; + } + else if (month <= lbRTC_AUGUST) { + mail_start_idx = 1; + } + else if (month <= lbRTC_NOVEMBER) { + mail_start_idx = 2; + } + + *mail_no = mail_start_no_table[mail_start_idx]; + + selected_event = RANDOM(not_send_num); + max = mPr_MOTHER_MAIL_MONTHLY_NUM; + if (month == lbRTC_AUGUST) { + max = 8; + } + + for (i = 0; i < max; i++) { + if (mPr_CheckMotherMailMonthly(send_data, month, i) == FALSE) { + if (selected_event <= 0) { + *event_no = i; + break; + } + + selected_event--; + } + } + + *mail_no += *event_no + (month - 1 - mail_start_idx * 3) * 2; + + if (month == lbRTC_MAY && *event_no == 1) { + *present = may_2_item_table[RANDOM(1)]; + } + else if (month == lbRTC_DECEMBER) { + if (*event_no == 0) { + *present = ITM_FOOD_APPLE; + } + else { + *present = december_2_item_table[RANDOM(6)]; + } + } + else if (month == lbRTC_NOVEMBER) { + *present = ITM_FOOD_MUSHROOM; + } +} +#pragma pool_data reset + +static int mPr_GetMotherMailNormalNotSendNum(mPr_mother_mail_data_c* send_data) { + int not_send_num = 0; + int i; + int j; + + for (i = 0; i < mPr_MOTHER_MAIL_NORMAL_NUM; i++) { + for (j = 0; j < 8; j++) { + if (((send_data->normal[i] >> j) & 1) == 0) { + not_send_num++; + } + } + } + + return not_send_num; +} + +static void mPr_SetMotherMailNormal(mPr_mother_mail_data_c* send_data, int idx) { + int slot = idx / 8; + idx -= (idx / 8) * 8; + send_data->normal[slot] |= (1 << idx); +} + +static int mPr_CheckMotherMailNormal(mPr_mother_mail_data_c* send_data, int idx) { + int slot = idx / 8; + idx -= (idx / 8) * 8; + return (send_data->normal[slot] >> idx) & 1; +} + +// TODO: we need to make an enum for each player mother mail event id +static void mPr_GetMotherMailNormalData(mPr_mother_mail_data_c* send_data, int* mail_no, mActor_name_t* present, int* event_no, int no_send_num) { + int selected_event; + int i; + + *event_no = -1; + selected_event = RANDOM(no_send_num); + + for (i = 0; i < 56; i++) { + if (mPr_CheckMotherMailNormal(send_data, i) == FALSE) { + if (selected_event <= 0) { + *event_no = i; + break; + } + + selected_event--; + } + } + + *mail_no = 0x12C + *event_no; + + switch (*event_no) { + case 1: + case 16: + mSP_SelectRandomItem_New(NULL, present, 1, NULL, 0, mSP_KIND_CLOTH, mSP_LISTTYPE_ABC, FALSE); + break; + + case 3: + case 21: + case 22: + case 47: + *present = mFI_GetOtherFruit(); + break; + + case 12: + *present = ITM_MONEY_1000; + break; + + case 37: + *present = FTR_PAPA_BEAR; + break; + + case 38: + *present = FTR_DRACAENA; + break; + + case 40: + mSP_RandomUmbSelect(present, 1); + break; + + default: + *present = EMPTY_NO; + break; + } +} + +static void mPr_SendMotherMailNormal(mPr_mother_mail_info_c* mother_mail, lbRTC_time_c* send_time) { + int mail_no = -1; + int monthly_not_send_num = 0; + int event_no; + mActor_name_t present = EMPTY_NO; + + if (RANDOM(100) < 20) { + int not_send_num = mPr_GetMotherMailNormalNotSendNum(&mother_mail->data); + if (not_send_num == 0) { + bzero(&mother_mail->data, sizeof(mPr_mother_mail_data_c)); + monthly_not_send_num = mPr_GetMotherMailMonthlyNotSendNum(&mother_mail->data, send_time->month); + } + + if (monthly_not_send_num > 0) { + mPr_GetMotherMailMonthlyData(&mother_mail->data, &mail_no, &present, &event_no, send_time->month, monthly_not_send_num); + + if (mPr_SendMotherMailPost(&Common_Get(now_private)->player_ID, Common_Get(player_no), present, mPr_GetMotherMailPaperType(send_time->month, send_time->day), mail_no) == TRUE) { + mPr_SetMotherMailMonthly(&mother_mail->data, send_time->month, event_no); + } + } + else { + mPr_GetMotherMailNormalData(&mother_mail->data, &mail_no, &present, &event_no, not_send_num); + + if (mPr_SendMotherMailPost(&Common_Get(now_private)->player_ID, Common_Get(player_no), present, mPr_GetMotherMailPaperType(send_time->month, send_time->day), mail_no) == TRUE) { + mPr_SetMotherMailNormal(&mother_mail->data, event_no); + } + } + } + + mTM_set_renew_time(&mother_mail->date, send_time); +} + +static void mPr_SendMotherMail(mPr_mother_mail_info_c* mother_mail, lbRTC_time_c* send_time) { + if (mPr_SendMotherMailDate(mother_mail, send_time) == FALSE) { + mPr_SendMotherMailNormal(mother_mail, send_time); + } +} + +extern void mPr_SendMailFromMother() { + Private_c* priv = Common_Get(now_private); + u8 player_no = Common_Get(player_no); + lbRTC_time_c* rtc_time = Common_GetPointer(time.rtc_time); + + if (mLd_PlayerManKindCheckNo(player_no) == FALSE && priv != NULL && mPr_NullCheckPersonalID(&priv->player_ID) == FALSE) { + mPr_mother_mail_info_c* mother_mail = Save_GetPointer(mother_mail[player_no]); + lbRTC_ymd_t* mail_date = &mother_mail->date; + + if (mail_date->year != mTM_rtcTime_ymd_clear_code.year && mail_date->month != mTM_rtcTime_ymd_clear_code.month && mail_date->day != mTM_rtcTime_ymd_clear_code.day) { + if (mail_date->year != rtc_time->year || mail_date->month != rtc_time->month || mail_date->day != rtc_time->day) { + mPr_SendMotherMail(mother_mail, rtc_time); + } + } + else { + mTM_set_renew_time(mail_date, rtc_time); + } + } +} + +static void mPr_GetForeingerAnimalMail(Mail_c* mail, Private_c* priv, mPr_animal_memory_c* anm_mem) { + AnmPersonalID_c anm_pid; + int mail_no; + u8 npc_name[ANIMAL_NAME_LEN]; + u8 header[40]; + u8 footer[48]; + int ofs; + int looks; + int header_back_start; + + looks = mNpc_GetLooks(anm_mem->npc_id); + ofs = RANDOM(3); + mail_no = 0xFC; + mail_no += ofs + (u8)looks * 3; + mHandbill_Set_free_str(0, priv->player_ID.player_name, PLAYER_NAME_LEN); // player's name + mNpc_LoadNpcNameString(npc_name, anm_mem->npc_id); + mHandbill_Set_free_str(1, npc_name, ANIMAL_NAME_LEN); // animal's name + mHandbill_Set_free_str(2, anm_mem->land_name, LAND_NAME_SIZE); // animal's current town name + mHandbill_Set_free_str(3, priv->player_ID.land_name, LAND_NAME_SIZE); // player's town name + mHandbill_Load_HandbillFromRom2(header, 40, &header_back_start, footer, 48, mail->content.body, mail_no); + mem_copy(mail->content.header, header, mHandbill_HEADER_LEN); + mem_copy(mail->content.footer, footer, mHandbill_FOOTER_LEN); + + mail->content.header_back_start = header_back_start; + mail->content.font = 0; + mail->content.mail_type = 0; + mail->present = EMPTY_NO; + mail->content.paper_type = mNpc_GetPaperType(); + + anm_pid.npc_id = anm_mem->npc_id; + anm_pid.land_id = mLd_BITMASK; + mLd_CopyLandName(anm_pid.land_name, anm_mem->land_name); + anm_pid.name_id = anm_mem->npc_id; + anm_pid.looks = looks; + + mMl_set_mail_name_npcinfo(&mail->header.sender, &anm_pid); + mPr_CopyPersonalID(&mail->header.recipient.personalID, &priv->player_ID); + mail->header.recipient.type = mMl_NAME_TYPE_PLAYER; +} + +extern void mPr_SendForeingerAnimalMail(Private_c* priv) { + Mail_c* mail = &l_mpr_mail; + mPr_animal_memory_c* anm_mem = &priv->animal_memory; + + if (mLd_PlayerManKindCheck() == FALSE) { + if (anm_mem->npc_id != RSV_NO && ITEM_NAME_GET_TYPE(anm_mem->npc_id) == NAME_TYPE_NPC && mPO_get_keep_mail_sum() < mPO_MAIL_STORAGE_SIZE) { + mMl_clear_mail(mail); + mPr_GetForeingerAnimalMail(mail, priv, anm_mem); + mPO_receipt_proc(mail, mPO_SENDTYPE_MAIL); + mPr_ClearAnimalMemory(anm_mem); + } + } +} + +extern void mPr_StartSetCompleteTalkInfo() { + if (mSM_CHECK_ALL_FISH_GET()) { + Common_Get(now_private)->complete_fish_insect_flags |= (1 << 0); + } + + if (mSM_CHECK_ALL_INSECT_GET()) { + Common_Get(now_private)->complete_fish_insect_flags |= (1 << 2); + } +} + +static void mPr_SetCompleteTalk(u8* comp_insect_fish_flags, int type) { + *comp_insect_fish_flags |= (1 << (type * 2) + 1); +} + +static int mPr_GetCompleteTalk(u8 comp_insect_fish_flags, int type) { + return (comp_insect_fish_flags >> ((type * 2) + 1)) & 1; +} + +extern void mPr_SetFishCompleteTalk() { + mPr_SetCompleteTalk(&Common_Get(now_private)->complete_fish_insect_flags, 0); +} + +extern int mPr_CheckFishCompleteTalk(u8 player_no) { + int res = FALSE; + + if (player_no < mPr_FOREIGNER && mPr_GetCompleteTalk(Save_Get(private[player_no]).complete_fish_insect_flags, 0) == TRUE) { + res = TRUE; + } + + return res; +} + +extern void mPr_SetInsectCompleteTalk() { + mPr_SetCompleteTalk(&Common_Get(now_private)->complete_fish_insect_flags, 1); +} + +extern int mPr_CheckInsectCompleteTalk(u8 player_no) { + int res = FALSE; + + if (player_no < mPr_FOREIGNER && mPr_GetCompleteTalk(Save_Get(private[player_no]).complete_fish_insect_flags, 1) == TRUE) { + res = TRUE; + } + + return res; +} + +static int mPr_GetTalkPermission(u8 comp_insect_fish_flags, int type) { + int base = type * 2; + int talk = base + 1; + + int res = FALSE; + if (((comp_insect_fish_flags >> base) & 1) == 0 || ((comp_insect_fish_flags >> talk) & 1) == 0) { + res = TRUE; + } + + return res; +} + +extern int mPr_GetFishCompTalkPermission() { + int res = FALSE; + + if (mSM_CHECK_ALL_FISH_GET()) { + res = mPr_GetTalkPermission(Common_Get(now_private)->complete_fish_insect_flags, 0); + } + + return res; +} + +extern int mPr_GetInsectCompTalkPermission() { + int res = FALSE; + + if (mSM_CHECK_ALL_INSECT_GET()) { + res = mPr_GetTalkPermission(Common_Get(now_private)->complete_fish_insect_flags, 1); + } + + return res; +} + +extern void mPr_ClearMapInfo(mPr_map_info_c* map_info, int max) { + for (max; max != 0; max--) { + mLd_ClearLandName(map_info->land_name); + map_info->land_id = 0; + map_info++; + } +} + +static void mPr_CopyMapInfo(mPr_map_info_c* dst, mPr_map_info_c* src) { + mem_copy((u8*)dst, (u8*)src, sizeof(mPr_map_info_c)); +} + +static void mPr_SetMapThisLand(mPr_map_info_c* map_info) { + if (map_info != NULL) { + mLd_CopyLandName(map_info->land_name, Save_Get(land_info).name); + map_info->land_id = Save_Get(land_info).id; + } +} + +static int mPr_GetMapFreeIdx(mPr_map_info_c* map_info, int max) { + int res = -1; + int i; + + for (i = 0; i < max; i++) { + if (!mLd_CheckId(map_info->land_id) || mLd_NullCheckLandName(map_info->land_name) == TRUE) { + res = i; + break; + } + + map_info++; + } + + return res; +} + +static int mPr_GetLandMapIdx(mPr_map_info_c* map_info, int max, mLd_land_info_c* land_info) { + int res = -1; + + if (map_info != NULL && land_info != NULL) { + int i; + + for (i = 0; i < max; i++) { + if (mLd_CheckCmpLand(map_info->land_name, map_info->land_id, land_info->name, land_info->id) == TRUE) { + res = i; + break; + } + + map_info++; + } + } + + return res; +} + +extern int mPr_GetThisLandMapIdx(mPr_map_info_c* map_info, int max) { + return mPr_GetLandMapIdx(map_info, max, Save_GetPointer(land_info)); +} + +static void mPr_PushMapInfo(mPr_map_info_c* map_info, int max) { + if (map_info != NULL) { + max--; + + if (max > 0) { + for (max; max > 0; max--) { + mPr_CopyMapInfo(map_info, map_info + 1); + map_info++; + } + } + + mPr_ClearMapInfo(map_info, 1); + } +} + +extern void mPr_SetNewMap(mPr_map_info_c* map_info, int max) { + if (map_info != NULL && mPr_GetThisLandMapIdx(map_info, max) == -1) { + int free_idx = mPr_GetMapFreeIdx(map_info, max); + if (free_idx != -1) { + map_info += free_idx; + } + else { + mPr_PushMapInfo(map_info, max); + free_idx = max - 1; + map_info += free_idx; + } + + if (map_info != NULL) { + mPr_SetMapThisLand(map_info); + } + } +} + +extern void mPr_RenewalMapInfo(mPr_map_info_c* map_info, int max, mLd_land_info_c* land_info) { + mPr_map_info_c map_save; + + int map_idx = mPr_GetLandMapIdx(map_info, max, land_info); + if (map_idx != -1) { + mPr_CopyMapInfo(&map_save, map_info + map_idx); + mPr_PushMapInfo(map_info + map_idx, max - map_idx); + + map_idx = mPr_GetMapFreeIdx(map_info, max); + if (map_idx != -1) { + mPr_CopyMapInfo(map_info + map_idx, &map_save); + } + } +} + +extern void mPr_RandomSetPlayerData_title_demo() { + Private_c* priv = Common_Get(now_private); + int i; + + priv->gender = RANDOM(4); // why not RANDOM(2)??? + priv->gender &= 1; + mPlib_change_player_cloth_info_lv2(priv, mPr_GetRandomCloth(priv->gender)); + priv->face = mPr_GetRandomFace(); + + for (i = 0; i < mHS_HOUSE_NUM; i++) { + Save_Get(homes[i]).door_original = -1; + } +} + +extern void mPr_PrintMapInfo_debug(gfxprint_t* gfxprint) { + Private_c* priv = Common_Get(now_private); + mPr_map_info_c* map_info; + int i; + + if (priv != NULL) { + map_info = priv->maps; + gfxprint_color(gfxprint, 30, 100, 100, 255); + gfxprint_locate8x8(gfxprint, 3, 21); + gfxprint_printf(gfxprint, "%04x ", Save_Get(land_info).id); + + gfxprint_locate8x8(gfxprint, 3, 22); + gfxprint_color(gfxprint, 30, 200, 70, 255); + + for (i = 0; i < mPr_FOREIGN_MAP_COUNT; i++) { + if (i == 4) { + gfxprint_locate8x8(gfxprint, 3, 23); + } + + if (mLd_CheckId(map_info->land_id) == TRUE) { + gfxprint_printf(gfxprint, "%04x ", map_info->land_id); + } + else { + gfxprint_printf(gfxprint, "**** "); + } + + map_info++; + } + } +} diff --git a/rel/player_select.c b/rel/player_select.c index 1fd5ed95..030334c2 100644 --- a/rel/player_select.c +++ b/rel/player_select.c @@ -293,7 +293,7 @@ extern void player_select_init(GAME* game) { u8* name = player_select->player_names[i]; if (mPr_CheckPrivate(private_p) == TRUE) { - mPr_CopyPlayerName(name, private_p); + mPr_CopyPlayerName(name, private_p->player_ID.player_name); if (private_p->exists == FALSE) { mem_copy(name + PLAYER_NAME_LEN, l_gaishutu_str, 10);