diff options
| author | Prakxo <87568477+Prakxo@users.noreply.github.com> | 2023-09-15 18:36:15 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-15 09:36:15 -0700 |
| commit | ef0a26fd481675a955b301d1b2261ded362c4190 (patch) | |
| tree | 0c2a9de1eda9cd4d465aa4845f18f1ba16584b93 | |
| parent | 898b6fb3a4157f2e681a42c6f420f4b9d7152cc9 (diff) | |
NPC PR 1/3 ok (#96)
* m_npc walk ok
Co-authored-by: Maide <you@example.com>
* fix protos
* fixes
* forgor some fixes
* struct names
---------
Co-authored-by: Maide <you@example.com>
| -rw-r--r-- | include/6D2720.h | 23 | ||||
| -rw-r--r-- | include/6DE300.h | 16 | ||||
| -rw-r--r-- | include/m_common_data.h | 72 | ||||
| -rw-r--r-- | include/m_field_info.h | 6 | ||||
| -rw-r--r-- | include/m_land.h | 2 | ||||
| -rw-r--r-- | include/m_npc.h | 58 | ||||
| -rw-r--r-- | include/m_npc_walk.h | 105 | ||||
| -rw-r--r-- | include/m_random_field.h | 42 | ||||
| -rw-r--r-- | include/sys_math.h | 1 | ||||
| -rw-r--r-- | linker_scripts/jp/symbol_addrs_code.txt | 56 | ||||
| -rw-r--r-- | src/code/m_npc_walk.c | 663 | ||||
| -rw-r--r-- | src/code/m_start_data_init.c | 44 | ||||
| -rw-r--r-- | src/overlays/actors/ovl_Toudai/ac_toudai.c | 4 | ||||
| -rw-r--r-- | src/overlays/gamestates/ovl_play/m_play.c | 7 | ||||
| -rw-r--r-- | yamls/jp/code.yaml | 5 |
15 files changed, 957 insertions, 147 deletions
diff --git a/include/6D2720.h b/include/6D2720.h index ff40168..4fe9a80 100644 --- a/include/6D2720.h +++ b/include/6D2720.h @@ -3,7 +3,6 @@ #include "ultra64.h" -struct mNpc_walk_c; // void func_800AEA80_jp(); // void mNPS_set_schedule_area(); @@ -12,28 +11,6 @@ struct mNpc_walk_c; // void func_800AEC74_jp(); // void mNPS_schedule_manager(); void mNPS_set_all_schedule_area(void); -// void func_800AEDD0_jp(); -// void func_800AEE38_jp(); -// void func_800AEE50_jp(); -// void func_800AEEE8_jp(); -// void func_800AEF1C_jp(); -// void func_800AEF4C_jp(); -// void func_800AEFC4_jp(); -// void func_800AF060_jp(); -// void func_800AF0A8_jp(); -// void func_800AF1E0_jp(); -// void func_800AF2A8_jp(); -// void func_800AF3E8_jp(); -// void func_800AF614_jp(); -// void func_800AF7BC_jp(); -// void func_800AF84C_jp(); -// void func_800AF9C8_jp(); -// void func_800AFA1C_jp(); -void mNpcW_InitNpcWalk(struct mNpc_walk_c* npc_walk); -// void func_800AFC1C_jp(); -// void func_800AFCAC_jp(); -// void func_800AFCD8_jp(); -// void func_800AFDA8_jp(); void func_800B0010_jp(void); #endif diff --git a/include/6DE300.h b/include/6DE300.h index caa7a52..106f274 100644 --- a/include/6DE300.h +++ b/include/6DE300.h @@ -69,20 +69,6 @@ UNK_RET mQst_CheckLimitbyPossessionIdx(s32 arg0); // void func_800BC724_jp(); // void func_800BC830_jp(); // void mQst_PrintQuestInfo(); -// void func_800BCBA0_jp(); -// void func_800BCBDC_jp(); -// void func_800BCC20_jp(); -// void func_800BCC30_jp(); -// void func_800BCC40_jp(); -// void func_800BCCFC_jp(); -// void func_800BCDCC_jp(); -// void func_800BCDFC_jp(); -// void func_800BCE80_jp(); -// void func_800BCEA4_jp(); -// void func_800BCF64_jp(); -// void func_800BCFA4_jp(); -// void func_800BCFC8_jp(); -// void func_800BD02C_jp(); -// void func_800BD1E4_jp(); + #endif diff --git a/include/m_common_data.h b/include/m_common_data.h index a53d6d2..dd96b67 100644 --- a/include/m_common_data.h +++ b/include/m_common_data.h @@ -121,42 +121,42 @@ typedef enum Season { typedef struct Time_c { /* 0x00 */ u32 season; - /* 0x04 */ u32 term_idx; - /* 0x08 */ s16 bgitem_profile; - /* 0x0A */ s16 bgitem_bank; - /* 0x0C */ s32 now_sec; - /* 0x10 */ lbRTC_time_c rtc_time; - /* 0x18 */ s16 rad_min; /* clock hand radial position for mins */ - /* 0x1A */ s16 rad_hour; /* clock hand radial position for hours */ - /* 0x1C */ u8 time_signal; - /* 0x1D */ u8 under_sec; + /* 0x04 */ u32 termIdx; + /* 0x08 */ s16 bgitemProfile; + /* 0x0A */ s16 bgitemBank; + /* 0x0C */ s32 nowSec; + /* 0x10 */ lbRTC_time_c rtcTime; + /* 0x18 */ s16 radMin; + /* 0x1A */ s16 radHour; + /* 0x1C */ u8 timeSignal; + /* 0x1D */ u8 underSec; /* 0x1E */ u8 disp; - /* 0x1F */ u8 rtc_crashed; - /* 0x20 */ s32 rtc_enabled; - /* 0x24 */ s32 add_sec; - /* 0x28 */ s32 add_idx; + /* 0x1F */ u8 rtcCrashed; + /* 0x20 */ s32 rtcEnabled; + /* 0x24 */ s32 addSec; + /* 0x28 */ s32 addIdx; } Time_c; // size = 0x2C typedef struct FamicomEmuCommonData { - /* 0x00 */ s16 unk_00; - /* 0x02 */ s16 unk_02; - /* 0x04 */ s16 unk_04; - /* 0x06 */ s16 unk_06; - /* 0x08 */ s16 unk_08; - /* 0x0A */ s16 unk_0A; - /* 0x0C */ s16 unk_0C; - /* 0x0E */ s16 unk_0E; - /* 0x10 */ s16 unk_10; - /* 0x12 */ s16 unk_12; - /* 0x14 */ s16 unk_14; - /* 0x16 */ s16 unk_16; - /* 0x18 */ s16 unk_18; - /* 0x1A */ s16 unk_1A; - /* 0x1C */ s16 unk_1C; - /* 0x1E */ s16 unk_1E; - /* 0x20 */ s16 unk_20; - /* 0x22 */ s16 unk_22; - /* 0x24 */ s16 unk_24; + /* 0x00 */ s16 unk00; + /* 0x02 */ s16 unk02; + /* 0x04 */ s16 unk04; + /* 0x06 */ s16 unk06; + /* 0x08 */ s16 unk08; + /* 0x0A */ s16 unk0A; + /* 0x0C */ s16 unk0C; + /* 0x0E */ s16 unk0E; + /* 0x10 */ s16 unk10; + /* 0x12 */ s16 unk12; + /* 0x14 */ s16 unk14; + /* 0x16 */ s16 unk16; + /* 0x18 */ s16 unk18; + /* 0x1A */ s16 unk1A; + /* 0x1C */ s16 unk1C; + /* 0x1E */ s16 unk1E; + /* 0x20 */ s16 unk20; + /* 0x22 */ s16 unk22; + /* 0x24 */ s16 unk24; }FamicomEmuCommonData; // size >= 0x26 typedef void (*CommonData_100E4_Func)(struct Game_Play*); @@ -164,7 +164,9 @@ typedef void (*CommonData_100E4_Func)(struct Game_Play*); typedef struct CommonData { /* 0x00000 */ u8 unk00000[0x14]; /* 0x00014 */ s32 unk_00014; - /* 0x00018 */ u8 unk00018[0x8]; + /* 0x00018 */ u8 nowNpcMax; + /* 0x00019 */ u8 removeAnimalIdx; + /* 0x0001A */ u8 unk1A[0x20 - 0x1A]; /* 0x00020 */ Private_c private[PLAYER_NUM]; /* player data */ /* 0x02F60 */ mLd_land_info_c land_info; /* town name & id */ /* 0x02F6A */ u8 unk02F6A[0x61E]; @@ -223,7 +225,7 @@ typedef struct CommonData { /* 0x1014C */ UNK_TYPE1 unk_1014C[0x2]; /* 0x1014E */ s16 unk_1014E; /* 0x10150 */ UNK_TYPE1 unk_10150[0x10]; - /* 0x10160 */ mNpc_NpcList_c npclist[ANIMAL_NUM_MAX]; + /* 0x10160 */ NpcList npclist[ANIMAL_NUM_MAX]; /* 0x104A8 */ u16 house_owner_name; /* 0x104AA */ u16 last_field_id; /* 0x104AC */ UNK_TYPE1 unk_104AC[0x1]; @@ -233,7 +235,7 @@ typedef struct CommonData { /* 0x10598 */ mQst_not_saved_c quest; /* 0x105A0 */ u32 scene_from_title_demo; /* 0x105A4 */ UNK_TYPE1 unk_105A4[0xF0]; - /* 0x10694 */ mNpc_walk_c npc_walk; + /* 0x10694 */ NpcWalking npcWalk; /* 0x10710 */ UNK_TYPE1 unk_10710[0x3C]; /* 0x1074C */ UNK_TYPE unk_1074C; /* 0x10750 */ UNK_TYPE1 unk_10750[0x66]; diff --git a/include/m_field_info.h b/include/m_field_info.h index 913190e..758931e 100644 --- a/include/m_field_info.h +++ b/include/m_field_info.h @@ -30,7 +30,7 @@ struct Game_Play; // void func_80088458_jp(); // void func_800884E0_jp(); // void func_800885A8_jp(); -// void func_80088710_jp(); +s32 mFI_Wpos2BlockNum(s32*, s32*, Vec3f); // void func_80088780_jp(); // void func_8008883C_jp(); // void func_800888AC_jp(); @@ -57,13 +57,13 @@ struct Game_Play; // void func_8008907C_jp(); // void func_80089114_jp(); // void func_800891AC_jp(); -// void func_80089268_jp(); +u8 mFI_BkNum2BlockType(s32,s32); // void func_800892CC_jp(); // void func_8008930C_jp(); // void func_80089348_jp(); // void func_800893C8_jp(); // void func_80089404_jp(); -// void func_80089440_jp(); +void mFI_BlockKind2BkNum(s32*,s32*,s32); // void func_800894D0_jp(); // void func_80089538_jp(); // void func_800895B8_jp(); diff --git a/include/m_land.h b/include/m_land.h index 7569415..65ecff4 100644 --- a/include/m_land.h +++ b/include/m_land.h @@ -4,7 +4,7 @@ #include "ultra64.h" // Town name character count -#define LAND_NAME_SIZE 8 +#define LAND_NAME_SIZE 6 #define LAND_NAME_MURA_SIZE (LAND_NAME_SIZE + 2) typedef struct mLd_land_info_c { diff --git a/include/m_npc.h b/include/m_npc.h index 8d83bff..62f82cf 100644 --- a/include/m_npc.h +++ b/include/m_npc.h @@ -4,27 +4,59 @@ #include "ultra64.h" #include "m_actor.h" #include "unk.h" - -struct mMl_get_npcinfo_from_mail_name_arg0; +#include "m_land.h" +#include "6DB420.h" +#include "m_mail.h" #define ANIMAL_NUM_MAX 15 /* Maximum number of villagers possible in town */ -typedef struct mNpc_NpcList_c { - /* 0x00 */ char unk00[0x38]; -} mNpc_NpcList_c; // size = 0x38 +typedef struct NpcList { + /* 0x00 */ char unk00[0x10]; + /* 0x10 */ Vec3f position; + /* 0x14 */ char unk14[0x1C]; +} NpcList; // size = 0x38 + +typedef struct AnmHome_c { + /* 0x00 */ u8 typeUnused; /* Likely the house type, but seems to be unused outside of SChk_Anmhome_c_sub */ + /* 0x01 */ u8 blockX; /* acre x position */ + /* 0x02 */ u8 blockZ; /* acre y position */ + /* 0x03 */ u8 utX; /* unit x position */ + /* 0x04 */ u8 utZ; /* unit z position */ +} AnmHome_c; // size = 0x5 + +typedef struct AnmPersonalId_c { + /* 0x00 */ u16 npcId; /* id */ + /* 0x02 */ u16 landId; /* town id */ + /* 0x04 */ u8 landName[LAND_NAME_SIZE]; /* town name */ + /* 0x0A */ u8 nameId; /* lower byte of the id */ + /* 0x0B */ u8 looks; /* internal name for personality */ +} AnmPersonalID_c; // size = 0xC typedef struct Animal_c { - /* 0x000 */ char unk000[0x528]; -} Animal_c; // size = 0x528 + /* 0x000 */ AnmPersonalID_c id; + /* 0x00C */ char unk00C[0x4D4]; + /* 0x4E0 */ AnmHome_c homeInfo; + /* 0x4E5 */ char unk4E5[0x43]; +} Animal_c; + +typedef enum NpcLooks{ + /* 0 */ NPC_LOOKS_GIRL, + /* 1 */ NPC_LOOKS_KO_GIRL, + /* 2 */ NPC_LOOKS_BOY, + /* 3 */ NPC_LOOKS_SPORT_MAN, + /* 4 */ NPC_LOOKS_GRIM_MAN, + /* 5 */ NPC_LOOKS_NANIWA_LADY, + + /* 6 */ NPC_LOOKS_NUM +}NpcLooks; -// void func_800A6810_jp(); // void func_800A6920_jp(); // void func_800A6940_jp(); // void func_800A695C_jp(); -// void func_800A6978_jp(); -// void func_800A69C8_jp(); -// void mNpc_CopyAnimalPersonalID(); -// void func_800A6A6C_jp(); +void mNpc_ClearAnimalPersonalID(AnmPersonalID_c*); +s32 mNpc_CheckFreeAnimalPersonalID(AnmPersonalID_c*); +void mNpc_CopyAnimalPersonalID(AnmPersonalID_c*, AnmPersonalID_c*); +s32 mNpc_CheckCmpAnimalPersonalID(AnmPersonalID_c*, AnmPersonalID_c*); // void func_800A6AF0_jp(); // void func_800A6B58_jp(); // void func_800A6B6C_jp(); @@ -130,7 +162,7 @@ s32 mNpc_GetLooks(u16 arg0); // void func_800AAEFC_jp(); void func_800AB054_jp(void); void func_800AB09C_jp(void); -void mNpc_SetNpcList(mNpc_NpcList_c* npclist, Animal_c* animals, s32 count, s32 malloc_flag); +void mNpc_SetNpcList(NpcList* npclist, Animal_c* animals, s32 count, s32 malloc_flag); void mNpc_SetNpcinfo(struct Actor* actor, s8 arg1); // void func_800AB498_jp(); // void func_800AB62C_jp(); diff --git a/include/m_npc_walk.h b/include/m_npc_walk.h index 6b8116c..1b5328d 100644 --- a/include/m_npc_walk.h +++ b/include/m_npc_walk.h @@ -2,10 +2,111 @@ #define M_NPC_WALK_H #include "ultra64.h" +#include "m_npc.h" -typedef struct mNpc_walk_c { +#define NPCW_GET_WALK_NUM(x) (int)((x) / 3) +#define NPCW_MAX NPCW_GET_WALK_NUM(ANIMAL_NUM_MAX) + +typedef struct NpcWalk { /* 0x00 */ char unk00[0x7C]; -} mNpc_walk_c; // size = 0x7C +} NpcWalk; // size = 0x7C + +typedef struct NpcWalkGoalData { + /* 0x0 */ u8* types; + /* 0x1 */ u8 count; + /* 0x2 */ s32 time; +} NpcWalkGoalData; // size = 0x6 + +typedef struct NpcWalkGoalDataTable { + /* 0x0 */ NpcWalkGoalData* data; + /* 0x4 */ int count; +} NpcWalkGoalDataTable; // size = 0x8 + +typedef struct NpcWalkAppear { + /* 0x0 */ u8 status; + /* 0x1 */ u8 way; +} NpcWalkAppear; // size = 0x2; + +typedef struct NpcWalkInfo { + /* 0x00 */ AnmPersonalID_c id; + /* 0x0C */ s32 idx; + /* 0x10 */ u8 status; + /* 0x11 */ u8 type; + /* 0x12 */ u8 goalX; + /* 0x13 */ u8 goalZ; + /* 0x14 */ NpcWalkAppear appearInfo; +} NpcWalkInfo; // size = 0x18 + +typedef struct NpcWalking { + /* 0x00 */ NpcWalkInfo info[NPCW_MAX]; + /* 0x78 */ u16 idxUse; + /* 0x7A */ u8 infoUse; + /* 0x7B */ u8 infoMax; +} NpcWalking; //size = 0x7C + +typedef enum WalkGoal{ + /* 0 */ NPCW_GOAL_SHRINE, /* Shrine/Wishing Well acre */ + /* 1 */ NPCW_GOAL_HOME, /* Randomly selected acre with a villager house */ + /* 2 */ NPCW_GOAL_ALONE, /* Randomly selected acre with no other animals in it */ + /* 3 */ NPCW_GOAL_MY_HOME, /* Acre containing the villager's house */ + + /* 4 */ NPCW_GOAL_NUM +}WalkGoal; + +typedef enum WalkGoalBlock{ + /* 0 */ NPCW_GOAL_BLOCK_SHRINE, + /* 1 */ NPCW_GOAL_BLOCK_HOME, + + /* 2 */ NPCW_GOAL_BLOCK_NUM +}WalkGoalBlock; + +typedef enum WalkAppearStatus { + /* 0 */ NPCW_APPEAR_STATUS_0, + /* 1 */ NPCW_APPEAR_STATUS_1, + + /* 2 */ NPCW_APPEAR_STATUS_NUM +}WalkAppearStatus; + +typedef enum WalkAppearDirection { + /* 0 */ NPCW_APPEAR_WAY_UP, + /* 1 */ NPCW_APPEAR_WAY_DOWN, + /* 2 */ NPCW_APPEAR_WAY_LEFT, + /* 3 */ NPCW_APPEAR_WAY_RIGHT, + + /* 4 */ NPCW_APPEAR_WAY_NUM +}WalkAppearDirection; + +typedef enum WalkInfoStatus { + /* 0 */ NPCW_INFO_STATUS_0, + /* 1 */ NPCW_INFO_STATUS_WALKING, + /* 2 */ NPCW_INFO_STATUS_2, + /* 3 */ NPCW_INFO_STATUS_3, + /* 4 */ NPCW_INFO_STATUS_4, + + /* 5 */ NPCW_INFO_STATUS_NUM +}WalkInfoStatus; +NpcWalkGoalData* mNpcW_GetGoalDataInfo(s32 looks, s32 time); +void mNpcW_ClearNpcWalkAppear(NpcWalkAppear* info); +void mNpcW_ClearNpcWalkInfo(NpcWalkInfo* info , s32 count); +void mNpcW_ClearNpcWalk(NpcWalking* walk); +s32 mNpcW_CheckFreeNpcWalkInfo(NpcWalkInfo* info ); +s32 mNpcW_GetFreeNpcWalkInfoIdx(NpcWalkInfo* info , s32 num ); +s32 mNpcW_GetNpcWalkInfoIdx(NpcWalkInfo* info , s32 num , AnmPersonalID_c* anmId ); +s32 mNpcW_GetNpcWalkInfoIdxbyIdx(NpcWalkInfo* info , s32 num , s32 idx ); +s32 mNpcW_DecideNpc(Animal_c* animal , u16 used ); +void mNpcW_SetNpcWalkInfo(NpcWalkInfo* info , Animal_c* animal , s32 idx ); +s32 mNpcW_ChangeNpcWalk(NpcWalking* walk , NpcWalkInfo* info ); +s32 mNpcW_GetAloneBlock(u8* goalBlockX , u8* goalBlockZ ); +void mNpcW_GetBlockXZNumExceptHome(s32* goalBlockX , s32* goalBlockZ , Animal_c* animal ); +s32 mNpcW_CheckDiffBlockWalkNpcHome(s32 blockX , s32 blockZ , NpcWalkInfo* info ); +void mNpcW_SetHomeBlockSource(NpcWalking* walk , Animal_c* animal ); +void mNpcW_InitGoalBlockSource(NpcWalking* walk , Animal_c* animal ); +void mNpcW_SetGoalBlock(NpcWalkInfo* info ); +void mNpcW_InitNpcWalk(NpcWalking* walk ); +s32 mNpcW_GetAppearStatusWay(u8* status , u8* way , Animal_c* animal ); +s32* mNpcW_GetArriveStayCountP(s32 idx ); +s32 mNpcW_GetWalkInfoStatusGoalAnimalIdx(s32* status , s32* goal , s32 idx ); +s32 mNpcW_GetNearGate(s32* targetUtX , s32* targetUtZ , s32 blockX , s32 blockZ , s32 utX , s32 utZ ); #endif diff --git a/include/m_random_field.h b/include/m_random_field.h new file mode 100644 index 0000000..ba52e3e --- /dev/null +++ b/include/m_random_field.h @@ -0,0 +1,42 @@ +#ifndef M_RANDOM_FIELD_H +#define M_RANDOM_FIELD_H + +#include "ultra64.h" + + +#define RANDOM_FIELD_BLOCKKIND_SHRINE (1 << 2) + +#define RANDOM_FIELD_BLOCK_TYPE_MAX 108 +#define RANDOM_FIELD_DIRECT_ERROR 100 + +typedef enum RandomFieldDirection { + /* 0 */ RANDOM_FIELD_DIRECT_NORTH, + /* 1 */ RANDOM_FIELD_DIRECT_WEST, + /* 2 */ RANDOM_FIELD_DIRECT_SOUTH, + /* 3 */ RANDOM_FIELD_DIRECT_EAST, + + /* 4 */ RANDOM_FIELD_DIRECT_NUM +}RandomFieldDirection; + +typedef struct RandomFieldGate { + /* 0x00 */ s32 ut0; + /* 0x04 */ s32 ut1; +} RandomFieldGate; + +// void func_800BCBA0_jp(); +// void func_800BCBDC_jp(); +// void func_800BCC20_jp(); +// void func_800BCC30_jp(); +// void func_800BCC40_jp(); +// void func_800BCCFC_jp(); +// void func_800BCDCC_jp(); +// void func_800BCDFC_jp(); +// void func_800BCE80_jp(); +// void func_800BCEA4_jp(); +// void func_800BCF64_jp(); +// void func_800BCFA4_jp(); +RandomFieldGate* mRF_BlockTypeDirect2GateData(s32*, u8, s32); +// void func_800BD02C_jp(); +// void func_800BD1E4_jp(); + +#endif diff --git a/include/sys_math.h b/include/sys_math.h index 133bdd8..028151f 100644 --- a/include/sys_math.h +++ b/include/sys_math.h @@ -2,6 +2,7 @@ #define SYS_MATH_H #include "ultra64.h" +#include "libc64/qrand.h" /* Macro to generate a random float in the range of [0, n) */ #define RANDOM_F(n) (fqrand() * (f32)(n)) diff --git a/linker_scripts/jp/symbol_addrs_code.txt b/linker_scripts/jp/symbol_addrs_code.txt index 749f301..5828856 100644 --- a/linker_scripts/jp/symbol_addrs_code.txt +++ b/linker_scripts/jp/symbol_addrs_code.txt @@ -1318,7 +1318,7 @@ func_80088344_jp = 0x80088344; // type:func func_80088458_jp = 0x80088458; // type:func func_800884E0_jp = 0x800884E0; // type:func func_800885A8_jp = 0x800885A8; // type:func -func_80088710_jp = 0x80088710; // type:func +mFI_Wpos2BlockNum = 0x80088710; // type:func func_80088780_jp = 0x80088780; // type:func func_8008883C_jp = 0x8008883C; // type:func func_800888AC_jp = 0x800888AC; // type:func @@ -1345,13 +1345,13 @@ func_8008902C_jp = 0x8008902C; // type:func func_8008907C_jp = 0x8008907C; // type:func func_80089114_jp = 0x80089114; // type:func func_800891AC_jp = 0x800891AC; // type:func -func_80089268_jp = 0x80089268; // type:func +mFI_BkNum2BlockType = 0x80089268; // type:func func_800892CC_jp = 0x800892CC; // type:func func_8008930C_jp = 0x8008930C; // type:func func_80089348_jp = 0x80089348; // type:func func_800893C8_jp = 0x800893C8; // type:func func_80089404_jp = 0x80089404; // type:func -func_80089440_jp = 0x80089440; // type:func +mFI_BlockKind2BkNum = 0x80089440; // type:func func_800894D0_jp = 0x800894D0; // type:func func_80089538_jp = 0x80089538; // type:func func_800895B8_jp = 0x800895B8; // type:func @@ -2246,10 +2246,10 @@ func_800A6810_jp = 0x800A6810; // type:func func_800A6920_jp = 0x800A6920; // type:func func_800A6940_jp = 0x800A6940; // type:func func_800A695C_jp = 0x800A695C; // type:func -func_800A6978_jp = 0x800A6978; // type:func -func_800A69C8_jp = 0x800A69C8; // type:func +mNpc_ClearAnimalPersonalID = 0x800A6978; // type:func +mNpc_CheckFreeAnimalPersonalID = 0x800A69C8; // type:func mNpc_CopyAnimalPersonalID = 0x800A6A04; // type:func -func_800A6A6C_jp = 0x800A6A6C; // type:func +mNpc_CheckCmpAnimalPersonalID = 0x800A6A6C; // type:func func_800A6AF0_jp = 0x800A6AF0; // type:func func_800A6B58_jp = 0x800A6B58; // type:func func_800A6B6C_jp = 0x800A6B6C; // type:func @@ -2443,28 +2443,28 @@ func_800AEBC8_jp = 0x800AEBC8; // type:func func_800AEC74_jp = 0x800AEC74; // type:func mNPS_schedule_manager = 0x800AED08; // type:func mNPS_set_all_schedule_area = 0x800AED68; // type:func -func_800AEDD0_jp = 0x800AEDD0; // type:func -func_800AEE38_jp = 0x800AEE38; // type:func -func_800AEE50_jp = 0x800AEE50; // type:func -func_800AEEE8_jp = 0x800AEEE8; // type:func -func_800AEF1C_jp = 0x800AEF1C; // type:func -func_800AEF4C_jp = 0x800AEF4C; // type:func -func_800AEFC4_jp = 0x800AEFC4; // type:func -func_800AF060_jp = 0x800AF060; // type:func -func_800AF0A8_jp = 0x800AF0A8; // type:func -func_800AF1E0_jp = 0x800AF1E0; // type:func -func_800AF2A8_jp = 0x800AF2A8; // type:func -func_800AF3E8_jp = 0x800AF3E8; // type:func -func_800AF614_jp = 0x800AF614; // type:func -func_800AF7BC_jp = 0x800AF7BC; // type:func -func_800AF84C_jp = 0x800AF84C; // type:func -func_800AF9C8_jp = 0x800AF9C8; // type:func -func_800AFA1C_jp = 0x800AFA1C; // type:func +mNpcW_GetGoalDataInfo = 0x800AEDD0; // type:func +mNpcW_ClearNpcWalkAppear = 0x800AEE38; // type:func +mNpcW_ClearNpcWalkInfo = 0x800AEE50; // type:func +mNpcW_ClearNpcWalk = 0x800AEEE8; // type:func +mNpcW_CheckFreeNpcWalkInfo = 0x800AEF1C; // type:func +mNpcW_GetFreeNpcWalkInfoIdx = 0x800AEF4C; // type:func +mNpcW_GetNpcWalkInfoIdx = 0x800AEFC4; // type:func +mNpcW_GetNpcWalkInfoIdxbyIdx = 0x800AF060; // type:func +mNpcW_DecideNpc = 0x800AF0A8; // type:func +mNpcW_SetNpcWalkInfo = 0x800AF1E0; // type:func +mNpcW_ChangeNpcWalk = 0x800AF2A8; // type:func +mNpcW_GetAloneBlock = 0x800AF3E8; // type:func +mNpcW_GetBlockXZNumExceptHome = 0x800AF614; // type:func +mNpcW_CheckDiffBlockWalkNpcHome = 0x800AF7BC; // type:func +mNpcW_SetHomeBlockSource = 0x800AF84C; // type:func +mNpcW_InitGoalBlockSource = 0x800AF9C8; // type:func +mNpcW_SetGoalBlock = 0x800AFA1C; // type:func mNpcW_InitNpcWalk = 0x800AFAF8; // type:func -func_800AFC1C_jp = 0x800AFC1C; // type:func -func_800AFCAC_jp = 0x800AFCAC; // type:func -func_800AFCD8_jp = 0x800AFCD8; // type:func -func_800AFDA8_jp = 0x800AFDA8; // type:func +mNpcW_GetAppearStatusWay = 0x800AFC1C; // type:func +mNpcW_GetArriveStayCountP = 0x800AFCAC; // type:func +mNpcW_GetWalkInfoStatusGoalAnimalIdx = 0x800AFCD8; // type:func +mNpcW_GetNearGate = 0x800AFDA8; // type:func func_800B0010_jp = 0x800B0010; // type:func distance_between = 0x800B0080; // type:func distance_between2 = 0x800B00C4; // type:func @@ -2869,7 +2869,7 @@ func_800BCE80_jp = 0x800BCE80; // type:func func_800BCEA4_jp = 0x800BCEA4; // type:func func_800BCF64_jp = 0x800BCF64; // type:func func_800BCFA4_jp = 0x800BCFA4; // type:func -func_800BCFC8_jp = 0x800BCFC8; // type:func +mRF_BlockTypeDirect2GateData = 0x800BCFC8; // type:func func_800BD02C_jp = 0x800BD02C; // type:func func_800BD1E4_jp = 0x800BD1E4; // type:func func_800BD2B0_jp = 0x800BD2B0; // type:func diff --git a/src/code/m_npc_walk.c b/src/code/m_npc_walk.c new file mode 100644 index 0000000..60507ed --- /dev/null +++ b/src/code/m_npc_walk.c @@ -0,0 +1,663 @@ +#include "m_npc_walk.h" +#include "m_common_data.h" +#include "m_npc.h" +#include "m_random_field.h" +#include "sys_math.h" +#include "m_field_info.h" +#include "macros.h" +#include "attributes.h" + +#define mNpcW_TIME_2_SEC(hour, min, sec) ((hour)*3600 + (min)*60 + (sec)) +#define mNpcW_MAKE_SCHEDULE_TABLE(goal_data) \ + { goal_data, ARRAY_COUNT(goal_data) } + +s32 l_goal_block[NPCW_GOAL_BLOCK_NUM][2]; +s32 l_arrive_stay_count[ANIMAL_NUM_MAX]; + +u8 l_girl_time_12[] = { NPCW_GOAL_SHRINE, NPCW_GOAL_HOME, NPCW_GOAL_ALONE }; +u8 l_girl_time_18_30[] = { NPCW_GOAL_SHRINE, NPCW_GOAL_HOME }; + +NpcWalkGoalData l_girl_goal_data[] = { + { NULL, 0, mNpcW_TIME_2_SEC(6, 0, 0) }, + { l_girl_time_12, ARRAY_COUNT(l_girl_time_12), mNpcW_TIME_2_SEC(12, 0, 0) }, + { NULL, 0, mNpcW_TIME_2_SEC(13, 0, 0) }, + { l_girl_time_18_30, ARRAY_COUNT(l_girl_time_18_30), mNpcW_TIME_2_SEC(18, 30, 0) }, + { NULL, 0, mNpcW_TIME_2_SEC(24, 0, 0) }, +}; + +NpcWalkGoalDataTable l_girl_goal_table = mNpcW_MAKE_SCHEDULE_TABLE(l_girl_goal_data); + +u8 l_kogirl_time_ed[] = { NPCW_GOAL_SHRINE, NPCW_GOAL_HOME }; + +NpcWalkGoalData l_kogirl_goal_data[] = { { l_kogirl_time_ed, ARRAY_COUNT(l_kogirl_time_ed), + mNpcW_TIME_2_SEC(24, 0, 0) } }; + +NpcWalkGoalDataTable l_kogirl_goal_table = mNpcW_MAKE_SCHEDULE_TABLE(l_kogirl_goal_data); + +u8 l_boy_time_12[] = { NPCW_GOAL_ALONE }; +u8 l_boy_time_19_30[] = { NPCW_GOAL_SHRINE, NPCW_GOAL_HOME }; + +NpcWalkGoalData l_boy_goal_data[] = { + { NULL, 0, mNpcW_TIME_2_SEC(9, 0, 0) }, + { l_boy_time_12, ARRAY_COUNT(l_boy_time_12), mNpcW_TIME_2_SEC(12, 0, 0) }, + { NULL, 0, mNpcW_TIME_2_SEC(14, 0, 0) }, + { l_boy_time_19_30, ARRAY_COUNT(l_boy_time_19_30), mNpcW_TIME_2_SEC(19, 30, 0) }, + { NULL, 0, mNpcW_TIME_2_SEC(24, 0, 0) }, +}; + +NpcWalkGoalDataTable l_boy_goal_table = mNpcW_MAKE_SCHEDULE_TABLE(l_boy_goal_data); + +u8 l_sports_man_time_12[] = { NPCW_GOAL_SHRINE, NPCW_GOAL_HOME, NPCW_GOAL_ALONE, NPCW_GOAL_ALONE }; +u8 l_sports_man_time_23[] = { NPCW_GOAL_SHRINE, NPCW_GOAL_SHRINE, NPCW_GOAL_HOME, NPCW_GOAL_HOME, NPCW_GOAL_ALONE }; + +NpcWalkGoalData l_sports_man_goal_data[] = { + { NULL, 0, mNpcW_TIME_2_SEC(6, 30, 0) }, + { l_sports_man_time_12, ARRAY_COUNT(l_sports_man_time_12), mNpcW_TIME_2_SEC(12, 0, 0) }, + { NULL, 0, mNpcW_TIME_2_SEC(12, 30, 0) }, + { l_sports_man_time_23, ARRAY_COUNT(l_sports_man_time_23), mNpcW_TIME_2_SEC(23, 0, 0) }, + { NULL, 0, mNpcW_TIME_2_SEC(24, 0, 0) } +}; + +NpcWalkGoalDataTable l_sports_man_goal_table = mNpcW_MAKE_SCHEDULE_TABLE(l_sports_man_goal_data); + +u8 l_grim_man_time_ed[] = { NPCW_GOAL_SHRINE, NPCW_GOAL_SHRINE, NPCW_GOAL_SHRINE, NPCW_GOAL_ALONE, NPCW_GOAL_ALONE, + NPCW_GOAL_ALONE, NPCW_GOAL_ALONE, NPCW_GOAL_ALONE, NPCW_GOAL_ALONE, NPCW_GOAL_ALONE }; + +NpcWalkGoalData l_grim_man_goal_data[] = { + { l_grim_man_time_ed, ARRAY_COUNT(l_grim_man_time_ed), mNpcW_TIME_2_SEC(24, 0, 0) }, +}; + +NpcWalkGoalDataTable l_grim_man_goal_table = mNpcW_MAKE_SCHEDULE_TABLE(l_grim_man_goal_data); + +u8 l_naniwa_lady_time_1_30[] = { NPCW_GOAL_SHRINE, NPCW_GOAL_SHRINE, NPCW_GOAL_SHRINE, NPCW_GOAL_SHRINE, + NPCW_GOAL_SHRINE, NPCW_GOAL_SHRINE, NPCW_GOAL_SHRINE, NPCW_GOAL_ALONE, + NPCW_GOAL_ALONE, NPCW_GOAL_ALONE }; +u8 l_naniwa_lady_time_13[] = { NPCW_GOAL_HOME }; +u8 l_naniwa_lady_time_21[] = { NPCW_GOAL_SHRINE, NPCW_GOAL_SHRINE, NPCW_GOAL_HOME, NPCW_GOAL_HOME, NPCW_GOAL_ALONE }; + +NpcWalkGoalData l_naniwa_lady_goal_data[] = { + { l_naniwa_lady_time_1_30, ARRAY_COUNT(l_naniwa_lady_time_1_30), mNpcW_TIME_2_SEC(1, 30, 0) }, + { NULL, 0, mNpcW_TIME_2_SEC(10, 0, 0) }, + { l_naniwa_lady_time_13, ARRAY_COUNT(l_naniwa_lady_time_13), mNpcW_TIME_2_SEC(13, 0, 0) }, + { NULL, 0, mNpcW_TIME_2_SEC(14, 0, 0) }, + { l_naniwa_lady_time_21, ARRAY_COUNT(l_naniwa_lady_time_21), mNpcW_TIME_2_SEC(21, 0, 0) }, + { NULL, 0, mNpcW_TIME_2_SEC(22, 0, 0) }, + { l_naniwa_lady_time_1_30, ARRAY_COUNT(l_naniwa_lady_time_1_30), mNpcW_TIME_2_SEC(24, 0, 0) }, +}; + +NpcWalkGoalDataTable l_naniwa_lady_goal_table = mNpcW_MAKE_SCHEDULE_TABLE(l_naniwa_lady_goal_data); + +NpcWalkGoalDataTable* l_looks_goal_table[NPC_LOOKS_NUM] = { &l_girl_goal_table, &l_kogirl_goal_table, + &l_boy_goal_table, &l_sports_man_goal_table, + &l_grim_man_goal_table, &l_naniwa_lady_goal_table }; + +NpcWalkGoalData* mNpcW_GetGoalDataInfo(s32 looks, s32 time) { + NpcWalkGoalDataTable* table = l_looks_goal_table[looks]; + NpcWalkGoalData* data = table->data; + s32 i; + + for (i = 0; i < table->count; i++) { + if (data->time > time) { + break; + } + + data++; + } + + if (i == table->count) { + data = &table->data[table->count - 1]; + } + + return data; +} + +void mNpcW_ClearNpcWalkAppear(NpcWalkAppear* info) { + info->status = NPCW_APPEAR_STATUS_NUM; + info->way = NPCW_APPEAR_WAY_NUM; +} +void mNpcW_ClearNpcWalkInfo(NpcWalkInfo* info, s32 count) { + for (; count != 0 && info != NULL; count--) { + bzero(info, sizeof(NpcWalkInfo)); + mNpc_ClearAnimalPersonalID(&info->id); + info->idx = -1; + info->status = NPCW_INFO_STATUS_NUM; + info->type = NPCW_GOAL_NUM; + mNpcW_ClearNpcWalkAppear(&info->appearInfo); + + info++; + } +} + +void mNpcW_ClearNpcWalk(NpcWalking* walk) { + bzero(walk, sizeof(NpcWalking)); + mNpcW_ClearNpcWalkInfo(&walk->info[0], NPCW_MAX); +} + +s32 mNpcW_CheckFreeNpcWalkInfo(NpcWalkInfo* info) { + s32 res = FALSE; + + if (info != NULL) { + res = mNpc_CheckFreeAnimalPersonalID(&info->id); + } + + return res; +} + +s32 mNpcW_GetFreeNpcWalkInfoIdx(NpcWalkInfo* info, s32 num) { + s32 idx = -1; + s32 i; + + for (i = 0; i < num; i++) { + if (mNpcW_CheckFreeNpcWalkInfo(info) == TRUE) { + idx = i; + break; + } + + info++; + } + + return idx; +} + +s32 mNpcW_GetNpcWalkInfoIdx(NpcWalkInfo* info, s32 num, AnmPersonalID_c* anmId) { + s32 idx = -1; + s32 i; + + if ((anmId != NULL) && (mNpc_CheckFreeAnimalPersonalID(anmId) == FALSE)) { + for (i = 0; i < num; i++) { + if (mNpc_CheckCmpAnimalPersonalID(anmId, &info->id) == TRUE) { + idx = i; + break; + } + + info++; + } + } + + return idx; +} + +s32 mNpcW_GetNpcWalkInfoIdxbyIdx(NpcWalkInfo* info, s32 num, s32 idx) { + s32 ret = -1; + s32 i; + + if ((idx >= 0) && (idx < ANIMAL_NUM_MAX)) { + for (i = 0; i < num; i++) { + if (info->idx == idx) { + ret = i; + break; + } + + info++; + } + } + + return ret; +} + +s32 mNpcW_DecideNpc(Animal_c* animal, u16 used) { + s32 idx; + u16 exist; + u16 goal; + s32 unused; + s32 nowSec; + s32 i; + + exist = 0; + goal = 0; + unused = 0; + nowSec = common_data.time.nowSec; + idx = -1; + + for (i = 0; i < ANIMAL_NUM_MAX; i++) { + if (mNpc_CheckFreeAnimalPersonalID(&animal->id) == FALSE) { + NpcWalkGoalData* data; + exist |= (1 << i); + + data = mNpcW_GetGoalDataInfo(animal->id.looks, nowSec); + if (data->count > 0) { + goal |= (1 << i); + + if (((used >> i) & 1) == FALSE) { + unused++; + } + } + } + + animal++; + } + + if (unused > 0) { + s32 selectedNum; + u32 selectionField = (exist & ~used) & goal; + + selectedNum = RANDOM(unused) + 1; + + while (selectedNum != 0) { + if ((selectionField & 1) == TRUE) { + selectedNum--; + } + + idx++; + selectionField >>= 1; + } + } + + return idx; +} + +void mNpcW_SetNpcWalkInfo(NpcWalkInfo* info, Animal_c* animal, s32 idx) { + NpcWalkGoalData* data; + s32 nowSec = common_data.time.nowSec; + u32 index; + + mNpc_CopyAnimalPersonalID(&info->id, &animal->id); + info->idx = idx; + data = mNpcW_GetGoalDataInfo(animal->id.looks, nowSec); + + if (data->count > 0) { + index = RANDOM(data->count); + info->type = data->types[index]; + } else { + info->type = NPCW_GOAL_MY_HOME; + } + info->status = 1; +} + +s32 mNpcW_ChangeNpcWalk(NpcWalking* walk, NpcWalkInfo* info) { + s32 free_idx; + s32 idx = -1; + s32 i; + + mNpcW_ClearNpcWalkInfo(info, 1); + walk->infoUse--; + free_idx = mNpcW_GetFreeNpcWalkInfoIdx(walk->info, NPCW_MAX); + + if (free_idx != -1) { + NpcWalkInfo* free_info = &walk->info[free_idx]; + + mNpcW_ClearNpcWalkInfo(free_info, 1); + idx = mNpcW_DecideNpc(common_data.animals, walk->idxUse); + + if (idx == -1) { + walk->idxUse = 0; + for (i = 0; i < ANIMAL_NUM_MAX; i++) { + if (i == walk->info[i].idx) { + walk->idxUse |= (1 << i); + } + } + + idx = mNpcW_DecideNpc(common_data.animals, walk->idxUse); + } + + mNpcW_SetNpcWalkInfo(free_info, &common_data.animals[idx], idx); + walk->idxUse |= (1 << idx); + mNpcW_SetGoalBlock(free_info); + } + + return idx; +} + +s32 mNpcW_GetAloneBlock(u8* goalBlockX, u8* goalBlockZ) { + Animal_c* animal = common_data.animals; + NpcList* npcList = common_data.npclist; + u8 block_field[FG_BLOCK_Z_NUM + 2]; + u8 count = 0; + s32 selected; + s32 blockX; + s32 blockZ; + s32 i; + s32 j; + s32 z; + + *goalBlockX = 0; + *goalBlockZ = 0; + + bzero(block_field, FG_BLOCK_Z_NUM + 2); + for (i = 0; i < ANIMAL_NUM_MAX; i++) { + if (mNpc_CheckFreeAnimalPersonalID(&animal->id) == FALSE && + mFI_Wpos2BlockNum(&blockX, &blockZ, npcList->position) == TRUE) { + block_field[blockZ] |= (1 << blockX); + count++; + } + + animal++; + npcList++; + } + + z = 1; + selected = RANDOM(FG_BLOCK_TOTAL_NUM - count); + for (i = 1; i < BLOCK_Z_NUM - 3; i++) { + for (j = 1; j < BLOCK_X_NUM - 1; j++) { + if (((block_field[z] >> j) & 1) == 0) { + if (selected <= 0) { + *goalBlockX = j; + *goalBlockZ = i; + return TRUE; + } else { + selected--; + } + } + } + + z++; + } + + return FALSE; +} + +void mNpcW_GetBlockXZNumExceptHome(s32* goalBlockX, s32* goalBlockZ, Animal_c* animal) { + u8 possibleX = 0xFF; + u8 possibleZ = 0xFF; + + s32 x = 0; + s32 z = 0; + + s32 chosenX; + s32 chosenZ; + + s32 i; + + for (i = 0; i < ANIMAL_NUM_MAX; i++) { + if (mNpc_CheckFreeAnimalPersonalID(&animal->id) == FALSE) { + u8 homeX = animal->homeInfo.blockX - 1; + u8 homeZ = animal->homeInfo.blockZ - 1; + + if (((possibleX >> homeX) & 1) == 1) { + possibleX &= ~(1 << homeX); + x++; + } + + if (((possibleZ >> homeZ) & 1) == 1) { + possibleZ &= ~(1 << homeZ); + z++; + } + } + + animal++; + } + + chosenX = RANDOM(FG_BLOCK_X_NUM - x); + chosenZ = RANDOM(FG_BLOCK_Z_NUM - z); + + for (i = 0; i < FG_BLOCK_X_NUM; i++) { + if (((possibleX >> i) & 1) == 1) { + if (chosenX <= 0) { + break; + } else { + chosenX--; + } + } + } + + *goalBlockX = i + 1; + + for (i = 0; i < FG_BLOCK_Z_NUM; i++) { + if (((possibleZ >> i) & 1) == 1) { + if (chosenZ <= 0) { + break; + } else { + chosenZ--; + } + } + } + + *goalBlockZ = i + 1; +} + +s32 mNpcW_CheckDiffBlockWalkNpcHome(s32 blockX, s32 blockZ, NpcWalkInfo* info) { + s32 res = FALSE; + AnmHome_c* home; + s32 i; + s32 idx; + + for (i = 0; i < NPCW_MAX; i++) { + idx = info->idx; + if (idx != -1) { + home = &common_data.animals[idx].homeInfo; + + if (home->blockX == blockX && home->blockZ == blockZ) { + break; + } + } + + info++; + } + + if (i == NPCW_MAX) { + res = TRUE; + } + + return res; +} + +void mNpcW_SetHomeBlockSource(NpcWalking* walk, Animal_c* animal) { + Animal_c* animalP = animal; + u16 field; + s32 num; + s32 i; + + field = 0; + num = 0; + + l_goal_block[NPCW_GOAL_BLOCK_HOME][0] = 0; + l_goal_block[NPCW_GOAL_BLOCK_HOME][1] = 0; + + for (i = 0; i < ANIMAL_NUM_MAX; i++) { + if (mNpc_CheckFreeAnimalPersonalID(&animal->id) == FALSE) { + AnmHome_c* home = &animal->homeInfo; + + if (mNpcW_CheckDiffBlockWalkNpcHome(home->blockX, home->blockZ, walk->info) == TRUE) { + field |= (1 << i); + num++; + } + } + + animal++; + } + + if (num > 0) { + s32 chosen = RANDOM(num); + AnmHome_c* homeInfo; + + for (i = 0; i < ANIMAL_NUM_MAX; i++) { + if (((field >> i) & 1) == 1) { + if (chosen == 0) { + break; + } else { + chosen--; + } + } + } + + homeInfo = &animalP[i].homeInfo; + l_goal_block[NPCW_GOAL_BLOCK_HOME][0] = homeInfo->blockX + 1; + l_goal_block[NPCW_GOAL_BLOCK_HOME][1] = homeInfo->blockZ + 1; + } + + if (l_goal_block[NPCW_GOAL_BLOCK_HOME][0] == 0 || l_goal_block[NPCW_GOAL_BLOCK_HOME][1] == 0) { + mNpcW_GetBlockXZNumExceptHome(&l_goal_block[NPCW_GOAL_BLOCK_HOME][0], &l_goal_block[NPCW_GOAL_BLOCK_HOME][1], + animalP); + } +} + +void mNpcW_InitGoalBlockSource(NpcWalking* walk, Animal_c* animal) { + s32 shrineX; + s32 shrineZ; + UNUSED s32 pad; + + mFI_BlockKind2BkNum(&shrineX, &shrineZ, 4); + + l_goal_block[NPCW_GOAL_BLOCK_SHRINE][0] = shrineX; + l_goal_block[NPCW_GOAL_BLOCK_SHRINE][1] = shrineZ; + + mNpcW_SetHomeBlockSource(walk, animal); +} +void mNpcW_SetGoalBlock(NpcWalkInfo* info) { + s32 idx; + + switch (info->type) { + case NPCW_GOAL_SHRINE: + info->goalX = l_goal_block[NPCW_GOAL_BLOCK_SHRINE][0]; + info->goalZ = l_goal_block[NPCW_GOAL_BLOCK_SHRINE][1]; + break; + + case NPCW_GOAL_HOME: + info->goalX = l_goal_block[NPCW_GOAL_BLOCK_HOME][0]; + info->goalZ = l_goal_block[NPCW_GOAL_BLOCK_HOME][1]; + break; + + case NPCW_GOAL_ALONE: + mNpcW_GetAloneBlock(&info->goalX, &info->goalZ); + break; + + case NPCW_GOAL_MY_HOME: + idx = info->idx; + + info->goalX = common_data.animals[idx].homeInfo.blockX; + info->goalZ = common_data.animals[idx].homeInfo.blockZ; + break; + + default: + info->goalX = 0; + info->goalZ = 0; + break; + } +} + +void mNpcW_InitNpcWalk(NpcWalking* walk) { + Animal_c* animals; + NpcWalkInfo* info = walk->info; + s32 idx; + s32 i; + + mNpcW_ClearNpcWalk(walk); + bzero(l_goal_block, sizeof(l_goal_block)); + bzero(l_arrive_stay_count, sizeof(l_arrive_stay_count)); + + animals = common_data.animals; + walk->infoMax = NPCW_GET_WALK_NUM(common_data.nowNpcMax); + + for (i = 0; i < walk->infoMax; i++) { + idx = mNpcW_DecideNpc(animals, walk->idxUse); + + mNpcW_SetNpcWalkInfo(info, &common_data.animals[idx], idx); + walk->idxUse |= (1 << idx); + info++; + } + + walk->infoUse = walk->infoMax; + mNpcW_InitGoalBlockSource(walk, animals); +} + +s32 mNpcW_GetAppearStatusWay(u8* status, u8* way, Animal_c* animal) { + NpcWalking* walk = &common_data.npcWalk; + s32 infoIdx; + s32 res = FALSE; + + *status = NPCW_APPEAR_STATUS_NUM; + + infoIdx = mNpcW_GetNpcWalkInfoIdx(walk->info, NPCW_MAX, &animal->id); + + if (infoIdx >= 0) { + *status = walk->info[infoIdx].appearInfo.status; + *way = walk->info[infoIdx].appearInfo.way; + res = TRUE; + } else { + *status = NPCW_APPEAR_STATUS_0; + *way = NPCW_APPEAR_WAY_NUM; + } + + return res; +} + +s32* mNpcW_GetArriveStayCountP(s32 idx) { + if (idx >= 0 && idx < ANIMAL_NUM_MAX) { + return &l_arrive_stay_count[idx]; + } + + return NULL; +} + +s32 mNpcW_GetWalkInfoStatusGoalAnimalIdx(s32* status, s32* goal, s32 idx) { + s32 res = FALSE; + + *status = NPCW_INFO_STATUS_NUM; + *goal = NPCW_GOAL_NUM; + + if (idx >= 0 && idx < ANIMAL_NUM_MAX) { + NpcWalking* walk = &common_data.npcWalk; + s32 info_idx = mNpcW_GetNpcWalkInfoIdx(walk->info, NPCW_MAX, &common_data.animals[idx].id); + + if (info_idx >= 0) { + res = TRUE; + *status = walk->info[info_idx].status; + *goal = walk->info[info_idx].type; + } + } + + return res; +} + +s32 mNpcW_GetNearGate(s32* targetUtX, s32* targetUtZ, s32 blockX, s32 blockZ, s32 utX, s32 utZ) { + u8 blockType; + RandomFieldGate* gate; + s32 difference; + UNUSED s32 pad; + s32 x; + s32 z; + s32 gateCount; + s32 i; + s32 res = FALSE; + s32 direction; + + *targetUtX = UT_X_NUM; + *targetUtZ = UT_Z_NUM; + + if (utX >= 0 && utX < UT_X_NUM && utZ >= 0 && utZ < UT_Z_NUM) { + blockType = mFI_BkNum2BlockType(blockX, blockZ); + x = utX < (UT_X_NUM / 2) ? utX : UT_X_NUM - utX; + z = utZ < (UT_Z_NUM / 2) ? utZ : UT_Z_NUM - utZ; + + if (x < z) { + if (utX < (UT_X_NUM / 2)) { + direction = RANDOM_FIELD_DIRECT_WEST; + } else { + direction = RANDOM_FIELD_DIRECT_EAST; + } + } else { + if (utZ < (UT_Z_NUM / 2)) { + direction = RANDOM_FIELD_DIRECT_NORTH; + } else { + direction = RANDOM_FIELD_DIRECT_SOUTH; + } + } + + gate = mRF_BlockTypeDirect2GateData(&gateCount, blockType, direction); + if (gate != NULL && gateCount > 0) { + + for (i = 0; i < gateCount; i++) { + x = gate->ut1 & 0xF; + z = gate->ut1 >> 4; + + if (direction == RANDOM_FIELD_DIRECT_WEST || direction == RANDOM_FIELD_DIRECT_WEST) { + difference = utZ - z; + difference = ABS(difference); + } else { + difference = utX - x; + difference = ABS(difference); + } + + if (difference < UT_BASE_NUM) { + *targetUtX = x; + *targetUtZ = z; + res = TRUE; + } + + gate++; + } + } + } + + return res; +} diff --git a/src/code/m_start_data_init.c b/src/code/m_start_data_init.c index 86ed5b3..43ca1bf 100644 --- a/src/code/m_start_data_init.c +++ b/src/code/m_start_data_init.c @@ -42,24 +42,24 @@ void famicom_emu_initial_common_data(void) { FamicomEmuCommonData* famicom = &common_data.famicom_emu_common_data; - famicom->unk_00 = 0; - famicom->unk_02 = 0x3E8; - famicom->unk_04 = 0x3E8; - famicom->unk_06 = 0x9C4; - famicom->unk_08 = 0; - famicom->unk_0A = 0; - famicom->unk_0C = 0; - famicom->unk_0E = 0; - famicom->unk_10 = 0x64; - famicom->unk_14 = 0; - famicom->unk_16 = 0; - famicom->unk_18 = 0; - famicom->unk_1A = 0; - famicom->unk_1C = 0; - famicom->unk_1E = 0; - famicom->unk_20 = 0; - famicom->unk_22 = 0; - famicom->unk_24 = 0; + famicom->unk00 = 0; + famicom->unk02 = 0x3E8; + famicom->unk04 = 0x3E8; + famicom->unk06 = 0x9C4; + famicom->unk08 = 0; + famicom->unk0A = 0; + famicom->unk0C = 0; + famicom->unk0E = 0; + famicom->unk10 = 0x64; + famicom->unk14 = 0; + famicom->unk16 = 0; + famicom->unk18 = 0; + famicom->unk1A = 0; + famicom->unk1C = 0; + famicom->unk1E = 0; + famicom->unk20 = 0; + famicom->unk22 = 0; + famicom->unk24 = 0; } void decide_fruit(u16* fruit) { @@ -193,7 +193,7 @@ s32 mSDI_StartInitNew(Game* game2, s32 player_no, s32 malloc_flag) { UNUSED s32 pad[2]; common_data.scene_from_title_demo = SCENE_START_DEMO; - lbRTC_GetTime(&common_data.time.rtc_time); + lbRTC_GetTime(&common_data.time.rtcTime); priv = &common_data.private[player_no]; common_data.now_private = priv; @@ -271,7 +271,7 @@ s32 mSDI_StartInitFrom(Game* game2, s32 player_no, s32 malloc_flag) { } common_data.scene_from_title_demo = SCENE_FG; - lbRTC_GetTime(&common_data.time.rtc_time); + lbRTC_GetTime(&common_data.time.rtcTime); if (mFRm_CheckSaveData() == TRUE) { priv = &common_data.private[player_no]; @@ -320,7 +320,7 @@ s32 mSDI_StartInitNewPlayer(Game* game, s32 player_no, s32 malloc_flag) { UNUSED s32 pad; common_data.scene_from_title_demo = SCENE_START_DEMO2; - lbRTC_GetTime(&common_data.time.rtc_time); + lbRTC_GetTime(&common_data.time.rtcTime); priv = &common_data.private[player_no]; if (mFRm_CheckSaveData() == TRUE) { @@ -411,7 +411,7 @@ void mSDI_StartInitAfter(Game* game, s32 renewal_reserve_flag, s32 malloc_flag) } mQst_ClearNotSaveQuest(&common_data.quest); mNPS_set_all_schedule_area(); - mNpcW_InitNpcWalk(&common_data.npc_walk); + mNpcW_InitNpcWalk(&common_data.npcWalk); mHm_CheckRehouseOrder(); decide_fish_location(&common_data.fish_location); mTRC_init(game_play); diff --git a/src/overlays/actors/ovl_Toudai/ac_toudai.c b/src/overlays/actors/ovl_Toudai/ac_toudai.c index db08c4d..0527096 100644 --- a/src/overlays/actors/ovl_Toudai/ac_toudai.c +++ b/src/overlays/actors/ovl_Toudai/ac_toudai.c @@ -141,7 +141,7 @@ void aTOU_init(Toudai* this, Game_Play* game_play UNUSED) { } void aTOU_wait(Toudai* this, Game_Play* game_play UNUSED) { - if ((common_data.time.now_sec >= 0xFD20) || (common_data.time.now_sec < 0x4650)) { + if ((common_data.time.nowSec >= 0xFD20) || (common_data.time.nowSec < 0x4650)) { this->unk2BC = 1; this->skeletonInfo.frameControl.speed = 1.0f; aTOU_setup_action(this, 2); @@ -149,7 +149,7 @@ void aTOU_wait(Toudai* this, Game_Play* game_play UNUSED) { } void aTOU_lighting(Toudai* this, Game_Play* game_play UNUSED) { - if ((common_data.time.now_sec < 64800) && (common_data.time.now_sec >= 18000)) { + if ((common_data.time.nowSec < 64800) && (common_data.time.nowSec >= 18000)) { aTOU_setup_action(this, 3); } } diff --git a/src/overlays/gamestates/ovl_play/m_play.c b/src/overlays/gamestates/ovl_play/m_play.c index 0f9c254..8631106 100644 --- a/src/overlays/gamestates/ovl_play/m_play.c +++ b/src/overlays/gamestates/ovl_play/m_play.c @@ -24,6 +24,7 @@ #include "m_controller.h" #include "m_debug_display.h" #include "m_rcp.h" +#include "m_npc_walk.h" #include "6D2720.h" #include "m_lights.h" #include "m_private.h" @@ -101,11 +102,11 @@ static u16 S_se_endcheck_timeout; void Game_play_Reset_destiny(void) { Private_Sub_A86* temp = &common_data.now_private->unk_A86; - u8* day = &common_data.time.rtc_time.day; - u8* month = &common_data.time.rtc_time.month; + u8* day = &common_data.time.rtcTime.day; + u8* month = &common_data.time.rtcTime.month; if ((temp->unk_08 != 0) && - ((common_data.time.rtc_time.year != temp->unk_06) || (*month != temp->unk_05) || (*day != temp->unk_03))) { + ((common_data.time.rtcTime.year != temp->unk_06) || (*month != temp->unk_05) || (*day != temp->unk_03))) { temp->unk_08 = 0; } } diff --git a/yamls/jp/code.yaml b/yamls/jp/code.yaml index f2dc816..1357b92 100644 --- a/yamls/jp/code.yaml +++ b/yamls/jp/code.yaml @@ -56,6 +56,8 @@ - [0x6C97F0, asm, code/6C97F0] - [0x6CA4B0, asm, code/m_npc] - [0x6D2720, asm, code/6D2720] + - [0x6D2A70, c, code/m_npc_walk] + - [0x6D3CB0, asm, code/800B0010] - [0x6D3D20, asm, code/m_olib] - [0x6D4440, c, code/m_pause] - [0x6D44F0, asm, code/6D44F0] @@ -65,6 +67,7 @@ - [0x6DA460, asm, code/6DA460] - [0x6DB420, asm, code/6DB420] - [0x6DE300, asm, code/6DE300] + - [0x6E08E0, asm, code/m_random_field] - [0x6E0F50, asm, code/m_rcp] - [0x6E2300, asm, code/6E2300] - [0x6E30B0, asm, code/6E30B0] @@ -145,6 +148,7 @@ - [0x72B7A0, data, code/m_lib] - [0x72B7D0, .data, code/m_lights] - [0x72B7F0, data, code/72B7F0] + - [0x72F7D0, .data, code/m_npc_walk] - [0x72F980, .data, code/m_player_call] - [0x72F9B0, data, code/72F9B0] - [0x731940, .data, code/m_start_data_init] @@ -258,6 +262,7 @@ - { start: 0x73F4D0, type: .bss, vram: 0x80141E10, name: code/m_lights } - { start: 0x75B600, type: .bss, vram: 0x80141FA0, name: code/m_malloc } - { start: 0x75B600, type: bss, vram: 0x80141FE0, name: code/80141FE0 } + - { start: 0x73F4D0, type: .bss, vram: 0x801438B0, name: code/m_npc_walk } - { start: 0x73F4D0, type: .bss, vram: 0x80143900, name: code/m_player_call } - { start: 0x73F4D0, type: bss, vram: 0x80143910, name: code/80143910 } - { start: 0x73F4D0, type: .bss, vram: 0x80144670, name: code/m_submenu } |
