From 41c669ea83fadc1eb98a8877945f2411270f2502 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Wed, 26 Apr 2023 18:26:59 -0400 Subject: [PATCH] Implement & link m_house.c, m_home.c --- config/rel_slices.yml | 5 + include/libforest/gbi_extensions.h | 7 +- include/m_calendar.h | 12 +- include/m_cockroach.h | 18 ++ include/m_common_data.h | 12 +- include/m_font.h | 2 +- include/m_home.h | 112 +------- include/m_home_h.h | 161 +++++++++++ include/m_house.h | 44 +++ include/m_island.h | 16 ++ include/m_mail.h | 3 + include/m_name_table.h | 38 +++ include/m_npc.h | 14 + include/m_private.h | 4 + rel/m_home.c | 442 +++++++++++++++++++++++++++++ rel/m_house.c | 116 ++++++++ 16 files changed, 890 insertions(+), 116 deletions(-) create mode 100644 include/m_cockroach.h create mode 100644 include/m_home_h.h create mode 100644 include/m_house.h create mode 100644 include/m_island.h create mode 100644 include/m_name_table.h create mode 100644 rel/m_home.c create mode 100644 rel/m_house.c diff --git a/config/rel_slices.yml b/config/rel_slices.yml index d3aa6a10..1e3669b4 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -4,6 +4,11 @@ m_debug_hayakawa.c: .text: [0x803965E4, 0x803973E8] .rodata: [0x80641D50, 0x80641D90] .data: [0x80651328, 0x80651358] +m_home.c: + .text: [0x803B2E88, 0x803B3688] + .data: [0x806546C8, 0x80655340] +m_house.c: + .text: [0x803B3688, 0x803B3880] m_kabu_manager.c: .text: [0x803B5CC4, 0x803B6280] .rodata: [0x80642480, 0x806424C0] diff --git a/include/libforest/gbi_extensions.h b/include/libforest/gbi_extensions.h index 51fd1723..9e80461a 100644 --- a/include/libforest/gbi_extensions.h +++ b/include/libforest/gbi_extensions.h @@ -18,9 +18,6 @@ extern "C" { #define G_SETCOMBINE_TEV 0xD0 #define G_SETTILE_DOLPHIN 0xD2 -#define G_OFF 0 -#define G_ON 1 - #define G_FIRST_CMD G_SETTEXEDGEALPHA /* Triangle/Quad vertex bit size */ @@ -209,7 +206,7 @@ typedef struct { unsigned int d1:3; unsigned int Ab1:3; unsigned int Ad1:3; -} Gsetcombine; +} Gsetcombine_new; typedef struct { int cmd:8; /* 0xCF */ @@ -367,6 +364,7 @@ typedef struct { unsigned int alpha1:3; } combiner_tev_alpha; +/* static combiner_tev_alpha tbla[8] = { { 0, TEV_ALPHA_COMBINED, 0, TEV_ALPHA_ONE }, { 0, TEV_ALPHA_TEXEL0, 0, TEV_ALPHA_TEXEL0 }, @@ -412,6 +410,7 @@ static combiner_tev_color tblc[32] = { { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO }, { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO } }; +*/ /* New Command Macros */ #define gsDPParam2(cmd, tag, param, extra) \ diff --git a/include/m_calendar.h b/include/m_calendar.h index 73c1dc95..2fb28399 100644 --- a/include/m_calendar.h +++ b/include/m_calendar.h @@ -10,12 +10,12 @@ extern "C" { /* sizeof(mCD_player_calendar_c) == 0x68 */ typedef struct calendar_player_info_s { - u32 played_days[lbRTC_MONTHS_MAX]; /* bitfield of days where 1 bit represents a day played */ - u32 event_days[lbRTC_MONTHS_MAX]; /* bitfield of events where 1 bit represents an event was on that day */ - u16 event_flags; /* flags for specific event days the player played on */ - u16 edit; /* unsure, might have something to do with saving an edit */ - lbRTC_year_t year; /* year calendar was last updated */ - lbRTC_month_t month; /* month calendar was last updated */ + /* 0x00 */ u32 played_days[lbRTC_MONTHS_MAX]; /* bitfield of days where 1 bit represents a day played */ + /* 0x30 */ u32 event_days[lbRTC_MONTHS_MAX]; /* bitfield of events where 1 bit represents an event was on that day */ + /* 0x60 */ u16 event_flags; /* flags for specific event days the player played on */ + /* 0x62 */ u8 edit; /* unsure, might have something to do with saving an edit */ + /* 0x64 */ lbRTC_year_t year; /* year calendar was last updated */ + /* 0x66 */ lbRTC_month_t month; /* month calendar was last updated */ } mCD_player_calendar_c; #ifdef __cplusplus diff --git a/include/m_cockroach.h b/include/m_cockroach.h new file mode 100644 index 00000000..bcc21f71 --- /dev/null +++ b/include/m_cockroach.h @@ -0,0 +1,18 @@ +#ifndef M_COCKROACH_H +#define M_COCKROACH_H + +#include "types.h" +#include "m_home_h.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void mCkRh_InitGokiSaveData_1Room_ByHomeData(mHm_hs_c* home); +extern void mCkRh_InitGokiSaveData_IslandPlayerRoom(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_common_data.h b/include/m_common_data.h index 8f3336e0..fb68385f 100644 --- a/include/m_common_data.h +++ b/include/m_common_data.h @@ -6,7 +6,7 @@ #include "m_land_h.h" #include "lb_rtc.h" #include "m_flashrom.h" -#include "m_home.h" +#include "m_home_h.h" #include "m_private.h" #include "m_npc.h" #include "m_field_make.h" @@ -77,9 +77,13 @@ typedef struct Save_s { /* 0x0212DC */ lbRTC_time_c last_grow_time; /* last time that a new villager moved into town */ /* 0x0212E4 */ u8 _tmp4[0xAA]; /* 0x02138E */ u8 saved_rom_debug; /* flag to set save to 'debug rom' mode */ - /* 0x02138F */ u8 _tmp5[0x1199]; + /* 0x02138F */ u8 _tmp5[0x11]; + /* 0x0213A0 */ u8 keep_house_size[PLAYER_NUM]; /* saved flags for house sizes */ + /* 0x0213A4 */ u8 _tmp6[0x1184]; /* 0x022528 */ OSTime time_delta; /* time delta against GC RTC */ - /* 0x022530 */ u8 _tmp6[0x3AD0]; + /* 0x022530 */ u8 _tmp7[0x1C30]; + /* 0x024160 */ Anmret_c return_animal; /* information about villager which moved back in to your town after moving to someone else's town */ + /* 0x02416C */ u8 _tmp8[0x1E94]; } Save_t; typedef union save_u { @@ -97,6 +101,8 @@ typedef struct common_data_s { /* 0x026008 */ int player_data_mode; /* 0x02600C */ u8 _clip[0x104]; /* Temporary, clip is a struct with size 0x104 */ /* 0x026110 */ Time_c time; + /* 0x02613C */ Private_c* now_private; + /* 0x026140 */ mHm_hs_c* now_home; } common_data_t; extern common_data_t common_data; diff --git a/include/m_font.h b/include/m_font.h index d8780979..70d24ac0 100644 --- a/include/m_font.h +++ b/include/m_font.h @@ -5,7 +5,7 @@ #include "m_lib.h" #include "graph.h" #include "game.h" -#include "gbi_extensions.h" +#include "libforest/gbi_extensions.h" #ifdef __cplusplus extern "C" { diff --git a/include/m_home.h b/include/m_home.h index fcde6133..24ccce18 100644 --- a/include/m_home.h +++ b/include/m_home.h @@ -2,6 +2,7 @@ #define M_HOME_H #include "types.h" +#include "m_home_h.h" #include "m_field_make.h" #include "m_actor_type.h" #include "m_personal_id.h" @@ -13,109 +14,16 @@ extern "C" { #endif -#define HOME_MAILBOX_SIZE 10 -#define HANIWA_ITEM_HOLD_NUM 4 -#define HANIWA_MESSAGE_LEN 128 - -/* sizeof(mHm_rmsz_c) == 6 */ -typedef struct home_size_info_s { - /* 0x00 */ struct { - /* 0x00 */ u8 day; - /* 0x01 */ u8 month; - /* 0x02 */ u16 year; - } upgrade_order_date; /* date you ordered an upgrade, seems to be a struct */ - - /* 0x04 */ u8 size:3; /* current house size */ - /* 0x04 */ u8 next_size:3; /* next house size when upgrade is ordered */ - /* 0x04 */ u8 statue_rank:2; /* statue ranking, 0 = gold, 1 = silver, 2 = bronze, 3 = jade */ - /* 0x05 */ u8 renew:1; /* refresh house size & 'outlook' palette */ - /* 0x05 */ u8 statue_ordered:1; /* set when statue is ordered from Nook */ - /* 0x05 */ u8 basement_ordered:1; /* set when basement has been ordered */ - /* 0x05 */ u8 pad:5; /* unused? */ -} mHm_rmsz_c; - -/* sizeof(Haniwa_Item_c) == 8 */ -typedef struct home_haniwa_item_s { - /* 0x00 */ mActor_name_t item; /* held item */ - /* 0x02 */ s16 exchange_type; /* type of exchange (sale, free, trade) */ - /* 0x04 */ u32 extra_data; /* trade related data */ -} Haniwa_Item_c; - -/* sizeof(Haniwa_c) == 0xA4 */ -typedef struct home_haniwa_s { - /* 0x00 */ Haniwa_Item_c items[HANIWA_ITEM_HOLD_NUM]; /* held items */ - /* 0x20 */ u8 message[HANIWA_MESSAGE_LEN]; /* message for visitors */ - /* 0xA0 */ u32 bells; /* held bells from selling items */ -} Haniwa_c; - -/* sizeof(mHm_wf_c) == 2 */ -typedef struct home_wall_floor_s { - /* 0x00 */ u8 flooring_idx; - /* 0x01 */ u8 wallpaper_idx; -} mHm_wf_c; - -/* sizeof(mHm_goki_c) == 0xA */ -typedef struct home_goki_s { - /* 0x00 */ lbRTC_time_c time; /* last time updated */ - /* 0x08 */ u8 num; /* number of cockroaches in the house */ -} mHm_goki_c; - -/* sizeof(mHm_lyr_c) == 0x228 */ -typedef struct home_layer_s { - /* 0x000 */ mActor_name_t items[UT_Z_NUM][UT_X_NUM]; /* Furniture item actors */ - /* 0x200 */ u64 ftr_switch; /* Bitfield for controlling which furniture items are active, max of 64 */ - /* 0x208 */ u32 unk_208[8]; /* Only referenced in mISL_gc_to_agb_layer */ -} mHm_lyr_c; - -/* sizeof(mHm_flr_c) == 0x8A8 */ -typedef struct home_floor_s { - /* 0x000 */ mHm_lyr_c layer_main; - /* 0x228 */ mHm_lyr_c layer_secondary; /* Also storage layer 0 */ - /* 0x450 */ mHm_lyr_c layer_storage1; - /* 0x678 */ mHm_lyr_c layer_storage2; - /* 0x8A0 */ mHm_wf_c wall_floor; - /* 0x8A2 */ TempoBeat_c tempo_beat; - /* 0x8A4 */ struct { - u8 wall_original:1; /* is wallpaper a pattern (original)? */ - u8 floor_original:1; /* is flooring a pattern (original)? */ - u8 bit_2_7:6; /* unused? */ - } fllot_bit; /* Name exposed? by mISL_gc_to_agb_fllot_bit */ -} mHm_flr_c; - -/* sizeof(mHm_hs_c) == 0x26B0 */ -typedef struct home_s { - /* 0x0000 */ PersonalID_c ownerID; /* owner player's ID */ - /* 0x0014 */ u8 unk_14[6]; - /* 0x001A */ TempoBeat_c haniwa_tempo; /* unsure about this */ - /* 0x001C */ lbRTC_ymd_t hra_mark_time; /* last HRA judge date */ - /* 0x0020 */ u32 hra_mark_info; /* bitfield of HRA info pulled when HRA mails letter */ - /* 0x0024 */ struct { - u8 house_updated:1; /* signals HRA to re-score house */ - u8 has_saved:1; /* whether or not the player has saved at this house before */ - u8 hra_member:1; /* whether or not the house has been setup for HRA membership */ - u8 has_basement:1; /* set when the basement is built */ - u8 bit_4:1; /* unused */ - u8 bit_5:1; /* unused */ - u8 bit_6:1; /* unused */ - u8 bit_7:1; /* unused */ - } flags; - /* 0x0026 */ mHm_rmsz_c size_info; /* home size info */ - /* 0x002C */ u8 outlook_pal; /* current house palette */ - /* 0x002D */ u8 ordered_outlook_pal; /* house palette ordered at Nook's via upgrade */ - /* 0x002E */ u8 next_outlook_pal; /* next house palette set via all other means (villager, Wisp, paint @ Nook's, ...) */ - /* 0x002F */ u8 door_original; /* player design shown on door, apparently called 'original', maybe 'original design'? */ - /* 0x0030 */ u8 unk_30[8]; /* unused? */ - /* 0x0038 */ mHm_flr_c main_floor; /* main floor */ - /* 0x08E0 */ mHm_flr_c upper_floor; /* second floor */ - /* 0x1188 */ mHm_flr_c basement; /* basement floor */ - /* 0x1A30 */ Mail_c mailbox[HOME_MAILBOX_SIZE]; /* mailbox */ - /* 0x25D4 */ Haniwa_c haniwa; /* gyroid info */ - /* 0x2678 */ mHm_goki_c goki; /* cockroach info */ - /* 0x2684 */ u32 music_box[2]; /* bitfield of inserted music */ - /* 0x268C */ u8 unk_286C[36]; /* unused? */ -} mHm_hs_c; - +extern void mHm_ClearHomeInfo(int home_no); extern void mHm_ClearAllHomeInfo(); +extern void mHm_SetNowHome(); +extern void mHm_SetDefaultPlayerRoomData(int home_no); +extern void mHm_InitHomeInfo(mHm_hs_c* home, int player_no); +extern void mHm_CheckRehouseOrder(); +extern int mHm_KeepHouseSize(u8 player_no); +extern int mHm_CheckKeepHouseSize(u8 player_no); +extern int mHm_SetBasement(u8 home_no); +extern void mHm_InitCottage(mHm_cottage_c* cottage); #ifdef __cplusplus } diff --git a/include/m_home_h.h b/include/m_home_h.h new file mode 100644 index 00000000..b6c1c20f --- /dev/null +++ b/include/m_home_h.h @@ -0,0 +1,161 @@ +#ifndef M_HOME_H_H +#define M_HOME_H_H + +#include "types.h" +#include "m_field_make.h" +#include "m_actor_type.h" +#include "m_personal_id.h" +#include "audio.h" +#include "lb_rtc.h" +#include "m_mail.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define HOME_MAILBOX_SIZE 10 +#define HANIWA_ITEM_HOLD_NUM 4 +#define HANIWA_MESSAGE_LEN 128 + +enum { + mHm_ROOM_MAIN, + mHm_ROOM_UPPER, + mHm_ROOM_BASEMENT, + + mHm_ROOM_NUM +}; + +enum { + mHm_ROOMTYPE_SMALL, + mHm_ROOMTYPE_MEDIUM, + mHm_ROOMTYPE_LARGE, + mHm_ROOMTYPE_COTTAGE, + + mHm_ROOMTYPE_NUM +}; + +enum { + mHm_HOMESIZE_SMALL, /* initial size */ + mHm_HOMESIZE_MEDIUM, /* paid off first debt */ + mHm_HOMESIZE_LARGE, /* paid off second debt (excluding basement) */ + mHm_HOMESIZE_UPPER, /* paid off third debt & basement */ + mHm_HOMESIZE_STATUE, /* paid off final debt */ + + mHm_HOMESIZE_NUM +}; + +/* sizeof(mHm_rmsz_c) == 6 */ +typedef struct home_size_info_s { + /* 0x00 */ struct { + /* 0x00 */ u8 day; + /* 0x01 */ u8 month; + /* 0x02 */ u16 year; + } upgrade_order_date; /* date you ordered an upgrade, seems to be a struct */ + + /* 0x04 */ u8 size:3; /* current house size */ + /* 0x04 */ u8 next_size:3; /* next house size when upgrade is ordered */ + /* 0x04 */ u8 statue_rank:2; /* statue ranking, 0 = gold, 1 = silver, 2 = bronze, 3 = jade */ + /* 0x05 */ u8 renew:1; /* refresh house size & 'outlook' palette */ + /* 0x05 */ u8 statue_ordered:1; /* set when statue is ordered from Nook */ + /* 0x05 */ u8 basement_ordered:1; /* set when basement has been ordered */ + /* 0x05 */ u8 pad:5; /* unused? */ +} mHm_rmsz_c; + +/* sizeof(Haniwa_Item_c) == 8 */ +typedef struct home_haniwa_item_s { + /* 0x00 */ mActor_name_t item; /* held item */ + /* 0x02 */ s16 exchange_type; /* type of exchange (sale, free, trade) */ + /* 0x04 */ u32 extra_data; /* trade related data */ +} Haniwa_Item_c; + +/* sizeof(Haniwa_c) == 0xA4 */ +typedef struct home_haniwa_s { + /* 0x00 */ Haniwa_Item_c items[HANIWA_ITEM_HOLD_NUM]; /* held items */ + /* 0x20 */ u8 message[HANIWA_MESSAGE_LEN]; /* message for visitors */ + /* 0xA0 */ u32 bells; /* held bells from selling items */ +} Haniwa_c; + +/* sizeof(mHm_wf_c) == 2 */ +typedef struct home_wall_floor_s { + /* 0x00 */ u8 flooring_idx; + /* 0x01 */ u8 wallpaper_idx; +} mHm_wf_c; + +/* sizeof(mHm_goki_c) == 0xA */ +typedef struct home_goki_s { + /* 0x00 */ lbRTC_time_c time; /* last time updated */ + /* 0x08 */ u8 num; /* number of cockroaches in the house */ +} mHm_goki_c; + +/* sizeof(mHm_lyr_c) == 0x228 */ +typedef struct home_layer_s { + /* 0x000 */ mActor_name_t items[UT_Z_NUM][UT_X_NUM]; /* Furniture item actors */ + /* 0x200 */ u64 ftr_switch; /* Bitfield for controlling which furniture items are active, max of 64 */ + /* 0x208 */ u32 unk_208[8]; /* Only referenced in mISL_gc_to_agb_layer */ +} mHm_lyr_c; + +/* sizeof(mHm_flr_c) == 0x8A8 */ +typedef struct home_floor_s { + /* 0x000 */ mHm_lyr_c layer_main; + /* 0x228 */ mHm_lyr_c layer_secondary; /* Also storage layer 0 */ + /* 0x450 */ mHm_lyr_c layer_storage1; + /* 0x678 */ mHm_lyr_c layer_storage2; + /* 0x8A0 */ mHm_wf_c wall_floor; + /* 0x8A2 */ TempoBeat_c tempo_beat; + /* 0x8A4 */ struct { + u8 wall_original:1; /* is wallpaper a pattern (original)? */ + u8 floor_original:1; /* is flooring a pattern (original)? */ + u8 bit_2_7:6; /* unused? */ + } fllot_bit; /* Name exposed? by mISL_gc_to_agb_fllot_bit */ +} mHm_flr_c; + +/* sizeof(mHm_flg_c) == 1 */ +typedef struct home_flags_s { + u8 house_updated:1; /* signals HRA to re-score house */ + u8 has_saved:1; /* whether or not the player has saved at this house before */ + u8 hra_member:1; /* whether or not the house has been setup for HRA membership */ + u8 has_basement:1; /* set when the basement is built */ + u8 bit_4:1; /* unused */ + u8 bit_5:1; /* unused */ + u8 bit_6:1; /* unused */ + u8 bit_7:1; /* unused */ +} mHm_flg_c; + +/* sizeof(mHm_hs_c) == 0x26B0 */ +typedef struct home_s { + /* 0x0000 */ PersonalID_c ownerID; /* owner player's ID */ + /* 0x0014 */ u8 unk_14[6]; + /* 0x001A */ TempoBeat_c haniwa_tempo; /* unsure about this */ + /* 0x001C */ lbRTC_ymd_t hra_mark_time; /* last HRA judge date */ + /* 0x0020 */ u32 hra_mark_info; /* bitfield of HRA info pulled when HRA mails letter */ + /* 0x0024 */ mHm_flg_c flags; + /* 0x0026 */ mHm_rmsz_c size_info; /* home size info */ + /* 0x002C */ u8 outlook_pal; /* current house palette */ + /* 0x002D */ u8 ordered_outlook_pal; /* house palette ordered at Nook's via upgrade */ + /* 0x002E */ u8 next_outlook_pal; /* next house palette set via all other means (villager, Wisp, paint @ Nook's, ...) */ + /* 0x002F */ u8 door_original; /* player design shown on door, apparently called 'original', maybe 'original design'? */ + /* 0x0030 */ u8 unk_30[8]; /* unused? */ + /* 0x0038 */ mHm_flr_c floors[mHm_ROOM_NUM]; /* house floors, might be a union idk */ + /* 0x1A30 */ Mail_c mailbox[HOME_MAILBOX_SIZE]; /* mailbox */ + /* 0x25D4 */ Haniwa_c haniwa; /* gyroid info */ + /* 0x2678 */ mHm_goki_c goki; /* cockroach info */ + /* 0x2684 */ u32 music_box[2]; /* bitfield of inserted music */ + /* 0x268C */ u8 unk_286C[36]; /* unused? */ +} mHm_hs_c; + +/* sizeof(mHm_cottage_c) == 0x8C8 */ +typedef struct home_cottage_s { + /* 0x000 */ mHm_wf_c unused_wall_floor; /* Has wallpaper & flooring bounds checks in sChk_CheckSaveData_Cattage */ + /* 0x002 */ u8 unk_2[2]; /* struct/array that is two bytes long, maybe another wall floor? */ + /* 0x004 */ u8 unk_4; /* direct copy in agb_to_gc_cottage, GBA only? */ + /* 0x005 */ u8 unk_5; /* direct copy in agb_to_gc_cottage, GBA only? */ + /* 0x008 */ mHm_flr_c room; /* Cottage room */ + /* 0x8B0 */ mHm_goki_c goki; /* Cottage cockroaches */ + /* 0x8BC */ u32 music_box[2]; /* Cottage music storage... separate from main home? */ +} mHm_cottage_c; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_house.h b/include/m_house.h new file mode 100644 index 00000000..b1b3942c --- /dev/null +++ b/include/m_house.h @@ -0,0 +1,44 @@ +#ifndef M_HOUSE_H +#define M_HOUSE_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * House arrangement byte breakdown + * + * PX = player x + * HX = house x + * + * xx xx xx xx + * P3 P2 P1 P0 + * + * Example: + * 01 11 10 00 + * P3 P2 P1 P0 + * H1 H3 H2 H0 + **/ + +enum { + mHS_HOUSE0, /* Top-left house */ + mHS_HOUSE1, /* Top-right house */ + mHS_HOUSE2, /* Bottom-left house */ + mHS_HOUSE3, /* Bottom-right house */ + + mHS_HOUSE_NUM +}; + +extern void mHS_house_init(); +extern int mHS_get_arrange_idx(int player_no); +extern int mHS_get_pl_no(int house_no); +extern int mHS_get_pl_no_detail(int home_no); +extern int mHS_set_use(int player_no, int house_no); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_island.h b/include/m_island.h new file mode 100644 index 00000000..19c4d3dd --- /dev/null +++ b/include/m_island.h @@ -0,0 +1,16 @@ +#ifndef M_ISLAND_H +#define M_ISLAND_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_mail.h b/include/m_mail.h index e9dd4c73..4067987e 100644 --- a/include/m_mail.h +++ b/include/m_mail.h @@ -59,6 +59,9 @@ typedef struct mail_s { /* 0x02E */ Mail_ct_c content; } Mail_c; +extern int mMl_strlen(u8* str, int maxlen, u8 check_char); +extern void mMl_clear_mail_box(Mail_c* mail_box, int count); + #ifdef __cplusplus } #endif diff --git a/include/m_name_table.h b/include/m_name_table.h new file mode 100644 index 00000000..485226f6 --- /dev/null +++ b/include/m_name_table.h @@ -0,0 +1,38 @@ +#ifndef M_NAME_TABLE_H +#define M_NAME_TABLE_H + +#include "types.h" +#include "m_actor_type.h" + +/* TODO: these defintions are likely included from an auto-gen source */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define EMPTY_NO 0x0000 + +#define FTR_REDALOHASHIRT 0x1814 +#define FTR_BLUEALOHASHIRT 0x1818 + +#define FTR_TAPEDECK 0x1E58 + +#define ITM_COLLEGERULE 0x2B00 + +#define FTR_ORANGEBOX 0x30F8 + +#define DOOR_START 0x4000 +#define DOOR0 DOOR_START /* 0x4000 */ +#define DOOR1 (DOOR0 + 1) /* 0x4001 */ + +#define EXIT_DOOR 0x4080 + +#define RSV_DOOR 0xFE1B +#define RSV_WALL_NO 0xFFFE /* interior wall item, no collision */ +#define RSV_NO 0xFFFF /* reserved space, can't interact but no collision */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_npc.h b/include/m_npc.h index b59de054..8a9dafab 100644 --- a/include/m_npc.h +++ b/include/m_npc.h @@ -111,6 +111,20 @@ typedef struct animal_s { /* 0x000 */ u8 unused[24]; /* unknown usage/unused */ } Animal_c; +/* + Struct for keeping track of an event where a villager can briefly return to your town after + moving away to another town. The time limit seems to be 60 days, and the villager will only + appear once per player during that time if the player talks to them. +*/ + +/* sizeof(Anmret_c) == 0xC */ +typedef struct animal_return_s { + /* 0x00 */ mActor_name_t npc_id; /* id of the villager who left */ + /* 0x02 */ u8 talk_bit; /* which players have already interacted with this villager */ + /* 0x03 */ u8 exist; /* if the villager exists */ + /* 0x04 */ lbRTC_time_c renew_time; /* time that this struct was updated */ +} Anmret_c; + extern void mNpc_PrintRemoveInfo(gfxprint_t* gfxprint); extern void mNpc_PrintFriendship_fdebug(gfxprint_t* gfxprint); diff --git a/include/m_private.h b/include/m_private.h index 537de221..a151d552 100644 --- a/include/m_private.h +++ b/include/m_private.h @@ -160,6 +160,10 @@ extern s16 mPr_GetGoodsPower(); extern s16 mPr_GetMoneyPower(); 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); #ifdef __cplusplus } diff --git a/rel/m_home.c b/rel/m_home.c new file mode 100644 index 00000000..25823311 --- /dev/null +++ b/rel/m_home.c @@ -0,0 +1,442 @@ +#include "m_home.h" + +#include "m_common_data.h" +#include "m_house.h" +#include "m_string.h" +#include "m_font.h" +#include "m_mail.h" +#include "m_lib.h" +#include "m_name_table.h" +#include "m_field_make.h" +#include "libultra/libultra.h" +#include "m_cockroach.h" +#include "m_personal_id.h" +#include "m_private.h" + +static mActor_name_t l_player_room_2_utinfo[UT_X_NUM * UT_Z_NUM] = { + RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + DOOR0, RSV_WALL_NO, RSV_WALL_NO, RSV_DOOR, RSV_DOOR, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_DOOR, RSV_DOOR, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO +}; + +static mActor_name_t l_player_room_bm_utinfo[UT_X_NUM * UT_Z_NUM] = { + RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_DOOR, RSV_DOOR, RSV_WALL_NO, RSV_WALL_NO, DOOR0, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, RSV_DOOR, RSV_DOOR, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO +}; + +static mActor_name_t l_proom_s_tmp[UT_X_NUM * UT_Z_NUM] = { + RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, RSV_WALL_NO, RSV_DOOR, RSV_DOOR, RSV_WALL_NO, RSV_WALL_NO, DOOR0, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, RSV_WALL_NO, RSV_DOOR, RSV_DOOR, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, RSV_WALL_NO, EXIT_DOOR, EXIT_DOOR, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO +}; + +static mActor_name_t l_proom_m_tmp[UT_X_NUM * UT_Z_NUM] = { + RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_DOOR, RSV_DOOR, RSV_WALL_NO, RSV_WALL_NO, DOOR0, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_DOOR, RSV_DOOR, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EXIT_DOOR, EXIT_DOOR, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO +}; + +static mActor_name_t l_proom_l_tmp[UT_X_NUM * UT_Z_NUM] = { + RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, DOOR1, RSV_WALL_NO, RSV_WALL_NO, RSV_DOOR, RSV_DOOR, RSV_WALL_NO, RSV_WALL_NO, DOOR0, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_DOOR, RSV_DOOR, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EXIT_DOOR, EXIT_DOOR, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO +}; + +static mActor_name_t l_proom_cottage_tmp[UT_X_NUM * UT_Z_NUM] = { + RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_DOOR, RSV_DOOR, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, EXIT_DOOR, EXIT_DOOR, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, RSV_WALL_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, + EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO, EMPTY_NO +}; + +#define HANIWA_MSG_LINES 4 + +#pragma pool_data on +extern void mHm_ClearHomeInfo(int home_no) { + static int haniwa_msg[HANIWA_MSG_LINES] = { 0x76A, 0x76B, 0x76C, 0x76D }; /* These are probably defines somewhere from auto-gen */ + + int no; + mHm_hs_c* home; + u8 haniwa_msg_buf[HANIWA_MESSAGE_LEN]; + u16* item_p; + u16* src_p; + int i; + u8* haniwa_msg_p; + int j; + + no = home_no & 3; + home = Save_GetPointer(homes[no]); + bzero(home, sizeof(mHm_hs_c)); + mPr_ClearPersonalID(&home->ownerID); + bcopy(l_proom_s_tmp, home->floors[mHm_ROOM_MAIN].layer_main.items, (UT_X_NUM * UT_Z_NUM) * sizeof(u16)); + home->floors[mHm_ROOM_MAIN].layer_main.ftr_switch = 0; + *((u32*)&home->floors[mHm_ROOM_MAIN].layer_main.ftr_switch + 1) = 0; /* ftr_switch might be a union? */ + *((u32*)&home->floors[mHm_ROOM_MAIN].layer_main.ftr_switch + 0) = 0; + + item_p = (u16*)home->floors[mHm_ROOM_BASEMENT].layer_main.items; + src_p = l_player_room_bm_utinfo; + for (i = 0; i < UT_X_NUM * UT_Z_NUM; i++) { + *item_p++ = *src_p++; + } + + item_p = ((u16*)home->floors[mHm_ROOM_UPPER].layer_main.items); + src_p = l_player_room_2_utinfo; + for (i = 0; i < UT_X_NUM * UT_Z_NUM; i++) { + *item_p++ = *src_p++; + } + + mMl_clear_mail_box(home->mailbox, HOME_MAILBOX_SIZE); + Save_Set(homes[no].outlook_pal, no); + Save_Set(homes[no].next_outlook_pal, no); + mCkRh_InitGokiSaveData_1Room_ByHomeData(home); + mHm_SetDefaultPlayerRoomData(no); + + haniwa_msg_p = home->haniwa.message; + for (j = 0; j < HANIWA_MSG_LINES; j++) { + int len; + + mString_Load_StringFromRom(haniwa_msg_buf, HANIWA_MESSAGE_LEN, haniwa_msg[j]); + len = mMl_strlen(haniwa_msg_buf, HANIWA_MESSAGE_LEN, CHAR_SPACE); + haniwa_msg_buf[len] = CHAR_NEW_LINE; + mem_copy(haniwa_msg_p, haniwa_msg_buf, len + 1); + haniwa_msg_p += len + 1; + } + + Save_Set(keep_house_size[no], 0); + Save_Set(homes[no].door_original, 0xFF); +} +#pragma pool_data reset + +extern void mHm_ClearAllHomeInfo() { + int i; + + for (i = 0; i < PLAYER_NUM; i++) { + mHm_ClearHomeInfo(i); + } +} + +extern void mHm_SetNowHome() { + mHm_hs_c* now_home = NULL; + + if (Common_Get(player_no) < PLAYER_NUM) { + now_home = Save_GetPointer(homes[mHS_get_arrange_idx(Common_Get(player_no))]); + } + + Common_Set(now_home, now_home); +} + +/* sizeof(mHm_player_room_default_data_c) == 0x10 */ +typedef struct { + /* 0x00 */ u8 wall_num; + /* 0x01 */ u8 floor_num; + /* 0x04 */ int item_ut_x; + /* 0x08 */ int item_ut_z; + /* 0x0C */ mActor_name_t item; +} mHm_player_room_default_data_c; + +static mHm_player_room_default_data_c l_mHm_player_room_default_data[PLAYER_NUM] = { + { 3, 38, 4, 1, FTR_TAPEDECK }, /* Top-left house, stone wall & old flooring */ + { 41, 42, 4, 1, FTR_TAPEDECK }, /* Top-right house, wood panelling & steel flooring */ + { 55, 5, 4, 1, FTR_TAPEDECK }, /* Bottom-left house, shanty wall & birch flooring */ + { 42, 34, 4, 1, FTR_TAPEDECK } /* Bottom-right house, concrete wall & charcoal tile */ +}; + +extern void mHm_SetDefaultPlayerRoomData(int home_no) { + int i; + + int ut_x = l_mHm_player_room_default_data[home_no & 3].item_ut_x; + int ut_z = l_mHm_player_room_default_data[home_no & 3].item_ut_z; + + Save_Set(homes[home_no & 3].floors[mHm_ROOM_MAIN].layer_main.items[ut_z][ut_x], l_mHm_player_room_default_data[home_no & 3].item); + Save_Set(homes[home_no & 3].floors[mHm_ROOM_MAIN].layer_main.items[1][1], FTR_ORANGEBOX); + Save_Set(homes[home_no & 3].floors[mHm_ROOM_MAIN].layer_secondary.items[1][1], ITM_COLLEGERULE); + + for (i = 0; i < mHm_ROOM_NUM; i++) { + Save_Set(homes[home_no & 3].floors[i].wall_floor.flooring_idx, l_mHm_player_room_default_data[home_no & 3].floor_num); + Save_Set(homes[home_no & 3].floors[i].wall_floor.wallpaper_idx, l_mHm_player_room_default_data[home_no & 3].wall_num); + } +} + +extern void mHm_InitHomeInfo(mHm_hs_c* home, int player_no) { + mPr_CopyPersonalID(&home->ownerID, Save_GetPointer(private[player_no].player_ID)); +} + +static void mHm_ChangeWallDoorFG(mActor_name_t* dst, int roomtype, int set) { + static mActor_name_t* player_room_tmp_table[mHm_ROOMTYPE_NUM] = { + l_proom_s_tmp, /* small room layout (default) */ + l_proom_m_tmp, /* medium room layout */ + l_proom_l_tmp, /* large room layout */ + l_proom_cottage_tmp /* island cottage layout */ + }; + + mActor_name_t* src; + int i; + + if (roomtype < mHm_ROOMTYPE_SMALL || roomtype >= mHm_ROOMTYPE_NUM) { + roomtype = mHm_ROOMTYPE_SMALL; + } + + src = player_room_tmp_table[roomtype]; + for (i = 0; i < UT_X_NUM * UT_Z_NUM; i++) { + if (*src != EMPTY_NO) { + if (set == FALSE) { + *dst = EMPTY_NO; /* clear */ + } + else { + *dst = *src; /* set */ + } + } + + src++; + dst++; + } +} + +static void mHm_EraseWallDoor(mActor_name_t* items, int roomtype) { + mHm_ChangeWallDoorFG(items, roomtype, FALSE); +} + +static void mHm_SetWallDoor(mActor_name_t* items, int roomtype) { + mHm_ChangeWallDoorFG(items, roomtype, TRUE); +} + +static void mHm_RehouseWallDoor(mHm_hs_c* home, int home_size) { + static int room_size[mHm_HOMESIZE_NUM] = { + mHm_ROOMTYPE_SMALL, /* mHm_HOMESIZE_SMALL */ + mHm_ROOMTYPE_MEDIUM, /* mHm_HOMESIZE_MEDIUM */ + mHm_ROOMTYPE_LARGE, /* mHm_HOMESIZE_LARGE */ + mHm_ROOMTYPE_LARGE, /* mHm_HOMESIZE_UPPER */ + mHm_ROOMTYPE_SMALL /* mHm_HOMESIZE_STATUE */ + }; + + int new_size; + int old_size; + + if (home_size < mHm_HOMESIZE_MEDIUM || home_size >= mHm_HOMESIZE_NUM) { + home_size = mHm_HOMESIZE_MEDIUM; + } + + old_size = room_size[home_size - 1]; + new_size = room_size[home_size]; + + mHm_EraseWallDoor((u16*)home->floors[mHm_ROOM_MAIN].layer_main.items, old_size); + mHm_EraseWallDoor((u16*)home->floors[mHm_ROOM_MAIN].layer_secondary.items, old_size); + mHm_SetWallDoor((u16*)home->floors[mHm_ROOM_MAIN].layer_main.items, new_size); + mHm_SetWallDoor((u16*)home->floors[mHm_ROOM_MAIN].layer_secondary.items, new_size); +} + +#define CHECK_ORDER_DATE(home, rtc_time) \ + ((home)->size_info.upgrade_order_date.day != (rtc_time)->day || \ + (home)->size_info.upgrade_order_date.month != (rtc_time)->month || \ + (home)->size_info.upgrade_order_date.year != (rtc_time)->year) + +extern void mHm_CheckRehouseOrder() { + mHm_hs_c* home = Save_Get(homes); + lbRTC_time_c* rtc_time = Common_GetPointer(time.rtc_time); + int i; + + for (i = 0; i < PLAYER_NUM; i++) { + if (mPr_NullCheckPersonalID(&home->ownerID) == FALSE) { + if (home->outlook_pal != home->next_outlook_pal) { + home->outlook_pal = home->next_outlook_pal; + } + + if (home->size_info.size != home->size_info.next_size && home->size_info.next_size < mHm_HOMESIZE_STATUE) { + if (CHECK_ORDER_DATE(home, rtc_time)) { + home->outlook_pal = home->ordered_outlook_pal; + home->next_outlook_pal = home->ordered_outlook_pal; + home->size_info.size = home->size_info.next_size; + home->size_info.renew = TRUE; + mHm_RehouseWallDoor(home, home->size_info.size); + } + } + else { + if (home->size_info.basement_ordered) { + if (CHECK_ORDER_DATE(home, rtc_time)) { + mHm_SetBasement(i); + home->size_info.renew = TRUE; + } + } + else if (home->size_info.statue_ordered == TRUE) { + if (CHECK_ORDER_DATE(home, rtc_time)) { + home->size_info.next_size = mHm_HOMESIZE_STATUE; + } + } + } + } + home++; + } + + for (i = 0; i < PLAYER_NUM; i++) { + u32* state_flags = Save_GetPointer(private[i].state_flags); + *state_flags &= (~0x200); /* TODO: these need an enum/defines */ + } +} + +extern int mHm_KeepHouseSize(u8 player_no) { + int arrange_idx; + mHm_hs_c* home; + u8* keep_house_size; + int res = FALSE; + + if (player_no < PLAYER_NUM) { + arrange_idx = mHS_get_arrange_idx(player_no); + home = Save_GetPointer(homes[arrange_idx]); + keep_house_size = Save_GetPointer(keep_house_size[arrange_idx]); + + res = TRUE; + + /* I don't think this is a union or struct due to the unused first bit */ + /* But maybe... perhaps they used a pad bit for the topmost bit unlike other structs */ + *keep_house_size = 0; + *keep_house_size |= home->size_info.size; + *keep_house_size |= home->size_info.next_size << 3; + *keep_house_size |= home->size_info.renew << 6; + } + + return res; +} + +typedef union { + u8 raw; + struct { + u8 unused:1; + u8 renew:1; + u8 next_size:3; + u8 size:3; + } bits; +} keep_u; + +extern int mHm_CheckKeepHouseSize(u8 player_no) { + int arrange_idx; + mHm_hs_c* home; + u8* keep_house_size; + int res = FALSE; + + if (player_no < PLAYER_NUM) { + arrange_idx = mHS_get_arrange_idx(player_no); + keep_house_size = Save_GetPointer(keep_house_size[arrange_idx]); + home = Save_Get(homes + arrange_idx); + + if ((*keep_house_size & 7) == home->size_info.size && + ((*keep_house_size >> 3) & 7) == home->size_info.next_size && + ((*keep_house_size >> 6) & 1) == home->size_info.renew) { + res = TRUE; + } + } + + return res; +} + +extern int mHm_SetBasement(u8 home_no) { + if (home_no < PLAYER_NUM) { + mHm_flg_c* flags = Save_GetPointer(homes[home_no].flags); + if (flags->has_basement == FALSE) { + flags->has_basement = TRUE; + return TRUE; + } + } + + return FALSE; +} + +static void mHm_SetDefaultCottageData(mHm_cottage_c* cottage) { + if (cottage == NULL) { + return; + } + + cottage->room.wall_floor.flooring_idx = 13; + cottage->room.wall_floor.wallpaper_idx = 13; + + cottage->room.layer_main.items[3][3] = FTR_REDALOHASHIRT; + cottage->room.layer_main.items[3][6] = FTR_BLUEALOHASHIRT; + cottage->room.layer_main.items[6][3] = FTR_REDALOHASHIRT; + cottage->room.layer_main.items[6][6] = FTR_BLUEALOHASHIRT; +} + +extern void mHm_InitCottage(mHm_cottage_c* cottage) { + if (cottage != NULL) { + bzero(cottage, sizeof(mHm_cottage_c)); + mHm_SetWallDoor((u16*)cottage->room.layer_main.items, mHm_ROOMTYPE_COTTAGE); + mCkRh_InitGokiSaveData_IslandPlayerRoom(); + mHm_SetDefaultCottageData(cottage); + } +} diff --git a/rel/m_house.c b/rel/m_house.c new file mode 100644 index 00000000..ecf3c974 --- /dev/null +++ b/rel/m_house.c @@ -0,0 +1,116 @@ +#include "m_house.h" + +#include "m_common_data.h" +#include "m_home.h" +#include "m_private.h" + +#define DEFAULT_ARRANGEMENT ((mHS_HOUSE3 << 6) | (mHS_HOUSE2 << 4) | (mHS_HOUSE1 << 2) | (mHS_HOUSE0 << 0)) + +#define ARRANGE_GET(player_no) (((u32)Save_Get(house_arrangement) >> ((player_no) * 2)) & 3) +#define ARRANGE_MOVE(player_no, house_no) ((house_no) << ((player_no) * 2)) + +/** + * @brief Initializes the `house_arrangement` variable to its default state. + * + * The default state is: + * Player0: House0 + * Player1: House1 + * Player2: House2 + * Player3: House3 + **/ +extern void mHS_house_init() { + Save_Set(house_arrangement, DEFAULT_ARRANGEMENT); +} + +/** + * @brief Retrieves the house arrangement value for a given player index. + * + * @return The house index for the player. + **/ +extern int mHS_get_arrange_idx(int player_no) { + return ARRANGE_GET(player_no); +} + +/** + * @brief Returns the index of the player who owns the house index from `house_arrangement`. + * + * @return The owning player index for the house. + **/ +extern int mHS_get_pl_no(int house_no) { + int i; + u32 arrangement = Save_Get(house_arrangement); + + for (i = 0; i < PLAYER_NUM; i++) { + if ((arrangement & 3) == house_no) { + break; + } + + arrangement >>= 2; + } + + return i; +} + +/** + * @brief Returns the index of the player who owns a house by checking house owner IDs. + * + * @return The owning player index for the house. + **/ +extern int mHS_get_pl_no_detail(int home_no) { + mHm_hs_c* home = Save_Get(homes + (home_no & 3)); + + if (mPr_NullCheckPersonalID(&home->ownerID) == FALSE) { + int i; + for (i = 0; i < PLAYER_NUM; i++) { + if (mPr_CheckCmpPersonalID(&home->ownerID, Save_GetPointer(private[i].player_ID))) { + return i; + } + } + } + + return -1; +} + +/* TODO: this probably had some macro.. maybe refactor? */ +/** + * @brief Sets the house arrangement value for `player_no` to `house_no`. + * + * This function also swaps houses with whichever player is set in house_arrangement + * with the house currently assigned to `player_no`. + * + * @return TRUE when successfully set, FALSE otherwise. + **/ +extern int mHS_set_use(int player_no, int house_no) { + int now_player_no; + u32 house_arrangement; + int mask; + int plr_shift; + int new_shift; + int res = FALSE; + + if (player_no < PLAYER_NUM && house_no < PLAYER_NUM) { + now_player_no = mHS_get_pl_no(house_no); + if (mPr_NullCheckPersonalID(Save_GetPointer(homes[house_no].ownerID)) == TRUE) { + if (now_player_no != player_no) { + plr_shift = player_no * 2; + new_shift = now_player_no * 2; + house_arrangement = Save_Get(house_arrangement); + + /* create bitmask to clear previous saved indices */ + mask = 0xffffffff; + mask ^= (3 << plr_shift) | (3 << new_shift); /* Remove the bits relating to both player indicies */ + + /* Swap the player who currently owns our selected house with whatever house our player "owns" currently */ + Save_Set(house_arrangement, ( + ((house_arrangement & mask) | /* Clear old values */ + (((house_arrangement >> plr_shift) & 3)) << new_shift) | /* move current player house idx to old player house idx */ + (house_no << plr_shift))); /* set current player new house idx */ + } + + mHm_InitHomeInfo(Save_Get(homes + house_no), player_no); + res = TRUE; + } + } + + return res; +}