summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrakxo <87568477+Prakxo@users.noreply.github.com>2023-09-15 18:36:15 +0200
committerGitHub <noreply@github.com>2023-09-15 09:36:15 -0700
commitef0a26fd481675a955b301d1b2261ded362c4190 (patch)
tree0c2a9de1eda9cd4d465aa4845f18f1ba16584b93
parent898b6fb3a4157f2e681a42c6f420f4b9d7152cc9 (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.h23
-rw-r--r--include/6DE300.h16
-rw-r--r--include/m_common_data.h72
-rw-r--r--include/m_field_info.h6
-rw-r--r--include/m_land.h2
-rw-r--r--include/m_npc.h58
-rw-r--r--include/m_npc_walk.h105
-rw-r--r--include/m_random_field.h42
-rw-r--r--include/sys_math.h1
-rw-r--r--linker_scripts/jp/symbol_addrs_code.txt56
-rw-r--r--src/code/m_npc_walk.c663
-rw-r--r--src/code/m_start_data_init.c44
-rw-r--r--src/overlays/actors/ovl_Toudai/ac_toudai.c4
-rw-r--r--src/overlays/gamestates/ovl_play/m_play.c7
-rw-r--r--yamls/jp/code.yaml5
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 }