Files
ac-decomp/src/ac_ev_ghost_schedule.c_inc
T
2024-01-17 13:18:25 -05:00

377 lines
10 KiB
Plaintext

static void aEGH_look_player(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
if (ghost->npc_class.action.step == aNPC_ACTION_END_STEP) {
u8 action = 4;
s16 player_y = ghost->npc_class.actor_class.player_angle_y;
s16 rot_y = ghost->npc_class.actor_class.shape_info.rotation.y;
s16 diff = player_y - rot_y;
if (ABS(diff) < DEG2SHORT_ANGLE(67.5f)) {
action = 0;
}
aEGH_set_request_act(ghost, 4, action, 2, 1, 0, 0);
}
}
static int aEGH_bitset_func(u16 bit) {
u32 player_no = Common_Get(player_no);
mEv_gst_c* ghost_save = (mEv_gst_c*)mEv_get_save_area(mEv_EVENT_GHOST, 54);
mEv_gst_common_c* ghost_common = (mEv_gst_common_c*)mEv_get_common_area(mEv_EVENT_GHOST, 55);
if (player_no == mPr_FOREIGNER) {
if (ghost_common != NULL) {
ghost_common->flags |= bit;
return TRUE;
}
}
else if (ghost_save != NULL) {
ghost_save->flags |= (u16)(bit << player_no);
return TRUE;
}
return FALSE;
}
static int aEGH_bitclr_func(u16 bit) {
u32 player_no = Common_Get(player_no);
mEv_gst_c* ghost_save = (mEv_gst_c*)mEv_get_save_area(mEv_EVENT_GHOST, 54);
mEv_gst_common_c* ghost_common = (mEv_gst_common_c*)mEv_get_common_area(mEv_EVENT_GHOST, 55);
if (player_no == mPr_FOREIGNER) {
if (ghost_common != NULL) {
ghost_common->flags &= ~bit;
return TRUE;
}
}
else if (ghost_save != NULL) {
ghost_save->flags &= ~(u16)(bit << player_no);
return TRUE;
}
return FALSE;
}
static u16 aEGH_bitcheck_func(u16 bit) {
u32 player_no = Common_Get(player_no);
mEv_gst_c* ghost_save = (mEv_gst_c*)mEv_get_save_area(mEv_EVENT_GHOST, 54);
mEv_gst_common_c* ghost_common = (mEv_gst_common_c*)mEv_get_common_area(mEv_EVENT_GHOST, 55);
if (player_no == mPr_FOREIGNER) {
if (ghost_common != NULL) {
return ghost_common->flags & bit;
}
}
else if (ghost_save != NULL) {
return (u16)(bit << player_no) & ghost_save->flags;
}
return FALSE;
}
static int aEGH_equal_block(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
int bx;
int bz;
mFI_Wpos2BlockNum(&bx, &bz, GET_PLAYER_ACTOR(play)->actor_class.world.position);
return bx == ghost->npc_class.actor_class.block_x && bz == ghost->npc_class.actor_class.block_z;
}
static int aEGH_time_over() {
return Common_Get(time.now_sec) > (4 * mTM_SECONDS_IN_HOUR);
}
static void aEGH_byebye_check(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
ACTOR* actorx = (ACTOR*)ghost;
if (
mDemo_Check(mDemo_TYPE_TALK, actorx) == FALSE &&
mDemo_Check(mDemo_TYPE_SPEAK, actorx) == FALSE &&
aEGH_time_over() != FALSE
) {
if (aEGH_equal_block(ghost, play)) {
switch (ghost->think_act) {
case aEGH_THINK_SPEAK:
{
aEGH_setup_think_proc(ghost, play, aEGH_THINK_BYEBYE);
ghost->msg_no = 0x2EDD;
ghost->npc_class.actor_class.talk_distance = 1000.0f;
ghost->_9AA = 1;
break;
}
case aEGH_THINK_NORMAL_WAIT:
case aEGH_THINK_IRAI_AF:
case aEGH_THINK_BYE:
case aEGH_THINK_WELCOM:
{
Actor_delete((ACTOR*)ghost);
break;
}
}
}
else {
aEGH_setup_think_proc(ghost, play, aEGH_THINK_IRAI);
}
}
}
static void aEGH_irai(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
if (ghost->npc_class.actor_class.player_distance_xz > 220.0f) {
aEGH_setup_think_proc(ghost, play, aEGH_THINK_BYE);
}
}
static void aEGH_bye(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
if (ghost->npc_class.actor_class.player_distance_xz < 200.0f) {
aEGH_setup_think_proc(ghost, play, aEGH_THINK_WELCOM);
}
}
static void aEGH_byebye(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
if (ghost->alpha == 0) {
Actor_delete((ACTOR*)ghost);
}
else {
if (ghost->bye_bye_timer != 0) {
ghost->bye_bye_timer--;
if (ghost->bye_bye_timer == 0) {
sAdo_SysTrgStart(0x16C);
}
}
else {
if (ghost->bye_bye_angle < 30000) {
ghost->bye_bye_angle += 60;
}
ghost->npc_class.actor_class.shape_info.rotation.y += ghost->bye_bye_angle;
ghost->npc_class.actor_class.world.angle.y = ghost->npc_class.actor_class.shape_info.rotation.y;
ghost->npc_class.movement.mv_angl = ghost->npc_class.actor_class.world.angle.y;
ghost->npc_class.movement.mv_add_angl = 0;
}
if (ghost->bye_bye_scale_timer != 0) {
ghost->bye_bye_scale_timer--;
}
else {
ghost->npc_class.actor_class.scale.x += -0.00004f;
ghost->npc_class.actor_class.scale.z = ghost->npc_class.actor_class.scale.x;
}
}
}
static void aEGH_speak_byebye(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
ACTOR* actorx = (ACTOR*)ghost;
if (
mDemo_Check(mDemo_TYPE_TALK, actorx) == FALSE &&
mDemo_Check(mDemo_TYPE_SPEAK, actorx) == FALSE &&
aEGH_equal_block(ghost, play) == FALSE
) {
aEGH_setup_think_proc(ghost, play, aEGH_THINK_IRAI);
}
}
static void aEGH_think_main_proc(NPC_ACTOR* actorx, GAME_PLAY* play) {
EV_GHOST_ACTOR* ghost = (EV_GHOST_ACTOR*)actorx;
(*ghost->think_proc)(ghost, play);
aEGH_look_player(ghost, play);
}
static void aEGH_think_init_proc(NPC_ACTOR* actorx, GAME_PLAY* play) {
EV_GHOST_ACTOR* ghost = (EV_GHOST_ACTOR*)actorx;
u8 think_act;
if (ghost->_9AC) {
ghost->_9AC = FALSE;
}
else {
if (aEGH_bitcheck_func(aEGH_BIT_FOUND_GHOST)) {
ghost->alpha = 140;
think_act = aEGH_THINK_SPEAK;
}
else {
ghost->alpha = 0;
think_act = aEGH_THINK_IRAI_AF;
}
actorx->actor_class.status_data.weight = 255;
actorx->condition_info.hide_request = FALSE;
aEGH_setup_think_proc(ghost, play, think_act);
actorx->condition_info.demo_flg = aNPC_COND_DEMO_SKIP_FOOTSTEPS_VFX |
aNPC_COND_DEMO_SKIP_FEEL_CHECK |
aNPC_COND_DEMO_SKIP_FOOTSTEPS |
aNPC_COND_DEMO_SKIP_ENTRANCE_CHECK |
aNPC_COND_DEMO_SKIP_HEAD_LOOKAT;
}
}
static void aEGH_normal_wait_init(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
(*Common_Get(clip).npc_clip->animation_init_proc)((ACTOR*)ghost, 126, FALSE);
ghost->npc_class.draw.main_animation.keyframe.frame_control.mode = cKF_FRAMECONTROL_REPEAT;
ghost->npc_class.action.idx = 0;
aEGH_set_request_act(ghost, 4, 0, 0, 0, 0, 0);
}
static void aEGH_irai_init(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
ghost->npc_class.actor_class.talk_distance = 80.0f;
aEGH_normal_wait_init(ghost, play);
ghost->msg_no = 0x2EE2;
}
static void aEGH_irai_af_init(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
ghost->npc_class.actor_class.talk_distance = 55.0f;
ghost->msg_no = 0x2EE7;
(*Common_Get(clip).npc_clip->chg_schedule_proc)((NPC_ACTOR*)ghost, play, 5);
ghost->npc_class.actor_class.status_data.weight = 80;
}
static void aEGH_bye_init(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
ghost->npc_class.actor_class.talk_distance = 280.0f;
aEGH_normal_wait_init(ghost, play);
ghost->msg_no = 0x2ED8;
}
static void aEGH_welcom_init(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
ghost->npc_class.actor_class.talk_distance = 200.0f;
aEGH_normal_wait_init(ghost, play);
ghost->msg_no = 0x2ED3;
}
static void aEGH_byebye_init(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
aEGH_bitclr_func(aEGH_BIT_FOUND_GHOST);
ghost->bye_bye_angle = -1000;
ghost->bye_bye_timer = 25;
ghost->bye_bye_scale_timer = 48;
ghost->bye_bye_transparency_delay_timer = 43;
aEGH_normal_wait_init(ghost, play);
ghost->npc_class.head.lock_flag = TRUE;
}
static aEGH_setup_c dt_tbl[aEGH_THINK_NUM] = {
{
aEGH_THINK_PROC_BYE,
aEGH_THINK_INIT_NORMAL_WAIT,
aEGH_TALK_REQUEST_NONE,
aEGH_TALK_END_WAIT,
aEGH_THINK_NORMAL_WAIT
},
{
aEGH_THINK_PROC_BYEBYE,
aEGH_THINK_INIT_BYEBYE,
aEGH_TALK_REQUEST_NONE,
aEGH_TALK_END_WAIT,
aEGH_THINK_IRAI
},
{
aEGH_THINK_PROC_NONE,
aEGH_THINK_INIT_WELCOM,
aEGH_TALK_REQUEST_FORCE,
aEGH_TALK_END_WAIT,
aEGH_THINK_WELCOM
},
{
aEGH_THINK_PROC_BYE,
aEGH_THINK_INIT_BYE,
aEGH_TALK_REQUEST_FORCE,
aEGH_TALK_GIVE_ME_WAIT,
aEGH_THINK_NORMAL_WAIT
},
{
aEGH_THINK_PROC_IRAI,
aEGH_THINK_INIT_IRAI,
aEGH_TALK_REQUEST_FORCE,
aEGH_TALK_SELECT_WAIT,
aEGH_THINK_SPEAK
},
{
aEGH_THINK_PROC_SPEAK_BYEBYE,
aEGH_THINK_INIT_NORMAL_WAIT,
aEGH_TALK_REQUEST_FORCE,
aEGH_TALK_SELECT_ROOF,
aEGH_THINK_IRAI
},
{
aEGH_THINK_PROC_NONE,
aEGH_THINK_INIT_IRAI_AF,
aEGH_TALK_REQUEST_NORM,
aEGH_TALK_END_WAIT,
aEGH_THINK_SPEAK
}
};
static aEGH_PROC proc_table[aEGH_THINK_PROC_NUM] = {
(aEGH_PROC)&none_proc1,
&aEGH_irai,
&aEGH_bye,
&aEGH_byebye,
&aEGH_speak_byebye
};
static aEGH_PROC init_table[aEGH_THINK_INIT_NUM] = {
(aEGH_PROC)&none_proc1,
&aEGH_normal_wait_init,
&aEGH_irai_init,
&aEGH_irai_af_init,
&aEGH_bye_init,
&aEGH_welcom_init,
&aEGH_byebye_init
};
static void aEGH_setup_think_proc(EV_GHOST_ACTOR* ghost, GAME_PLAY* play, u8 think_act) {
static aNPC_TALK_REQUEST_PROC talk_request_table[aEGH_TALK_REQUEST_NUM] = {
(aNPC_TALK_REQUEST_PROC)&none_proc1,
&aEGH_norm_talk_request,
&aEGH_force_talk_request
};
aEGH_setup_c* data = &dt_tbl[think_act];
ghost->think_act = think_act;
ghost->think_proc = proc_table[data->think_proc];
ghost->npc_class.talk_info.talk_request_proc = talk_request_table[data->talk_request_proc];
ghost->talk_act = data->talk_act;
ghost->after_talk_think_act = data->talk_after_act;
(*init_table[data->think_init_proc])(ghost, play);
ghost->_9A7 = TRUE;
}
static void aEGH_think_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int think_type) {
switch (think_type) {
case 0:
aEGH_think_init_proc(actorx, play);
break;
case 1:
aEGH_think_main_proc(actorx, play);
break;
}
}
static void aEGH_schedule_init_proc(NPC_ACTOR* actorx, GAME_PLAY* play) {
actorx->think.think_proc = &aEGH_think_proc;
(*Common_Get(clip).npc_clip->think_proc)(actorx, play, aNPC_THINK_SPECIAL, 0);
}
static void aEGH_schedule_main_proc(NPC_ACTOR* actorx, GAME_PLAY* play) {
if ((*Common_Get(clip).npc_clip->think_proc)(actorx, play, -1, 1) == FALSE) {
(*Common_Get(clip).npc_clip->think_proc)(actorx, play, -1, 2);
}
}
static void aEGH_schedule_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int sched_type) {
switch (sched_type) {
case 0:
aEGH_schedule_init_proc(actorx, play);
break;
case 1:
aEGH_schedule_main_proc(actorx, play);
break;
}
}