diff --git a/config/rel_slices.yml b/config/rel_slices.yml index fe2d4c6c..2f491205 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -71,6 +71,10 @@ m_police_box.c: .text: [0x803DE8A0, 0x803DEE38] .rodata: [0x806431C8, 0x806431D8] .data: [0x8065BE98, 0x8065BEF0] +m_random_field.c: + .text: [0x803E4B20, 0x803E50E4] + .rodata: [0x80643218, 0x80643240] + .data: [0x8065C098, 0x8065C588] m_room_type/mRmTp_FtrItemNo2FtrIdx.c: .text: [0x803E7878, 0x803E78BC] #m_time.c: # unlinked until function callers that reorder local static variables are implemented. diff --git a/include/m_collision_bg.h b/include/m_collision_bg.h index c72ed981..f161d66e 100644 --- a/include/m_collision_bg.h +++ b/include/m_collision_bg.h @@ -58,6 +58,7 @@ extern f32 mCoBG_GetBgY_AngleS_FromWpos(s_xyz* angle_to_ground, xyz_t wpos, f32 extern int mCoBG_CheckWaterAttribute_OutOfSea(u32 attribute); extern int mCoBG_CheckHole_OrgAttr(u32 attribute); extern f32 mCoBG_GetBgY_OnlyCenter_FromWpos2(xyz_t wpos, f32 foot_dist); +extern int mCoBG_Attribute2CheckPlant(u32 attribute, const xyz_t* wpos); extern f32 mCoBG_GetWaterHeight_File(xyz_t wpos, char* file, int line); #define mCoBG_GetWaterHeight(wpos) mCoBG_GetWaterHeight_File(wpos, __FILE__, __LINE__) diff --git a/include/m_field_info.h b/include/m_field_info.h index 0fc37efb..44c03624 100644 --- a/include/m_field_info.h +++ b/include/m_field_info.h @@ -21,6 +21,8 @@ extern "C" { #define mFI_ROW_TO_CHARSTR(row) ((row) + 'A') #define mFI_COL_TO_CHARSTR(col) ((col) + '0') +#define mFI_NUM_SOUND_SOURCES 6 + enum field_type { mFI_FIELDTYPE_FG, mFI_FIELDTYPE_1, @@ -100,6 +102,15 @@ typedef struct block_table_s { mActor_name_t* items; } mFI_block_tbl_c; +enum { + mFI_SOUND_SOURCE_POND = 3, // TODO: might not be correct name +}; + +typedef struct sound_source_info_s { + s16 kind; + xyz_t wpos; +} mFI_sound_source_info_c; + extern int mFI_CheckFieldData(); extern mActor_name_t mFI_GetFieldId(); extern int mFI_GetClimate(); @@ -120,6 +131,12 @@ extern mCoBG_Collision_u* mFI_GetBkNum2ColTop(int block_x, int block_z); extern u32 mFI_BkNum2BlockKind(int block_x, int block_z); extern int mFI_BlockKind2BkNum(int* block_x, int* block_z, u32 block_kind); extern int mFI_GetBlockUtNum2FG(mActor_name_t* fg_item, int block_x, int block_z, int ut_x, int ut_z); +extern void mFI_UtNum2CenterWpos(xyz_t* wpos, int ut_x, int ut_z); +extern u8 mFI_GetBlockXMax(); +extern u8 mFI_GetBlockZMax(); +extern u8 mFI_BkNum2BlockType(); +extern mFI_sound_source_info_c* mFI_GetSoundSourcePBlockNum(int block_x,int block_z); +extern int mFI_Wpos2UtNum(int* ut_x, int* ut_z, xyz_t wpos); extern void mFI_PrintNowBGNum(gfxprint_t* gfxprint); extern void mFI_PrintFgAttr(gfxprint_t* gfxprint); diff --git a/include/m_field_make.h b/include/m_field_make.h index 9e745f9d..414e3b03 100644 --- a/include/m_field_make.h +++ b/include/m_field_make.h @@ -37,6 +37,13 @@ typedef struct fg_items_s { /* 0x000 */ mActor_name_t items[UT_Z_NUM][UT_X_NUM]; } mFM_fg_c; +/* sizeof (mFM_combo_info_c) == 6 */ +typedef struct block_combo_s { + /* 0x00 */ mActor_name_t bg_id; + /* 0x02 */ mActor_name_t fg_id; + /* 0x05 */ u8 type; +} mFM_combo_info_c; + #ifdef __cplusplus } #endif diff --git a/include/m_random_field.h b/include/m_random_field.h new file mode 100644 index 00000000..6ac1fd66 --- /dev/null +++ b/include/m_random_field.h @@ -0,0 +1,77 @@ +#ifndef M_RANDOM_FIELD_H +#define M_RANDOM_FIELD_H + +#include "types.h" +#include "m_random_field_h.h" +#include "m_field_make.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define mRF_BLOCK_TYPE_MAX 108 // TODO: this is likely a giant enum lol +#define mRF_DIRECT_ERROR 100 + +enum { + mRF_GATE_NONE, + mRF_GATE1_TYPE0, + mRF_GATE1_TYPE1, + mRF_GATE2_TYPE0, + mRF_GATE2_TYPE1, + mRF_GATE3_TYPE0, + + mRF_GATE_TYPE_NUM +}; + +enum { + mRF_DIRECT_NORTH, + mRF_DIRECT_WEST, + mRF_DIRECT_SOUTH, + mRF_DIRECT_EAST, + + mRF_DIRECT_NUM +}; + +enum { + mRF_RIVER0, + mRF_RIVER1, + mRF_RIVER2, + mRF_RIVER3, + mRF_RIVER4, + mRF_RIVER5, + mRF_RIVER6, + + mRF_RIVER_NUM +}; + +enum { + mRF_FIELD_STEP1, /* first level */ + mRF_FIELD_STEP2, /* second level*/ + mRF_FIELD_STEP3, /* third level */ + mRF_FIELD_STEP4, /* fourth level */ + + mRF_FIELD_STEP_NUM +}; + +typedef struct gate_s { + int ut0; + int ut1; +} mRF_gate_c; + +extern u32 mRF_Type2BlockInfo(u8 type); +extern int mRF_SearchPond(int* ut_x, int* ut_z, int block_x, int block_z); +extern mRF_gate_c* mRF_BlockTypeDirect2GateData(int* gate_count, u8 block_type, int direct); +extern void mRF_CheckBeastRoad(); +extern int mRF_RiverIdx2NextDirect(int river_idx); +extern int mRF_BlockType2RiverNextDirect(u8 type); +extern void mRF_IslandBgData_To_VillageData(); +extern int mRF_CheckFieldStep3(); + +extern mFM_combo_info_c data_combi_table[]; +extern int data_combi_table_number; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_random_field_h.h b/include/m_random_field_h.h index 43998a50..c10f8802 100644 --- a/include/m_random_field_h.h +++ b/include/m_random_field_h.h @@ -1,5 +1,5 @@ -#ifndef M_RANDOM_FIELD_H -#define M_RANDOM_FIELD_H +#ifndef M_RANDOM_FIELD_H_H +#define M_RANDOM_FIELD_H_H #include "types.h" @@ -31,13 +31,13 @@ extern "C" { #define mRF_BLOCKKIND_OCEAN (1 << 20) #define mRF_BLOCKKIND_ISLAND (1 << 21) #define mRF_BLOCKKIND_OFFING (1 << 22) -#define mRF_BLOCKKIND_23 (1 << 23) -#define mRF_BLOCKKIND_24 (1 << 24) -#define mRF_BLOCKKIND_25 (1 << 25) -#define mRF_BLOCKKIND_26 (1 << 26) -#define mRF_BLOCKKIND_27 (1 << 27) -#define mRF_BLOCKKIND_28 (1 << 28) -#define mRF_BLOCKKIND_29 (1 << 29) +#define mRF_BLOCKKIND_RIVER0 (1 << 23) +#define mRF_BLOCKKIND_RIVER1 (1 << 24) +#define mRF_BLOCKKIND_RIVER2 (1 << 25) +#define mRF_BLOCKKIND_RIVER3 (1 << 26) +#define mRF_BLOCKKIND_RIVER4 (1 << 27) +#define mRF_BLOCKKIND_RIVER5 (1 << 28) +#define mRF_BLOCKKIND_RIVER6 (1 << 29) #define mRF_BLOCKKIND_DOCK (1 << 30) #define mRF_BLOCKKIND_ISLAND_LEFT (1 << 31) diff --git a/include/m_random_field_ovl.h b/include/m_random_field_ovl.h new file mode 100644 index 00000000..bedf03cb --- /dev/null +++ b/include/m_random_field_ovl.h @@ -0,0 +1,19 @@ +#ifndef M_RANDOM_FIELD_OVL_H +#define M_RANDOM_FIELD_OVL_H + +#include "types.h" +#include "m_random_field_h.h" +#include "m_field_make.h" +#include "game_h.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void mRF_MakeRandomField_ovl(mFM_combination_c* combi_table, mFM_combo_info_c* combo_info, int combo_count, GAME* game); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rel/m_random_field.c b/rel/m_random_field.c new file mode 100644 index 00000000..bc08dd4b --- /dev/null +++ b/rel/m_random_field.c @@ -0,0 +1,1028 @@ +#include "m_random_field.h" + +#include "m_random_field_ovl.h" +#include "m_collision_bg.h" +#include "m_field_info.h" +#include "m_common_data.h" +#include "m_scene.h" + +extern void mRF_MakeRandomField(mFM_combination_c* combi_table, mFM_combo_info_c* combo_info, int combo_count, GAME* game) { + mRF_MakeRandomField_ovl(combi_table, combo_info, combo_count, game); +} + +static u32 mRF_block_info[mRF_BLOCK_TYPE_MAX] = { + mRF_BLOCKKIND_BORDER, + mRF_BLOCKKIND_BORDER | mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_BORDER, + mRF_BLOCKKIND_BORDER, + mRF_BLOCKKIND_BORDER, + mRF_BLOCKKIND_BORDER, + mRF_BLOCKKIND_BORDER, + mRF_BLOCKKIND_BORDER, + mRF_BLOCKKIND_BORDER, + mRF_BLOCKKIND_RAILROAD | mRF_BLOCKKIND_TUNNEL, + mRF_BLOCKKIND_RAILROAD | mRF_BLOCKKIND_TUNNEL, + mRF_BLOCKKIND_STATION | mRF_BLOCKKIND_RAILROAD, + mRF_BLOCKKIND_RAILROAD | mRF_BLOCKKIND_DUMP, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RAILROAD | mRF_BLOCKKIND_18 | mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_PLAYER, + mRF_BLOCKKIND_CLIFF, + mRF_BLOCKKIND_CLIFF, + mRF_BLOCKKIND_CLIFF, + mRF_BLOCKKIND_CLIFF, + mRF_BLOCKKIND_CLIFF, + mRF_BLOCKKIND_CLIFF, + mRF_BLOCKKIND_CLIFF, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_WATERFALL | mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_WATERFALL | mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_18 | mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_18 | mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_WATERFALL | mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_18 | mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_18 | mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_18 | mRF_BLOCKKIND_RIVER1, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_WATERFALL | mRF_BLOCKKIND_RIVER1, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_WATERFALL | mRF_BLOCKKIND_RIVER1, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_18 | mRF_BLOCKKIND_RIVER1, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_18 | mRF_BLOCKKIND_RIVER1, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RIVER2, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RIVER2, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RIVER2, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_WATERFALL | mRF_BLOCKKIND_RIVER2, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_WATERFALL | mRF_BLOCKKIND_RIVER2, + mRF_BLOCKKIND_NONE, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_18 | mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_18 | mRF_BLOCKKIND_RIVER1, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_18 | mRF_BLOCKKIND_RIVER2, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_18 | mRF_BLOCKKIND_RIVER3, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_18 | mRF_BLOCKKIND_RIVER4, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_18 | mRF_BLOCKKIND_RIVER5, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_18 | mRF_BLOCKKIND_RIVER6, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER1, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER2, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER3, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER4, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER5, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER6, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_SLOPE, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_SLOPE, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_SLOPE, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_SLOPE, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_SLOPE, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_SLOPE, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_SLOPE, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_BORDER, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_BORDER, + mRF_BLOCKKIND_MARINE, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_MARINE | mRF_BLOCKKIND_18 | mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_SHOP | mRF_BLOCKKIND_RAILROAD, + mRF_BLOCKKIND_SHRINE, + mRF_BLOCKKIND_POSTOFFICE | mRF_BLOCKKIND_RAILROAD, + mRF_BLOCKKIND_POLICE, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_POOL | mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_POOL | mRF_BLOCKKIND_RIVER1, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_POOL | mRF_BLOCKKIND_RIVER2, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_POOL | mRF_BLOCKKIND_RIVER3, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_POOL | mRF_BLOCKKIND_RIVER4, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_POOL | mRF_BLOCKKIND_RIVER5, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_POOL | mRF_BLOCKKIND_RIVER6, + mRF_BLOCKKIND_BORDER, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BORDER | mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_BORDER, + mRF_BLOCKKIND_RAILROAD | mRF_BLOCKKIND_BORDER, + mRF_BLOCKKIND_MARINE | mRF_BLOCKKIND_BORDER, + mRF_BLOCKKIND_MARINE | mRF_BLOCKKIND_BORDER, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_MARINE | mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_NONE, + mRF_BLOCKKIND_MUSEUM, + mRF_BLOCKKIND_MARINE | mRF_BLOCKKIND_TAILORS, + mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RAILROAD | mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER1, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER1, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER1, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_MARINE | mRF_BLOCKKIND_OCEAN | mRF_BLOCKKIND_OFFING, + mRF_BLOCKKIND_MARINE | mRF_BLOCKKIND_OCEAN | mRF_BLOCKKIND_OFFING, + mRF_BLOCKKIND_MARINE | mRF_BLOCKKIND_OCEAN | mRF_BLOCKKIND_OFFING, + mRF_BLOCKKIND_MARINE | mRF_BLOCKKIND_OCEAN | mRF_BLOCKKIND_OFFING, + mRF_BLOCKKIND_MARINE | mRF_BLOCKKIND_OCEAN | mRF_BLOCKKIND_ISLAND | mRF_BLOCKKIND_ISLAND_LEFT, + mRF_BLOCKKIND_MARINE | mRF_BLOCKKIND_OCEAN | mRF_BLOCKKIND_ISLAND, + mRF_BLOCKKIND_MARINE | mRF_BLOCKKIND_DOCK, + mRF_BLOCKKIND_MARINE | mRF_BLOCKKIND_OCEAN | mRF_BLOCKKIND_OFFING, + mRF_BLOCKKIND_MARINE | mRF_BLOCKKIND_OCEAN | mRF_BLOCKKIND_OFFING, + mRF_BLOCKKIND_MARINE | mRF_BLOCKKIND_OCEAN | mRF_BLOCKKIND_OFFING, + mRF_BLOCKKIND_MARINE | mRF_BLOCKKIND_OCEAN | mRF_BLOCKKIND_OFFING, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER1, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER1, + mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER1 +}; + +extern u32 mRF_Type2BlockInfo(u8 type) { + if (type < mRF_BLOCK_TYPE_MAX) { + return mRF_block_info[type]; + } + + return mRF_BLOCKKIND_NONE; +} + +static int mRF_GateType2GateCount(int gate_type) { + static u8 gate_count_table[mRF_GATE_TYPE_NUM] = { + 0, 1, 1, 2, 2, 3 + }; + + if (gate_type < mRF_GATE_TYPE_NUM) { + return gate_count_table[gate_type]; + } + + return 0; +} + +extern int mRF_SearchPond(int* ut_x, int* ut_z, int block_x, int block_z) { + mFI_sound_source_info_c* s_source_info = mFI_GetSoundSourcePBlockNum(block_x, block_z); + + if (s_source_info != NULL) { + int i; + + for (i = 0; i < mFI_NUM_SOUND_SOURCES; i++, s_source_info++) { + if (s_source_info->kind == mFI_SOUND_SOURCE_POND) { + if (mFI_Wpos2UtNum(ut_x, ut_z, s_source_info->wpos)) { + return TRUE; + } + } + } + } + + return FALSE; +} + +static int mRF_Attr2BeastRoadAttr(int attr) { + switch (attr) { + case mCoBG_ATTRIBUTE_GRASS0: + case mCoBG_ATTRIBUTE_GRASS1: + return mCoBG_ATTRIBUTE_GRASS2; + + case mCoBG_ATTRIBUTE_SOIL0: + case mCoBG_ATTRIBUTE_SOIL1: + return mCoBG_ATTRIBUTE_SOIL2; + + default: + return attr; + } +} + +#define GATE_UT(z, x) ((((z) & 0xF) << 4) | ((x) & 0xF)) +#define GATE(z0, x0, z1, x1) { GATE_UT(z0, x0), GATE_UT(z1, x1) } + +static mRF_gate_c gate1_type0_up[1] = { GATE(0, 7, 1, 7) }; +static mRF_gate_c gate1_type0_lt[1] = { GATE(7, 0, 7, 1) }; +static mRF_gate_c gate1_type0_dn[1] = { GATE(15, 7, 14, 7) }; +static mRF_gate_c gate1_type0_rt[1] = { GATE(7, 15, 7, 14) }; + +static mRF_gate_c gate1_type1_up[1] = { GATE(0, 7, 1, 7) }; +static mRF_gate_c gate1_type1_lt[1] = { GATE(9, 0, 9, 1) }; +static mRF_gate_c gate1_type1_dn[1] = { GATE(15, 7, 14, 7) }; +static mRF_gate_c gate1_type1_rt[1] = { GATE(9, 15, 9, 14) }; + +static mRF_gate_c gate2_type0_up[2] = { GATE(0, 5, 1, 5), GATE(0, 12, 1, 12) }; +static mRF_gate_c gate2_type0_lt[2] = { GATE(5, 0, 5, 1), GATE(12, 0, 12, 1) }; +static mRF_gate_c gate2_type0_dn[2] = { GATE(15, 5, 14, 5), GATE(15, 12, 14, 12) }; +static mRF_gate_c gate2_type0_rt[2] = { GATE(5, 15, 5, 14), GATE(12, 15, 12, 14) }; + +static mRF_gate_c gate2_type1_up[2] = { GATE(0, 2, 1, 2), GATE(0, 11, 1, 11) }; +static mRF_gate_c gate2_type1_lt[2] = { GATE(2, 0, 2, 1), GATE(11, 0, 11, 1) }; +static mRF_gate_c gate2_type1_dn[2] = { GATE(15, 2, 14, 2), GATE(15, 11, 14, 11) }; +static mRF_gate_c gate2_type1_rt[2] = { GATE(2, 15, 2, 14), GATE(11, 15, 11, 14) }; + +static mRF_gate_c gate3_type0_up[3] = { GATE(0, 2, 1, 2), GATE(0, 8, 1, 8), GATE(0, 12, 1, 12) }; +static mRF_gate_c gate3_type0_lt[3] = { GATE(2, 0, 2, 1), GATE(8, 0, 8, 1), GATE(12, 0, 12, 1) }; +static mRF_gate_c gate3_type0_dn[3] = { GATE(15, 2, 14, 2), GATE(15, 8, 14, 8), GATE(15, 12, 14, 12) }; +static mRF_gate_c gate3_type0_rt[3] = { GATE(2, 15, 2, 14), GATE(8, 15, 8, 14), GATE(12, 15, 12, 14) }; + +static mRF_gate_c* mRF_gate_correct_info[mRF_GATE_TYPE_NUM][mRF_DIRECT_NUM] = { + { NULL, NULL, NULL, NULL }, + { gate1_type0_up, gate1_type0_lt, gate1_type0_dn, gate1_type0_rt }, + { gate1_type1_up, gate1_type1_lt, gate1_type1_dn, gate1_type1_rt }, + { gate2_type0_up, gate2_type0_lt, gate2_type0_dn, gate2_type0_rt }, + { gate2_type1_up, gate2_type1_lt, gate2_type1_dn, gate2_type1_rt }, + { gate3_type0_up, gate3_type0_lt, gate3_type0_dn, gate3_type0_rt }, +}; + +static u8 mRF_gate_info2[mRF_BLOCK_TYPE_MAX][mRF_DIRECT_NUM] = { + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE1_TYPE1, // west + mRF_GATE1_TYPE0, // south + mRF_GATE1_TYPE1 // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE1_TYPE1, // west + mRF_GATE1_TYPE0, // south + mRF_GATE1_TYPE1 // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE1_TYPE1, // west + mRF_GATE2_TYPE1, // south + mRF_GATE1_TYPE1 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE1_TYPE0, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE2_TYPE0, // west + mRF_GATE1_TYPE0, // south + mRF_GATE2_TYPE0 // east + }, + { + mRF_GATE2_TYPE0, // north + mRF_GATE2_TYPE0, // west + mRF_GATE1_TYPE0, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE2_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE2_TYPE0, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE2_TYPE0, // south + mRF_GATE2_TYPE0 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE2_TYPE0, // west + mRF_GATE2_TYPE0, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE2_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE2_TYPE0, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE2_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE1_TYPE0, // south + mRF_GATE2_TYPE0 // east + }, + { + mRF_GATE2_TYPE1, // north + mRF_GATE2_TYPE0, // west + mRF_GATE2_TYPE1, // south + mRF_GATE2_TYPE0 // east + }, + { + mRF_GATE3_TYPE0, // north + mRF_GATE2_TYPE0, // west + mRF_GATE2_TYPE1, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE3_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE3_TYPE0, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE2_TYPE1, // north + mRF_GATE1_TYPE0, // west + mRF_GATE3_TYPE0, // south + mRF_GATE2_TYPE0 // east + }, + { + mRF_GATE2_TYPE1, // north + mRF_GATE2_TYPE0, // west + mRF_GATE3_TYPE0, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE3_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE3_TYPE0, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE3_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE2_TYPE1, // south + mRF_GATE2_TYPE0 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE3_TYPE0, // west + mRF_GATE1_TYPE0, // south + mRF_GATE3_TYPE0 // east + }, + { + mRF_GATE2_TYPE0, // north + mRF_GATE3_TYPE0, // west + mRF_GATE1_TYPE0, // south + mRF_GATE2_TYPE1 // east + }, + { + mRF_GATE2_TYPE0, // north + mRF_GATE2_TYPE1, // west + mRF_GATE2_TYPE0, // south + mRF_GATE2_TYPE1 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE2_TYPE1, // west + mRF_GATE2_TYPE0, // south + mRF_GATE3_TYPE0 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE3_TYPE0, // west + mRF_GATE2_TYPE0, // south + mRF_GATE2_TYPE1 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE3_TYPE0, // west + mRF_GATE1_TYPE0, // south + mRF_GATE3_TYPE0 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE2_TYPE1, // west + mRF_GATE2_TYPE0, // south + mRF_GATE3_TYPE0 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE3_TYPE0, // west + mRF_GATE2_TYPE0, // south + mRF_GATE2_TYPE1 // east + }, + { + mRF_GATE2_TYPE0, // north + mRF_GATE2_TYPE1, // west + mRF_GATE2_TYPE0, // south + mRF_GATE2_TYPE1 // east + }, + { + mRF_GATE2_TYPE0, // north + mRF_GATE2_TYPE1, // west + mRF_GATE1_TYPE0, // south + mRF_GATE3_TYPE0 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE1_TYPE0, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE2_TYPE1, // north + mRF_GATE1_TYPE0, // west + mRF_GATE2_TYPE1, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE2_TYPE1, // west + mRF_GATE1_TYPE0, // south + mRF_GATE2_TYPE1 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE2_TYPE1, // west + mRF_GATE1_TYPE0, // south + mRF_GATE2_TYPE1 // east + }, + { + mRF_GATE2_TYPE1, // north + mRF_GATE1_TYPE0, // west + mRF_GATE1_TYPE0, // south + mRF_GATE2_TYPE1 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE2_TYPE1, // west + mRF_GATE2_TYPE1, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE2_TYPE1, // north + mRF_GATE2_TYPE1, // west + mRF_GATE1_TYPE0, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE2_TYPE1, // south + mRF_GATE2_TYPE1 // east + }, + { + mRF_GATE2_TYPE1, // north + mRF_GATE1_TYPE0, // west + mRF_GATE2_TYPE1, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE2_TYPE1, // west + mRF_GATE1_TYPE0, // south + mRF_GATE2_TYPE1 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE2_TYPE1, // west + mRF_GATE1_TYPE0, // south + mRF_GATE2_TYPE1 // east + }, + { + mRF_GATE2_TYPE1, // north + mRF_GATE1_TYPE0, // west + mRF_GATE1_TYPE0, // south + mRF_GATE2_TYPE1 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE2_TYPE1, // west + mRF_GATE2_TYPE1, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE2_TYPE1, // north + mRF_GATE2_TYPE1, // west + mRF_GATE1_TYPE0, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE2_TYPE1, // south + mRF_GATE2_TYPE1 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE2_TYPE0, // west + mRF_GATE1_TYPE0, // south + mRF_GATE2_TYPE0 // east + }, + { + mRF_GATE2_TYPE0, // north + mRF_GATE2_TYPE0, // west + mRF_GATE1_TYPE0, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE2_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE2_TYPE0, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE2_TYPE0, // south + mRF_GATE2_TYPE0 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE2_TYPE0, // west + mRF_GATE2_TYPE0, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE2_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE2_TYPE0, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE2_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE1_TYPE0, // south + mRF_GATE2_TYPE0 // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE_NONE, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE2_TYPE1, // north + mRF_GATE1_TYPE0, // west + mRF_GATE_NONE, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE1_TYPE1, // west + mRF_GATE1_TYPE0, // south + mRF_GATE1_TYPE1 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE1_TYPE0, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE1_TYPE1, // west + mRF_GATE1_TYPE0, // south + mRF_GATE1_TYPE1 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE1_TYPE0, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE2_TYPE1, // north + mRF_GATE1_TYPE0, // west + mRF_GATE2_TYPE1, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE2_TYPE1, // west + mRF_GATE1_TYPE0, // south + mRF_GATE2_TYPE1 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE2_TYPE1, // west + mRF_GATE1_TYPE0, // south + mRF_GATE2_TYPE1 // east + }, + { + mRF_GATE2_TYPE1, // north + mRF_GATE1_TYPE0, // west + mRF_GATE1_TYPE0, // south + mRF_GATE2_TYPE1 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE2_TYPE1, // west + mRF_GATE2_TYPE1, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE2_TYPE1, // north + mRF_GATE2_TYPE1, // west + mRF_GATE1_TYPE0, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE2_TYPE1, // south + mRF_GATE2_TYPE1 // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE2_TYPE1, // north + mRF_GATE1_TYPE0, // west + mRF_GATE_NONE, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE_NONE, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE1_TYPE1, // west + mRF_GATE2_TYPE1, // south + mRF_GATE1_TYPE1 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE3_TYPE0, // west + mRF_GATE1_TYPE0, // south + mRF_GATE3_TYPE0 // east + }, + { + mRF_GATE3_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE3_TYPE0, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE2_TYPE1, // north + mRF_GATE1_TYPE0, // west + mRF_GATE3_TYPE0, // south + mRF_GATE2_TYPE0 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE2_TYPE1, // west + mRF_GATE2_TYPE0, // south + mRF_GATE3_TYPE0 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE3_TYPE0, // west + mRF_GATE2_TYPE0, // south + mRF_GATE2_TYPE1 // east + }, + { + mRF_GATE3_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE3_TYPE0, // south + mRF_GATE1_TYPE0 // east + }, + { + mRF_GATE3_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE2_TYPE1, // south + mRF_GATE2_TYPE0 // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE1_TYPE0, // west + mRF_GATE1_TYPE0, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE_NONE, // north + mRF_GATE_NONE, // west + mRF_GATE_NONE, // south + mRF_GATE_NONE // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE3_TYPE0, // west + mRF_GATE1_TYPE0, // south + mRF_GATE3_TYPE0 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE2_TYPE1, // west + mRF_GATE2_TYPE0, // south + mRF_GATE3_TYPE0 // east + }, + { + mRF_GATE1_TYPE0, // north + mRF_GATE3_TYPE0, // west + mRF_GATE2_TYPE0, // south + mRF_GATE2_TYPE1 // east + } +}; + +static int mRF_BlockTypeDirect2GateType(u8 block_type, int direct) { + return mRF_gate_info2[block_type][direct]; +} + + +extern mRF_gate_c* mRF_BlockTypeDirect2GateData(int* gate_count, u8 block_type, int direct) { + int type = mRF_BlockTypeDirect2GateType(block_type, direct); + int count = mRF_GateType2GateCount(type); + + *gate_count = count; + return mRF_gate_correct_info[type][direct]; +} + +static int mRF_BlockInf2CheckBeastRoad(u8 block_type, mCoBG_Collision_u* collision_data) { + int i; + int j; + xyz_t wpos = { 0.0f, 0.0f, 0.0f }; + int changed_attribute_count = 0; + int col_ut; + mCoBG_Collision_u* col; + u32 attrib; + + for (i = 0; i < mRF_DIRECT_NUM; i++) { + int gate_count; + mRF_gate_c* gate_p = mRF_BlockTypeDirect2GateData(&gate_count, block_type, i); + + if (gate_p != NULL) { + for (j = 0; j < gate_count; j++) { + /* process first unit */ + { + col_ut = gate_p[j].ut0; + col = collision_data + (u8)col_ut; + attrib = col->data.unit_attribute; + + mFI_UtNum2CenterWpos(&wpos, col_ut & 0xF, (col_ut >> 4) & 0xF); + + /* only bother updating the unit attribute if the unit can grow collideable plants in it */ + if (mCoBG_Attribute2CheckPlant(attrib, &wpos) > 0) { + u32 new_attrib = mRF_Attr2BeastRoadAttr(attrib); + changed_attribute_count++; + + col->data.unit_attribute = new_attrib; + } + } + + /* process second unit */ + { + col_ut = gate_p[j].ut1; + col = collision_data + (u8)col_ut; + attrib = col->data.unit_attribute; + + mFI_UtNum2CenterWpos(&wpos, col_ut & 0xF, (col_ut >> 4) & 0xF); + + /* only bother updating the unit attribute if the unit can grow collideable plants in it */ + if (mCoBG_Attribute2CheckPlant(attrib, &wpos) > 0) { + u32 new_attrib = mRF_Attr2BeastRoadAttr(attrib); + changed_attribute_count++; + + col->data.unit_attribute = new_attrib; + } + } + } + } + } + + return !changed_attribute_count; +} + +extern void mRF_CheckBeastRoad() { + if (Save_Get(scene_no) == SCENE_FG) { + int max_bx = mFI_GetBlockXMax() - 1; + int max_bz = mFI_GetBlockZMax() - 1; + + int block_x; + int block_z; + + for (block_z = 1; block_z < max_bz; block_z++) { + for (block_x = 1; block_x < max_bx; block_x++) { + mCoBG_Collision_u* collision_data = mFI_GetBkNum2ColTop(block_x, block_z); + u8 type = mFI_BkNum2BlockType(block_x, block_z); + + mRF_BlockInf2CheckBeastRoad(type, collision_data); + } + } + } +} + +static u8 l_river_next_direct[mRF_RIVER_NUM] = { + mRF_DIRECT_SOUTH, + mRF_DIRECT_EAST, + mRF_DIRECT_WEST, + mRF_DIRECT_EAST, + mRF_DIRECT_SOUTH, + mRF_DIRECT_WEST, + mRF_DIRECT_SOUTH +}; + +extern int mRF_RiverIdx2NextDirect(int river_idx) { + if (river_idx >= mRF_RIVER0 && river_idx < mRF_RIVER_NUM) { + return l_river_next_direct[river_idx]; + } + + return mRF_DIRECT_SOUTH; +} + +extern int mRF_BlockType2RiverNextDirect(u8 type) { + u32 block_kind = mRF_Type2BlockInfo(type); + u32 river_kinds[mRF_RIVER_NUM] = { + mRF_BLOCKKIND_RIVER0, + mRF_BLOCKKIND_RIVER1, + mRF_BLOCKKIND_RIVER2, + mRF_BLOCKKIND_RIVER3, + mRF_BLOCKKIND_RIVER4, + mRF_BLOCKKIND_RIVER5, + mRF_BLOCKKIND_RIVER6 + }; + + int i; + + for (i = 0; i < mRF_RIVER_NUM; i++) { + if ((block_kind & river_kinds[i]) != 0) { + return mRF_RiverIdx2NextDirect(i); + } + } + + return mRF_DIRECT_ERROR; +} + +static int mRF_FindBgNameTypeCombiNum(mActor_name_t bg_id, u8 type) { + mFM_combo_info_c* combo_info = data_combi_table; + int combi_num = data_combi_table_number; + int i; + + for (i = 0; i < combi_num; i++) { + if (combo_info->bg_id == bg_id && combo_info->type == type) { + return i; + } + combo_info++; + } + + return 0; +} + +extern void mRF_IslandBgData_To_VillageData() { + int left_bg_idx = Save_Get(island.bg_data[0]) & 3; + int right_bg_idx = Save_Get(island.bg_data[1]) & 3; + int island_left_bx; + int island_left_bz; + /* TODO: enums for these */ + mActor_name_t left_t = left_bg_idx + 0x74; + mActor_name_t right_t = right_bg_idx + 0x70; + + if (mFI_BlockKind2BkNum(&island_left_bx, &island_left_bz, mRF_BLOCKKIND_ISLAND_LEFT)) { + mActor_name_t left_bg_name = mRF_FindBgNameTypeCombiNum(left_t, 0x62); + mActor_name_t right_bg_name = mRF_FindBgNameTypeCombiNum(right_t, 0x63); + + Save_Set(combi_table[island_left_bz][island_left_bx].combination_type, left_bg_name); + Save_Set(combi_table[island_left_bz][island_left_bx + 1].combination_type, right_bg_name); + } +} + +extern int mRF_CheckFieldStep3() { + return Save_Get(combi_table[0][0]).height == mRF_FIELD_STEP3; +}