mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-06-09 03:59:38 -04:00
Implement & link ac_npc2
This commit is contained in:
+1
-1
@@ -1100,7 +1100,7 @@ config.libs = [
|
||||
Object(NonMatching, "actor/npc/ac_kamakura_npc0.c"),
|
||||
Object(NonMatching, "actor/npc/ac_normal_npc.c"),
|
||||
Object(Matching, "actor/npc/ac_npc.c"),
|
||||
Object(NonMatching, "actor/npc/ac_npc2.c"),
|
||||
Object(Matching, "actor/npc/ac_npc2.c"),
|
||||
Object(Matching, "actor/npc/ac_npc_conv_master.c"),
|
||||
Object(Matching, "actor/npc/ac_npc_curator.c"),
|
||||
Object(Matching, "actor/npc/ac_npc_depart_master.c"),
|
||||
|
||||
+94
-8
@@ -155,6 +155,7 @@ enum {
|
||||
aNPC_ATTENTION_TYPE_NUM
|
||||
};
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
enum {
|
||||
aNPC_THINK_WAIT,
|
||||
aNPC_THINK_WANDER,
|
||||
@@ -169,6 +170,19 @@ enum {
|
||||
|
||||
aNPC_THINK_NUM
|
||||
};
|
||||
#else
|
||||
enum {
|
||||
aNPC_THINK_WAIT,
|
||||
aNPC_THINK_HIDE,
|
||||
aNPC_THINK_WANDER,
|
||||
aNPC_THINK_OUT_OF_ROOM,
|
||||
aNPC_THINK_EXIT_WAIT,
|
||||
aNPC_THINK_INTO_ROOM,
|
||||
aNPC_THINK_SPECIAL,
|
||||
|
||||
aNPC_THINK_NUM
|
||||
};
|
||||
#endif
|
||||
|
||||
enum {
|
||||
aNPC_THINK_TYPE_INIT,
|
||||
@@ -459,6 +473,15 @@ enum {
|
||||
|
||||
#define aNPC_ACT_NONE 0xFF
|
||||
|
||||
enum {
|
||||
aNPC_ACTION_PROC_TYPE_INIT,
|
||||
aNPC_ACTION_PROC_TYPE_CHG_DATA,
|
||||
aNPC_ACTION_PROC_TYPE_MAIN,
|
||||
|
||||
aNPC_ACTION_PROC_TYPE_NUM
|
||||
};
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
enum {
|
||||
aNPC_ACT_WAIT,
|
||||
aNPC_ACT_WALK,
|
||||
@@ -487,14 +510,6 @@ enum {
|
||||
aNPC_ACT_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aNPC_ACTION_PROC_TYPE_INIT,
|
||||
aNPC_ACTION_PROC_TYPE_CHG_DATA,
|
||||
aNPC_ACTION_PROC_TYPE_MAIN,
|
||||
|
||||
aNPC_ACTION_PROC_TYPE_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aNPC_ACTION_TYPE_WAIT,
|
||||
aNPC_ACTION_TYPE_WAIT_KI,
|
||||
@@ -556,6 +571,77 @@ enum {
|
||||
|
||||
aNPC_ACTION_TYPE_NUM
|
||||
};
|
||||
#else
|
||||
enum {
|
||||
aNPC_ACT_WAIT,
|
||||
aNPC_ACT_WALK,
|
||||
aNPC_ACT_RUN,
|
||||
aNPC_ACT_TURN,
|
||||
aNPC_ACT_TURN2,
|
||||
aNPC_ACT_TALK,
|
||||
aNPC_ACT_KEITAI_ON,
|
||||
aNPC_ACT_KEITAI_OFF,
|
||||
aNPC_ACT_ENSOU,
|
||||
aNPC_ACT_WAIT_E,
|
||||
aNPC_ACT_TRANS,
|
||||
aNPC_ACT_GET,
|
||||
aNPC_ACT_CONTRACT,
|
||||
aNPC_ACT_NOT_CONTRACT,
|
||||
aNPC_ACT_NOT_CONTRACT2,
|
||||
aNPC_ACT_CHANGE_CLOTH,
|
||||
aNPC_ACT_SPECIAL,
|
||||
|
||||
aNPC_ACT_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aNPC_ACTION_TYPE_WAIT,
|
||||
aNPC_ACTION_TYPE_WAIT_KI,
|
||||
aNPC_ACTION_TYPE_WAIT_DO,
|
||||
aNPC_ACTION_TYPE_WAIT_AI,
|
||||
aNPC_ACTION_TYPE_WAIT_NEMU,
|
||||
aNPC_ACTION_TYPE_WALK,
|
||||
aNPC_ACTION_TYPE_WALK_KI,
|
||||
aNPC_ACTION_TYPE_WALK_DO,
|
||||
aNPC_ACTION_TYPE_WALK_AI,
|
||||
aNPC_ACTION_TYPE_RUN,
|
||||
aNPC_ACTION_TYPE_RUN_KI,
|
||||
aNPC_ACTION_TYPE_RUN_DO,
|
||||
aNPC_ACTION_TYPE_RUN_AI,
|
||||
aNPC_ACTION_TYPE_TURN,
|
||||
aNPC_ACTION_TYPE_TURN2,
|
||||
aNPC_ACTION_TYPE_TALK_TURN,
|
||||
aNPC_ACTION_TYPE_TALK,
|
||||
aNPC_ACTION_TYPE_KEITAI_ON,
|
||||
aNPC_ACTION_TYPE_KEITAI_OFF,
|
||||
aNPC_ACTION_TYPE_TRANS_MOVE,
|
||||
aNPC_ACTION_TYPE_TRANSFER,
|
||||
aNPC_ACTION_TYPE_TRANS_WAIT,
|
||||
aNPC_ACTION_TYPE_SEND_MAIL,
|
||||
aNPC_ACTION_TYPE_GET_MOVE,
|
||||
aNPC_ACTION_TYPE_GET,
|
||||
aNPC_ACTION_TYPE_GET_PULL,
|
||||
aNPC_ACTION_TYPE_GET_PULL_WAIT,
|
||||
aNPC_ACTION_TYPE_GET_PUTAWAY,
|
||||
aNPC_ACTION_TYPE_GET_EAT,
|
||||
aNPC_ACTION_TYPE_GET_CHANGE,
|
||||
aNPC_ACTION_TYPE_GET_RETURN,
|
||||
aNPC_ACTION_TYPE_GET_F,
|
||||
aNPC_ACTION_TYPE_GET_PULL_F,
|
||||
aNPC_ACTION_TYPE_GET_PULL_WAIT_F,
|
||||
aNPC_ACTION_TYPE_GET_PUTAWAY_F,
|
||||
aNPC_ACTION_TYPE_GET_RETURN_F,
|
||||
aNPC_ACTION_TYPE_ESTIMATE_F,
|
||||
aNPC_ACTION_TYPE_CONTRACT,
|
||||
aNPC_ACTION_TYPE_CONTRACT_PULL,
|
||||
aNPC_ACTION_TYPE_CONTRACT_PUTAWAY,
|
||||
aNPC_ACTION_TYPE_NOT_CONTRACT,
|
||||
aNPC_ACTION_TYPE_ENSOU,
|
||||
aNPC_ACTION_TYPE_WAIT_E,
|
||||
|
||||
aNPC_ACTION_TYPE_NUM
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef void (*aNPC_ACTION_PROC)(NPC_ACTOR*, GAME_PLAY*, int);
|
||||
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ extern void sAdo_SysTrgStart(u16 id);
|
||||
extern void sAdo_PlyWalkSe(u16 walk, const xyz_t* pos);
|
||||
extern void sAdo_PlyWalkSeRoom(u8 walk, const xyz_t* pos);
|
||||
extern void sAdo_NpcWalkSe(u16 se_no, const xyz_t* pos);
|
||||
extern void sAdo_NpcWalkSeRoom(u16 se_no, const xyz_t* pos);
|
||||
extern void sAdo_NpcWalkSeRoom(u8 se_no, const xyz_t* pos);
|
||||
|
||||
extern void sAdo_PlayerStatusLevel(f32 speed, int p);
|
||||
|
||||
|
||||
@@ -177,8 +177,12 @@ typedef enum audio_sound_effects {
|
||||
NA_SE_UCHIWA = 0x167,
|
||||
NA_SE_LAWNMOWER = 0x177,
|
||||
|
||||
NA_SE_207 = 0x207,
|
||||
|
||||
NA_SE_SCOOP_SHIGEMI = 0x401,
|
||||
|
||||
NA_SE_40B = 0x40B,
|
||||
|
||||
NA_SE_CAMERA_MOVE1 = 0x40D,
|
||||
NA_SE_CAMERA_MOVE2,
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ extern void Na_SysTrgStart(u16);
|
||||
extern void Na_PlyWalkSe(u16, u16, f32);
|
||||
extern void Na_PlyWalkSeRoom(u8, u16, f32);
|
||||
extern void Na_NpcWalkSe(u16, u16, f32);
|
||||
extern void Na_NpcWalkSeRoom(u16, u16, f32);
|
||||
extern void Na_NpcWalkSeRoom(u8, u16, f32);
|
||||
extern void Na_PlayerStatusLevel(f32, int);
|
||||
extern void Na_VoiceSe(u8, u8, u8, s16, u8, u8);
|
||||
extern void Na_MessageStatus(u8);
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
#define aNPC_NPC2
|
||||
#include "ac_npc2.h"
|
||||
#include "ac_npc.h"
|
||||
|
||||
#include "libultra/libultra.h"
|
||||
#include "m_common_data.h"
|
||||
#include "m_player_lib.h"
|
||||
#include "m_msg.h"
|
||||
#include "ac_handOverItem.h"
|
||||
#include "sys_matrix.h"
|
||||
#include "m_rcp.h"
|
||||
#include "jsyswrap.h"
|
||||
#include "dolphin/os.h"
|
||||
#include "ac_ev_ghost.h"
|
||||
#include "m_melody.h"
|
||||
#include "m_actor_shadow.h"
|
||||
#include "m_event_map_npc.h"
|
||||
#include "m_malloc.h"
|
||||
|
||||
#define aNPC_UNIT_RIGHT (1 << 0)
|
||||
#define aNPC_UNIT_LEFT (1 << 1)
|
||||
#define aNPC_UNIT_DOWN (1 << 2)
|
||||
#define aNPC_UNIT_UP (1 << 3)
|
||||
#define aNPC_UNIT_ALL (aNPC_UNIT_UP | aNPC_UNIT_DOWN | aNPC_UNIT_LEFT | aNPC_UNIT_RIGHT)
|
||||
|
||||
enum {
|
||||
aNPC_SEARCH_ROUTE_FORWARD,
|
||||
aNPC_SEARCH_ROUTE_BACKWARD,
|
||||
aNPC_SEARCH_ROUTE_CANCEL,
|
||||
|
||||
aNPC_SEARCH_ROUTE_NUM = aNPC_SEARCH_ROUTE_CANCEL
|
||||
};
|
||||
|
||||
enum {
|
||||
aNPC_ROUTE_ERROR,
|
||||
aNPC_ROUTE_FINISH,
|
||||
aNPC_ROUTE_MOVING,
|
||||
|
||||
aNPC_ROUTE_NUM
|
||||
};
|
||||
|
||||
extern aNPC_draw_data_c npc_draw_data_tbl[];
|
||||
|
||||
#define aNPC_CLOTH_TEX_SIZE ((32*32)/2)
|
||||
#define aNPC_CLOTH_PAL_SIZE (16*sizeof(u16))
|
||||
|
||||
#define aNPC_GET_TYPE(npc) (ITEM_NAME_GET_TYPE((npc)->actor_class.npc_id))
|
||||
#define aNPC_IS_NRM_NPC(npc) (aNPC_GET_TYPE(npc) == NAME_TYPE_NPC)
|
||||
#define aNPC_IS_SP_NPC(npc) (aNPC_GET_TYPE(npc) == NAME_TYPE_SPNPC)
|
||||
#define aNPC_GET_ANM(npc) ((npc)->npc_info.animal)
|
||||
#define aNPC_GET_LOOKS(npc) (aNPC_GET_ANM(npc)->id.looks)
|
||||
|
||||
typedef struct npc_control_cloth_s {
|
||||
/* 0x00 */ u8 dma_flag;
|
||||
/* 0x01 */ u8 init_flag;
|
||||
/* 0x02 */ s16 _02;
|
||||
/* 0x04 */ mActor_name_t cloth_item;
|
||||
/* 0x06 */ s8 in_use_count;
|
||||
/* 0x07 */ u8 id;
|
||||
/* 0x08 */ Object_Bank_c texture_bank;
|
||||
/* 0x0A */ Object_Bank_c palette_bank;
|
||||
} aNPC_cloth_c;
|
||||
|
||||
typedef struct npc_unit_info_s {
|
||||
int x;
|
||||
int z;
|
||||
int direct;
|
||||
} aNPC_unit_info_c;
|
||||
|
||||
#define aNPC_CTRL_CLOTH_NUM 10
|
||||
#define aNPC2_UNIT_X_NUM 6
|
||||
#define aNPC2_UNIT_Z_NUM 7
|
||||
#define aNPC2_UNIT_NUM (aNPC2_UNIT_X_NUM * aNPC2_UNIT_Z_NUM)
|
||||
#define aNPC_ROUTE_NODE_MAX 20
|
||||
|
||||
typedef struct npc_control_actor_s {
|
||||
/* 0x000 */ ACTOR actor_class;
|
||||
/* 0x174 */ aNPC_cloth_c cloth[aNPC_CTRL_CLOTH_NUM];
|
||||
/* 0x8F4 */ u8 _8F4[0x928 - 0x8F4]; // TODO
|
||||
/* 0x928 */ int unit_info[aNPC2_UNIT_Z_NUM][aNPC2_UNIT_X_NUM];
|
||||
/* 0x9D0 */ aNPC_unit_info_c route[aNPC_ROUTE_NODE_MAX];
|
||||
/* 0xAC0 */ int route_node_count;
|
||||
/* 0xAC4 */ int safe_ux[4];
|
||||
/* 0xAD4 */ int safe_uz[4];
|
||||
} NPC_CONTROL_ACTOR;
|
||||
|
||||
static aNPC_Clip_c aNPC_clip;
|
||||
static u16 aNPC_req_default_data[aNPC_REQUEST_ARG_NUM] = { 0, 0, 0, 0, 0, 0 };
|
||||
static ACTOR* aNPC_ctrlActor = NULL;
|
||||
|
||||
static void aNPC_actor_ct_c(ACTOR* actorx, GAME* game);
|
||||
static void aNPC_actor_dt_c(ACTOR* actorx, GAME* game);
|
||||
static void aNPC_actor_move_c(ACTOR* actorx, GAME* game);
|
||||
|
||||
// clang-format off
|
||||
ACTOR_PROFILE Npc2_Profile = {
|
||||
mAc_PROFILE_NPC, // @BUG - shouldn't this be mAc_PROFILE_NPC2???
|
||||
ACTOR_PART_CONTROL,
|
||||
ACTOR_STATE_NO_DRAW_WHILE_CULLED | ACTOR_STATE_NO_MOVE_WHILE_CULLED,
|
||||
EMPTY_NO,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(NPC_CONTROL_ACTOR),
|
||||
&aNPC_actor_ct_c,
|
||||
&aNPC_actor_dt_c,
|
||||
&aNPC_actor_move_c,
|
||||
mActor_NONE_PROC1,
|
||||
NULL,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static void aNPC_set_frame_sub_speed(NPC_ACTOR* nactorx, int seqNo);
|
||||
static void aNPC_TumbleSe(xyz_t* pos_p);
|
||||
static void aNPC_WalkSe(xyz_t* pos_p);
|
||||
static void aNPC_OngenTrgStart(NPC_ACTOR* nactorx, u16 se_no);
|
||||
static int aNPC_set_request_act(NPC_ACTOR* nactorx, u8 prio, u8 act_idx, u8 act_type, u16* args);
|
||||
static int aNPC_set_head_request(NPC_ACTOR* nactorx, u8 prio, u8 type, ACTOR* target_actor, xyz_t* target_pos);
|
||||
static void aNPC_set_feel_info(NPC_ACTOR* nactorx, int feel, int timer);
|
||||
static void aNPC_set_dst_pos(NPC_ACTOR* nactorx, f32 pos_x, f32 pos_z);
|
||||
static void aNPC_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play);
|
||||
static void aNPC_action_proc(NPC_ACTOR* nactorx, GAME_PLAY* play);
|
||||
static void aNPC_talk_area_check(NPC_ACTOR* nactorx, GAME_PLAY* play);
|
||||
static void aNPC_set_feel_effect(GAME* game, NPC_ACTOR* nactorx);
|
||||
static void aNPC_set_other_effect(GAME* game, NPC_ACTOR* nactorx);
|
||||
static void aNPC_act_get_chg_cloth(NPC_ACTOR* nactorx, GAME_PLAY* play);
|
||||
static void aNPC_set_hide_request(NPC_ACTOR* nactorx, u8 req);
|
||||
static int aNPC_setP_friendship(NPC_ACTOR* nactorx);
|
||||
static void aNPC_set_schedule(NPC_ACTOR* nactorx, GAME_PLAY* play);
|
||||
static void aNPC_dma_draw_data_proc(aNPC_draw_data_c* draw_data_p, mActor_name_t npc_name);
|
||||
static void aNPC_WalkSeRoom(xyz_t* pos_p);
|
||||
static int aNPC_route_check(NPC_ACTOR* nactorx, GAME_PLAY* play, int ux, int uz, int turn);
|
||||
|
||||
#include "../src/actor/npc/ac_npc_data.c_inc"
|
||||
#include "../src/actor/npc/ac_npc_cloth.c_inc"
|
||||
#include "../src/actor/npc/ac_npc_anime.c_inc"
|
||||
#include "../src/actor/npc/ac_npc_sound.c_inc"
|
||||
#include "../src/actor/npc/ac_npc_hand.c_inc"
|
||||
#include "../src/actor/npc/ac_npc_head.c_inc"
|
||||
#include "../src/actor/npc/ac_npc_talk.c_inc"
|
||||
#include "../src/actor/npc/ac_npc2_move.c_inc"
|
||||
#include "../src/actor/npc/ac_npc_draw.c_inc"
|
||||
#include "../src/actor/npc/ac_npc_effect.c_inc"
|
||||
#include "../src/actor/npc/ac_npc2_action.c_inc"
|
||||
#include "../src/actor/npc/ac_npc2_think.c_inc"
|
||||
#include "../src/actor/npc/ac_npc2_schedule.c_inc"
|
||||
#include "../src/actor/npc/ac_npc_init.c_inc"
|
||||
#include "../src/actor/npc/ac_npc_ct.c_inc"
|
||||
#include "../src/actor/npc/ac_npc_dt.c_inc"
|
||||
#include "../src/actor/npc/ac_npc_save.c_inc"
|
||||
#include "../src/actor/npc/ac_npc_ctrl.c_inc"
|
||||
|
||||
#undef aNPC_NPC2
|
||||
@@ -0,0 +1,108 @@
|
||||
enum {
|
||||
aNPC_ACT_CONTRACT_STEP_CONTRACT1,
|
||||
aNPC_ACT_CONTRACT_STEP_CONTRACT2,
|
||||
aNPC_ACT_CONTRACT_STEP_CONTRACT3,
|
||||
|
||||
aNPC_ACT_CONTRACT_STEP_NUM
|
||||
};
|
||||
|
||||
static void aNPC_act_contract_chg_step(NPC_ACTOR* nactorx, u8 step) {
|
||||
static u8 act_idx[] = {
|
||||
aNPC_ACTION_TYPE_CONTRACT,
|
||||
aNPC_ACTION_TYPE_CONTRACT_PULL,
|
||||
aNPC_ACTION_TYPE_CONTRACT_PUTAWAY,
|
||||
};
|
||||
|
||||
nactorx->action.step = step;
|
||||
aNPC_setupAction(nactorx, act_idx[step]);
|
||||
}
|
||||
|
||||
static int aNPC_act_contract_return_contract(NPC_ACTOR* nactorx) {
|
||||
int ret = FALSE;
|
||||
|
||||
if (nactorx->condition_info.talk_condition != aNPC_TALK_TYPE_NONE) {
|
||||
if (aNPC_set_request_act(nactorx, 4, aNPC_ACT_TALK, aNPC_ACT_OBJ_DEFAULT, aNPC_req_default_data) == TRUE) {
|
||||
nactorx->condition_info.demo_flg = 0;
|
||||
nactorx->action.step = aNPC_ACTION_END_STEP;
|
||||
ret = TRUE;
|
||||
}
|
||||
} else {
|
||||
nactorx->condition_info.demo_flg = 0;
|
||||
nactorx->action.step = aNPC_ACTION_END_STEP;
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void aNPC_act_contract1(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
if (nactorx->draw.main_animation_state == cKF_STATE_STOPPED) {
|
||||
ACTOR* item = CLIP(handOverItem_clip)->chg_master_proc((ACTOR*)nactorx);
|
||||
|
||||
if (item != NULL) {
|
||||
CLIP(handOverItem_clip)->chg_request_mode_proc((ACTOR*)nactorx, aHOI_REQUEST_GET_PULL);
|
||||
nactorx->left_hand.item_actor_p = item;
|
||||
nactorx->left_hand.item = CLIP(handOverItem_clip)->item;
|
||||
if (nactorx->action.idx == aNPC_ACT_NOT_CONTRACT) {
|
||||
CLIP(handOverItem_clip)->player_after_mode = aHOI_REQUEST_RETURN;
|
||||
}
|
||||
|
||||
aNPC_act_contract_chg_step(nactorx, aNPC_ACT_CONTRACT_STEP_CONTRACT2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_act_contract2(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
if (nactorx->draw.main_animation_state == cKF_STATE_STOPPED) {
|
||||
switch (CLIP(handOverItem_clip)->player_after_mode) {
|
||||
case aHOI_REQUEST_PUTAWAY:
|
||||
CLIP(handOverItem_clip)->chg_request_mode_proc((ACTOR*)nactorx, aHOI_REQUEST_PUTAWAY);
|
||||
aNPC_act_contract_chg_step(nactorx, aNPC_ACT_CONTRACT_STEP_CONTRACT3);
|
||||
break;
|
||||
case aHOI_REQUEST_RETURN:
|
||||
aNPC_act_contract_return_contract(nactorx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_act_contract3(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
if (nactorx->draw.main_animation_state == cKF_STATE_STOPPED) {
|
||||
aNPC_clear_left_hand_info(nactorx);
|
||||
aNPC_act_contract_return_contract(nactorx);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_act_contract_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
static aNPC_SUB_PROC act_proc[] = {
|
||||
&aNPC_act_contract1,
|
||||
&aNPC_act_contract2,
|
||||
&aNPC_act_contract3,
|
||||
};
|
||||
|
||||
if ((*nactorx->talk_info.talk_end_check_proc)((ACTOR*)nactorx, (GAME*)play) == TRUE) {
|
||||
aNPC_setup_talk_end(nactorx);
|
||||
nactorx->action.step = aNPC_ACTION_END_STEP;
|
||||
} else {
|
||||
(*act_proc[nactorx->action.step])(nactorx, play);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_act_contract_chg_data_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
nactorx->action.act_obj = aNPC_ACT_OBJ_PLAYER;
|
||||
}
|
||||
|
||||
static void aNPC_act_contract_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
nactorx->condition_info.demo_flg = aNPC_COND_DEMO_SKIP_ENTRANCE_CHECK | aNPC_COND_DEMO_SKIP_HEAD_LOOKAT | aNPC_COND_DEMO_SKIP_TALK_CHECK | aNPC_COND_DEMO_SKIP_ITEM | aNPC_COND_DEMO_SKIP_FORWARD_CHECK | aNPC_COND_DEMO_SKIP_OBJ_COL_CHECK | aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV | aNPC_COND_DEMO_SKIP_MOVE_RANGE_CHECK;
|
||||
aNPC_act_contract_chg_step(nactorx, aNPC_ACT_CONTRACT_STEP_CONTRACT1);
|
||||
}
|
||||
|
||||
static void aNPC_act_contract_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
static aNPC_SUB_PROC act_proc[] = {
|
||||
&aNPC_act_contract_init_proc,
|
||||
&aNPC_act_contract_chg_data_proc,
|
||||
&aNPC_act_contract_main_proc,
|
||||
};
|
||||
|
||||
(*act_proc[proc_type])(nactorx, play);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
enum {
|
||||
aNPC_ACT_NOT_CONTRACT_STEP_NOT_CONTRACT1,
|
||||
|
||||
aNPC_ACT_NOT_CONTRACT_STEP_NUM
|
||||
};
|
||||
|
||||
static void aNPC_act_not_contract_chg_step(NPC_ACTOR* nactorx, u8 step) {
|
||||
static u8 act_idx[] = {
|
||||
aNPC_ACTION_TYPE_NOT_CONTRACT,
|
||||
};
|
||||
|
||||
nactorx->action.step = step;
|
||||
aNPC_setupAction(nactorx, act_idx[step]);
|
||||
}
|
||||
|
||||
static void aNPC_act_not_contract1(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
if (nactorx->draw.main_animation_frame >= 18) {
|
||||
if (nactorx->left_hand.item_actor_p != NULL) {
|
||||
aNPC_clear_left_hand_info(nactorx);
|
||||
} else if (nactorx->draw.main_animation_state == cKF_STATE_STOPPED && aNPC_act_contract_return_contract(nactorx) == TRUE) {
|
||||
CLIP(handOverItem_clip)->chg_request_mode_proc((ACTOR*)nactorx, aHOI_REQUEST_RETURN_WAIT);
|
||||
CLIP(handOverItem_clip)->player_after_mode = aHOI_REQUEST_PUTAWAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_act_not_contract_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
static aNPC_SUB_PROC act_proc[] = {
|
||||
&aNPC_act_not_contract1,
|
||||
};
|
||||
|
||||
if ((*nactorx->talk_info.talk_end_check_proc)((ACTOR*)nactorx, (GAME*)play) == TRUE) {
|
||||
aNPC_setup_talk_end(nactorx);
|
||||
nactorx->action.step = aNPC_ACTION_END_STEP;
|
||||
} else {
|
||||
(*act_proc[nactorx->action.step])(nactorx, play);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_act_not_contract_chg_data_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
nactorx->action.act_obj = aNPC_ACT_OBJ_PLAYER;
|
||||
}
|
||||
|
||||
static void aNPC_act_not_contract_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
nactorx->condition_info.demo_flg = aNPC_COND_DEMO_SKIP_ENTRANCE_CHECK | aNPC_COND_DEMO_SKIP_HEAD_LOOKAT | aNPC_COND_DEMO_SKIP_TALK_CHECK | aNPC_COND_DEMO_SKIP_ITEM | aNPC_COND_DEMO_SKIP_FORWARD_CHECK | aNPC_COND_DEMO_SKIP_OBJ_COL_CHECK | aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV | aNPC_COND_DEMO_SKIP_MOVE_RANGE_CHECK;
|
||||
CLIP(handOverItem_clip)->chg_request_mode_proc((ACTOR*)nactorx, aHOI_REQUEST_RETURN);
|
||||
aNPC_act_not_contract_chg_step(nactorx, aNPC_ACT_NOT_CONTRACT_STEP_NOT_CONTRACT1);
|
||||
}
|
||||
|
||||
static void aNPC_act_not_contract_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
static aNPC_SUB_PROC act_proc[] = {
|
||||
&aNPC_act_not_contract_init_proc,
|
||||
&aNPC_act_not_contract_chg_data_proc,
|
||||
&aNPC_act_not_contract_main_proc,
|
||||
};
|
||||
|
||||
(*act_proc[proc_type])(nactorx, play);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
enum {
|
||||
aNPC_ACT_PUTAWAY_STEP_PUTAWAY,
|
||||
|
||||
aNPC_ACT_PUTAWAY_STEP_NUM
|
||||
};
|
||||
|
||||
static void aNPC_act_putaway_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
if (!aNPC_act_anm_seq(nactorx) && CLIP(tools_clip) != NULL) {
|
||||
if (CLIP(tools_clip)->aTOL_chg_request_mode_proc((ACTOR*)nactorx, nactorx->right_hand.item_actor_p, aTOL_ACTION_DESTRUCT) == TRUE) {
|
||||
nactorx->right_hand.item_type = aNPC_ITEM_TYPE_NONE;
|
||||
nactorx->right_hand.item_actor_p = NULL;
|
||||
nactorx->action.step = aNPC_ACTION_END_STEP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_act_putaway_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
nactorx->action.step = aNPC_ACT_PUTAWAY_STEP_PUTAWAY;
|
||||
nactorx->draw.sub_anim_type = aNPC_SUB_ANIM_NONE;
|
||||
aNPC_setupAction(nactorx, aNPC_ACTION_TYPE_KEITAI_OFF);
|
||||
}
|
||||
|
||||
static void aNPC_act_putaway_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
static aNPC_SUB_PROC act_proc[] = {
|
||||
&aNPC_act_putaway_init_proc,
|
||||
(aNPC_SUB_PROC)&none_proc1,
|
||||
&aNPC_act_putaway_main_proc,
|
||||
};
|
||||
|
||||
(*act_proc[proc_type])(nactorx, play);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
enum {
|
||||
aNPC_ACT_TAKEOUT_STEP_TAKEOUT,
|
||||
|
||||
aNPC_ACT_TAKEOUT_STEP_NUM
|
||||
};
|
||||
|
||||
static void aNPC_act_takeout_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
nactorx->action.step = aNPC_ACT_TAKEOUT_STEP_TAKEOUT;
|
||||
aNPC_setupAction(nactorx, aNPC_ACTION_TYPE_KEITAI_ON);
|
||||
}
|
||||
|
||||
static void aNPC_act_takeout_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
static aNPC_SUB_PROC act_proc[] = {
|
||||
&aNPC_act_takeout_init_proc,
|
||||
(aNPC_SUB_PROC)&none_proc1,
|
||||
&aNPC_act_anm_seq_allways_proc,
|
||||
};
|
||||
|
||||
(*act_proc[proc_type])(nactorx, play);
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
enum {
|
||||
aNPC_ACT_WALK_STEP_MAIN,
|
||||
|
||||
aNPC_ACT_WALK_STEP_NUM
|
||||
};
|
||||
|
||||
static void aNPC_act_walk_setupAction(NPC_ACTOR* nactorx, u8 feel) {
|
||||
static u8 walk_action[] = {
|
||||
aNPC_ACTION_TYPE_WALK,
|
||||
aNPC_ACTION_TYPE_WALK_KI,
|
||||
aNPC_ACTION_TYPE_WALK_DO,
|
||||
aNPC_ACTION_TYPE_WALK_AI,
|
||||
aNPC_ACTION_TYPE_WALK,
|
||||
aNPC_ACTION_TYPE_WALK,
|
||||
aNPC_ACTION_TYPE_WALK_DO,
|
||||
aNPC_ACTION_TYPE_WALK_AI,
|
||||
aNPC_ACTION_TYPE_WALK_DO
|
||||
};
|
||||
static u8 run_action[] = {
|
||||
aNPC_ACTION_TYPE_RUN,
|
||||
aNPC_ACTION_TYPE_RUN_KI,
|
||||
aNPC_ACTION_TYPE_RUN_DO,
|
||||
aNPC_ACTION_TYPE_RUN_AI,
|
||||
aNPC_ACTION_TYPE_RUN,
|
||||
aNPC_ACTION_TYPE_RUN,
|
||||
aNPC_ACTION_TYPE_RUN_DO,
|
||||
aNPC_ACTION_TYPE_RUN_AI,
|
||||
aNPC_ACTION_TYPE_RUN_DO
|
||||
};
|
||||
u8 act;
|
||||
|
||||
nactorx->action.feel = feel;
|
||||
if (nactorx->action.idx == aNPC_ACT_WALK) {
|
||||
act = walk_action[feel];
|
||||
} else {
|
||||
act = run_action[feel];
|
||||
}
|
||||
|
||||
aNPC_setupAction(nactorx, act);
|
||||
}
|
||||
|
||||
typedef int (*aNPC_ACT_WALK_PROC)(NPC_ACTOR* nactorx, GAME_PLAY* play);
|
||||
|
||||
static void aNPC_act_walk_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
static aNPC_ACT_WALK_PROC act_proc[] = {
|
||||
&aNPC_act_move,
|
||||
&aNPC_act_avoid_move,
|
||||
&aNPC_act_search_move,
|
||||
&aNPC_act_to_point_move,
|
||||
};
|
||||
|
||||
if (nactorx->draw.main_animation_state == cKF_STATE_CONTINUE) {
|
||||
u8 feel = aNPC_get_feel_info(nactorx);
|
||||
|
||||
if (nactorx->action.feel != feel) {
|
||||
aNPC_act_walk_setupAction(nactorx, feel);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(*act_proc[nactorx->action.type])(nactorx, play)) {
|
||||
nactorx->action.step = aNPC_ACTION_END_STEP;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_act_walk_chg_data_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
u16* arg_p = nactorx->request.act_args;
|
||||
s16 prev_move_x = nactorx->action.move_x;
|
||||
s16 prev_move_z = nactorx->action.move_z;
|
||||
|
||||
nactorx->action.act_obj = arg_p[0];
|
||||
nactorx->action.act_obj_id = arg_p[1];
|
||||
nactorx->action.move_x = arg_p[2];
|
||||
nactorx->action.move_z = arg_p[3];
|
||||
|
||||
if (nactorx->action.step == aNPC_ACTION_END_STEP && (nactorx->action.move_x != prev_move_x || nactorx->action.move_z != prev_move_z)) {
|
||||
nactorx->action.step = aNPC_ACT_WALK_STEP_MAIN;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_act_walk_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
u16* arg_p = nactorx->request.act_args;
|
||||
u8 feel;
|
||||
|
||||
nactorx->action.step = aNPC_ACT_WALK_STEP_MAIN;
|
||||
nactorx->movement.arrival_area_radius = 72.0f;
|
||||
feel = aNPC_get_feel_info(nactorx);
|
||||
aNPC_act_walk_setupAction(nactorx, feel);
|
||||
}
|
||||
|
||||
static void aNPC_act_walk_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int type) {
|
||||
static aNPC_SUB_PROC act_proc[] = { &aNPC_act_walk_init_proc, &aNPC_act_walk_chg_data_proc, &aNPC_act_walk_main_proc };
|
||||
|
||||
(*act_proc[type])(nactorx, play);
|
||||
}
|
||||
@@ -0,0 +1,380 @@
|
||||
// clang-format off
|
||||
static u8 aNPC_wait_action[] = {
|
||||
aNPC_ACTION_TYPE_WAIT,
|
||||
aNPC_ACTION_TYPE_WAIT_KI,
|
||||
aNPC_ACTION_TYPE_WAIT_DO,
|
||||
aNPC_ACTION_TYPE_WAIT_AI,
|
||||
aNPC_ACTION_TYPE_WAIT_NEMU,
|
||||
aNPC_ACTION_TYPE_WAIT,
|
||||
aNPC_ACTION_TYPE_WAIT_DO,
|
||||
aNPC_ACTION_TYPE_WAIT_AI,
|
||||
aNPC_ACTION_TYPE_WAIT_DO,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static void aNPC_set_be_out_home(NPC_ACTOR* nactorx) {
|
||||
mNpc_NpcList_c* list_p;
|
||||
|
||||
aNPC_GET_ANM(nactorx)->is_home = FALSE;
|
||||
list_p = nactorx->npc_info.list;
|
||||
list_p->position.x = list_p->house_position.x + mFI_UT_WORLDSIZE_HALF_X_F;
|
||||
list_p->position.y = list_p->house_position.y;
|
||||
list_p->position.z = list_p->house_position.z + mFI_UT_WORLDSIZE_HALF_Z_F;
|
||||
}
|
||||
|
||||
static int aNPC_check_arrive_destination(NPC_ACTOR* nactorx) {
|
||||
f32 range = nactorx->movement.arrival_area_radius;
|
||||
f32 dist;
|
||||
f32 distX = nactorx->movement.avoid_pos_x - nactorx->actor_class.world.position.x;
|
||||
f32 distZ = nactorx->movement.avoid_pos_z - nactorx->actor_class.world.position.z;
|
||||
int ret = FALSE;
|
||||
|
||||
dist = SQ(distX) + SQ(distZ);
|
||||
if (dist < range) {
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_trace_route(NPC_ACTOR* nactorx) {
|
||||
int ret = TRUE;
|
||||
|
||||
if (aNPC_check_arrive_destination(nactorx) == TRUE) {
|
||||
switch (nactorx->schedule.type) {
|
||||
case aNPC_SCHEDULE_TYPE_FIELD:
|
||||
case aNPC_SCHEDULE_TYPE_IN_HOUSE:
|
||||
case aNPC_SCHEDULE_TYPE_WANDER: {
|
||||
NPC_CONTROL_ACTOR* ctrl = (NPC_CONTROL_ACTOR*)aNPC_ctrlActor;
|
||||
aNPC_unit_info_c* route = ctrl->route + nactorx->movement.avoid_direction;
|
||||
|
||||
aNPC_set_avoid_pos(nactorx, (route->x + 1.5f) * mFI_UT_WORLDSIZE_X_F, (route->z + 1.5f) * mFI_UT_WORLDSIZE_Z_F);
|
||||
if (ctrl->route_node_count == nactorx->movement.avoid_direction) {
|
||||
aNPC_set_dst_pos(nactorx, nactorx->movement.avoid_pos_x, nactorx->movement.avoid_pos_z);
|
||||
ret = FALSE;
|
||||
} else {
|
||||
nactorx->movement.avoid_direction++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void aNPC_set_feel_info(NPC_ACTOR* nactorx, int feel, int timer) {
|
||||
Animal_c* animal = nactorx->npc_info.animal;
|
||||
|
||||
if (animal != NULL) {
|
||||
int feel_timer = nactorx->condition_info.feel_tim;
|
||||
|
||||
if (feel != animal->mood) {
|
||||
animal->mood = feel;
|
||||
if (feel == mNpc_FEEL_NORMAL) {
|
||||
feel_timer = 0;
|
||||
} else {
|
||||
feel_timer = timer * FRAMES_PER_MINUTE;
|
||||
}
|
||||
} else {
|
||||
feel_timer += timer * FRAMES_PER_MINUTE;
|
||||
if (feel_timer > (10 * FRAMES_PER_MINUTE)) {
|
||||
feel_timer = 10 * FRAMES_PER_MINUTE;
|
||||
}
|
||||
}
|
||||
|
||||
nactorx->condition_info.feel_tim = feel_timer;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_set_act_obj(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
switch (nactorx->action.act_obj) {
|
||||
case aNPC_ACT_OBJ_PLAYER:
|
||||
nactorx->movement.target = GET_PLAYER_ACTOR_ACTOR(play);
|
||||
break;
|
||||
case aNPC_ACT_OBJ_TARGET_NPC:
|
||||
nactorx->movement.target =
|
||||
Actor_info_fgName_search(&play->actor_info, nactorx->action.act_obj_id, ACTOR_PART_NPC);
|
||||
break;
|
||||
default:
|
||||
nactorx->movement.target = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int aNPC_check_live_target(ACTOR* actorx) {
|
||||
int ret = TRUE;
|
||||
|
||||
if (actorx == NULL || (actorx->mv_proc == NULL && actorx->dw_proc == NULL)) {
|
||||
ret = FALSE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_act_wait(NPC_ACTOR* nactorx) {
|
||||
int ret = TRUE;
|
||||
|
||||
if (nactorx->draw.main_animation_state == cKF_STATE_CONTINUE) {
|
||||
if (nactorx->draw.loop_flag == FALSE) {
|
||||
if (nactorx->condition_info.fatigue < 200) {
|
||||
ret = FALSE;
|
||||
}
|
||||
} else {
|
||||
nactorx->draw.loop_flag--;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_act_move(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
int ret = TRUE;
|
||||
|
||||
aNPC_set_mv_angl(nactorx);
|
||||
if (aNPC_trace_route(nactorx) == FALSE) {
|
||||
ret = FALSE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_act_search_move(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
ACTOR* target = nactorx->movement.target;
|
||||
int ret = TRUE;
|
||||
|
||||
if (!aNPC_check_live_target(target)) {
|
||||
ret = FALSE;
|
||||
} else {
|
||||
xyz_t dst_pos;
|
||||
int ux;
|
||||
int uz;
|
||||
|
||||
xyz_t_move(&dst_pos, &target->world.position);
|
||||
mFI_Wpos2UtNum(&ux, &uz, dst_pos);
|
||||
|
||||
aNPC_route_check(nactorx, play, ux, uz, FALSE);
|
||||
aNPC_set_mv_angl(nactorx);
|
||||
if (aNPC_trace_route(nactorx) == FALSE) {
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_act_avoid_move(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
ACTOR* target = nactorx->movement.target;
|
||||
int ret = TRUE;
|
||||
|
||||
if (!aNPC_check_live_target(target)) {
|
||||
ret = FALSE;
|
||||
} else {
|
||||
aNPC_set_mv_angl(nactorx);
|
||||
if (aNPC_trace_route(nactorx) == FALSE) {
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_act_demo_move(NPC_ACTOR* nactorx) {
|
||||
ACTOR* target = nactorx->movement.target;
|
||||
int ret = TRUE;
|
||||
|
||||
if (!aNPC_check_live_target(target)) {
|
||||
ret = FALSE;
|
||||
} else {
|
||||
xyz_t pos;
|
||||
|
||||
xyz_t_move(&pos, &target->world.position);
|
||||
aNPC_set_dst_pos(nactorx, pos.x, pos.z);
|
||||
aNPC_set_mv_angl(nactorx);
|
||||
if (aNPC_check_arrive_destination(nactorx) == TRUE) {
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_act_to_point_move(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
int ret = TRUE;
|
||||
|
||||
if (nactorx->movement.dst_pos_x == nactorx->movement.avoid_pos_x && nactorx->movement.dst_pos_z == nactorx->movement.avoid_pos_z) {
|
||||
aNPC_set_dst_pos(nactorx, nactorx->action.move_x, nactorx->action.move_z);
|
||||
} else {
|
||||
nactorx->movement.dst_pos_x = nactorx->action.move_x;
|
||||
nactorx->movement.dst_pos_z = nactorx->action.move_z;
|
||||
}
|
||||
|
||||
aNPC_set_mv_angl(nactorx);
|
||||
if (aNPC_check_arrive_destination(nactorx) == TRUE) {
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_act_turn(NPC_ACTOR* nactorx) {
|
||||
int ret = TRUE;
|
||||
|
||||
if (nactorx->actor_class.shape_info.rotation.y == nactorx->movement.mv_angl) {
|
||||
ret = FALSE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_act_search_turn(NPC_ACTOR* nactorx) {
|
||||
ACTOR* target = nactorx->movement.target;
|
||||
int ret = TRUE;
|
||||
|
||||
if (!aNPC_check_live_target(target)) {
|
||||
ret = FALSE;
|
||||
} else {
|
||||
aNPC_set_dst_pos(nactorx, target->world.position.x, target->world.position.z);
|
||||
if (nactorx->actor_class.shape_info.rotation.y == nactorx->movement.mv_angl) {
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_act_to_point_turn(NPC_ACTOR* nactorx) {
|
||||
int ret = TRUE;
|
||||
|
||||
aNPC_set_dst_pos(nactorx, nactorx->action.move_x, nactorx->action.move_z);
|
||||
if (nactorx->actor_class.shape_info.rotation.y == nactorx->movement.mv_angl) {
|
||||
ret = FALSE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_act_anm_seq(NPC_ACTOR* nactorx) {
|
||||
int ret = TRUE;
|
||||
|
||||
if (nactorx->draw.main_animation_state == cKF_STATE_STOPPED) {
|
||||
ret = FALSE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void aNPC_act_anm_seq_allways_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
if (!aNPC_act_anm_seq(nactorx)) {
|
||||
nactorx->action.step = aNPC_ACTION_END_STEP;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_act_return_trans_item(NPC_ACTOR* nactorx) {
|
||||
if (nactorx->condition_info.talk_condition != aNPC_TALK_TYPE_NONE) {
|
||||
if (aNPC_set_request_act(nactorx, 4, aNPC_ACT_TALK, aNPC_ACT_OBJ_DEFAULT, aNPC_req_default_data) == TRUE) {
|
||||
nactorx->condition_info.demo_flg = nactorx->condition_info.trans_demo_flg_save;
|
||||
nactorx->action.step = aNPC_ACTION_END_STEP;
|
||||
}
|
||||
} else {
|
||||
nactorx->condition_info.demo_flg = 0;
|
||||
nactorx->action.step = aNPC_ACTION_END_STEP;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_act_special_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int type) {
|
||||
(*nactorx->action.act_proc)(nactorx, play, type);
|
||||
}
|
||||
|
||||
// included act files
|
||||
|
||||
#include "../src/actor/npc/ac_npc_act_wait.c_inc"
|
||||
#include "../src/actor/npc/ac_npc2_act_walk.c_inc"
|
||||
#include "../src/actor/npc/ac_npc_act_turn.c_inc"
|
||||
#include "../src/actor/npc/ac_npc_act_talk.c_inc"
|
||||
#include "../src/actor/npc/ac_npc2_act_takeout.c_inc"
|
||||
#include "../src/actor/npc/ac_npc2_act_putaway.c_inc"
|
||||
#include "../src/actor/npc/ac_npc_act_trans.c_inc"
|
||||
#include "../src/actor/npc/ac_npc_act_get.c_inc"
|
||||
#include "../src/actor/npc/ac_npc2_act_contract.c_inc"
|
||||
#include "../src/actor/npc/ac_npc2_act_not_contract.c_inc"
|
||||
#include "../src/actor/npc/ac_npc_act_ensou.c_inc"
|
||||
|
||||
typedef void (*aNPC_ACT_PROC)(NPC_ACTOR* nactorx, GAME_PLAY* play, int type);
|
||||
|
||||
static aNPC_ACT_PROC aNPC_act_proc[] = {
|
||||
&aNPC_act_wait_proc,
|
||||
&aNPC_act_walk_proc,
|
||||
&aNPC_act_walk_proc,
|
||||
&aNPC_act_turn_proc,
|
||||
&aNPC_act_turn_proc,
|
||||
&aNPC_act_talk_proc,
|
||||
&aNPC_act_takeout_proc,
|
||||
&aNPC_act_putaway_proc,
|
||||
&aNPC_act_ensou_proc,
|
||||
&aNPC_act_talk_proc,
|
||||
&aNPC_act_trans_proc,
|
||||
&aNPC_act_get_proc,
|
||||
&aNPC_act_contract_proc,
|
||||
&aNPC_act_contract_proc,
|
||||
&aNPC_act_not_contract_proc,
|
||||
&aNPC_act_get_proc,
|
||||
&aNPC_act_special_proc,
|
||||
};
|
||||
|
||||
static void aNPC_chk_request_act(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
if (nactorx->request.act_priority >= nactorx->action.priority && nactorx->request.act_priority != 0) {
|
||||
u8 prev_idx = nactorx->action.idx;
|
||||
u8 prev_obj = nactorx->action.act_obj;
|
||||
mActor_name_t prev_obj_name = nactorx->action.act_obj_id;
|
||||
|
||||
nactorx->action.prev_idx = nactorx->action.idx;
|
||||
nactorx->action.prev_step = nactorx->action.step;
|
||||
nactorx->action.priority = nactorx->request.act_priority;
|
||||
nactorx->action.idx = nactorx->request.act_idx;
|
||||
nactorx->action.type = nactorx->request.act_type;
|
||||
|
||||
(*aNPC_act_proc[nactorx->action.idx])(nactorx, play, aNPC_ACTION_PROC_TYPE_CHG_DATA);
|
||||
if (nactorx->action.act_obj != prev_obj || nactorx->action.act_obj_id != prev_obj_name) {
|
||||
aNPC_set_act_obj(nactorx, play);
|
||||
}
|
||||
|
||||
if (nactorx->request.act_idx != prev_idx) {
|
||||
(*aNPC_act_proc[nactorx->action.idx])(nactorx, play, aNPC_ACTION_PROC_TYPE_INIT);
|
||||
}
|
||||
}
|
||||
|
||||
nactorx->request.act_priority = 0;
|
||||
}
|
||||
|
||||
static int aNPC_set_request_act(NPC_ACTOR* nactorx, u8 prio, u8 act_idx, u8 act_type, u16* args) {
|
||||
int ret = FALSE;
|
||||
|
||||
if (prio >= nactorx->request.act_priority) {
|
||||
nactorx->request.act_priority = prio;
|
||||
nactorx->request.act_idx = act_idx;
|
||||
nactorx->request.act_type = act_type;
|
||||
|
||||
if (args != NULL) {
|
||||
mem_copy((u8*)nactorx->request.act_args, (u8*)args, sizeof(nactorx->request.act_args));
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void aNPC_action_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
aNPC_chk_request_act(nactorx, play);
|
||||
|
||||
if (nactorx->action.step != aNPC_ACTION_END_STEP && nactorx->action.idx != aNPC_ACT_NONE) {
|
||||
(*aNPC_act_proc[nactorx->action.idx])(nactorx, play, aNPC_ACTION_PROC_TYPE_MAIN);
|
||||
}
|
||||
|
||||
if (nactorx->action.step == aNPC_ACTION_END_STEP) {
|
||||
nactorx->action.priority = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
static f32 aNPC_get_rev_val(f32 rev, f32 amount) {
|
||||
if (ABS(rev) >= amount) {
|
||||
if (rev < 0.0f) {
|
||||
return -amount;
|
||||
} else {
|
||||
return amount;
|
||||
}
|
||||
} else {
|
||||
return rev;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_BGcheck(NPC_ACTOR* nactorx, ACTOR* actorx) {
|
||||
if ((nactorx->condition_info.demo_flg & aNPC_COND_DEMO_SKIP_BGCHECK) == 0) {
|
||||
if (ClObj_DID_COLLIDE(nactorx->collision.pipe.collision_obj)) {
|
||||
mCoBG_BgCheckControll(NULL, actorx, nactorx->collision.BGcheck_radius, 0.0f, TRUE, FALSE, 0);
|
||||
nactorx->collision.bg_rev_add = 0.0f;
|
||||
} else {
|
||||
xyz_t rev;
|
||||
f32 amount;
|
||||
|
||||
mCoBG_BgCheckControll(&rev, actorx, nactorx->collision.BGcheck_radius, 0.0f, TRUE, TRUE, 0);
|
||||
amount = nactorx->collision.bg_rev_add;
|
||||
|
||||
amount += 1.0f;
|
||||
if (amount > 4.0f) {
|
||||
amount = 4.0f;
|
||||
}
|
||||
|
||||
nactorx->collision.bg_rev_add = amount;
|
||||
actorx->world.position.x += aNPC_get_rev_val(rev.x, amount);
|
||||
actorx->world.position.y += aNPC_get_rev_val(rev.y, amount);
|
||||
actorx->world.position.z += aNPC_get_rev_val(rev.z, amount);
|
||||
}
|
||||
} else {
|
||||
mCoBG_InitBgCheckResult(&actorx->bg_collision_check.result);
|
||||
nactorx->collision.bg_rev_add = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_set_over_friendship(NPC_ACTOR* nactorx) {
|
||||
if (ITEM_NAME_GET_TYPE(nactorx->actor_class.npc_id) != NAME_TYPE_SPNPC) {
|
||||
int over_friendship = 0;
|
||||
|
||||
switch (Now_Private->destiny.type) {
|
||||
case mPr_DESTINY_UNPOPULAR:
|
||||
over_friendship = -0x100;
|
||||
break;
|
||||
case mPr_DESTINY_POPULAR:
|
||||
if (mNpc_GetLooks2Sex(nactorx->npc_info.animal->id.looks) != Now_Private->gender) {
|
||||
over_friendship = 0x100;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
nactorx->condition_info.over_friendship = over_friendship;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_set_mv_angl(NPC_ACTOR* nactorx) {
|
||||
s16 angle = atans_table(nactorx->movement.avoid_pos_z - nactorx->actor_class.world.position.z,
|
||||
nactorx->movement.avoid_pos_x - nactorx->actor_class.world.position.x);
|
||||
|
||||
nactorx->movement.mv_angl = angle;
|
||||
}
|
||||
|
||||
static void aNPC_set_avoid_pos(NPC_ACTOR* nactorx, f32 avoid_pos_x, f32 avoid_pos_z) {
|
||||
nactorx->movement.avoid_pos_x = avoid_pos_x;
|
||||
nactorx->movement.avoid_pos_z = avoid_pos_z;
|
||||
aNPC_set_mv_angl(nactorx);
|
||||
}
|
||||
|
||||
static void aNPC_set_dst_pos(NPC_ACTOR* nactorx, f32 dst_pos_x, f32 dst_pos_z) {
|
||||
nactorx->movement.dst_pos_x = dst_pos_x;
|
||||
nactorx->movement.dst_pos_z = dst_pos_z;
|
||||
nactorx->movement.move_timer = 0;
|
||||
aNPC_set_avoid_pos(nactorx, dst_pos_x, dst_pos_z);
|
||||
}
|
||||
|
||||
static void aNPC_check_feel_tim(NPC_ACTOR* nactorx) {
|
||||
Animal_c* animal_p = nactorx->npc_info.animal;
|
||||
|
||||
if (animal_p != NULL) {
|
||||
if ((nactorx->condition_info.demo_flg & aNPC_COND_DEMO_SKIP_FEEL_CHECK) == 0 &&
|
||||
nactorx->condition_info.feel_tim > 0) {
|
||||
nactorx->condition_info.feel_tim--;
|
||||
}
|
||||
|
||||
if (nactorx->condition_info.feel_tim == 0) {
|
||||
animal_p->mood = mNpc_FEEL_NORMAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_calc_force_call_timer(NPC_ACTOR* nactorx) {
|
||||
if (mDemo_Get_talk_actor() == NULL && nactorx->think.force_call_timer != 0) {
|
||||
nactorx->think.force_call_timer--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void aNPC_calc_timer(NPC_ACTOR* nactorx) {
|
||||
aNPC_calc_force_call_timer(nactorx);
|
||||
}
|
||||
|
||||
static void aNPC_position_move(ACTOR* actorx) {
|
||||
NPC_ACTOR* nactorx = (NPC_ACTOR*)actorx;
|
||||
f32 accel;
|
||||
|
||||
if (actorx->speed < nactorx->movement.speed.max_speed) {
|
||||
accel = nactorx->movement.speed.acceleration;
|
||||
} else {
|
||||
accel = nactorx->movement.speed.deceleration;
|
||||
}
|
||||
|
||||
chase_f(&actorx->speed, nactorx->movement.speed.max_speed, accel * 0.5f);
|
||||
#ifndef aNPC_NPC2
|
||||
Actor_position_speed_set(actorx);
|
||||
#else
|
||||
Actor_position_moveF(actorx);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void aNPC_angle_calc(NPC_ACTOR* nactorx) {
|
||||
chase_angle(&nactorx->actor_class.shape_info.rotation.y, nactorx->movement.mv_angl, nactorx->movement.mv_add_angl);
|
||||
nactorx->actor_class.world.angle.y = nactorx->actor_class.shape_info.rotation.y;
|
||||
}
|
||||
|
||||
static void aNPC_set_body_angle(NPC_ACTOR* nactorx) {
|
||||
s16 angle;
|
||||
|
||||
if (nactorx->movement.override_body_angle_flag == TRUE) {
|
||||
angle = nactorx->movement.body_angle;
|
||||
} else {
|
||||
angle = (nactorx->actor_class.speed * 3640.0f) / 3.0f;
|
||||
}
|
||||
|
||||
chase_angle(&nactorx->actor_class.shape_info.rotation.x, angle, 224);
|
||||
}
|
||||
|
||||
static void aNPC_calc_fatigue(NPC_ACTOR* nactorx) {
|
||||
static int fatigue_add_table[] = {
|
||||
-2, -2, -2, -2, -2, 1, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
int fatigue = nactorx->condition_info.fatigue;
|
||||
|
||||
fatigue += fatigue_add_table[nactorx->condition_info.action];
|
||||
if (fatigue < 0) {
|
||||
fatigue = 0;
|
||||
} else if (fatigue > 1600) {
|
||||
fatigue = 1600;
|
||||
}
|
||||
|
||||
nactorx->condition_info.fatigue = fatigue;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int talk_flag;
|
||||
s16 mv_angl_add;
|
||||
u8 speed_type;
|
||||
} aNPC_setup_data_c;
|
||||
|
||||
static void aNPC_setupAction(NPC_ACTOR* nactorx, u8 action) {
|
||||
// clang-format off
|
||||
static aNPC_setup_data_c setup_data[aNPC_ACTION_TYPE_NUM] = {
|
||||
{FALSE, 0x0100, 0x00},
|
||||
{FALSE, 0x0100, 0x00},
|
||||
{FALSE, 0x0100, 0x00},
|
||||
{FALSE, 0x0100, 0x00},
|
||||
{FALSE, 0x0100, 0x00},
|
||||
{FALSE, 0x0400, 0x01},
|
||||
{FALSE, 0x0400, 0x01},
|
||||
{FALSE, 0x0400, 0x01},
|
||||
{FALSE, 0x0400, 0x01},
|
||||
{FALSE, 0x0400, 0x02},
|
||||
{FALSE, 0x0400, 0x02},
|
||||
{FALSE, 0x0400, 0x02},
|
||||
{FALSE, 0x0400, 0x02},
|
||||
{FALSE, 0x0800, 0x00},
|
||||
{FALSE, 0x0800, 0x00},
|
||||
{FALSE, 0x0800, 0x00},
|
||||
{ TRUE, 0x0400, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{FALSE, 0x0000, 0x00},
|
||||
{ TRUE, 0x0000, 0x00},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
aNPC_setup_data_c* data_p = &setup_data[action];
|
||||
aNPC_spd_c* speed_p = &aNPC_spd_data[data_p->speed_type];
|
||||
|
||||
nactorx->condition_info.action = action;
|
||||
nactorx->movement.mv_add_angl = data_p->mv_angl_add;
|
||||
nactorx->movement.speed.max_speed = speed_p->max_speed;
|
||||
nactorx->movement.speed.acceleration = speed_p->acceleration;
|
||||
nactorx->movement.speed.deceleration = speed_p->deceleration;
|
||||
|
||||
if (data_p->speed_type == 0) {
|
||||
nactorx->actor_class.speed = 0.0f;
|
||||
}
|
||||
|
||||
nactorx->talk_info.demo_code = aNPC_MANPU_CODE_NONE;
|
||||
aNPC_Animation_init((ACTOR*)nactorx, aNPC_animeSeqNoTable[(int)action], data_p->talk_flag);
|
||||
}
|
||||
|
||||
static void aNPC_actor_move_hide(ACTOR* actorx, GAME* game) {
|
||||
NPC_ACTOR* nactorx = (NPC_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
|
||||
aNPC_schedule_proc(nactorx, play);
|
||||
aNPC_action_proc(nactorx, play);
|
||||
aNPC_check_feel_tim(nactorx);
|
||||
}
|
||||
|
||||
static void aNPC_actor_move_show_before(ACTOR* actorx, GAME* game) {
|
||||
NPC_ACTOR* nactorx = (NPC_ACTOR*)actorx;
|
||||
|
||||
aNPC_anime_proc(nactorx, game);
|
||||
aNPC_tex_anm_ctrl(nactorx);
|
||||
aNPC_position_move(actorx);
|
||||
aNPC_BGcheck(nactorx, actorx);
|
||||
}
|
||||
|
||||
static void aNPC_actor_move_show_after(ACTOR* actorx, GAME* game) {
|
||||
NPC_ACTOR* nactorx = (NPC_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
|
||||
aNPC_set_anime_speed(nactorx);
|
||||
aNPC_set_body_angle(nactorx);
|
||||
aNPC_check_feel_tim(nactorx);
|
||||
aNPC_calc_timer(nactorx);
|
||||
Actor_world_to_eye(actorx, nactorx->eye_y);
|
||||
|
||||
if ((nactorx->condition_info.demo_flg & aNPC_COND_DEMO_SKIP_OBJ_COL_CHECK) == 0) {
|
||||
CollisionCheck_Uty_ActorWorldPosSetPipeC(actorx, &nactorx->collision.pipe);
|
||||
CollisionCheck_setOC(game, &play->collision_check, &nactorx->collision.pipe.collision_obj);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_actor_move_show(ACTOR* actorx, GAME* game) {
|
||||
NPC_ACTOR* nactorx = (NPC_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
|
||||
aNPC_set_over_friendship(nactorx);
|
||||
aNPC_actor_move_show_before(actorx, game);
|
||||
aNPC_schedule_proc(nactorx, play);
|
||||
aNPC_action_proc(nactorx, play);
|
||||
aNPC_talk_request_check(actorx, game);
|
||||
aNPC_angle_calc(nactorx);
|
||||
aNPC_calc_fatigue(nactorx);
|
||||
aNPC_actor_move_show_after(actorx, game);
|
||||
}
|
||||
|
||||
static void aNPC_actor_move(ACTOR* actorx, GAME* game) {
|
||||
NPC_ACTOR* nactorx = (NPC_ACTOR*)actorx;
|
||||
|
||||
if (nactorx->condition_info.hide_flg != nactorx->condition_info.hide_request) {
|
||||
u8 hide_req = nactorx->condition_info.hide_request;
|
||||
|
||||
nactorx->condition_info.hide_flg = hide_req;
|
||||
actorx->shape_info.draw_shadow = hide_req ^ 1;
|
||||
}
|
||||
|
||||
if (nactorx->condition_info.hide_flg == TRUE) {
|
||||
aNPC_actor_move_hide(actorx, game);
|
||||
} else {
|
||||
aNPC_actor_move_show(actorx, game);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
static void aNPC_set_hide_request(NPC_ACTOR* nactorx, u8 hide) {
|
||||
nactorx->condition_info.hide_request = hide;
|
||||
if (nactorx->condition_info.hide_flg != hide && hide != TRUE) {
|
||||
aNPC_clear_all_morph_counter(nactorx);
|
||||
nactorx->condition_info.fatigue = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_set_hide_flg(NPC_ACTOR* nactorx, u8 hide_flg) {
|
||||
u8 inv = hide_flg ^ 1;
|
||||
|
||||
aNPC_set_hide_request(nactorx, hide_flg);
|
||||
nactorx->condition_info.hide_flg = hide_flg;
|
||||
nactorx->actor_class.shape_info.draw_shadow = inv;
|
||||
}
|
||||
|
||||
#include "../src/actor/npc/ac_npc2_schedule_field.c_inc"
|
||||
#include "../src/actor/npc/ac_npc2_schedule_in_house.c_inc"
|
||||
|
||||
static void aNPC_sleep_schedule_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
if (nactorx->schedule.type != nactorx->npc_info.schedule->current_type) {
|
||||
aNPC_set_schedule(nactorx, play);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_sleep_schedule_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
aNPC_set_hide_flg(nactorx, TRUE);
|
||||
aNPC_think_init_proc(nactorx, play, aNPC_THINK_WAIT);
|
||||
}
|
||||
|
||||
static void aNPC_sleep_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
static aNPC_SUB_PROC sche_proc[] = {
|
||||
&aNPC_sleep_schedule_init_proc,
|
||||
&aNPC_sleep_schedule_main_proc,
|
||||
};
|
||||
|
||||
(*sche_proc[proc_type])(nactorx, play);
|
||||
}
|
||||
|
||||
static void aNPC_stand_schedule_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
if (!aNPC_think_chk_interrupt_proc(nactorx, play) && nactorx->action.step == aNPC_ACTION_END_STEP) {
|
||||
if (nactorx->action.idx == aNPC_ACT_WAIT) {
|
||||
aNPC_think_main_proc(nactorx, play);
|
||||
} else {
|
||||
aNPC_think_init_proc(nactorx, play, aNPC_THINK_WAIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_stand_schedule_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
aNPC_set_hide_flg(nactorx, FALSE);
|
||||
aNPC_think_init_proc(nactorx, play, aNPC_THINK_WAIT);
|
||||
}
|
||||
|
||||
static void aNPC_stand_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
static aNPC_SUB_PROC sche_proc[] = {
|
||||
&aNPC_stand_schedule_init_proc,
|
||||
&aNPC_stand_schedule_main_proc,
|
||||
};
|
||||
|
||||
(*sche_proc[proc_type])(nactorx, play);
|
||||
}
|
||||
|
||||
static void aNPC_wander_schedule_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
aNPC_think_main_proc(nactorx, play);
|
||||
}
|
||||
|
||||
static void aNPC_wander_schedule_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
aNPC_set_hide_flg(nactorx, FALSE);
|
||||
aNPC_think_init_proc(nactorx, play, aNPC_THINK_WANDER);
|
||||
}
|
||||
|
||||
static void aNPC_wander_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
static aNPC_SUB_PROC sche_proc[] = {
|
||||
&aNPC_wander_schedule_init_proc,
|
||||
&aNPC_wander_schedule_main_proc,
|
||||
};
|
||||
|
||||
(*sche_proc[proc_type])(nactorx, play);
|
||||
}
|
||||
|
||||
static void aNPC_special_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
(*nactorx->schedule.schedule_proc)(nactorx, play, proc_type);
|
||||
}
|
||||
|
||||
static aNPC_SCHEDULE_PROC aNPC_sche_proc[] = {
|
||||
&aNPC_field_schedule_proc,
|
||||
&aNPC_in_house_schedule_proc,
|
||||
&aNPC_sleep_schedule_proc,
|
||||
&aNPC_stand_schedule_proc,
|
||||
&aNPC_wander_schedule_proc,
|
||||
&aNPC_wander_schedule_proc,
|
||||
&aNPC_special_schedule_proc,
|
||||
};
|
||||
|
||||
static void aNPC_schedule_init(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
int type = nactorx->schedule.type;
|
||||
|
||||
(*aNPC_sche_proc[type])(nactorx, play, aNPC_SCHEDULE_PROC_INIT);
|
||||
}
|
||||
|
||||
static void aNPC_chg_schedule(NPC_ACTOR* nactorx, GAME_PLAY* play, u8 type) {
|
||||
nactorx->schedule.type = type;
|
||||
aNPC_schedule_init(nactorx, play);
|
||||
}
|
||||
|
||||
static void aNPC_set_schedule(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
aNPC_chg_schedule(nactorx, play, nactorx->npc_info.schedule->current_type);
|
||||
}
|
||||
|
||||
static void aNPC_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
int type = nactorx->schedule.type;
|
||||
|
||||
if (type != aNPC_SCHEDULE_NONE) {
|
||||
(*aNPC_sche_proc[type])(nactorx, play, aNPC_SCHEDULE_PROC_MAIN);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_first_set_schedule(NPC_ACTOR* nactorx) {
|
||||
mNPS_schedule_c* sched_p = mNPS_get_schedule_area(&aNPC_GET_ANM(nactorx)->id);
|
||||
|
||||
if (sched_p == NULL) {
|
||||
sched_p = &nactorx->schedule.schedule;
|
||||
sched_p->current_type = mNPS_SCHED_WANDER;
|
||||
nactorx->schedule.type = aNPC_SCHEDULE_TYPE_WANDER;
|
||||
} else {
|
||||
nactorx->schedule.type = sched_p->current_type;
|
||||
}
|
||||
|
||||
nactorx->npc_info.schedule = sched_p;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
enum {
|
||||
aNPC_SCHEDULE_FIELD_STEP_OUT_OF_ROOM,
|
||||
aNPC_SCHEDULE_FIELD_STEP_EXIT_WAIT,
|
||||
aNPC_SCHEDULE_FIELD_STEP_HIDE,
|
||||
|
||||
aNPC_SCHEDULE_FIELD_STEP_NUM
|
||||
};
|
||||
|
||||
static void aNPC_field_schedule_think_init(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
static int think_idx[] = { aNPC_THINK_OUT_OF_ROOM, aNPC_THINK_EXIT_WAIT, aNPC_THINK_WAIT };
|
||||
|
||||
aNPC_think_init_proc(nactorx, play, think_idx[nactorx->schedule.step]);
|
||||
}
|
||||
|
||||
static void aNPC_field_schedule_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
aNPC_think_main_proc(nactorx, play);
|
||||
|
||||
if (nactorx->think.end_flag == TRUE) {
|
||||
nactorx->schedule.step++;
|
||||
if (nactorx->schedule.step > aNPC_SCHEDULE_FIELD_STEP_HIDE) {
|
||||
nactorx->schedule.step = aNPC_SCHEDULE_FIELD_STEP_HIDE;
|
||||
}
|
||||
|
||||
aNPC_field_schedule_think_init(nactorx, play);
|
||||
} else if (nactorx->schedule.step == aNPC_SCHEDULE_FIELD_STEP_HIDE) {
|
||||
if (nactorx->schedule.type != nactorx->npc_info.schedule->current_type &&
|
||||
nactorx->condition_info.talk_condition == aNPC_TALK_TYPE_NONE) {
|
||||
aNPC_set_schedule(nactorx, play);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_field_schedule_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
u8 step = aNPC_SCHEDULE_FIELD_STEP_OUT_OF_ROOM;
|
||||
u8 hide = FALSE;
|
||||
|
||||
if (!aNPC_GET_ANM(nactorx)->is_home) {
|
||||
step = aNPC_SCHEDULE_FIELD_STEP_HIDE;
|
||||
hide = TRUE;
|
||||
nactorx->actor_class.world.position.x = 0.0f;
|
||||
nactorx->actor_class.world.position.z = 0.0f;
|
||||
}
|
||||
|
||||
aNPC_set_hide_flg(nactorx, hide);
|
||||
nactorx->schedule.step = step;
|
||||
aNPC_field_schedule_think_init(nactorx, play);
|
||||
}
|
||||
|
||||
static void aNPC_field_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
static aNPC_SUB_PROC sche_proc[] = {
|
||||
&aNPC_field_schedule_init_proc,
|
||||
&aNPC_field_schedule_main_proc,
|
||||
};
|
||||
|
||||
(*sche_proc[proc_type])(nactorx, play);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
enum {
|
||||
aNPC_SCHEDULE_IN_HOUSE_STEP_HIDE,
|
||||
aNPC_SCHEDULE_IN_HOUSE_STEP_INTO_ROOM,
|
||||
aNPC_SCHEDULE_IN_HOUSE_STEP_WANDER,
|
||||
|
||||
aNPC_SCHEDULE_IN_HOUSE_STEP_NUM
|
||||
};
|
||||
|
||||
static void aNPC_in_house_schedule_think_init(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
static int think_idx[] = { aNPC_THINK_HIDE, aNPC_THINK_INTO_ROOM, aNPC_THINK_WANDER };
|
||||
|
||||
aNPC_think_init_proc(nactorx, play, think_idx[nactorx->schedule.step]);
|
||||
}
|
||||
|
||||
static void aNPC_in_house_schedule_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
aNPC_think_main_proc(nactorx, play);
|
||||
|
||||
if (nactorx->think.end_flag == TRUE) {
|
||||
nactorx->schedule.step++;
|
||||
aNPC_in_house_schedule_think_init(nactorx, play);
|
||||
} else {
|
||||
u8 type = (u32)nactorx->npc_info.schedule->current_type;
|
||||
|
||||
if (nactorx->schedule.type != type) {
|
||||
if (type != mNPS_SCHED_SLEEP &&
|
||||
nactorx->condition_info.talk_condition == aNPC_TALK_TYPE_NONE) {
|
||||
aNPC_set_schedule(nactorx, play);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_in_house_schedule_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
u8 step = aNPC_SCHEDULE_IN_HOUSE_STEP_WANDER;
|
||||
u8 hide = FALSE;
|
||||
|
||||
if (!aNPC_GET_ANM(nactorx)->is_home && aNPC_IS_NRM_NPC(nactorx)) {
|
||||
step = aNPC_SCHEDULE_IN_HOUSE_STEP_HIDE;
|
||||
hide = TRUE;
|
||||
nactorx->actor_class.world.position.x = 0.0f;
|
||||
nactorx->actor_class.world.position.z = 0.0f;
|
||||
}
|
||||
|
||||
aNPC_set_hide_flg(nactorx, hide);
|
||||
nactorx->schedule.step = step;
|
||||
aNPC_in_house_schedule_think_init(nactorx, play);
|
||||
}
|
||||
|
||||
static void aNPC_in_house_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
static aNPC_SUB_PROC sche_proc[] = {
|
||||
&aNPC_in_house_schedule_init_proc,
|
||||
&aNPC_in_house_schedule_main_proc,
|
||||
};
|
||||
|
||||
(*sche_proc[proc_type])(nactorx, play);
|
||||
}
|
||||
@@ -0,0 +1,853 @@
|
||||
static void aNPC_chg_entrance_fg(mActor_name_t fg) {
|
||||
mActor_name_t* fg_p = mFI_UtNum2UtFG(3, 8);
|
||||
fg_p[0] = fg;
|
||||
fg_p[1] = fg;
|
||||
}
|
||||
|
||||
static int aNPC_check_uzai_cross(NPC_ACTOR* nactorx) {
|
||||
int ret = FALSE;
|
||||
|
||||
if (ClObj_DID_COLLIDE(nactorx->collision.pipe.collision_obj)) {
|
||||
ACTOR* collide_actor = nactorx->collision.pipe.collision_obj.collided_actor;
|
||||
|
||||
if (collide_actor->part == ACTOR_PART_PLAYER && !F32_IS_ZERO(gamePT->mcon.adjusted_pR)) {
|
||||
// @BUG - this should access x and not z
|
||||
#ifndef BUGFIXES
|
||||
f32 dx = nactorx->actor_class.world.position.z - collide_actor->world.position.x;
|
||||
#else
|
||||
f32 dx = nactorx->actor_class.world.position.x - collide_actor->world.position.x;
|
||||
#endif
|
||||
f32 dz = nactorx->actor_class.world.position.z - collide_actor->world.position.z;
|
||||
s16 angleY = atans_table(dz, dx);
|
||||
s16 d_angleY = angleY - collide_actor->world.angle.y;
|
||||
|
||||
if (ABS(d_angleY) < DEG2SHORT_ANGLE2(135.0f)) {
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void aNPC_check_uzai(NPC_ACTOR* nactorx) {
|
||||
static int max_uzai_cross[] = { 600, 240 };
|
||||
static int max_uzai_tool[] = { 3, 1 };
|
||||
// clang-format off
|
||||
static int base_msg_no_table[][mNpc_LOOKS_NUM] = {
|
||||
{
|
||||
0x2E11,
|
||||
0x2E1C,
|
||||
0x2E0C,
|
||||
0x2E27,
|
||||
0x2E2C,
|
||||
0x2E37,
|
||||
},
|
||||
{
|
||||
0x3579,
|
||||
0x357C,
|
||||
0x357F,
|
||||
0x3582,
|
||||
0x3585,
|
||||
0x3588,
|
||||
},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
if (aNPC_IS_NRM_NPC(nactorx)) {
|
||||
int mem_idx =
|
||||
mNpc_GetAnimalMemoryIdx(&Now_Private->player_ID, nactorx->npc_info.animal->memories, ANIMAL_MEMORY_NUM);
|
||||
|
||||
if (mem_idx != -1 && (nactorx->condition_info.demo_flg & aNPC_COND_DEMO_SKIP_LOVE_CHECK) == 0) {
|
||||
int step = nactorx->uzai.step;
|
||||
|
||||
if (aNPC_check_uzai_cross(nactorx) == TRUE) {
|
||||
step += 2;
|
||||
} else {
|
||||
step -= 1;
|
||||
}
|
||||
|
||||
if (step > max_uzai_cross[nactorx->uzai.cross == 1] ||
|
||||
nactorx->uzai.tool == max_uzai_tool[nactorx->uzai.cross == 1]) {
|
||||
Animal_c* animal = nactorx->npc_info.animal;
|
||||
int msg_no;
|
||||
f32 msg_max = 5;
|
||||
int pushed = FALSE;
|
||||
int islander = FALSE;
|
||||
|
||||
if (mNpc_CheckIslandAnimal(animal) == TRUE) {
|
||||
msg_max = 3;
|
||||
islander = TRUE;
|
||||
}
|
||||
|
||||
mISL_SetNowPlayerAction(mISL_PLAYER_ACTION_UZAI_PUSHED);
|
||||
msg_no = base_msg_no_table[islander][animal->id.looks];
|
||||
if (aNPC_force_call_req_proc(nactorx, msg_no + (int)RANDOM_F(msg_max)) == TRUE) {
|
||||
nactorx->uzai.tool = 0;
|
||||
nactorx->uzai.cross = 1;
|
||||
step = 0;
|
||||
aNPC_set_feel_info(nactorx, aNPC_uzai_feel[mNpc_GetNpcLooks((ACTOR*)nactorx)], 1);
|
||||
nactorx->think.force_call_camera_type = CAMERA2_PROCESS_TALK;
|
||||
nactorx->uzai.flag = 0;
|
||||
}
|
||||
} else {
|
||||
if (step < 0) {
|
||||
step = 0;
|
||||
}
|
||||
|
||||
nactorx->uzai.flag = 0;
|
||||
}
|
||||
|
||||
nactorx->uzai.step = step;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int aNPC_chk_talk_start(NPC_ACTOR* nactorx) {
|
||||
ACTOR* palActor = nactorx->palActor;
|
||||
int ret = FALSE;
|
||||
|
||||
if (palActor != NULL) {
|
||||
switch (nactorx->condition_info.talk_condition) {
|
||||
case aNPC_TALK_TYPE_START:
|
||||
aNPC_set_request_act(nactorx, 4, nactorx->talk_info.default_act, aNPC_ACT_TYPE_DEFAULT,
|
||||
aNPC_req_default_data);
|
||||
ret = TRUE;
|
||||
break;
|
||||
case aNPC_TALK_TYPE_CONTINUE:
|
||||
if (aNPC_chk_right_hand(nactorx) == TRUE) {
|
||||
aNPC_chk_left_hand(nactorx);
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_check_fatigue(NPC_ACTOR* nactorx) {
|
||||
int ret = FALSE;
|
||||
|
||||
if (aNPC_IS_NRM_NPC(nactorx)) {
|
||||
switch (nactorx->action.type) {
|
||||
case aNPC_ACT_TYPE_DEFAULT:
|
||||
case aNPC_ACT_TYPE_TO_POINT:
|
||||
if ((nactorx->think.interrupt_flags & aNPC_THINK_INTERRUPT_FATIGUE) != 0 &&
|
||||
nactorx->condition_info.fatigue >= 1600) {
|
||||
ret = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_drt_table[4] = {
|
||||
aNPC_UNIT_DOWN,
|
||||
aNPC_UNIT_RIGHT,
|
||||
aNPC_UNIT_UP,
|
||||
aNPC_UNIT_LEFT,
|
||||
};
|
||||
|
||||
static int aNPC_back_drt_table[5] = {
|
||||
aNPC_UNIT_LEFT, aNPC_UNIT_RIGHT, aNPC_UNIT_UP, 0, aNPC_UNIT_DOWN,
|
||||
};
|
||||
|
||||
static int aNPC_left_drt_table[5] = {
|
||||
aNPC_UNIT_UP, aNPC_UNIT_DOWN, aNPC_UNIT_RIGHT, 0, aNPC_UNIT_LEFT,
|
||||
};
|
||||
|
||||
static int aNPC_right_drt_table[5] = {
|
||||
aNPC_UNIT_DOWN, aNPC_UNIT_UP, aNPC_UNIT_LEFT, 0, aNPC_UNIT_RIGHT,
|
||||
};
|
||||
|
||||
static int aNPC_pl_chk_drt_table[4] = {
|
||||
aNPC_UNIT_UP,
|
||||
aNPC_UNIT_DOWN,
|
||||
aNPC_UNIT_LEFT,
|
||||
aNPC_UNIT_RIGHT,
|
||||
};
|
||||
|
||||
static int aNPC_add_numX[5] = {
|
||||
1, -1, 0, 0, 0,
|
||||
};
|
||||
|
||||
static int aNPC_add_numZ[5] = {
|
||||
0, 0, 1, 0, -1,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
aNPC_unit_info_c unit_info;
|
||||
int unit;
|
||||
int move_dir;
|
||||
} aNPC_route_work_c;
|
||||
|
||||
typedef struct {
|
||||
aNPC_route_work_c work[aNPC2_UNIT_NUM];
|
||||
int n_work;
|
||||
u8 _34C[aNPC2_UNIT_NUM];
|
||||
int* unit_info_p;
|
||||
u8 dst_ux;
|
||||
u8 dst_uz;
|
||||
s8 dx;
|
||||
s8 dz;
|
||||
u8 now_ux;
|
||||
u8 now_uz;
|
||||
u8 now_dir;
|
||||
u8 now_idx;
|
||||
int* now_unit_p;
|
||||
aNPC_route_work_c* now_work_p;
|
||||
u8 first;
|
||||
u8 initial_lookup;
|
||||
u8 player_ux;
|
||||
u8 player_uz;
|
||||
int calc_dx;
|
||||
int calc_dz;
|
||||
} aNPC_route_search_table_c;
|
||||
|
||||
static aNPC_route_search_table_c tbl;
|
||||
|
||||
static int aNPC_think_turn_this_unit(void) {
|
||||
int ret = FALSE;
|
||||
|
||||
tbl.dx = tbl.dst_ux - tbl.now_ux;
|
||||
tbl.dz = tbl.dst_uz - tbl.now_uz;
|
||||
|
||||
if (tbl.now_dir == aNPC_UNIT_UP || tbl.now_dir == aNPC_UNIT_DOWN) {
|
||||
if (tbl.dx != 0) {
|
||||
if (ABS(tbl.dx) > ABS(tbl.dz)) {
|
||||
if (tbl.dx < 0) {
|
||||
if ((*tbl.now_unit_p) & aNPC_UNIT_LEFT) {
|
||||
tbl.now_dir = aNPC_UNIT_LEFT;
|
||||
ret = TRUE;
|
||||
}
|
||||
} else {
|
||||
if ((*tbl.now_unit_p) & aNPC_UNIT_RIGHT) {
|
||||
tbl.now_dir = aNPC_UNIT_RIGHT;
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (tbl.dz != 0) {
|
||||
if (ABS(tbl.dz) > ABS(tbl.dx)) {
|
||||
if (tbl.dz < 0) {
|
||||
if ((*tbl.now_unit_p) & aNPC_UNIT_UP) {
|
||||
tbl.now_dir = aNPC_UNIT_UP;
|
||||
ret = TRUE;
|
||||
}
|
||||
} else {
|
||||
if ((*tbl.now_unit_p) & aNPC_UNIT_DOWN) {
|
||||
tbl.now_dir = aNPC_UNIT_DOWN;
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_decide_turn_this_unit(void) {
|
||||
int ret = FALSE;
|
||||
|
||||
if (((*tbl.now_unit_p) & aNPC_left_drt_table[tbl.now_dir >> 1]) != 0) {
|
||||
tbl.now_dir = aNPC_left_drt_table[tbl.now_dir >> 1];
|
||||
} else if (((*tbl.now_unit_p) & aNPC_right_drt_table[tbl.now_dir >> 1]) != 0) {
|
||||
tbl.now_dir = aNPC_right_drt_table[tbl.now_dir >> 1];
|
||||
} else {
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_forward_search_turn_point(void) {
|
||||
if (tbl.n_work >= aNPC2_UNIT_NUM) {
|
||||
tbl.n_work = -1;
|
||||
return aNPC_SEARCH_ROUTE_CANCEL;
|
||||
}
|
||||
|
||||
if (!tbl.first) {
|
||||
tbl.now_work_p = tbl.work + (tbl.n_work + 1);
|
||||
tbl.n_work++;
|
||||
tbl.now_work_p->unit_info.x = tbl.now_ux + aNPC_add_numX[tbl.now_dir >> 1];
|
||||
tbl.now_work_p->unit_info.z = tbl.now_uz + aNPC_add_numZ[tbl.now_dir >> 1];
|
||||
tbl.now_work_p->unit_info.direct = tbl.now_dir;
|
||||
tbl.now_work_p->move_dir = tbl.now_dir;
|
||||
} else {
|
||||
tbl.now_work_p = tbl.work + tbl.n_work;
|
||||
tbl.first = FALSE;
|
||||
}
|
||||
|
||||
tbl.now_ux = tbl.now_work_p->unit_info.x;
|
||||
tbl.now_uz = tbl.now_work_p->unit_info.z;
|
||||
tbl.now_dir = tbl.now_work_p->unit_info.direct;
|
||||
tbl.now_idx = tbl.now_ux + tbl.now_uz * aNPC2_UNIT_X_NUM;
|
||||
tbl.now_unit_p = &tbl.now_work_p->unit;
|
||||
|
||||
if (!tbl.initial_lookup) {
|
||||
*tbl.now_unit_p = tbl.unit_info_p[tbl.now_idx];
|
||||
}
|
||||
|
||||
tbl.initial_lookup = FALSE;
|
||||
tbl.calc_dx = tbl.player_ux - tbl.now_ux;
|
||||
tbl.calc_dz = tbl.player_uz - tbl.now_uz;
|
||||
|
||||
if (ABS((int)tbl.calc_dx) + ABS((int)tbl.calc_dz) == 1) {
|
||||
(*tbl.now_unit_p) &= aNPC_pl_chk_drt_table[ABS((int)tbl.calc_dx) * 2 + (((int)tbl.calc_dx + 1) >> 1) +
|
||||
(((int)tbl.calc_dz + 1) >> 1)] ^
|
||||
aNPC_UNIT_ALL;
|
||||
}
|
||||
|
||||
if (*tbl.now_unit_p == 0) {
|
||||
tbl.n_work = -1;
|
||||
return aNPC_SEARCH_ROUTE_CANCEL;
|
||||
}
|
||||
|
||||
if (tbl.now_ux == tbl.dst_ux && tbl.now_uz == tbl.dst_uz) {
|
||||
return aNPC_SEARCH_ROUTE_CANCEL;
|
||||
}
|
||||
|
||||
if (tbl._34C[tbl.now_idx] == TRUE) {
|
||||
return aNPC_SEARCH_ROUTE_BACKWARD;
|
||||
}
|
||||
|
||||
if (!aNPC_think_turn_this_unit() && ((*tbl.now_unit_p) & tbl.now_dir) == 0 &&
|
||||
aNPC_decide_turn_this_unit() == TRUE) {
|
||||
return aNPC_SEARCH_ROUTE_BACKWARD;
|
||||
}
|
||||
|
||||
tbl._34C[tbl.now_idx] = TRUE;
|
||||
tbl.now_work_p->unit_info.direct = tbl.now_dir;
|
||||
(*tbl.now_unit_p) &= tbl.now_dir ^ aNPC_UNIT_ALL;
|
||||
return aNPC_SEARCH_ROUTE_FORWARD;
|
||||
}
|
||||
|
||||
static int aNPC_back_search_turn_point(void) {
|
||||
int unit;
|
||||
int back_dir;
|
||||
int i;
|
||||
|
||||
tbl.initial_lookup = TRUE;
|
||||
if (tbl.n_work == 0) {
|
||||
if (((*tbl.now_unit_p) & aNPC_back_drt_table[tbl.now_dir >> 1]) == 0) {
|
||||
if (((*tbl.now_unit_p) & aNPC_left_drt_table[tbl.now_dir >> 1]) == 0) {
|
||||
if (((*tbl.now_unit_p) & aNPC_right_drt_table[tbl.now_dir >> 1]) == 0) {
|
||||
tbl.n_work = -1;
|
||||
return aNPC_SEARCH_ROUTE_CANCEL;
|
||||
} else {
|
||||
tbl.now_work_p->unit_info.direct = aNPC_right_drt_table[tbl.now_dir >> 1];
|
||||
}
|
||||
} else {
|
||||
tbl.now_work_p->unit_info.direct = aNPC_left_drt_table[tbl.now_dir >> 1];
|
||||
}
|
||||
} else {
|
||||
tbl.now_work_p->unit_info.direct = aNPC_back_drt_table[tbl.now_dir >> 1];
|
||||
}
|
||||
|
||||
tbl.first = TRUE;
|
||||
return aNPC_SEARCH_ROUTE_FORWARD;
|
||||
}
|
||||
|
||||
tbl.now_work_p = &tbl.work[--tbl.n_work];
|
||||
tbl.now_ux = tbl.now_work_p->unit_info.x;
|
||||
tbl.now_uz = tbl.now_work_p->unit_info.z;
|
||||
tbl.now_dir = tbl.now_work_p->unit_info.direct;
|
||||
tbl.now_idx = tbl.now_ux + tbl.now_uz * aNPC2_UNIT_X_NUM;
|
||||
tbl.now_unit_p = &tbl.now_work_p->unit;
|
||||
|
||||
(*tbl.now_unit_p) &= ((u8)tbl.now_work_p->unit_info.direct ^ aNPC_UNIT_ALL);
|
||||
|
||||
if ((*tbl.now_unit_p) == 0) {
|
||||
tbl.n_work = -1;
|
||||
return aNPC_SEARCH_ROUTE_CANCEL;
|
||||
}
|
||||
|
||||
unit = *tbl.now_unit_p;
|
||||
back_dir = aNPC_back_drt_table[tbl.now_work_p->move_dir >> 1];
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (unit & (1 << 3)) {
|
||||
if (back_dir != aNPC_pl_chk_drt_table[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unit <<= 1;
|
||||
}
|
||||
|
||||
if (i == 4) {
|
||||
tbl._34C[tbl.now_idx] = FALSE;
|
||||
return aNPC_SEARCH_ROUTE_BACKWARD;
|
||||
}
|
||||
|
||||
tbl.now_dir = aNPC_pl_chk_drt_table[i];
|
||||
tbl.now_work_p->unit_info.direct = (u8)aNPC_pl_chk_drt_table[i];
|
||||
tbl.initial_lookup = FALSE;
|
||||
return aNPC_SEARCH_ROUTE_FORWARD;
|
||||
}
|
||||
|
||||
static void aNPC_copy_route(NPC_CONTROL_ACTOR* ctrl, aNPC_route_search_table_c* search, int n) {
|
||||
aNPC_unit_info_c* route = ctrl->route;
|
||||
int dir;
|
||||
int dir_flag;
|
||||
int i;
|
||||
int node_count;
|
||||
|
||||
route->x = search->work[1].unit_info.x;
|
||||
route->z = search->work[1].unit_info.z;
|
||||
dir = search->work[0].unit_info.direct;
|
||||
route->direct = dir;
|
||||
route++;
|
||||
|
||||
dir_flag = FALSE;
|
||||
for (i = 1, node_count = 1; i <= n; i++) {
|
||||
if (dir != search->work[i].unit_info.direct) {
|
||||
if (dir_flag == TRUE) {
|
||||
node_count++;
|
||||
route->x = search->work[i].unit_info.x;
|
||||
route->z = search->work[i].unit_info.z;
|
||||
route->direct = dir;
|
||||
route++;
|
||||
}
|
||||
|
||||
dir_flag = FALSE;
|
||||
node_count++;
|
||||
route->x = search->work[i + 1].unit_info.x;
|
||||
route->z = search->work[i + 1].unit_info.z;
|
||||
route->direct = search->work[i].unit_info.direct;
|
||||
route++;
|
||||
|
||||
dir = search->work[i].unit_info.direct;
|
||||
} else {
|
||||
dir_flag = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
route->x = search->work[n].unit_info.x;
|
||||
route->z = search->work[n].unit_info.z;
|
||||
route->direct = search->work[n].unit_info.direct;
|
||||
ctrl->route_node_count = node_count;
|
||||
}
|
||||
|
||||
typedef int (*aNPC_SEARCH_ROUTE_PROC)(void);
|
||||
|
||||
static int aNPC_route_check(NPC_ACTOR* nactorx, GAME_PLAY* play, int dst_ux, int dst_uz, int turn_flag) {
|
||||
static aNPC_SEARCH_ROUTE_PROC search_route_proc[] = {
|
||||
&aNPC_forward_search_turn_point,
|
||||
&aNPC_back_search_turn_point,
|
||||
};
|
||||
|
||||
int ret = aNPC_ROUTE_ERROR;
|
||||
|
||||
if (nactorx->movement.movement_ut_x != dst_ux || nactorx->movement.movement_ut_z != dst_uz || turn_flag == TRUE) {
|
||||
NPC_CONTROL_ACTOR* ctrl = (NPC_CONTROL_ACTOR*)aNPC_ctrlActor;
|
||||
int* unit_info_p = (int*)ctrl->unit_info;
|
||||
int dir;
|
||||
int ux;
|
||||
int uz;
|
||||
int turn_unit_info = 0;
|
||||
|
||||
dir = aNPC_drt_table[((nactorx->actor_class.world.angle.y + DEG2SHORT_ANGLE2(45.0f)) >> 14) &
|
||||
3]; // >> 14 = / DEG2SHORT_ANGLE2(90.0f) [0x4000]
|
||||
bzero(&tbl, sizeof(tbl));
|
||||
mFI_Wpos2UtNum(&ux, &uz, nactorx->actor_class.world.position);
|
||||
ux--;
|
||||
uz--;
|
||||
|
||||
tbl.work[0].unit_info.x = ux;
|
||||
tbl.work[0].unit_info.z = uz;
|
||||
tbl.work[0].unit_info.direct = dir;
|
||||
tbl.unit_info_p = unit_info_p;
|
||||
tbl.dst_ux = dst_ux;
|
||||
tbl.dst_uz = dst_uz;
|
||||
tbl.first = TRUE;
|
||||
tbl.initial_lookup = FALSE;
|
||||
|
||||
{
|
||||
ACTOR* playerx = GET_PLAYER_ACTOR_ACTOR(play);
|
||||
|
||||
if (playerx == NULL) {
|
||||
tbl.player_ux = 0xFF;
|
||||
tbl.player_uz = 0xFF;
|
||||
} else {
|
||||
mFI_Wpos2UtNum(&ux, &uz, playerx->world.position);
|
||||
ux--;
|
||||
uz--;
|
||||
tbl.player_ux = ux;
|
||||
tbl.player_uz = uz;
|
||||
}
|
||||
}
|
||||
|
||||
if (turn_flag == TRUE) {
|
||||
turn_unit_info = dir & *(unit_info_p + ux + uz * aNPC2_UNIT_X_NUM);
|
||||
*(unit_info_p + ux + uz * aNPC2_UNIT_X_NUM) &= dir ^ aNPC_UNIT_ALL;
|
||||
}
|
||||
|
||||
{
|
||||
int res = aNPC_SEARCH_ROUTE_FORWARD;
|
||||
int count = 0;
|
||||
|
||||
while (TRUE) {
|
||||
res = (*search_route_proc[res])();
|
||||
if (res == aNPC_SEARCH_ROUTE_CANCEL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (count > (aNPC2_UNIT_X_NUM * (aNPC2_UNIT_Z_NUM - 1))) {
|
||||
tbl.n_work = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (tbl.n_work < 0) {
|
||||
ret = aNPC_ROUTE_ERROR;
|
||||
} else if (tbl.n_work == 0) {
|
||||
ret = aNPC_ROUTE_FINISH;
|
||||
} else {
|
||||
aNPC_unit_info_c* route;
|
||||
f32 pos_x;
|
||||
f32 pos_z;
|
||||
|
||||
nactorx->movement.movement_ut_x = dst_ux;
|
||||
nactorx->movement.movement_ut_z = dst_uz;
|
||||
aNPC_copy_route(ctrl, &tbl, tbl.n_work);
|
||||
if (dst_uz == (aNPC2_UNIT_Z_NUM - 1)) {
|
||||
pos_x = 160.0f;
|
||||
pos_z = 300.0f;
|
||||
} else {
|
||||
pos_x = (dst_ux + 1) * mFI_UT_WORLDSIZE_X_F;
|
||||
pos_z = (dst_uz + 1) * mFI_UT_WORLDSIZE_Z_F;
|
||||
}
|
||||
|
||||
aNPC_set_dst_pos(nactorx, pos_x, pos_z);
|
||||
nactorx->movement.avoid_direction = 1;
|
||||
|
||||
ctrl = (NPC_CONTROL_ACTOR*)aNPC_ctrlActor;
|
||||
route = ctrl->route;
|
||||
pos_x = (route[0].x + 1.5f) * mFI_UT_WORLDSIZE_X_F;
|
||||
pos_z = (route[0].z + 1.5f) * mFI_UT_WORLDSIZE_Z_F;
|
||||
aNPC_set_avoid_pos(nactorx, pos_x, pos_z);
|
||||
ret = aNPC_ROUTE_MOVING;
|
||||
}
|
||||
|
||||
if (turn_flag == TRUE) {
|
||||
*(unit_info_p + ux + uz * aNPC2_UNIT_X_NUM) |= turn_unit_info;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void aNPC_turn_to_another_route(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
u16 arg_data[aNPC_REQUEST_ARG_NUM];
|
||||
u8 act_idx = aNPC_ACT_WAIT;
|
||||
|
||||
bzero(arg_data, sizeof(arg_data));
|
||||
if (aNPC_route_check(nactorx, play, nactorx->movement.movement_ut_x, nactorx->movement.movement_ut_z, TRUE) ==
|
||||
aNPC_ROUTE_MOVING) {
|
||||
act_idx = aNPC_ACT_TURN;
|
||||
arg_data[2] = (int)nactorx->movement.avoid_pos_x;
|
||||
arg_data[3] = (int)nactorx->movement.avoid_pos_z;
|
||||
}
|
||||
|
||||
aNPC_set_request_act(nactorx, 1, act_idx, aNPC_ACT_TYPE_DEFAULT, arg_data);
|
||||
}
|
||||
|
||||
static int aNPC_avoid_obstacle(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
int ret = FALSE;
|
||||
|
||||
if ((nactorx->think.interrupt_flags & aNPC_THINK_INTERRUPT_OBSTACLE) != 0) {
|
||||
if (ClObj_DID_COLLIDE(nactorx->collision.pipe.collision_obj)) {
|
||||
if ((nactorx->collision.pipe.collision_obj.collision_flags1 & 1)) {
|
||||
s16 d_angle = nactorx->actor_class.player_angle_y - nactorx->actor_class.shape_info.rotation.y;
|
||||
|
||||
if (ABS(d_angle) < DEG2SHORT_ANGLE2(45.0f)) {
|
||||
aNPC_turn_to_another_route(nactorx, play);
|
||||
} else {
|
||||
aNPC_set_request_act(nactorx, 1, aNPC_ACT_WAIT, aNPC_ACT_TYPE_DEFAULT, aNPC_req_default_data);
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_hate_player(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
ACTOR* playerx = GET_PLAYER_ACTOR_ACTOR(play);
|
||||
u16 arg_data[aNPC_REQUEST_ARG_NUM];
|
||||
u8 act_idx;
|
||||
|
||||
bzero(arg_data, sizeof(arg_data));
|
||||
arg_data[0] = aNPC_ACT_OBJ_PLAYER;
|
||||
|
||||
if (playerx == NULL) {
|
||||
act_idx = aNPC_ACT_WAIT;
|
||||
} else {
|
||||
NPC_CONTROL_ACTOR* ctrl = (NPC_CONTROL_ACTOR*)aNPC_ctrlActor;
|
||||
int safe_ux;
|
||||
int safe_uz;
|
||||
int player_ux;
|
||||
int player_uz;
|
||||
int idx;
|
||||
|
||||
mFI_Wpos2UtNum(&player_ux, &player_uz, playerx->world.position);
|
||||
player_ux--;
|
||||
player_uz--;
|
||||
|
||||
idx = (player_uz < 3) + (player_ux < 3) * 2;
|
||||
safe_ux = ctrl->safe_ux[idx];
|
||||
safe_uz = ctrl->safe_uz[idx];
|
||||
|
||||
if (nactorx->movement.movement_ut_x == safe_ux && nactorx->movement.movement_ut_z == safe_uz) {
|
||||
if (nactorx->action.step == aNPC_ACTION_END_STEP) {
|
||||
if (nactorx->action.idx == aNPC_ACT_TURN) {
|
||||
act_idx = aNPC_ACT_WALK;
|
||||
arg_data[2] = (int)nactorx->movement.avoid_pos_x;
|
||||
arg_data[3] = (int)nactorx->movement.avoid_pos_z;
|
||||
} else {
|
||||
act_idx = aNPC_ACT_WAIT;
|
||||
}
|
||||
} else {
|
||||
act_idx = nactorx->action.idx;
|
||||
}
|
||||
} else {
|
||||
if (aNPC_route_check(nactorx, play, safe_ux, safe_uz, FALSE) == aNPC_ROUTE_MOVING) {
|
||||
aNPC_unit_info_c* route = ctrl->route;
|
||||
int dir = route[0].direct;
|
||||
|
||||
if (dir !=
|
||||
aNPC_drt_table[(((nactorx->actor_class.world.angle.y + DEG2SHORT_ANGLE2(45.0f)) >> 14) & 3)]) {
|
||||
act_idx = aNPC_ACT_TURN;
|
||||
} else {
|
||||
act_idx = aNPC_ACT_WALK;
|
||||
}
|
||||
|
||||
arg_data[2] = (int)nactorx->movement.avoid_pos_x;
|
||||
arg_data[3] = (int)nactorx->movement.avoid_pos_z;
|
||||
} else {
|
||||
act_idx = aNPC_ACT_WAIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return aNPC_set_request_act(nactorx, 1, act_idx, aNPC_ACT_TYPE_AVOID, arg_data);
|
||||
}
|
||||
|
||||
static int aNPC_love_player(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
int ret = FALSE;
|
||||
|
||||
if (Now_Private->gender != mNpc_GetLooks2Sex(aNPC_GET_LOOKS(nactorx))) {
|
||||
NPC_CONTROL_ACTOR* ctrl = (NPC_CONTROL_ACTOR*)aNPC_ctrlActor;
|
||||
ACTOR* playerx = GET_PLAYER_ACTOR_ACTOR(play);
|
||||
u8 next_act = aNPC_ACT_WAIT;
|
||||
u16 arg_data[aNPC_REQUEST_ARG_NUM];
|
||||
|
||||
bzero(arg_data, sizeof(arg_data));
|
||||
arg_data[0] = aNPC_ACT_OBJ_PLAYER;
|
||||
if (nactorx->think.force_call_flag == aNPC_FORCE_CALL_NONE && nactorx->think.force_call_timer == 0) {
|
||||
nactorx->think.force_call_flag = aNPC_FORCE_CALL_REQUEST;
|
||||
}
|
||||
|
||||
if (playerx != NULL) {
|
||||
int player_ux;
|
||||
int player_uz;
|
||||
|
||||
mFI_Wpos2UtNum(&player_ux, &player_uz, playerx->world.position);
|
||||
player_ux--;
|
||||
player_uz--;
|
||||
|
||||
if (nactorx->movement.movement_ut_x == player_ux && nactorx->movement.movement_ut_z == player_uz) {
|
||||
if (nactorx->action.step == aNPC_ACTION_END_STEP && nactorx->action.idx == aNPC_ACT_TURN) {
|
||||
next_act = aNPC_ACT_WALK;
|
||||
arg_data[2] = (int)nactorx->movement.avoid_pos_x;
|
||||
arg_data[3] = (int)nactorx->movement.avoid_pos_z;
|
||||
}
|
||||
} else if (aNPC_route_check(nactorx, play, player_ux, player_uz, FALSE) == aNPC_ROUTE_MOVING) {
|
||||
aNPC_unit_info_c* route = ctrl->route;
|
||||
int dir = route[0].direct;
|
||||
|
||||
if (dir !=
|
||||
aNPC_drt_table[(((nactorx->actor_class.world.angle.y + DEG2SHORT_ANGLE2(45.0f)) >> 14) & 3)]) {
|
||||
next_act = aNPC_ACT_TURN;
|
||||
} else {
|
||||
next_act = aNPC_ACT_WALK;
|
||||
}
|
||||
|
||||
arg_data[2] = (int)nactorx->movement.avoid_pos_x;
|
||||
arg_data[3] = (int)nactorx->movement.avoid_pos_z;
|
||||
}
|
||||
}
|
||||
|
||||
ret = aNPC_set_request_act(nactorx, 1, next_act, aNPC_ACT_TYPE_AVOID, arg_data);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_chk_friendship_lv(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
int ret = FALSE;
|
||||
int friendship = (*nactorx->condition_info.friendship) + nactorx->condition_info.over_friendship;
|
||||
|
||||
if (friendship < 0) {
|
||||
ret = aNPC_hate_player(nactorx, play);
|
||||
} else if (friendship > 128) {
|
||||
ret = aNPC_love_player(nactorx, play);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_chk_friendship_sub(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
s8* friendship_p = nactorx->condition_info.friendship;
|
||||
int ret = FALSE;
|
||||
|
||||
if (friendship_p == NULL) {
|
||||
if (aNPC_IS_NRM_NPC(nactorx) && aNPC_setP_friendship(nactorx) == TRUE) {
|
||||
ret = aNPC_chk_friendship_lv(nactorx, play);
|
||||
}
|
||||
} else {
|
||||
ret = aNPC_chk_friendship_lv(nactorx, play);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_chk_friendship(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
int ret = FALSE;
|
||||
|
||||
if ((nactorx->think.interrupt_flags & aNPC_THINK_INTERRUPT_FRIENDSHIP) != 0 && !aNPC_IS_SP_NPC(nactorx)) {
|
||||
switch (nactorx->action.idx) {
|
||||
case aNPC_ACT_WAIT:
|
||||
case aNPC_ACT_WALK:
|
||||
case aNPC_ACT_RUN:
|
||||
ret = aNPC_chk_friendship_sub(nactorx, play);
|
||||
break;
|
||||
default:
|
||||
if (nactorx->action.step == aNPC_ACTION_END_STEP) {
|
||||
ret = aNPC_chk_friendship_sub(nactorx, play);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_think_chk_interrupt_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
int ret = FALSE;
|
||||
|
||||
if (aNPC_chk_talk_start(nactorx) == TRUE) {
|
||||
ret = TRUE;
|
||||
} else if (aNPC_chk_right_hand(nactorx) == FALSE) {
|
||||
ret = TRUE;
|
||||
} else if (aNPC_chk_left_hand(nactorx) == FALSE) {
|
||||
ret = TRUE;
|
||||
} else {
|
||||
aNPC_check_uzai(nactorx);
|
||||
if (!F32_IS_ZERO(nactorx->actor_class.speed)) {
|
||||
if (aNPC_check_fatigue(nactorx) == TRUE) {
|
||||
aNPC_set_request_act(nactorx, 1, aNPC_ACT_WAIT, aNPC_ACT_TYPE_DEFAULT, aNPC_req_default_data);
|
||||
ret = TRUE;
|
||||
} else {
|
||||
ret = aNPC_avoid_obstacle(nactorx, play);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == FALSE) {
|
||||
ret = aNPC_chk_friendship(nactorx, play);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void aNPC_think_wait_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
aNPC_set_request_act(nactorx, 1, aNPC_ACT_WAIT, aNPC_ACT_TYPE_DEFAULT, aNPC_req_default_data);
|
||||
}
|
||||
|
||||
static void aNPC_think_wait_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
if (proc_type == aNPC_THINK_PROC_INIT) {
|
||||
aNPC_think_wait_init_proc(nactorx, play);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_think_hide_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
ACTOR* playerx = GET_PLAYER_ACTOR_ACTOR(play);
|
||||
|
||||
if (playerx != NULL && playerx->world.position.z < 270.0f &&
|
||||
mEvNM_CheckJointEvent(nactorx->actor_class.npc_id) == FALSE) {
|
||||
nactorx->think.end_flag = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_think_hide_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
static aNPC_SUB_PROC think_proc[] = {
|
||||
&aNPC_think_wait_init_proc,
|
||||
&aNPC_think_hide_main_proc,
|
||||
};
|
||||
|
||||
(*think_proc[proc_type])(nactorx, play);
|
||||
}
|
||||
|
||||
static void aNPC_think_special_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
(*nactorx->think.think_proc)(nactorx, play, proc_type);
|
||||
}
|
||||
|
||||
#include "../src/actor/npc/ac_npc2_think_wander.c_inc"
|
||||
#include "../src/actor/npc/ac_npc2_think_out_of_room.c_inc"
|
||||
#include "../src/actor/npc/ac_npc2_think_exit_wait.c_inc"
|
||||
#include "../src/actor/npc/ac_npc2_think_into_room.c_inc"
|
||||
|
||||
static aNPC_THINK_PROC aNPC_think_proc_tbl[] = {
|
||||
&aNPC_think_wait_proc,
|
||||
&aNPC_think_hide_proc,
|
||||
&aNPC_think_wander_proc,
|
||||
&aNPC_think_out_of_room_proc,
|
||||
&aNPC_think_exit_wait_proc,
|
||||
&aNPC_think_into_room_proc,
|
||||
&aNPC_think_special_proc,
|
||||
};
|
||||
|
||||
static void aNPC_think_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int think_idx) {
|
||||
nactorx->think.interrupt_flags = aNPC_THINK_INTERRUPT_OBSTACLE |
|
||||
aNPC_THINK_INTERRUPT_FATIGUE | aNPC_THINK_INTERRUPT_FRIENDSHIP;
|
||||
nactorx->think.idx = think_idx;
|
||||
(*aNPC_think_proc_tbl[think_idx])(nactorx, play, aNPC_THINK_PROC_INIT);
|
||||
nactorx->think.end_flag = FALSE;
|
||||
}
|
||||
|
||||
static void aNPC_think_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
int think_idx = nactorx->think.idx;
|
||||
|
||||
(*aNPC_think_proc_tbl[think_idx])(nactorx, play, aNPC_THINK_PROC_MAIN);
|
||||
}
|
||||
|
||||
static int aNPC_think_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int think_idx, int proc_type) {
|
||||
int ret = FALSE;
|
||||
|
||||
switch (proc_type) {
|
||||
case aNPC_THINK_TYPE_INIT:
|
||||
aNPC_think_init_proc(nactorx, play, think_idx);
|
||||
break;
|
||||
case aNPC_THINK_TYPE_CHK_INTERRUPT:
|
||||
ret = aNPC_think_chk_interrupt_proc(nactorx, play);
|
||||
break;
|
||||
case aNPC_THINK_TYPE_MAIN:
|
||||
aNPC_think_main_proc(nactorx, play);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
static void aNPC_think_exit_wait_decide_next_act_idx(NPC_ACTOR* nactorx) {
|
||||
u16 arg_data[aNPC_REQUEST_ARG_NUM];
|
||||
u8 act_idx = aNPC_ACT_WALK;
|
||||
s16 angle = DEG2SHORT_ANGLE2(45.0f);
|
||||
|
||||
bzero(arg_data, sizeof(arg_data));
|
||||
nactorx->condition_info.demo_flg =
|
||||
aNPC_COND_DEMO_SKIP_FEEL_CHECK | aNPC_COND_DEMO_SKIP_ENTRANCE_CHECK | aNPC_COND_DEMO_SKIP_HEAD_LOOKAT |
|
||||
aNPC_COND_DEMO_SKIP_TALK_CHECK | aNPC_COND_DEMO_SKIP_FORWARD_CHECK | aNPC_COND_DEMO_SKIP_BGCHECK |
|
||||
aNPC_COND_DEMO_SKIP_MOVE_Y | aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV | aNPC_COND_DEMO_SKIP_MOVE_RANGE_CHECK;
|
||||
if (nactorx->action.idx == aNPC_ACT_WALK) {
|
||||
nactorx->action.step = 0;
|
||||
angle = DEG2SHORT_ANGLE2(22.5f);
|
||||
}
|
||||
|
||||
if (ABS(nactorx->actor_class.shape_info.rotation.y) > angle) {
|
||||
act_idx = aNPC_ACT_TURN;
|
||||
}
|
||||
|
||||
arg_data[2] = (int)nactorx->actor_class.world.position.x;
|
||||
arg_data[3] = 360;
|
||||
aNPC_set_request_act(nactorx, 4, act_idx, aNPC_ACT_TYPE_TO_POINT, arg_data);
|
||||
}
|
||||
|
||||
static void aNPC_think_exit_wait_setup_exit_info(NPC_ACTOR* nactorx) {
|
||||
aNPC_OngenTrgStart(nactorx, NA_SE_40B);
|
||||
nactorx->actor_class.world.position.x = 0.0f;
|
||||
nactorx->actor_class.world.position.z = 0.0f;
|
||||
aNPC_set_hide_request(nactorx, TRUE);
|
||||
aNPC_chg_entrance_fg(EXIT_DOOR);
|
||||
nactorx->think.end_flag = TRUE;
|
||||
nactorx->actor_class.status_data.weight = 50;
|
||||
}
|
||||
|
||||
static int aNPC_think_exit_wait_chk_interrupt(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
int ret = FALSE;
|
||||
|
||||
if (aNPC_chk_talk_start(nactorx) == TRUE) {
|
||||
ret = TRUE;
|
||||
} else if (aNPC_chk_right_hand(nactorx) == FALSE) {
|
||||
ret = TRUE;
|
||||
} else if (aNPC_chk_left_hand(nactorx) == FALSE) {
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void aNPC_think_exit_wait_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
if (aNPC_think_exit_wait_chk_interrupt(nactorx, play) == FALSE) {
|
||||
if (nactorx->action.step == aNPC_ACTION_END_STEP && !mDemo_Check(mDemo_TYPE_TALK, (ACTOR*)nactorx)) {
|
||||
if (nactorx->action.idx == aNPC_ACT_WALK && nactorx->actor_class.world.position.z >= 360.0f) {
|
||||
aNPC_think_exit_wait_setup_exit_info(nactorx);
|
||||
} else {
|
||||
aNPC_think_exit_wait_decide_next_act_idx(nactorx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_think_exit_wait_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
nactorx->think.force_call_flag = aNPC_FORCE_CALL_NONE;
|
||||
nactorx->actor_class.status_data.weight = MASSTYPE_HEAVY;
|
||||
aNPC_set_be_out_home(nactorx);
|
||||
aNPC_chg_entrance_fg(RSV_NO);
|
||||
if (!mDemo_Check(mDemo_TYPE_TALK, (ACTOR*)nactorx)) {
|
||||
aNPC_think_exit_wait_decide_next_act_idx(nactorx);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_think_exit_wait_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
// clang-format off
|
||||
static aNPC_SUB_PROC think_proc[] = {
|
||||
&aNPC_think_exit_wait_init_proc,
|
||||
&aNPC_think_exit_wait_main_proc,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
(*think_proc[proc_type])(nactorx, play);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
static void aNPC_think_into_room_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
if (nactorx->action.step == aNPC_ACTION_END_STEP) {
|
||||
aNPC_chg_entrance_fg(EXIT_DOOR);
|
||||
nactorx->actor_class.status_data.weight = 50;
|
||||
nactorx->think.end_flag = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_think_into_room_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
u16 arg_data[aNPC_REQUEST_ARG_NUM];
|
||||
|
||||
bzero(arg_data, sizeof(arg_data));
|
||||
nactorx->think.force_call_flag = aNPC_FORCE_CALL_NONE;
|
||||
nactorx->actor_class.status_data.weight = MASSTYPE_HEAVY;
|
||||
nactorx->actor_class.world.position.x = 160.0f;
|
||||
nactorx->actor_class.world.position.y = 40.0f;
|
||||
nactorx->actor_class.world.position.z = 360.0f;
|
||||
nactorx->actor_class.shape_info.rotation.y = DEG2SHORT_ANGLE2(180.0f);
|
||||
nactorx->actor_class.world.angle.y = DEG2SHORT_ANGLE2(180.0f);
|
||||
aNPC_set_hide_request(nactorx, FALSE);
|
||||
aNPC_chg_entrance_fg(RSV_NO);
|
||||
|
||||
aNPC_GET_ANM(nactorx)->is_home = TRUE;
|
||||
nactorx->condition_info.demo_flg = aNPC_COND_DEMO_SKIP_FEEL_CHECK | aNPC_COND_DEMO_SKIP_ENTRANCE_CHECK | aNPC_COND_DEMO_SKIP_HEAD_LOOKAT |
|
||||
aNPC_COND_DEMO_SKIP_TALK_CHECK | aNPC_COND_DEMO_SKIP_FORWARD_CHECK | aNPC_COND_DEMO_SKIP_BGCHECK |
|
||||
aNPC_COND_DEMO_SKIP_MOVE_Y | aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV | aNPC_COND_DEMO_SKIP_MOVE_RANGE_CHECK;
|
||||
aNPC_OngenTrgStart(nactorx, NA_SE_40B);
|
||||
arg_data[2] = 160;
|
||||
arg_data[3] = 300;
|
||||
aNPC_set_request_act(nactorx, 4, aNPC_ACT_WALK, aNPC_ACT_TYPE_TO_POINT, arg_data);
|
||||
}
|
||||
|
||||
static void aNPC_think_into_room_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
// clang-format off
|
||||
static aNPC_SUB_PROC think_proc[] = {
|
||||
&aNPC_think_into_room_init_proc,
|
||||
&aNPC_think_into_room_main_proc,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
(*think_proc[proc_type])(nactorx, play);
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
static u8 aNPC_think_out_of_room_route_check(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
u8 act_idx = aNPC_ACT_WAIT;
|
||||
int route_ret;
|
||||
int i;
|
||||
|
||||
nactorx->movement.movement_ut_x = -1;
|
||||
nactorx->movement.movement_ut_z = -1;
|
||||
for (i = 2; i < 4; i++) {
|
||||
route_ret = aNPC_route_check(nactorx, play, i, aNPC2_UNIT_Z_NUM - 1, FALSE);
|
||||
if (route_ret == aNPC_ROUTE_MOVING) {
|
||||
NPC_CONTROL_ACTOR* ctrl = (NPC_CONTROL_ACTOR*)aNPC_ctrlActor;
|
||||
aNPC_unit_info_c* route = ctrl->route;
|
||||
int dir = route[0].direct;
|
||||
|
||||
if (dir !=
|
||||
aNPC_drt_table[(((nactorx->actor_class.world.angle.y + DEG2SHORT_ANGLE2(45.0f)) >> 14) & 3)]) {
|
||||
act_idx = aNPC_ACT_TURN;
|
||||
} else {
|
||||
act_idx = aNPC_ACT_WALK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (route_ret == aNPC_ROUTE_FINISH) {
|
||||
nactorx->think.end_flag = TRUE;
|
||||
act_idx = aNPC_ACT_WAIT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return act_idx;
|
||||
}
|
||||
|
||||
static int aNPC_think_out_of_room_chk_interrupt(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
int ret = FALSE;
|
||||
|
||||
if (aNPC_chk_talk_start(nactorx) == TRUE) {
|
||||
ret = TRUE;
|
||||
} else if (aNPC_chk_right_hand(nactorx) == FALSE) {
|
||||
ret = TRUE;
|
||||
} else if (aNPC_chk_left_hand(nactorx) == FALSE) {
|
||||
ret = TRUE;
|
||||
} else {
|
||||
if (!F32_IS_ZERO(nactorx->actor_class.speed)) {
|
||||
ret = aNPC_avoid_obstacle(nactorx, play);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void aNPC_think_out_of_room_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
if (aNPC_think_out_of_room_chk_interrupt(nactorx, play) == FALSE) {
|
||||
if (nactorx->actor_class.world.position.z >= 294.0f) {
|
||||
nactorx->think.end_flag = TRUE;
|
||||
} else {
|
||||
if (nactorx->action.step == aNPC_ACTION_END_STEP) {
|
||||
u8 act_idx = aNPC_think_out_of_room_route_check(nactorx, play);
|
||||
|
||||
if (act_idx == nactorx->action.idx) {
|
||||
nactorx->action.step = 0;
|
||||
}
|
||||
|
||||
aNPC_set_request_act(nactorx, 1, act_idx, aNPC_ACT_TYPE_DEFAULT, aNPC_req_default_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_think_out_of_room_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
nactorx->think.force_call_flag = aNPC_FORCE_CALL_NONE;
|
||||
aNPC_set_request_act(nactorx, 1, aNPC_think_out_of_room_route_check(nactorx, play), aNPC_ACT_TYPE_DEFAULT, aNPC_req_default_data);
|
||||
}
|
||||
|
||||
static void aNPC_think_out_of_room_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
// clang-format off
|
||||
static aNPC_SUB_PROC think_proc[] = {
|
||||
&aNPC_think_out_of_room_init_proc,
|
||||
&aNPC_think_out_of_room_main_proc,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
(*think_proc[proc_type])(nactorx, play);
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
static void aNPC_think_wander_decide_next(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
NPC_CONTROL_ACTOR* ctrl = (NPC_CONTROL_ACTOR*)aNPC_ctrlActor;
|
||||
u8 act_type;
|
||||
u16 arg_data[aNPC_REQUEST_ARG_NUM];
|
||||
u8 act_idx;
|
||||
|
||||
act_type = aNPC_ACT_TYPE_DEFAULT;
|
||||
bzero(arg_data, sizeof(arg_data));
|
||||
|
||||
if (aNPC_check_fatigue(nactorx) == TRUE) {
|
||||
act_idx = aNPC_ACT_WAIT;
|
||||
} else if (nactorx->action.idx == aNPC_ACT_TURN) {
|
||||
act_idx = aNPC_ACT_WALK;
|
||||
arg_data[2] = (int)nactorx->movement.avoid_pos_x;
|
||||
arg_data[3] = (int)nactorx->movement.avoid_pos_z;
|
||||
} else {
|
||||
int x;
|
||||
int z;
|
||||
|
||||
if (RANDOM_F(1.0f) < 0.75f) {
|
||||
act_idx = aNPC_ACT_WAIT;
|
||||
} else {
|
||||
int* unit_info_p = (int*)ctrl->unit_info;
|
||||
while (TRUE) {
|
||||
x = RANDOM(aNPC2_UNIT_X_NUM);
|
||||
z = RANDOM(aNPC2_UNIT_Z_NUM - 1);
|
||||
|
||||
if (*(unit_info_p + x + z * aNPC2_UNIT_X_NUM) != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (aNPC_route_check(nactorx, play, x, z, FALSE) == aNPC_ROUTE_MOVING) {
|
||||
aNPC_unit_info_c* route = ctrl->route;
|
||||
int dir = route[0].direct;
|
||||
|
||||
if (dir !=
|
||||
aNPC_drt_table[(((nactorx->actor_class.world.angle.y + DEG2SHORT_ANGLE2(45.0f)) >> 14) & 3)]) {
|
||||
act_idx = aNPC_ACT_TURN;
|
||||
} else {
|
||||
act_idx = aNPC_ACT_WALK;
|
||||
}
|
||||
|
||||
arg_data[2] = (int)nactorx->movement.avoid_pos_x;
|
||||
arg_data[3] = (int)nactorx->movement.avoid_pos_z;
|
||||
} else {
|
||||
act_idx = aNPC_ACT_WAIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (act_idx == nactorx->action.idx) {
|
||||
nactorx->action.step = 0;
|
||||
}
|
||||
|
||||
aNPC_set_request_act(nactorx, 1, act_idx, act_type, arg_data);
|
||||
}
|
||||
|
||||
static void aNPC_think_wander_next_act(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
if (nactorx->action.step == aNPC_ACTION_END_STEP) {
|
||||
aNPC_think_wander_decide_next(nactorx, play);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_think_wander_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
if (aNPC_think_chk_interrupt_proc(nactorx, play) == FALSE) {
|
||||
aNPC_think_wander_next_act(nactorx, play);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPC_think_wander_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
nactorx->condition_info.demo_flg = 0;
|
||||
nactorx->think.force_call_flag = aNPC_FORCE_CALL_NONE;
|
||||
aNPC_set_request_act(nactorx, 1, aNPC_ACT_WAIT, aNPC_ACT_TYPE_DEFAULT, aNPC_req_default_data);
|
||||
}
|
||||
|
||||
static void aNPC_think_wander_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
// clang-format off
|
||||
static aNPC_SUB_PROC think_proc[] = {
|
||||
&aNPC_think_wander_init_proc,
|
||||
&aNPC_think_wander_main_proc,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
(*think_proc[proc_type])(nactorx, play);
|
||||
}
|
||||
@@ -5,6 +5,7 @@ enum {
|
||||
};
|
||||
|
||||
static void aNPC_act_ensou_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
#ifndef aNPC_NPC2
|
||||
u8 step = aNPC_ACT_ENSOU_STEP_ENSOU;
|
||||
|
||||
if (nactorx->draw.main_animation_state == cKF_STATE_CONTINUE) {
|
||||
@@ -13,12 +14,24 @@ static void aNPC_act_ensou_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
}
|
||||
|
||||
nactorx->action.step = step;
|
||||
#else
|
||||
nactorx->condition_info.demo_flg = aNPC_COND_DEMO_SKIP_HEAD_LOOKAT;
|
||||
nactorx->action.step = aNPC_ACTION_END_STEP;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void aNPC_act_ensou_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
#ifndef aNPC_NPC2
|
||||
nactorx->condition_info.demo_flg = aNPC_COND_DEMO_SKIP_ENTRANCE_CHECK | aNPC_COND_DEMO_SKIP_HEAD_LOOKAT | aNPC_COND_DEMO_SKIP_FORWARD_CHECK | aNPC_COND_DEMO_SKIP_BGCHECK | aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV | aNPC_COND_DEMO_SKIP_MOVE_RANGE_CHECK;
|
||||
#else
|
||||
nactorx->condition_info.demo_flg = -1;
|
||||
#endif
|
||||
nactorx->action.step = aNPC_ACT_ENSOU_STEP_ENSOU;
|
||||
#ifndef aNPC_NPC2
|
||||
aNPC_setupAction(nactorx, aNPC_ACTION_TYPE_ENSOU_E);
|
||||
#else
|
||||
aNPC_setupAction(nactorx, aNPC_ACTION_TYPE_ENSOU);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void aNPC_act_ensou_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int type) {
|
||||
|
||||
@@ -107,11 +107,19 @@ static void aNPC_act_get_move(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
nactorx->movement.demo_move_timer--;
|
||||
}
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
if (!aNPC_act_search_move(nactorx) ||
|
||||
(nactorx->collision.collision_flag & (mCoBG_HIT_WALL | mCoBG_HIT_WALL_FRONT)) != 0 ||
|
||||
nactorx->movement.demo_move_timer == 0) {
|
||||
aNPC_act_get_chg_step(nactorx, aNPC_ACT_GET_STEP_GET);
|
||||
}
|
||||
#else
|
||||
if (!aNPC_act_demo_move(nactorx) ||
|
||||
(nactorx->collision.collision_flag & (mCoBG_HIT_WALL | mCoBG_HIT_WALL_FRONT)) != 0 ||
|
||||
nactorx->movement.demo_move_timer == 0) {
|
||||
aNPC_act_get_chg_step(nactorx, aNPC_ACT_GET_STEP_GET);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void aNPC_act_get(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
@@ -220,6 +228,7 @@ static void aNPC_act_get_chg_cloth(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
static void aNPC_act_get_chg_umb(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
if (nactorx->draw.umb_state == aNPC_CLOTH_CHG_STEP_END) {
|
||||
aNPC_act_get_putaway(nactorx, play);
|
||||
@@ -283,6 +292,7 @@ static void aNPC_act_get_chg_cloth_and_umb(NPC_ACTOR* nactorx, GAME_PLAY* play)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void aNPC_act_get_return(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
if (nactorx->draw.main_animation_state == cKF_STATE_STOPPED) {
|
||||
@@ -309,8 +319,13 @@ static void aNPC_act_get_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
&aNPC_act_get_putaway,
|
||||
&aNPC_act_get_putaway,
|
||||
&aNPC_act_get_chg_cloth,
|
||||
#ifndef aNPC_NPC2
|
||||
&aNPC_act_get_chg_umb,
|
||||
&aNPC_act_get_chg_cloth_and_umb,
|
||||
#else
|
||||
(aNPC_SUB_PROC)&none_proc1,
|
||||
(aNPC_SUB_PROC)&none_proc1,
|
||||
#endif
|
||||
&aNPC_act_get_return,
|
||||
&aNPC_act_trans_wait,
|
||||
&aNPC_act_estimate
|
||||
|
||||
@@ -39,6 +39,7 @@ static int aNPC_talk_end_check(ACTOR* actorx, GAME* game) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
static void aNPC_act_talk_chg_step(NPC_ACTOR* nactorx, u8 step) {
|
||||
// clang-format off
|
||||
static u8 act_idx[] = {
|
||||
@@ -51,6 +52,34 @@ static void aNPC_act_talk_chg_step(NPC_ACTOR* nactorx, u8 step) {
|
||||
nactorx->action.step = step;
|
||||
aNPC_setupAction(nactorx, act_idx[step]);
|
||||
}
|
||||
#else
|
||||
static void aNPC_act_talk_chg_step(NPC_ACTOR* nactorx, u8 step) {
|
||||
// clang-format off
|
||||
static u8 act_idx[][3] = {
|
||||
{
|
||||
aNPC_ACTION_TYPE_TALK_TURN,
|
||||
aNPC_ACTION_TYPE_TALK,
|
||||
aNPC_ACTION_TYPE_TALK,
|
||||
},
|
||||
{
|
||||
aNPC_ACTION_TYPE_WAIT_E,
|
||||
aNPC_ACTION_TYPE_WAIT_E,
|
||||
aNPC_ACTION_TYPE_WAIT_E,
|
||||
},
|
||||
};
|
||||
// clang-format on
|
||||
int idx;
|
||||
|
||||
if (nactorx->action.idx == aNPC_ACT_TALK) {
|
||||
idx = 0;
|
||||
} else {
|
||||
idx = 1;
|
||||
}
|
||||
|
||||
nactorx->action.step = step;
|
||||
aNPC_setupAction(nactorx, act_idx[idx][step]);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void aNPC_act_talk_turn(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
if (!aNPC_act_turn(nactorx)) {
|
||||
@@ -96,6 +125,7 @@ static void aNPC_act_talk_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
(*act_proc[nactorx->action.step])(nactorx, play);
|
||||
}
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
static void aNPC_act_talk_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
u8 step = aNPC_ACT_TALK_STEP_TALK_TURN;
|
||||
|
||||
@@ -119,6 +149,29 @@ static void aNPC_act_talk_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
|
||||
aNPC_act_talk_chg_step(nactorx, step);
|
||||
}
|
||||
#else
|
||||
static void aNPC_act_talk_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
u8 step = aNPC_ACT_TALK_STEP_TALK_TURN;
|
||||
|
||||
if (nactorx->action.idx == aNPC_ACT_WAIT_E) {
|
||||
nactorx->condition_info.demo_flg = aNPC_COND_DEMO_SKIP_ENTRANCE_CHECK | aNPC_COND_DEMO_SKIP_HEAD_LOOKAT | aNPC_COND_DEMO_SKIP_FORWARD_CHECK | aNPC_COND_DEMO_SKIP_BGCHECK | aNPC_COND_DEMO_SKIP_OBJ_COL_CHECK | aNPC_COND_DEMO_SKIP_MOVE_Y | aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV | aNPC_COND_DEMO_SKIP_MOVE_RANGE_CHECK;
|
||||
} else {
|
||||
nactorx->condition_info.demo_flg = 0;
|
||||
}
|
||||
|
||||
if (nactorx->condition_info.talk_condition == aNPC_TALK_TYPE_CONTINUE) {
|
||||
step = aNPC_ACT_TALK_STEP_TALK;
|
||||
} else {
|
||||
aNPC_Init_OrderValue();
|
||||
if (nactorx->talk_info.turn != aNPC_TALK_TURN_NORMAL) {
|
||||
step = aNPC_ACT_TALK_STEP_TALK_WAIT;
|
||||
}
|
||||
nactorx->condition_info.talk_condition = aNPC_TALK_TYPE_CONTINUE;
|
||||
}
|
||||
|
||||
aNPC_act_talk_chg_step(nactorx, step);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void aNPC_act_talk_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int type) {
|
||||
static aNPC_SUB_PROC act_proc[] = { &aNPC_act_talk_init_proc, (aNPC_SUB_PROC)&none_proc1, &aNPC_act_talk_main_proc };
|
||||
|
||||
@@ -11,6 +11,7 @@ enum {
|
||||
};
|
||||
|
||||
static void aNPC_act_trans_chg_step(NPC_ACTOR* nactorx, u8 step) {
|
||||
#ifndef aNPC_NPC2
|
||||
// clang-format off
|
||||
static u8 act_idx[] = {
|
||||
aNPC_ACTION_TYPE_WALK,
|
||||
@@ -22,6 +23,19 @@ static void aNPC_act_trans_chg_step(NPC_ACTOR* nactorx, u8 step) {
|
||||
aNPC_ACTION_TYPE_TALK,
|
||||
};
|
||||
// clang-format on
|
||||
#else
|
||||
// clang-format off
|
||||
static u8 act_idx[] = {
|
||||
aNPC_ACTION_TYPE_WALK,
|
||||
aNPC_ACTION_TYPE_TRANSFER,
|
||||
aNPC_ACTION_TYPE_TRANSFER,
|
||||
aNPC_ACTION_TYPE_TRANS_WAIT,
|
||||
aNPC_ACTION_TYPE_TRANS_WAIT,
|
||||
aNPC_ACTION_TYPE_SEND_MAIL,
|
||||
aNPC_ACTION_TYPE_TALK,
|
||||
};
|
||||
// clang-format on
|
||||
#endif
|
||||
|
||||
u8 timer = 0;
|
||||
|
||||
@@ -67,12 +81,21 @@ static void aNPC_act_trans_move(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
nactorx->movement.demo_move_timer--;
|
||||
}
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
if (!aNPC_act_search_move(nactorx) ||
|
||||
(nactorx->collision.collision_flag & (mCoBG_HIT_WALL | mCoBG_HIT_WALL_FRONT)) != 0 ||
|
||||
nactorx->movement.demo_move_timer == 0) {
|
||||
aNPC_act_trans_set_arg_data(nactorx);
|
||||
aNPC_act_trans_chg_step(nactorx, aNPC_ACT_TRANS_STEP_TRANS);
|
||||
}
|
||||
#else
|
||||
if (!aNPC_act_demo_move(nactorx) ||
|
||||
(nactorx->collision.collision_flag & (mCoBG_HIT_WALL | mCoBG_HIT_WALL_FRONT)) != 0 ||
|
||||
nactorx->movement.demo_move_timer == 0) {
|
||||
aNPC_act_trans_set_arg_data(nactorx);
|
||||
aNPC_act_trans_chg_step(nactorx, aNPC_ACT_TRANS_STEP_TRANS);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void aNPC_act_trans(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
|
||||
@@ -41,7 +41,11 @@ static void aNPC_act_turn_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
|
||||
nactorx->action.step = aNPC_ACT_TURN_STEP_MAIN;
|
||||
if (nactorx->action.type == aNPC_ACT_TYPE_AVOID) {
|
||||
#ifndef aNPC_NPC2
|
||||
aNPC_set_avoid_pos(nactorx, nactorx->action.move_x, nactorx->action.move_z, nactorx->request.act_args[4]);
|
||||
#else
|
||||
aNPC_set_avoid_pos(nactorx, nactorx->action.move_x, nactorx->action.move_z);
|
||||
#endif
|
||||
} else {
|
||||
aNPC_set_dst_pos(nactorx, nactorx->action.move_x, nactorx->action.move_z);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ static int aNPC_check_talk_anime(NPC_ACTOR* nactorx, int seqNo) {
|
||||
seqNo = nactorx->talk_info.default_turn_animation;
|
||||
} else {
|
||||
// clang-format off
|
||||
static int talk_def_anime[mNpc_FEEL_ALL_NUM] = {
|
||||
static int talk_turn_def_anime[mNpc_FEEL_ALL_NUM] = {
|
||||
aNPC_ANIM_WALK1,
|
||||
aNPC_ANIM_WALK1,
|
||||
aNPC_ANIM_WALK_DO1,
|
||||
@@ -46,7 +46,7 @@ static int aNPC_check_talk_anime(NPC_ACTOR* nactorx, int seqNo) {
|
||||
feel = aNPC_get_feel_info(nactorx);
|
||||
}
|
||||
|
||||
seqNo = talk_def_anime[feel];
|
||||
seqNo = talk_turn_def_anime[feel];
|
||||
}
|
||||
break;
|
||||
case aNPC_ANIM_TALK1:
|
||||
@@ -292,12 +292,17 @@ static void aNPC_anime_proc_foot(NPC_ACTOR* nactorx, GAME* game, xyz_t* pos_p, a
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
if (nactorx->draw.animation_id == aNPC_ANIM_KOKERU1) {
|
||||
aNPC_TumbleSe(pos_p);
|
||||
} else {
|
||||
aNPC_WalkSe(pos_p);
|
||||
}
|
||||
#else
|
||||
aNPC_WalkSeRoom(pos_p);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void aNPC_anime_proc_other(NPC_ACTOR* nactorx, aNPC_other_se_data_c* other_se_p) {
|
||||
|
||||
@@ -29,6 +29,7 @@ static int aNPC_setP_friendship(NPC_ACTOR* nactorx) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
static void aNPC_check_force_use_umbrella(NPC_ACTOR* nactorx) {
|
||||
u8 req = FALSE;
|
||||
|
||||
@@ -42,10 +43,150 @@ static void aNPC_check_force_use_umbrella(NPC_ACTOR* nactorx) {
|
||||
static void aNPC_set_start_pos(ACTOR* actorx) {
|
||||
NPC_ACTOR* nactorx = (NPC_ACTOR*)actorx;
|
||||
Animal_c* animal = aNPC_GET_ANM(nactorx);
|
||||
|
||||
|
||||
mNpcW_GetAppearStatusWay(&nactorx->condition_info.appear_flag, &nactorx->condition_info.appear_rotation, animal);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int aNPC_set_start_pos_sub(ACTOR* actorx, int uz) {
|
||||
int ux;
|
||||
int* unit_info_p;
|
||||
int unit_flag;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
unit_info_p = (int*)((NPC_CONTROL_ACTOR*)aNPC_ctrlActor)->unit_info;
|
||||
unit_flag = 0;
|
||||
i = 0;
|
||||
ret = TRUE;
|
||||
unit_info_p += uz * aNPC2_UNIT_X_NUM;
|
||||
for (i; i < aNPC2_UNIT_X_NUM; i++) {
|
||||
while (TRUE) {
|
||||
ux = RANDOM(aNPC2_UNIT_X_NUM);
|
||||
if (((unit_flag >> ux) & 1) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (*(unit_info_p + ux) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
unit_flag |= (1 << ux);
|
||||
}
|
||||
|
||||
ret = FALSE;
|
||||
exit:
|
||||
actorx->world.position.x = (ux + 1.5f) * mFI_UT_WORLDSIZE_X_F;
|
||||
actorx->world.position.z = (uz + 1.5f) * mFI_UT_WORLDSIZE_Z_F;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void aNPC_set_start_pos(ACTOR* actorx) {
|
||||
static int uz_def_tbl[3][2] = {
|
||||
{ 1, 2 },
|
||||
{ 0, 3 },
|
||||
{ 4, 5 },
|
||||
};
|
||||
|
||||
static f32 chk_val000[3] = {
|
||||
0.4f,
|
||||
0.1f,
|
||||
0.0f,
|
||||
};
|
||||
|
||||
static f32 chk_val001[3] = {
|
||||
1.0f,
|
||||
0.25f,
|
||||
0.0f,
|
||||
};
|
||||
|
||||
static f32 chk_val010[3] = {
|
||||
0.14f,
|
||||
1.0f,
|
||||
0.0f,
|
||||
};
|
||||
|
||||
static f32 chk_val011[3] = {
|
||||
1.0f,
|
||||
1.0f,
|
||||
0.0f,
|
||||
};
|
||||
|
||||
static f32 chk_val100[3] = {
|
||||
0.3f,
|
||||
0.0f,
|
||||
1.0f,
|
||||
};
|
||||
|
||||
static f32 chk_val101[3] = {
|
||||
1.0f,
|
||||
0.0f,
|
||||
1.0f,
|
||||
};
|
||||
|
||||
static f32 chk_val110[3] = {
|
||||
0.0f,
|
||||
1.0f,
|
||||
1.0f,
|
||||
};
|
||||
|
||||
static f32* chk_val_tbl[8] = {
|
||||
chk_val000, chk_val001, chk_val010, chk_val011, chk_val100, chk_val101, chk_val110, NULL,
|
||||
};
|
||||
|
||||
static s16 angl_tbl[] = {
|
||||
DEG2SHORT_ANGLE2(0.0f),
|
||||
DEG2SHORT_ANGLE2(90.0f),
|
||||
DEG2SHORT_ANGLE2(180.0f),
|
||||
DEG2SHORT_ANGLE2(270.0f),
|
||||
};
|
||||
|
||||
f32 rnd;
|
||||
int uz;
|
||||
int j;
|
||||
int idx;
|
||||
int uz_tbl[3][2];
|
||||
f32* check_p;
|
||||
int i;
|
||||
s16 angle;
|
||||
|
||||
i = 0;
|
||||
mem_copy((u8*)uz_tbl, (u8*)uz_def_tbl, sizeof(uz_tbl));
|
||||
uz = 0;
|
||||
idx = 0;
|
||||
|
||||
while (TRUE) {
|
||||
check_p = chk_val_tbl[i];
|
||||
rnd = RANDOM_F(1.0f);
|
||||
for (j = 0; j < 3; j++) {
|
||||
if (rnd >= check_p[j]) {
|
||||
idx = RANDOM(2);
|
||||
uz = uz_tbl[j][idx];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (aNPC_set_start_pos_sub(actorx, uz) != TRUE) {
|
||||
if (uz_tbl[j][0] == uz_tbl[j][1]) {
|
||||
i |= 1 << j;
|
||||
} else {
|
||||
uz_tbl[j][idx] = uz_tbl[j][idx ^ 1];
|
||||
}
|
||||
} else {
|
||||
angle = angl_tbl[RANDOM(ARRAY_COUNT(angl_tbl))];
|
||||
|
||||
actorx->shape_info.rotation.y = angle;
|
||||
actorx->world.angle.y = angle;
|
||||
((NPC_ACTOR*)actorx)->movement.mv_angl = angle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void aNPC_actor_schedule(NPC_ACTOR* nactorx, int type) {
|
||||
mNPS_schedule_c* sched_p = &nactorx->schedule.schedule;
|
||||
|
||||
@@ -59,14 +200,26 @@ static void aNPC_actor_schedule(NPC_ACTOR* nactorx, int type) {
|
||||
nactorx->schedule.type = aNPC_SCHEDULE_TYPE_STAND;
|
||||
break;
|
||||
case aNPC_CT_SCHED_TYPE_WANDER:
|
||||
#ifndef aNPC_NPC2
|
||||
sched_p->current_type = mNPS_SCHED_WANDER;
|
||||
nactorx->npc_info.schedule = sched_p;
|
||||
nactorx->schedule.type = aNPC_SCHEDULE_TYPE_WANDER;
|
||||
#else
|
||||
sched_p->current_type = aNPC_SCHEDULE_TYPE_IN_HOUSE;
|
||||
nactorx->npc_info.schedule = sched_p;
|
||||
nactorx->schedule.type = aNPC_SCHEDULE_TYPE_IN_HOUSE;
|
||||
#endif
|
||||
break;
|
||||
case aNPC_CT_SCHED_TYPE_WALK_WANDER:
|
||||
#ifndef aNPC_NPC2
|
||||
sched_p->current_type = mNPS_SCHED_WALK_WANDER;
|
||||
nactorx->npc_info.schedule = sched_p;
|
||||
nactorx->schedule.type = aNPC_SCHEDULE_TYPE_WALK_WANDER;
|
||||
#else
|
||||
sched_p->current_type = aNPC_SCHEDULE_TYPE_IN_HOUSE;
|
||||
nactorx->npc_info.schedule = sched_p;
|
||||
nactorx->schedule.type = aNPC_SCHEDULE_TYPE_IN_HOUSE;
|
||||
#endif
|
||||
break;
|
||||
case aNPC_CT_SCHED_TYPE_SPECIAL:
|
||||
sched_p->current_type = mNPS_SCHED_SPECIAL;
|
||||
@@ -120,12 +273,15 @@ static void aNPC_actor_ct(ACTOR* actorx, GAME* game, aNPC_ct_data_c* ct_data) {
|
||||
eye_y = (f32)draw_data.eye_height;
|
||||
scale = draw_data.scale;
|
||||
|
||||
cKF_SkeletonInfo_R_ct(&nactorx->draw.main_animation.keyframe, skeleton, NULL, nactorx->draw.main_animation.work, nactorx->draw.main_animation.morph);
|
||||
cKF_SkeletonInfo_R_ct(&nactorx->draw.sub_animation0.keyframe, skeleton, NULL, nactorx->draw.sub_animation0.work, nactorx->draw.sub_animation0.morph);
|
||||
cKF_SkeletonInfo_R_ct(&nactorx->draw.sub_animation1.keyframe, skeleton, NULL, nactorx->draw.sub_animation1.work, nactorx->draw.sub_animation1.morph);
|
||||
cKF_SkeletonInfo_R_ct(&nactorx->draw.main_animation.keyframe, skeleton, NULL, nactorx->draw.main_animation.work,
|
||||
nactorx->draw.main_animation.morph);
|
||||
cKF_SkeletonInfo_R_ct(&nactorx->draw.sub_animation0.keyframe, skeleton, NULL, nactorx->draw.sub_animation0.work,
|
||||
nactorx->draw.sub_animation0.morph);
|
||||
cKF_SkeletonInfo_R_ct(&nactorx->draw.sub_animation1.keyframe, skeleton, NULL, nactorx->draw.sub_animation1.work,
|
||||
nactorx->draw.sub_animation1.morph);
|
||||
Shape_Info_init(actorx, 0.0f, &mAc_ActorShadowEllipse, 9.0f, 17.0f);
|
||||
actorx->shape_info.ofs_y = 2.0f;
|
||||
|
||||
|
||||
{
|
||||
ClObjPipe_c* pipe_p = &nactorx->collision.pipe;
|
||||
|
||||
@@ -146,7 +302,7 @@ static void aNPC_actor_ct(ACTOR* actorx, GAME* game, aNPC_ct_data_c* ct_data) {
|
||||
|
||||
nactorx->collision.BGcheck_radius = 18.0f;
|
||||
nactorx->collision.check_kind = aNPC_BG_CHECK_TYPE_RANGE;
|
||||
|
||||
|
||||
nactorx->eye_y = eye_y;
|
||||
nactorx->action.idx = aNPC_ACT_NONE;
|
||||
|
||||
@@ -194,7 +350,7 @@ static void aNPC_actor_ct(ACTOR* actorx, GAME* game, aNPC_ct_data_c* ct_data) {
|
||||
xyz_t_move(&nactorx->feet[aNPC_FOOT_LEFT], &actorx->world.position);
|
||||
xyz_t_move(&nactorx->feet[aNPC_FOOT_RIGHT], &actorx->world.position);
|
||||
aNPC_set_hide_flg(nactorx, TRUE);
|
||||
|
||||
|
||||
if (name_type == NAME_TYPE_NPC) {
|
||||
Animal_c* animal = aNPC_GET_ANM(nactorx);
|
||||
mActor_name_t cloth = animal->cloth;
|
||||
@@ -213,7 +369,9 @@ static void aNPC_actor_ct(ACTOR* actorx, GAME* game, aNPC_ct_data_c* ct_data) {
|
||||
nactorx->talk_info.talk_end_check_proc = &aNPC_talk_end_check;
|
||||
aNPC_set_start_pos(actorx);
|
||||
aNPC_setP_friendship(nactorx);
|
||||
#ifndef aNPC_NPC2
|
||||
aNPC_check_force_use_umbrella(nactorx);
|
||||
#endif
|
||||
nactorx->talk_info.melody_inst = draw_data.voice_type;
|
||||
nactorx->talk_info.npc_voice_id = draw_data.voice_type;
|
||||
} else {
|
||||
@@ -237,7 +395,7 @@ static void aNPC_actor_ct(ACTOR* actorx, GAME* game, aNPC_ct_data_c* ct_data) {
|
||||
npc_name = mask_id; // r29
|
||||
nactorx->npc_info.mask = mask_npc;
|
||||
mask_npc->exists = TRUE;
|
||||
|
||||
|
||||
if (ITEM_NAME_GET_TYPE(npc_name) == NAME_TYPE_NPC) {
|
||||
aNPC_dma_draw_data_proc(&draw_data, mask_id);
|
||||
}
|
||||
@@ -250,6 +408,7 @@ static void aNPC_actor_ct(ACTOR* actorx, GAME* game, aNPC_ct_data_c* ct_data) {
|
||||
}
|
||||
|
||||
nactorx->npc_info.npc_name = npc_name;
|
||||
#ifndef aNPC_NPC2
|
||||
actorx->max_velocity_y = -20.0f;
|
||||
actorx->gravity = -1.0f;
|
||||
|
||||
@@ -260,12 +419,16 @@ static void aNPC_actor_ct(ACTOR* actorx, GAME* game, aNPC_ct_data_c* ct_data) {
|
||||
mFI_SetFG_common(EMPTY_NO, actorx->world.position, TRUE);
|
||||
}
|
||||
}
|
||||
#else
|
||||
actorx->max_velocity_y = 0.0f;
|
||||
actorx->gravity = 0.0f;
|
||||
#endif
|
||||
|
||||
actorx->scale.x = scale;
|
||||
actorx->scale.y = scale;
|
||||
actorx->scale.z = scale;
|
||||
actorx->unknown_b4 = TRUE;
|
||||
|
||||
|
||||
if (ct_data->sched_type != aNPC_CT_SCHED_TYPE_NONE) {
|
||||
aNPC_actor_schedule(nactorx, ct_data->sched_type);
|
||||
}
|
||||
|
||||
+147
-12
@@ -46,6 +46,101 @@ static void aNPC_rebuild_dma(void) {
|
||||
aNPC_rebuild_cloth_data();
|
||||
}
|
||||
|
||||
#ifdef aNPC_NPC2
|
||||
static void aNPC_set_safe_ut(NPC_CONTROL_ACTOR* ctrl) {
|
||||
static int chkX[4][9] = {
|
||||
{ 0, 1, 0, 1, 2, 0, 2, 1, 2 },
|
||||
{ 0, 1, 0, 1, 2, 0, 2, 1, 2 },
|
||||
{ 5, 4, 5, 4, 3, 5, 3, 4, 3 },
|
||||
{ 5, 4, 5, 4, 3, 5, 3, 4, 3 },
|
||||
};
|
||||
|
||||
static int chkZ[4][9] = {
|
||||
{ 0, 0, 1, 1, 0, 2, 1, 2, 2 },
|
||||
{ 5, 5, 4, 4, 5, 3, 4, 3, 3 },
|
||||
{ 0, 0, 1, 1, 0, 2, 1, 2, 2 },
|
||||
{ 5, 5, 4, 4, 5, 3, 4, 3, 3 },
|
||||
};
|
||||
|
||||
int* unit_info_p = (int*)ctrl->unit_info;
|
||||
int* safe_ux_p = ctrl->safe_ux;
|
||||
int* safe_uz_p = ctrl->safe_uz;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 9; j++) {
|
||||
if (*(unit_info_p + chkZ[i][j] * aNPC2_UNIT_X_NUM + chkX[i][j]) != 0) {
|
||||
*safe_ux_p = chkX[i][j];
|
||||
*safe_uz_p = chkZ[i][j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
safe_ux_p++;
|
||||
safe_uz_p++;
|
||||
}
|
||||
}
|
||||
|
||||
static int aNPC_make_unitInfo_sub(int ux, int uz, int* unit_info_p) {
|
||||
int ret = 0;
|
||||
|
||||
if (*((unit_info_p + ux) + uz * aNPC2_UNIT_X_NUM) == 0) {
|
||||
if (uz != 0 && *((unit_info_p + ux) + (uz - 1) * aNPC2_UNIT_X_NUM) == 0) {
|
||||
ret |= aNPC_UNIT_UP;
|
||||
}
|
||||
|
||||
if (uz != (aNPC2_UNIT_Z_NUM - 1) && *((unit_info_p + ux) + (uz + 1) * aNPC2_UNIT_X_NUM) == 0) {
|
||||
ret |= aNPC_UNIT_DOWN;
|
||||
}
|
||||
|
||||
if (ux != 0 && *((unit_info_p + (ux - 1)) + uz * aNPC2_UNIT_X_NUM) == 0) {
|
||||
ret |= aNPC_UNIT_LEFT;
|
||||
}
|
||||
|
||||
if (ux != (aNPC2_UNIT_X_NUM - 1) && *((unit_info_p + (ux + 1)) + uz * aNPC2_UNIT_X_NUM) == 0) {
|
||||
ret |= aNPC_UNIT_RIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void aNPC_make_unitInfo(NPC_CONTROL_ACTOR* ctrl) {
|
||||
int table[aNPC2_UNIT_Z_NUM][aNPC2_UNIT_X_NUM];
|
||||
int x;
|
||||
int z;
|
||||
mActor_name_t* fg_p = mFI_UtNum2UtFG(1, 1);
|
||||
|
||||
for (z = 0; z < aNPC2_UNIT_Z_NUM; z++) {
|
||||
for (x = 0; x < aNPC2_UNIT_X_NUM; x++) {
|
||||
table[z][x] = *fg_p != RSV_NO;
|
||||
fg_p++;
|
||||
}
|
||||
|
||||
fg_p += (UT_X_NUM - aNPC2_UNIT_X_NUM);
|
||||
}
|
||||
|
||||
{
|
||||
int* unit_info_p = (int*)ctrl->unit_info;
|
||||
|
||||
for (z = 0; z < aNPC2_UNIT_Z_NUM; z++) {
|
||||
for (x = 0; x < aNPC2_UNIT_X_NUM; x++) {
|
||||
*unit_info_p = aNPC_make_unitInfo_sub(x, z, (int*)table);
|
||||
unit_info_p++;
|
||||
}
|
||||
|
||||
// why are we doing this after every x row
|
||||
ctrl->unit_info[6][2] = aNPC_UNIT_UP;
|
||||
ctrl->unit_info[6][3] = aNPC_UNIT_UP;
|
||||
}
|
||||
}
|
||||
|
||||
aNPC_set_safe_ut(ctrl);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void aNPC_set_attention_request_proc(u8 type, ACTOR* target_p, xyz_t* pos_p) {
|
||||
aNPC_attention_c* attention_request = &CLIP(npc_clip)->attention_request;
|
||||
|
||||
@@ -195,7 +290,8 @@ static int aNPC_setupActor_sub(GAME_PLAY* play, s8 idx, mActor_name_t name, s16
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aNPC_setupActor_proc(GAME_PLAY* play, mActor_name_t name, s8 idx, int mvlist_no, s16 arg, int bx, int bz, int ux, int uz) {
|
||||
static int aNPC_setupActor_proc(GAME_PLAY* play, mActor_name_t name, s8 idx, int mvlist_no, s16 arg, int bx, int bz,
|
||||
int ux, int uz) {
|
||||
// clang-format off
|
||||
static s16 event_npc_profile_table[] = {
|
||||
mAc_PROFILE_EV_ARTIST,
|
||||
@@ -423,6 +519,7 @@ static int aNPC_setupActor_proc(GAME_PLAY* play, mActor_name_t name, s8 idx, int
|
||||
aNPC_setupActor_sub(play, idx, name, profile, &pos, mvlist_no, arg);
|
||||
}
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
static int aNPC_get_overlay_free_area_idx(aNPC_overlay_c* overlay, int max) {
|
||||
int i;
|
||||
|
||||
@@ -437,7 +534,8 @@ static int aNPC_get_overlay_free_area_idx(aNPC_overlay_c* overlay, int max) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void aNPC_get_overlay_area_proc_sub(ACTOR_DLFTBL* dlftbl, size_t size, size_t max_size, aNPC_overlay_c* overlay, int max, mActor_name_t npc_name) {
|
||||
static void aNPC_get_overlay_area_proc_sub(ACTOR_DLFTBL* dlftbl, size_t size, size_t max_size, aNPC_overlay_c* overlay,
|
||||
int max, mActor_name_t npc_name) {
|
||||
int idx = aNPC_get_overlay_free_area_idx(overlay, max);
|
||||
|
||||
if (idx != -1) {
|
||||
@@ -478,16 +576,17 @@ static void aNPC_get_overlay_area_proc(ACTOR_DLFTBL* dlftbl, u8* name_p, size_t
|
||||
case SP_NPC_SENDO:
|
||||
case SP_NPC_MASK_CAT:
|
||||
case SP_NPC_GO_HONE_NPC:
|
||||
aNPC_get_overlay_area_proc_sub(dlftbl, size, 0x3000, CLIP(npc_clip)->keep_k_overlay, 3, npc_name);
|
||||
aNPC_get_overlay_area_proc_sub(dlftbl, size, 0x3000, CLIP(npc_clip)->keep_k_overlay, 3,
|
||||
npc_name);
|
||||
break;
|
||||
default:
|
||||
aNPC_get_overlay_area_proc_sub(dlftbl, size, 0x2000, CLIP(npc_clip)->keep_s_overlay, 2, npc_name);
|
||||
aNPC_get_overlay_area_proc_sub(dlftbl, size, 0x2000, CLIP(npc_clip)->keep_s_overlay, 2,
|
||||
npc_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -561,7 +660,9 @@ static ACTOR* aNPC_get_actor_area_proc(size_t size, const char* actor_name, int
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
static void aNPC_free_actor_area_proc(ACTOR* actorx) {
|
||||
NPC_ACTOR* nactorx = (NPC_ACTOR*)actorx;
|
||||
NPC_ACTOR** actor = CLIP(npc_clip)->keep_actors;
|
||||
@@ -578,6 +679,11 @@ static void aNPC_free_actor_area_proc(ACTOR* actorx) {
|
||||
used++;
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void aNPC_free_actor_area_proc(ACTOR* actorx) {
|
||||
zelda_free(actorx);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void aNPC_dma_draw_data_proc(aNPC_draw_data_c* draw_data_p, mActor_name_t npc_name) {
|
||||
int idx = aNPC_get_draw_data_idx(npc_name);
|
||||
@@ -585,6 +691,7 @@ static void aNPC_dma_draw_data_proc(aNPC_draw_data_c* draw_data_p, mActor_name_t
|
||||
mem_copy((u8*)draw_data_p, (u8*)&npc_draw_data_tbl[idx], sizeof(aNPC_draw_data_c));
|
||||
}
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
typedef struct {
|
||||
u64 align;
|
||||
u8 buf[0x9D0];
|
||||
@@ -693,6 +800,7 @@ static void aNPC_free_overlay_area(aNPC_overlay_c* overlay_p, int n) {
|
||||
overlay_p++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void aNPC_actor_ct_c(ACTOR* actorx, GAME* game) {
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
@@ -706,10 +814,16 @@ static void aNPC_actor_ct_c(ACTOR* actorx, GAME* game) {
|
||||
CLIP(npc_clip) = &aNPC_clip;
|
||||
bzero(&aNPC_clip, sizeof(aNPC_clip));
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
CLIP(npc_clip)->setupActor_proc = &aNPC_setupActor_proc;
|
||||
CLIP(npc_clip)->get_overlay_area_proc = &aNPC_get_overlay_area_proc;
|
||||
CLIP(npc_clip)->free_overlay_area_proc = &aNPC_free_overlay_area_proc;
|
||||
CLIP(npc_clip)->get_actor_area_proc = &aNPC_get_actor_area_proc;
|
||||
#else
|
||||
CLIP(npc_clip)->get_overlay_area_proc = (aNPC_GET_OVERLAY_AREA_PROC)&Actor_get_overlay_area;
|
||||
CLIP(npc_clip)->free_overlay_area_proc = &Actor_free_overlay_area;
|
||||
CLIP(npc_clip)->get_actor_area_proc = (aNPC_GET_ACTOR_AREA_PROC)&zelda_malloc;
|
||||
#endif
|
||||
CLIP(npc_clip)->free_actor_area_proc = &aNPC_free_actor_area_proc;
|
||||
CLIP(npc_clip)->dma_draw_data_proc = &aNPC_dma_draw_data_proc;
|
||||
CLIP(npc_clip)->set_attention_request_proc = &aNPC_set_attention_request_proc;
|
||||
@@ -733,11 +847,17 @@ static void aNPC_actor_ct_c(ACTOR* actorx, GAME* game) {
|
||||
CLIP(npc_clip)->force_call_req_proc = &aNPC_force_call_req_proc;
|
||||
CLIP(npc_clip)->set_start_pos_proc = &aNPC_set_start_pos;
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
aNPC_keep_actor_class();
|
||||
aNPC_keep_n_overlay_area(CLIP(npc_clip)->keep_n_overlay);
|
||||
aNPC_keep_s_overlay_area(CLIP(npc_clip)->keep_s_overlay);
|
||||
aNPC_keep_k_overlay_area(CLIP(npc_clip)->keep_k_overlay);
|
||||
aNPC_keep_e_overlay_area(CLIP(npc_clip)->keep_e_overlay);
|
||||
#else
|
||||
if (Save_Get(scene_no) != SCENE_NPC_HOUSE) {
|
||||
Common_Set(make_npc2_actor, TRUE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (play->block_table.block_z == mISL_BLOCK_Z) {
|
||||
@@ -749,7 +869,7 @@ static void aNPC_actor_ct_c(ACTOR* actorx, GAME* game) {
|
||||
Animal_c* islander_p;
|
||||
mNpc_NpcList_c* list_p;
|
||||
mNPS_schedule_c* sched_p;
|
||||
|
||||
|
||||
island_p = &Save_Get(island);
|
||||
islander_p = &island_p->animal;
|
||||
list_p = &Common_Get(island_npclist[0]);
|
||||
@@ -762,7 +882,7 @@ static void aNPC_actor_ct_c(ACTOR* actorx, GAME* game) {
|
||||
uz = (int)islander_p->home_info.ut_z;
|
||||
} else {
|
||||
int ret = mFI_Wpos2BkandUtNuminBlock(&bx, &bz, &ux, &uz, list_p->position);
|
||||
|
||||
|
||||
if (ret == FALSE) {
|
||||
bx = (int)islander_p->home_info.block_x;
|
||||
bz = (int)islander_p->home_info.block_z;
|
||||
@@ -780,7 +900,7 @@ static void aNPC_actor_ct_c(ACTOR* actorx, GAME* game) {
|
||||
|
||||
if (mFI_RegistMoveActorList(list_p->name, bx, bz, ux, uz, -ANIMAL_NUM_MAX, 0)) {
|
||||
sched_p = Common_GetPointer(npc_schedule[ANIMAL_NUM_MAX]);
|
||||
|
||||
|
||||
if (sched_p->id != NULL) {
|
||||
mNPS_reset_schedule_area(sched_p->id);
|
||||
}
|
||||
@@ -792,11 +912,13 @@ static void aNPC_actor_ct_c(ACTOR* actorx, GAME* game) {
|
||||
|
||||
static void aNPC_actor_dt_c(ACTOR* actorx, GAME* game) {
|
||||
if (CLIP(npc_clip) != NULL) {
|
||||
#ifndef aNPC_NPC2
|
||||
aNPC_free_actor_class();
|
||||
aNPC_free_overlay_area(CLIP(npc_clip)->keep_n_overlay, 1);
|
||||
aNPC_free_overlay_area(CLIP(npc_clip)->keep_s_overlay, 2);
|
||||
aNPC_free_overlay_area(CLIP(npc_clip)->keep_k_overlay, 3);
|
||||
aNPC_free_overlay_area(CLIP(npc_clip)->keep_e_overlay, 2);
|
||||
#endif
|
||||
CLIP(npc_clip) = NULL;
|
||||
}
|
||||
}
|
||||
@@ -804,7 +926,8 @@ static void aNPC_actor_dt_c(ACTOR* actorx, GAME* game) {
|
||||
static int aNPC_check_cond_to_greeting(NPC_ACTOR* nactorx) {
|
||||
int ret = TRUE;
|
||||
|
||||
if (nactorx->actor_class.ct_proc != NULL || nactorx->palActor != NULL || nactorx->palActorIgnoreTimer != 0 || nactorx->condition_info.hide_flg == TRUE) {
|
||||
if (nactorx->actor_class.ct_proc != NULL || nactorx->palActor != NULL || nactorx->palActorIgnoreTimer != 0 ||
|
||||
nactorx->condition_info.hide_flg == TRUE) {
|
||||
ret = FALSE;
|
||||
} else {
|
||||
switch (aNPC_get_feel_info(nactorx)) {
|
||||
@@ -866,7 +989,7 @@ static void aNPC_greeting_area_check(GAME_PLAY* play) {
|
||||
actor = list->actor;
|
||||
for (n = list->num_actors; n != 0; n--) {
|
||||
NPC_ACTOR* nactor = (NPC_ACTOR*)actor;
|
||||
|
||||
|
||||
if (nactor->palActorIgnoreTimer > 0) {
|
||||
nactor->palActorIgnoreTimer--;
|
||||
}
|
||||
@@ -888,6 +1011,7 @@ static void aNPC_set_attention(void) {
|
||||
req_p->type = aNPC_ATTENTION_TYPE_NONE;
|
||||
}
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
static void aNPC_force_reset_out_of_door_flg(NPC_CONTROL_ACTOR* ctrl) {
|
||||
int timer;
|
||||
|
||||
@@ -915,6 +1039,7 @@ static void aNPC_reset_umb_open_flg(NPC_CONTROL_ACTOR* ctrl, ACTOR* actorx) {
|
||||
aNPC_force_reset_umb_open_flg(ctrl);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void aNPC_actor_move_c(ACTOR* actorx, GAME* game) {
|
||||
NPC_CONTROL_ACTOR* ctrl = (NPC_CONTROL_ACTOR*)actorx;
|
||||
@@ -926,6 +1051,7 @@ static void aNPC_actor_move_c(ACTOR* actorx, GAME* game) {
|
||||
}
|
||||
|
||||
aNPC_set_attention();
|
||||
#ifndef aNPC_NPC2
|
||||
if (mFI_ActorisBorn() == TRUE) {
|
||||
aNPC_force_reset_out_of_door_flg(ctrl);
|
||||
aNPC_force_reset_umb_open_flg(ctrl);
|
||||
@@ -942,8 +1068,16 @@ static void aNPC_actor_move_c(ACTOR* actorx, GAME* game) {
|
||||
} else {
|
||||
aNPC_force_reset_umb_open_flg(ctrl);
|
||||
}
|
||||
#else
|
||||
if (CLIP(npc_clip)->setupActor_proc == NULL && Common_Get(make_npc2_actor)) {
|
||||
aNPC_make_unitInfo(ctrl);
|
||||
ctrl->route_node_count = 0;
|
||||
CLIP(npc_clip)->setupActor_proc = &aNPC_setupActor_proc;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
static void aNPC_set_talk_area_info(GAME_PLAY* play) {
|
||||
NPC_CONTROL_ACTOR* ctrl = (NPC_CONTROL_ACTOR*)aNPC_ctrlActor;
|
||||
ACTOR* playerx = GET_PLAYER_ACTOR_ACTOR(play);
|
||||
@@ -957,7 +1091,7 @@ static void aNPC_set_talk_area_info(GAME_PLAY* play) {
|
||||
if (talk_actor != NULL && talk_actor->part == ACTOR_PART_NPC) {
|
||||
f32 dx;
|
||||
f32 dz;
|
||||
|
||||
|
||||
talk_area->frame_counter = play->game_frame;
|
||||
talk_area->talk_actor = talk_actor;
|
||||
|
||||
@@ -1000,3 +1134,4 @@ static void aNPC_talk_area_check(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
|
||||
nactorx->collision.turn_flag = turn;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -496,6 +496,7 @@ static aNPC_anim_info_c aNPC_animeTable[aNPC_ANIM_NUM] = {
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
// clang-format off
|
||||
static s16 aNPC_animeSeqNoTable[] = {
|
||||
aNPC_ANIM_WAIT1,
|
||||
@@ -557,6 +558,55 @@ static s16 aNPC_animeSeqNoTable[] = {
|
||||
aNPC_ANIM_CLAP1,
|
||||
};
|
||||
// clang-format on
|
||||
#else
|
||||
// clang-format off
|
||||
static s16 aNPC_animeSeqNoTable[] = {
|
||||
aNPC_ANIM_WAIT1,
|
||||
aNPC_ANIM_WAIT_KI1,
|
||||
aNPC_ANIM_WAIT_DO1,
|
||||
aNPC_ANIM_WAIT_AI1,
|
||||
aNPC_ANIM_WAIT_NEMU1,
|
||||
aNPC_ANIM_WALK1,
|
||||
aNPC_ANIM_WALK_KI1,
|
||||
aNPC_ANIM_WALK_DO1,
|
||||
aNPC_ANIM_WALK_AI1,
|
||||
aNPC_ANIM_RUN1,
|
||||
aNPC_ANIM_WALK_KI1,
|
||||
aNPC_ANIM_WALK_DO1,
|
||||
aNPC_ANIM_WALK_AI1,
|
||||
aNPC_ANIM_WALK1,
|
||||
aNPC_ANIM_WAIT1,
|
||||
aNPC_ANIM_TALK_TURN1,
|
||||
aNPC_ANIM_TALK1,
|
||||
aNPC_ANIM_KEITAI_ON1,
|
||||
aNPC_ANIM_KEITAI_OFF1,
|
||||
aNPC_ANIM_WALK1,
|
||||
aNPC_ANIM_TRANSFER1,
|
||||
aNPC_ANIM_TRANS_WAIT1,
|
||||
aNPC_ANIM_SEND_MAIL1,
|
||||
aNPC_ANIM_WALK1,
|
||||
aNPC_ANIM_GET1,
|
||||
aNPC_ANIM_GET_PULL1,
|
||||
aNPC_ANIM_GET_PULL_WAIT1,
|
||||
aNPC_ANIM_GET_PUTAWAY1,
|
||||
aNPC_ANIM_GET_EAT1,
|
||||
aNPC_ANIM_GET_CHANGE1,
|
||||
aNPC_ANIM_GET_RETURN1,
|
||||
aNPC_ANIM_GET_F1,
|
||||
aNPC_ANIM_GET_PULL_F1,
|
||||
aNPC_ANIM_GET_PULL_WAIT_F1,
|
||||
aNPC_ANIM_GET_PUTAWAY_F1,
|
||||
aNPC_ANIM_GET_RETURN_F1,
|
||||
aNPC_ANIM_ESTIMATE_F1,
|
||||
aNPC_ANIM_CONTRACT1,
|
||||
aNPC_ANIM_CONTRACT2,
|
||||
aNPC_ANIM_CONTRACT3,
|
||||
aNPC_ANIM_NOT_CONTRACT1,
|
||||
aNPC_ANIM_4HAKU_E1,
|
||||
aNPC_ANIM_WAIT_E1,
|
||||
};
|
||||
// clang-format on
|
||||
#endif
|
||||
|
||||
static s16 aNPC_sub_animeSeqNoTable[] = { -1, aNPC_ANIM_UMBRELLA1, aNPC_ANIM_UTIWA_WAIT1, aNPC_ANIM_TUE1 };
|
||||
|
||||
|
||||
@@ -3,8 +3,10 @@ static void aNPC_actor_dt(ACTOR* actorx, GAME* game) {
|
||||
NPC_ACTOR* nactorx = (NPC_ACTOR*)actorx;
|
||||
ACTOR* palActor = nactorx->palActor;
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
aNPC_reset_out_of_door_flg(ctrl, actorx);
|
||||
aNPC_reset_umb_open_flg(ctrl, actorx);
|
||||
#endif
|
||||
|
||||
if (eEC_CLIP != NULL) {
|
||||
eEC_CLIP->effect_kill_all_proc(actorx->npc_id);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifndef aNPC_NPC2
|
||||
static int aNPC_change_umbrella(NPC_ACTOR* nactorx) {
|
||||
int ret = FALSE;
|
||||
|
||||
@@ -18,9 +19,14 @@ static int aNPC_change_umbrella(NPC_ACTOR* nactorx) {
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int aNPC_putaway_right_item(NPC_ACTOR* nactorx) {
|
||||
#ifndef aNPC_NPC2
|
||||
static u8 next_act_idx[] = { aNPC_ACT_UMB_CLOSE, aNPC_ACT_NONE };
|
||||
#else
|
||||
static u8 next_act_idx[] = { aNPC_ACT_NONE, aNPC_ACT_KEITAI_OFF };
|
||||
#endif
|
||||
int ret = TRUE;
|
||||
|
||||
if (CLIP(tools_clip) != NULL &&
|
||||
@@ -37,7 +43,11 @@ static int aNPC_putaway_right_item(NPC_ACTOR* nactorx) {
|
||||
}
|
||||
|
||||
static int aNPC_takeout_right_item(NPC_ACTOR* nactorx) {
|
||||
#ifndef aNPC_NPC2
|
||||
static u8 next_act_idx[] = { aNPC_ACT_UMB_OPEN, aNPC_ACT_NONE };
|
||||
#else
|
||||
static u8 next_act_idx[] = { aNPC_ACT_NONE, aNPC_ACT_KEITAI_ON };
|
||||
#endif
|
||||
static int itemIdx_table[] = { TOOL_UMBRELLA0, TOOL_KEITAI };
|
||||
int ret = TRUE;
|
||||
|
||||
@@ -72,9 +82,12 @@ static int aNPC_takeout_right_item(NPC_ACTOR* nactorx) {
|
||||
nactorx->right_hand.item_type = requested;
|
||||
nactorx->right_hand.requested_item_type = aNPC_ITEM_TYPE_NONE;
|
||||
nactorx->right_hand.item_actor_p = tool;
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
if (mode == aTOL_ACTION_S_TAKEOUT) {
|
||||
nactorx->draw.sub_anim_type = aNPC_SUB_ANIM_UMBRELLA;
|
||||
}
|
||||
#endif
|
||||
|
||||
aNPC_set_request_act(nactorx, 4, next_act_idx[requested - aNPC_ITEM_TYPE_UMBRELLA], aNPC_ACT_TYPE_DEFAULT,
|
||||
aNPC_req_default_data);
|
||||
@@ -136,7 +149,11 @@ static int aNPC_chk_left_hand(NPC_ACTOR* nactorx) {
|
||||
nactorx->left_hand.requested_item_type = aNPC_ITEM_TYPE_NONE;
|
||||
nactorx->left_hand.item_type = aNPC_ITEM_TYPE_LEFT_HAND;
|
||||
nactorx->left_hand.item_actor_p = item_p;
|
||||
#ifndef aNPC_NPC2
|
||||
aNPC_set_request_act(nactorx, 4, aNPC_ACT_TRANS, aNPC_ACT_TYPE_DEFAULT, aNPC_req_default_data);
|
||||
#else
|
||||
aNPC_set_request_act(nactorx, 4, aNPC_ACT_TRANS, aNPC_ACT_TYPE_DEFAULT, aNPC_req_default_data);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -81,7 +81,9 @@ static void aNPC_look_target(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
|
||||
if (nactorx->palActor != NULL) {
|
||||
switch (nactorx->action.idx) {
|
||||
#ifndef aNPC_NPC2
|
||||
case aNPC_ACT_GREETING:
|
||||
#endif
|
||||
case aNPC_ACT_TALK:
|
||||
if (nactorx->talk_info.turn != aNPC_TALK_TURN_NONE) {
|
||||
target = nactorx->palActor;
|
||||
|
||||
@@ -2,6 +2,7 @@ static void aNPC_actor_save_for_normal(ACTOR* actorx) {
|
||||
NPC_ACTOR* nactorx = (NPC_ACTOR*)actorx;
|
||||
Animal_c* animal = aNPC_GET_ANM(nactorx);
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
if (nactorx->action.idx == aNPC_ACT_INTO_HOUSE) {
|
||||
int home_ux = animal->home_info.block_x * UT_X_NUM + animal->home_info.ut_x;
|
||||
int home_uz = animal->home_info.block_z * UT_Z_NUM + animal->home_info.ut_z;
|
||||
@@ -10,6 +11,7 @@ static void aNPC_actor_save_for_normal(ACTOR* actorx) {
|
||||
aNPC_setup_stay_my_house(nactorx);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
aNPC_cancel_cloth_data(nactorx);
|
||||
animal->cloth = nactorx->draw.next_cloth_no;
|
||||
@@ -22,8 +24,10 @@ static void aNPC_actor_save_for_normal(ACTOR* actorx) {
|
||||
int feel_tim;
|
||||
|
||||
switch (animal->mood) {
|
||||
#ifndef aNPC_NPC2
|
||||
case mNpc_FEEL_PITFALL:
|
||||
mFI_SetFG_common(EMPTY_NO, actorx->world.position, TRUE);
|
||||
#endif
|
||||
// fallthrough 5 -> 4, 7, & 8
|
||||
case mNpc_FEEL_SLEEPY:
|
||||
case mNpc_FEEL_UZAI_0:
|
||||
@@ -38,6 +42,12 @@ static void aNPC_actor_save_for_normal(ACTOR* actorx) {
|
||||
|
||||
animal->mood_time = feel_tim;
|
||||
}
|
||||
|
||||
#ifdef aNPC_NPC2
|
||||
if (nactorx->schedule.type == aNPC_SCHEDULE_TYPE_FIELD && nactorx->think.idx == aNPC_THINK_EXIT_WAIT) {
|
||||
aNPC_set_be_out_home(nactorx);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void aNPC_actor_save_for_special(ACTOR* actorx) {
|
||||
@@ -69,9 +79,11 @@ static void aNPC_actor_save(ACTOR* actorx, GAME* game) {
|
||||
aNPC_actor_save_for_special(actorx);
|
||||
}
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
if (nactorx->movement.move_timer >= 18000 && nactorx->npc_info.list != NULL) {
|
||||
xyz_t_move(&actorx->world.position, &nactorx->npc_info.list->position);
|
||||
}
|
||||
#endif
|
||||
|
||||
mNpc_RenewalSetNpc(actorx);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ static void aNPC_OngenTrgStart(NPC_ACTOR* nactorx, u16 se_no) {
|
||||
sAdo_OngenTrgStart(se_no, &nactorx->actor_class.world.position);
|
||||
}
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
static void aNPC_WalkSe(xyz_t* pos_p) {
|
||||
u32 attr;
|
||||
u16 se_no;
|
||||
@@ -18,3 +19,23 @@ static void aNPC_WalkSe(xyz_t* pos_p) {
|
||||
static void aNPC_TumbleSe(xyz_t* pos_p) {
|
||||
sAdo_OngenTrgStart(sAdo_Get_KokeruLabel(mCoBG_Wpos2Attribute(*pos_p, NULL)), pos_p);
|
||||
}
|
||||
#else
|
||||
static void aNPC_WalkSeRoom(xyz_t* pos_p) {
|
||||
switch (Save_Get(scene_no)) {
|
||||
case SCENE_START_DEMO:
|
||||
case SCENE_START_DEMO2:
|
||||
case SCENE_START_DEMO3:
|
||||
sAdo_NpcWalkSe(NA_SE_207, pos_p);
|
||||
break;
|
||||
default: {
|
||||
s8 floor_idx = Common_Get(floor_idx);
|
||||
|
||||
if (floor_idx >= 0 && floor_idx < FLOOR_ETC_END) {
|
||||
sAdo_NpcWalkSeRoom(floor_idx, pos_p);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -369,7 +369,7 @@ static int aNPC_check_timing_demoCode(ACTOR* actorx) {
|
||||
case 3:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef aNPC_NPC2
|
||||
switch (order) {
|
||||
case 3:
|
||||
case 5: {
|
||||
@@ -406,6 +406,70 @@ static int aNPC_check_timing_demoCode(ACTOR* actorx) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
switch (order) {
|
||||
case 3:
|
||||
case 5: {
|
||||
u16 args[aNPC_REQUEST_ARG_NUM];
|
||||
|
||||
bzero(args, sizeof(args));
|
||||
args[0] = mDemo_Get_OrderValue(mDemo_ORDER_NPC1, 0);
|
||||
if (aNPC_set_request_act(nactorx, 4, aNPC_ACT_GET, aNPC_ACT_TYPE_DEFAULT, args) == TRUE) {
|
||||
aNPC_clear_timing_demoCode(type);
|
||||
ret = FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
case 4: {
|
||||
u16 args[aNPC_REQUEST_ARG_NUM];
|
||||
|
||||
bzero(args, sizeof(args));
|
||||
args[0] = mDemo_Get_OrderValue(mDemo_ORDER_NPC1, 0);
|
||||
args[1] = mDemo_Get_OrderValue(mDemo_ORDER_NPC1, 1);
|
||||
args[2] = mDemo_Get_OrderValue(mDemo_ORDER_NPC1, 2);
|
||||
if (aNPC_set_request_act(nactorx, 4, aNPC_ACT_TRANS, aNPC_ACT_TYPE_DEFAULT, args) == TRUE) {
|
||||
aNPC_clear_timing_demoCode(type);
|
||||
ret = FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
nactorx->right_hand.requested_item_type = aNPC_ITEM_TYPE_KEITAI;
|
||||
aNPC_clear_timing_demoCode(type);
|
||||
break;
|
||||
case 7:
|
||||
nactorx->right_hand.requested_item_type = aNPC_ITEM_TYPE_PUTAWAY;
|
||||
aNPC_clear_timing_demoCode(type);
|
||||
break;
|
||||
case 8:
|
||||
if (aNPC_set_request_act(nactorx, 4, aNPC_ACT_CONTRACT, aNPC_ACT_TYPE_DEFAULT, aNPC_req_default_data) == TRUE) {
|
||||
aNPC_clear_timing_demoCode(type);
|
||||
ret = FALSE;
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
if (aNPC_set_request_act(nactorx, 4, aNPC_ACT_NOT_CONTRACT, aNPC_ACT_TYPE_DEFAULT, aNPC_req_default_data) == TRUE) {
|
||||
aNPC_clear_timing_demoCode(type);
|
||||
ret = FALSE;
|
||||
}
|
||||
break;
|
||||
case 13:
|
||||
if (aNPC_set_request_act(nactorx, 4, aNPC_ACT_NOT_CONTRACT2, aNPC_ACT_TYPE_DEFAULT, aNPC_req_default_data) == TRUE) {
|
||||
aNPC_clear_timing_demoCode(type);
|
||||
ret = FALSE;
|
||||
}
|
||||
break;
|
||||
case 15: {
|
||||
if (aNPC_set_request_act(nactorx, 4, aNPC_ACT_CHANGE_CLOTH, aNPC_ACT_TYPE_DEFAULT, aNPC_req_default_data) == TRUE) {
|
||||
Common_Set(npc_chg_cloth, Now_Private->cloth.item);
|
||||
aNPC_clear_timing_demoCode(type);
|
||||
ret = FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -467,6 +531,9 @@ static void aNPC_setup_talk_end(NPC_ACTOR* nactorx) {
|
||||
}
|
||||
nactorx->talk_info.feel = 0xFF;
|
||||
nactorx->condition_info.demo_flg = nactorx->condition_info.talk_demo_flg_save;
|
||||
#ifdef aNPC_NPC2
|
||||
nactorx->talk_info.melody_inst = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void aNPC_set_talk_info_talk_request_check(ACTOR* actorx) {
|
||||
@@ -581,12 +648,20 @@ static void aNPC_talk_request_check(ACTOR* actorx, GAME* game) {
|
||||
nactorx->condition_info.talk_condition == aNPC_TALK_TYPE_NONE && !nactorx->condition_info.hide_flg) {
|
||||
if (mEv_CheckTitleDemo() == 0 || mEv_CheckTitleDemo() == -9) {
|
||||
if (nactorx->action.idx != aNPC_ACT_TALK) {
|
||||
#ifndef aNPC_NPC2
|
||||
if (ITEM_NAME_GET_TYPE(actorx->npc_id) == NAME_TYPE_SPNPC &&
|
||||
(nactorx->npc_info.animal == NULL || nactorx->npc_info.animal->mood != mNpc_FEEL_PITFALL)) {
|
||||
aNPC_talk_request_event_npc(actorx, game);
|
||||
} else {
|
||||
aNPC_talk_request_normal_npc(actorx, game);
|
||||
}
|
||||
#else
|
||||
if (ITEM_NAME_GET_TYPE(actorx->npc_id) == NAME_TYPE_SPNPC) {
|
||||
aNPC_talk_request_event_npc(actorx, game);
|
||||
} else {
|
||||
aNPC_talk_request_normal_npc(actorx, game);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ extern void sAdo_NpcWalkSe(u16 se_no, const xyz_t* pos) {
|
||||
Na_NpcWalkSe(se_no, scalc, fcalc);
|
||||
}
|
||||
|
||||
extern void sAdo_NpcWalkSeRoom(u16 se_no, const xyz_t* pos) {
|
||||
extern void sAdo_NpcWalkSeRoom(u8 se_no, const xyz_t* pos) {
|
||||
|
||||
f32 fcalc;
|
||||
u16 scalc;
|
||||
|
||||
Reference in New Issue
Block a user