diff --git a/include/ac_ev_soncho2.h b/include/ac_ev_soncho2.h index ca2fa35b..78637c2c 100644 --- a/include/ac_ev_soncho2.h +++ b/include/ac_ev_soncho2.h @@ -3,6 +3,7 @@ #include "types.h" #include "m_actor.h" +#include "ac_npc.h" #ifdef __cplusplus extern "C" { @@ -10,9 +11,73 @@ extern "C" { extern ACTOR_PROFILE Ev_Soncho2_Profile; +typedef struct ac_npc_soncho2 NPC_SONCHO2; + +typedef void (*aEV_SONCHO2_PROC)(NPC_SONCHO2* soncho, GAME_PLAY* play); + +struct ac_npc_soncho2 { + NPC_ACTOR npc_class; + /* 0x994 */ aEV_SONCHO2_PROC _994; + /* 0x998 */ lbRTC_year_t year; + /* 0x99a */ lbRTC_month_t month; + /* 0x99b */ lbRTC_day_t day; + /* 0x99c */ mActor_name_t item; + /* 0x99e */ s16 timer; + /* 0x9a0 */ s16 center_x; + /* 0x9a2 */ s16 center_z; + /* 0x9a4 */ s16 goal_x; + /* 0x9a6 */ s16 goal_z; + /* 0x9a8 */ u8 think_idx; + /* 0x9a9 */ u8 think; + /* 0x9aa */ u8 _9aa; + /* 0x9ab */ u8 talk; + /* 0x9ac */ u8 _9ac; + /* 0x9ad */ u8 melody_inst; + /* 0x9ae */ u8 event; +}; + +struct ev_foot_race_data { + u8 _0 : 1; + int flags : 32; +}; + +typedef struct ev_foot_race_data aES2_FOOT_RACE_DATA; + +enum soncho2_talk { + aES2_TALK_0, + aES2_TALK_1, + aES2_TALK_2, + aES2_TALK_LIGHTHOUSE_QUEST_START_1, + aES2_TALK_LIGHTHOUSE_QUEST_START_2, + aES2_TALK_5, + aES2_TALK_6, + aES2_TALK_7, + aES2_TALK_8, + aES2_TALK_9, + aES2_TALK_a, + aES2_TALK_TUG_O_WAR +}; + +enum soncho2_think { + aES2_THINK_0, + aES2_THINK_AEROBICS, + aES2_THINK_BALL_TOSS, + aES2_THINK_3, + aES2_THINK_4, + aES2_THINK_FOOT_RACE, + aES2_THINK_LIGHTHOUSE_QUEST_START, + aES2_THINK_7, + aES2_THINK_8, + aES2_THINK_9, + aES2_THINK_a, + aES2_THINK_b, + aES2_THINK_c, + aES2_THINK_d, + aES2_THINK_TUG_O_WAR, +}; + #ifdef __cplusplus } #endif #endif - diff --git a/include/m_msg_data.h b/include/m_msg_data.h index f819ca21..88e87aa8 100644 --- a/include/m_msg_data.h +++ b/include/m_msg_data.h @@ -13,6 +13,11 @@ extern "C" { #define MSG_SANTA_WISH_WALL 0x2B55 #define MSG_SANTA_WISH_CARPET 0x2B56 #define MSG_SANTA_WISH_CLOTH 0x2B57 +#define MSG_SONCHO_EVENTS 0x3280 +#define MSG_SONCHO_EVENTS_COUNT 10 +#define MSG_HARVEST_FESTIVAL 0x3391 +#define MSG_SONCHO_LIGHTHOUSE_1 0x33f4 +#define MSG_SONCHO_LIGHTHOUSE_2 0x340b #define MSG_MAX 0x3F91 /* Maximum message id */ diff --git a/src/actor/npc/event/ac_ev_soncho2.c b/src/actor/npc/event/ac_ev_soncho2.c new file mode 100644 index 00000000..4cb66799 --- /dev/null +++ b/src/actor/npc/event/ac_ev_soncho2.c @@ -0,0 +1,93 @@ +#include "ac_ev_soncho2.h" +#include "m_common_data.h" +#include "m_string.h" +#include "m_msg.h" +#include "m_private.h" +#include "m_demo.h" +#include "m_soncho.h" +#include "m_calendar.h" +#include "m_play.h" +#include "m_player.h" +#include "m_player_lib.h" +#include "libultra/libultra.h" +#include "m_event_map_npc.h" + +int aES2_change_talk_proc(ACTOR* actorx, u8 talk_proc); +void aES2_setup_think_proc(ACTOR* actorx, GAME* game, u8 think_proc); +void aES2_schedule_proc(NPC_ACTOR* npc, GAME_PLAY* play, int schedule); + +void aES2_actor_ct(ACTOR* actor, GAME* game); +void aES2_actor_dt(ACTOR* actor, GAME* game); +void aES2_actor_init(ACTOR* actor, GAME* game); +void aES2_actor_save(ACTOR* actor, GAME* game); +void aES2_actor_move(ACTOR* actor, GAME* game); +void aES2_actor_draw(ACTOR* actor, GAME* game); +int aES2_talk_init(ACTOR* actorx, GAME* game); +int aES2_talk_end_chk(NPC_SONCHO2* actorx, GAME_PLAY* game); + +ACTOR_PROFILE Ev_Soncho2_Profile = { mAc_PROFILE_EV_SONCHO2, ACTOR_PART_NPC, 0, + SP_NPC_EV_SONCHO2, ACTOR_OBJ_BANK_KEEP, sizeof(NPC_SONCHO2), + &aES2_actor_ct, &aES2_actor_dt, &aES2_actor_init, + mActor_NONE_PROC1, &aES2_actor_save }; + +void aES2_actor_ct(ACTOR* actorx, GAME* game) { + static aNPC_ct_data_c ct_data = { &aES2_actor_move, &aES2_actor_draw, 5, mActor_NONE_PROC1, + &aES2_talk_init, (aNPC_TALK_END_CHECK_PROC)&aES2_talk_end_chk, 0 }; + NPC_SONCHO2* soncho = (NPC_SONCHO2*)actorx; + if (CLIP(npc_clip)->birth_check_proc(actorx, game) == TRUE) { + ACTOR* player = (ACTOR*)GET_PLAYER_ACTOR_GAME(game); + soncho->npc_class.schedule.schedule_proc = aES2_schedule_proc; + CLIP(npc_clip)->ct_proc(actorx, game, &ct_data); + soncho->npc_class.palActorIgnoreTimer = -1; + soncho->npc_class.draw.sub_anim_type = 0x3; + soncho->_9ac = FALSE; + soncho->melody_inst = 0; + CLIP(npc_clip)->set_dst_pos_proc((NPC_ACTOR*)actorx, player->world.position.x, player->world.position.z); + actorx->cull_width = 1350.0f; + soncho->year = Common_Get(time).rtc_time.year; + soncho->month = Common_Get(time).rtc_time.month; + soncho->day = Common_Get(time).rtc_time.day; + mCD_calendar_check_delete(-1, soncho->year, soncho->month, soncho->day); + } +} + +void aES2_actor_save(ACTOR* actor, GAME* game) { + mNpc_RenewalSetNpc(actor); +} + +void aES2_actor_dt(ACTOR* actor, GAME* game) { + CLIP(npc_clip)->dt_proc(actor, game); + mSC_delete_soncho(actor, (GAME_PLAY*)game); +} + +void aES2_actor_init(ACTOR* actor, GAME* game) { + CLIP(npc_clip)->init_proc(actor, game); +} + +int aES2_set_request_act(NPC_SONCHO2* soncho, u8 priority, int idx, int type, int p7, int x, int z) { + int res = FALSE; + u16 buff[6]; + if (priority >= soncho->npc_class.request.act_priority) { + bzero(buff, 12); + buff[0] = p7; + buff[2] = x; + buff[3] = z; + soncho->npc_class.request.act_priority = priority; + soncho->npc_class.request.act_idx = idx; + soncho->npc_class.request.act_type = type; + mem_copy((u8*)soncho->npc_class.request.act_args, (u8*)buff, 12); + res = TRUE; + } + return res; +} + +void aES2_actor_move(ACTOR* actor, GAME* game) { + CLIP(npc_clip)->move_proc(actor, game); +} + +void aES2_actor_draw(ACTOR* actor, GAME* game) { + CLIP(npc_clip)->draw_proc(actor, game); +} + +#include "src/actor/npc/event/ac_ev_soncho2_talk.c_inc" +#include "src/actor/npc/event/ac_ev_soncho2_think.c_inc" diff --git a/src/actor/npc/event/ac_ev_soncho2_talk.c_inc b/src/actor/npc/event/ac_ev_soncho2_talk.c_inc new file mode 100644 index 00000000..6e8f5b4f --- /dev/null +++ b/src/actor/npc/event/ac_ev_soncho2_talk.c_inc @@ -0,0 +1,152 @@ +int aES2_kinenhin_msg(ACTOR* actorx, int msg_no) { + NPC_SONCHO2* soncho = (NPC_SONCHO2*)actorx; + if (soncho->event == mSC_EVENT_HARVEST_FESTIVAL) { + return msg_no + MSG_HARVEST_FESTIVAL; + } else { + return soncho->event * MSG_SONCHO_EVENTS_COUNT + MSG_SONCHO_EVENTS + msg_no; + } +} + +void aES2_LightHouse_set_free_str() { + lbRTC_time_c time_1; + lbRTC_time_c time_2; + u8 day_str[4]; + lbRTC_TimeCopy(&time_1, &Common_Get(time).rtc_time); + lbRTC_Add_DD(&time_1, 0x7); + lbRTC_TimeCopy(&time_2, &Common_Get(time).rtc_time); + lbRTC_Add_DD(&time_2, 0x8); + mString_Load_DayStringFromRom(day_str, time_1.day); + mMsg_Set_free_str(mMsg_Get_base_window_p(), FALSE, day_str, 4); + mString_Load_DayStringFromRom(day_str, time_2.day); + mMsg_Set_free_str(mMsg_Get_base_window_p(), TRUE, day_str, 4); +} + +void aES2_talk_before_give(NPC_SONCHO2* soncho, GAME_PLAY* play) { + mMsg_Window_c* msg_p = mMsg_Get_base_window_p(); + if (mMsg_Check_MainNormalContinue(msg_p)) { + if (mPr_GetPossessionItemSumWithCond(Now_Private, EMPTY_NO, mPr_ITEM_COND_NORMAL) == 0) { + mMsg_Set_continue_msg_num(msg_p, aES2_kinenhin_msg((ACTOR*)soncho, 2)); + aES2_change_talk_proc((ACTOR*)soncho, aES2_TALK_0); + } else { + mMsg_Set_continue_msg_num(msg_p, aES2_kinenhin_msg((ACTOR*)soncho, 0x3)); + aES2_change_talk_proc((ACTOR*)soncho, aES2_TALK_1); + } + } +} + +void aES2_talk_give(NPC_SONCHO2* soncho, GAME_PLAY* play) { + if ((int)mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 0x1) == 0x2) { + mSC_item_string_set(soncho->item, EMPTY_NO); + mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 0x0, soncho->item); + mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 0x1, 0x7); + mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 0x2, 0x0); + mPr_SetFreePossessionItem(Now_Private, soncho->item, mPr_ITEM_COND_NORMAL); + aES2_change_talk_proc((ACTOR*)soncho, aES2_TALK_5); + mSC_trophy_set(soncho->event); + } +} + +int aES2_change_talk_proc(ACTOR* actorx, u8 talk_proc) { + NPC_SONCHO2* soncho = (NPC_SONCHO2*)actorx; + soncho->talk = talk_proc; + return TRUE; +} + +void aES2_set_norm_talk_info(ACTOR* actorx) { + NPC_SONCHO2* soncho = (NPC_SONCHO2*)actorx; + mDemo_Set_talk_turn(TRUE); + mDemo_Set_camera(3); + aES2_change_talk_proc((ACTOR*)soncho, aES2_TALK_5); + + switch (soncho->event) { + case 0x65: + if (mSC_LightHouse_Talk_After_Check()) { + mDemo_Set_msg_num(MSG_SONCHO_LIGHTHOUSE_1 + 6 + (int)RANDOM_F(3)); + } else { + mDemo_Set_msg_num(MSG_SONCHO_LIGHTHOUSE_1); + aES2_change_talk_proc((ACTOR*)soncho, aES2_TALK_LIGHTHOUSE_QUEST_START_1); + } + break; + case 0x66: + if (mSC_LightHouse_Talk_After_Check()) { + mDemo_Set_msg_num(MSG_SONCHO_LIGHTHOUSE_2 + 6 + (int)RANDOM_F(3)); + } else { + mDemo_Set_msg_num(MSG_SONCHO_LIGHTHOUSE_2); + aES2_change_talk_proc((ACTOR*)soncho, aES2_TALK_LIGHTHOUSE_QUEST_START_1); + } + break; + default: + aES2_change_talk_proc((ACTOR*)soncho, aES2_TALK_5); + if (Common_Get(player_no) == 4) { + mDemo_Set_msg_num(aES2_kinenhin_msg((ACTOR*)soncho, 0x9)); + aES2_change_talk_proc((ACTOR*)soncho, aES2_TALK_2); + } else if (mSC_trophy_get(soncho->event) != 0) { + if (mCD_calendar_event_check(soncho->year, soncho->month, soncho->day, -1, soncho->event)) { + mDemo_Set_msg_num(aES2_kinenhin_msg((ACTOR*)soncho, 6 + (int)RANDOM_F(3))); + } else { + mDemo_Set_msg_num(aES2_kinenhin_msg((ACTOR*)soncho, 0x5)); + } + aES2_change_talk_proc((ACTOR*)soncho, aES2_TALK_LIGHTHOUSE_QUEST_START_2); + } else { + aES2_change_talk_proc((ACTOR*)soncho, aES2_TALK_0); + if (mCD_calendar_event_check(soncho->year, soncho->month, soncho->day, -1, soncho->event)) { + mDemo_Set_msg_num(aES2_kinenhin_msg((ACTOR*)soncho, 0x1)); + } else { + mDemo_Set_msg_num(aES2_kinenhin_msg((ACTOR*)soncho, 0x0)); + } + } + break; + } +} + +void aES2_norm_talk_request(ACTOR* actorx, GAME* game) { + NPC_SONCHO2* soncho = (NPC_SONCHO2*)actorx; + if (soncho->_9ac == FALSE) { + mDemo_Request(mDemo_ORDER_7, actorx, aES2_set_norm_talk_info); + } else { + soncho->_9ac = FALSE; + } +} + +int aES2_talk_init(ACTOR* actorx, GAME* game) { + NPC_SONCHO2* soncho = (NPC_SONCHO2*)actorx; + soncho->npc_class.talk_info.talk_request_proc = (aNPC_TALK_REQUEST_PROC)none_proc1; + mDemo_Set_ListenAble(); + mDemo_Start(actorx); + if (soncho->talk == aES2_TALK_LIGHTHOUSE_QUEST_START_1) { + mSC_LightHouse_Quest_Start(); + aES2_LightHouse_set_free_str(); + } + if (soncho->talk == aES2_TALK_LIGHTHOUSE_QUEST_START_2) { + mSC_item_string_set(soncho->item, EMPTY_NO); + } + if (soncho->talk == aES2_TALK_2) { + mSC_item_string_set(soncho->item, EMPTY_NO); + mSC_event_name_set(soncho->event); + } + mCD_calendar_event_on(soncho->year, soncho->month, soncho->day, soncho->event); + return TRUE; +} + +int aES2_talk_end_chk(NPC_SONCHO2* soncho, GAME_PLAY* play) { + static aEV_SONCHO2_PROC proc[6] = { aES2_talk_before_give, + aES2_talk_give, + (aEV_SONCHO2_PROC)mActor_NONE_PROC1, + (aEV_SONCHO2_PROC)mActor_NONE_PROC1, + (aEV_SONCHO2_PROC)mActor_NONE_PROC1, + (aEV_SONCHO2_PROC)mActor_NONE_PROC1 }; + + ACTOR* actorx = (ACTOR*)soncho; + GAME* game = (GAME*)play; + int res = FALSE; + proc[soncho->talk](soncho, play); + if (mDemo_Check(0x8, actorx) == FALSE && mDemo_Check(0x7, actorx) == FALSE) { + aES2_setup_think_proc(actorx, game, soncho->think); + if (soncho->melody_inst) { + soncho->npc_class.talk_info.melody_inst = soncho->melody_inst; + soncho->melody_inst = 0; + } + res = TRUE; + } + return res; +} diff --git a/src/actor/npc/event/ac_ev_soncho2_think.c_inc b/src/actor/npc/event/ac_ev_soncho2_think.c_inc new file mode 100644 index 00000000..619959b7 --- /dev/null +++ b/src/actor/npc/event/ac_ev_soncho2_think.c_inc @@ -0,0 +1,260 @@ +void aES2_set_move_pos(NPC_SONCHO2* soncho) { + switch (soncho->think_idx) { + case aES2_THINK_LIGHTHOUSE_QUEST_START: + soncho->goal_x = soncho->center_x + 0xa0; + soncho->goal_z = soncho->center_z - 0x78; + break; + case 0x8: + soncho->goal_x = soncho->center_x + 0xc8; + soncho->goal_z = soncho->center_z + 0x28; + break; + case 0xa: + soncho->goal_x = soncho->center_x - 0x78; + soncho->goal_z = soncho->center_z - 0x78; + break; + default: + soncho->goal_x = soncho->center_x - 0xa0; + soncho->goal_z = soncho->center_z + 0x28; + break; + } +} + +void aES2_wait(NPC_SONCHO2* soncho, GAME_PLAY* play) { + static u8 field_table[4] = { aES2_THINK_FOOT_RACE, aES2_THINK_BALL_TOSS, aES2_THINK_TUG_O_WAR, + aES2_THINK_AEROBICS }; + ACTOR* actorx = (ACTOR*)soncho; + GAME* game = (GAME*)play; + u8 event = mSC_get_soncho_event(); + if (event != 0xff) { + soncho->npc_class.think.interrupt_flags = FALSE; + soncho->npc_class.condition_info.demo_flg = aNPC_COND_DEMO_SKIP_FORWARD_CHECK; + switch (event) { + case mSC_EVENT_SPRING_SPORTS_FAIR: + case mSC_EVENT_FALL_SPORTS_FAIR: { + u8 think_proc = field_table[(u8)mSC_get_soncho_field_event()]; + aES2_setup_think_proc(actorx, game, think_proc); + break; + } + case mSC_SPECIAL_EVENT_JAN_VACATION: + case mSC_SPECIAL_EVENT_FEB_VACATION: + if (Common_Get(player_no) == mPr_FOREIGNER || mSC_LightHouse_Talk_After_Check()) { + Actor_delete(actorx); + } else { + aES2_setup_think_proc(actorx, game, aES2_THINK_3); + } + break; + default: + aES2_setup_think_proc(actorx, game, aES2_THINK_4); + break; + } + if (event == mSC_EVENT_NEW_YEARS_EVE_COUNTDOWN && soncho->day != 31) { + soncho->year -= 1; + soncho->month = lbRTC_DECEMBER; + soncho->day = 31; + } + soncho->event = event; + soncho->item = mSC_trophy_item(event); + } +} + +void aES2_look_runner(NPC_SONCHO2* soncho, GAME_PLAY* play) { + s16* save_area = (s16*)mEv_get_save_area(mEv_EVENT_SPORTS_FAIR_FOOT_RACE, 0x8); + if (save_area != NULL) { + int flags = ((u16*)save_area)[1]; + if ((flags & 0x400) != 0) { + aES2_set_request_act(soncho, 0x4, aNPC_ACT_TURN2, aNPC_ACT_TYPE_TO_POINT, 0x0, save_area[5], save_area[6]); + } + } +} + +void aES2_bskt_birth(NPC_SONCHO2* soncho, GAME_PLAY* play) { + s16 oyasiro_p[3]; + if (mFI_SetOyasiroPos(oyasiro_p)) { + soncho->center_x = oyasiro_p[0]; + soncho->center_z = oyasiro_p[1]; + aES2_setup_think_proc((ACTOR*)soncho, (GAME*)play, aES2_THINK_LIGHTHOUSE_QUEST_START); + } +} + +void aES2_bskt_turn_next(NPC_SONCHO2* soncho, GAME_PLAY* play) { + if (soncho->npc_class.action.idx == aNPC_ACT_TURN && soncho->npc_class.action.step == 0xff) { + aES2_setup_think_proc((ACTOR*)soncho, (GAME*)play, ++soncho->think_idx); + } +} + +void aES2_bskt_move_next(NPC_SONCHO2* soncho, GAME_PLAY* play) { + if (soncho->npc_class.action.idx == aNPC_ACT_WALK && soncho->npc_class.action.step == 0xff) { + aES2_setup_think_proc((ACTOR*)soncho, (GAME*)play, ++soncho->think_idx); + } else { + if ((s16)soncho->npc_class.movement.dst_pos_x != soncho->goal_x || + (s16)soncho->npc_class.movement.dst_pos_z != soncho->goal_z) { + aES2_setup_think_proc((ACTOR*)soncho, (GAME*)play, --soncho->think_idx); + } + } +} + +void aES2_bskt_timer_next(NPC_SONCHO2* soncho, GAME_PLAY* play) { + if (soncho->timer > 0) { + soncho->timer--; + } else { + u8 think_proc = soncho->think_idx; + if (think_proc >= aES2_THINK_d) { + aES2_setup_think_proc((ACTOR*)soncho, (GAME*)play, aES2_THINK_LIGHTHOUSE_QUEST_START); + } else { + soncho->think_idx = ++think_proc; + aES2_setup_think_proc((ACTOR*)soncho, (GAME*)play, think_proc); + } + } +} + +void aES2_tug_of_war(NPC_SONCHO2* soncho, GAME_PLAY* play) { + ACTOR* actorx = (ACTOR*)soncho; + if (soncho->timer > 0) { + soncho->timer--; + } else { + aES2_setup_think_proc(actorx, (GAME*)play, soncho->think_idx); + } + if (soncho->npc_class.draw.animation_id == aNPC_ANIM_CLAP1) { + sAdo_OngenPos((u32)actorx, 0x2f, &actorx->world.position); + } +} + +void aES2_think_main_proc(NPC_SONCHO2* soncho, GAME_PLAY* play) { + soncho->npc_class.condition_info.demo_flg |= aNPC_COND_DEMO_SKIP_FOOTSTEPS; + soncho->_994(soncho, play); +} + +void aES2_think_init_proc(NPC_SONCHO2* soncho, GAME_PLAY* play) { + ACTOR* actorx = (ACTOR*)soncho; + actorx->status_data.weight = 0xfe; + soncho->npc_class.condition_info.hide_request = FALSE; + aES2_setup_think_proc((ACTOR*)actorx, (GAME*)play, aES2_THINK_0); +} + +void aES2_normal_wait_init(NPC_SONCHO2* soncho, GAME_PLAY* play) { + aES2_set_request_act(soncho, 0x4, aNPC_ACT_WAIT, aNPC_ACT_TYPE_DEFAULT, 0x0, 0x0, 0x0); +} + +void aES2_wander_init(NPC_SONCHO2* soncho, GAME_PLAY* play) { + ACTOR* actorx = (ACTOR*)soncho; + CLIP(npc_clip)->chg_schedule_proc((NPC_ACTOR*)soncho, play, aNPC_SCHEDULE_TYPE_WALK_WANDER); + actorx->status_data.weight = 0x50; +} + +void aES2_bskt_turn_init(NPC_SONCHO2* soncho, GAME_PLAY* play) { + aES2_set_move_pos(soncho); + aES2_set_request_act(soncho, 0x4, aNPC_ACT_TURN, aNPC_ACT_TYPE_TO_POINT, 0x0, soncho->goal_x, soncho->goal_z); +} + +void aES2_bskt_move_init(NPC_SONCHO2* soncho, GAME_PLAY* play) { + soncho->timer = 0x12c; + aES2_set_request_act(soncho, 0x4, aNPC_ACT_WALK, aNPC_ACT_TYPE_TO_POINT, 0x0, soncho->goal_x, soncho->goal_z); +} + +void aES2_force_wait_init(NPC_SONCHO2* soncho, GAME_PLAY* play) { + soncho->npc_class.action.idx = aNPC_ACT_RUN; + aES2_normal_wait_init(soncho, play); +} + +void aES2_tug_of_war_init(NPC_SONCHO2* soncho, GAME_PLAY* play) { + ACTOR* actorx = (ACTOR*)soncho; + soncho->npc_class.action.idx = aNPC_ACT_WAIT; + aES2_normal_wait_init(soncho, play); + soncho->timer = 0x12c; + CLIP(npc_clip)->set_dst_pos_proc((NPC_ACTOR*)soncho, actorx->world.position.x - 20.0f, + actorx->world.position.z + 50.0f); + soncho->npc_class.draw.main_animation.keyframe.frame_control.mode = 1; + if (RANDOM_F(1) < 0.5f) { + CLIP(npc_clip)->animation_init_proc(actorx, aNPC_ANIM_CLAP1, FALSE); + } else { + CLIP(npc_clip)->animation_init_proc(actorx, aNPC_ANIM_WAIT1, FALSE); + } +} + +static u8 dt_tbl[15][5] = { { 1, 1, 0, aES2_TALK_0, aES2_THINK_0 }, + { 0, 1, 0, aES2_TALK_0, aES2_THINK_AEROBICS }, + { 3, 1, 0, aES2_TALK_0, aES2_THINK_BALL_TOSS }, + { 0, 3, 1, aES2_TALK_0, aES2_THINK_3 }, + { 0, 3, 1, aES2_TALK_1, aES2_THINK_4 }, + { 2, 2, 1, aES2_TALK_2, aES2_THINK_FOOT_RACE }, + { 4, 4, 1, aES2_TALK_LIGHTHOUSE_QUEST_START_1, aES2_THINK_LIGHTHOUSE_QUEST_START }, + { 5, 5, 1, aES2_TALK_LIGHTHOUSE_QUEST_START_2, aES2_THINK_LIGHTHOUSE_QUEST_START }, + { 4, 4, 1, aES2_TALK_5, aES2_THINK_8 }, + { 6, 2, 1, aES2_TALK_6, aES2_THINK_8 }, + { 4, 4, 1, aES2_TALK_7, aES2_THINK_a }, + { 5, 5, 1, aES2_TALK_8, aES2_THINK_a }, + { 4, 4, 1, aES2_TALK_9, aES2_THINK_c }, + { 6, 2, 1, aES2_TALK_a, aES2_THINK_c }, + { 7, 6, 1, aES2_TALK_TUG_O_WAR, aES2_THINK_TUG_O_WAR } }; +static aEV_SONCHO2_PROC proc_table[8] = { (aEV_SONCHO2_PROC)mActor_NONE_PROC1, + aES2_wait, + aES2_look_runner, + aES2_bskt_birth, + aES2_bskt_turn_next, + aES2_bskt_move_next, + aES2_bskt_timer_next, + aES2_tug_of_war }; +static aEV_SONCHO2_PROC init_table[7] = { + (aEV_SONCHO2_PROC)mActor_NONE_PROC1, + aES2_normal_wait_init, + aES2_force_wait_init, + aES2_wander_init, + aES2_bskt_turn_init, + aES2_bskt_move_init, + aES2_tug_of_war_init, +}; + +void aES2_setup_think_proc(ACTOR* actorx, GAME* game, u8 think_idx) { + static aNPC_TALK_REQUEST_PROC talk_request_table[3] = { + (aNPC_TALK_REQUEST_PROC)mActor_NONE_PROC1, + aES2_norm_talk_request, + (aNPC_TALK_REQUEST_PROC)mActor_NONE_PROC1, + }; + NPC_SONCHO2* soncho = (NPC_SONCHO2*)actorx; + u8* data = dt_tbl[think_idx]; + + soncho->think_idx = think_idx; + + soncho->_994 = proc_table[data[0]]; + soncho->npc_class.talk_info.talk_request_proc = talk_request_table[data[2]]; + soncho->talk = data[3]; + soncho->think = data[4]; + + init_table[data[1]](soncho, (GAME_PLAY*)game); + + soncho->_9ac = TRUE; +} + +void aES2_think_proc(NPC_ACTOR* npc, GAME_PLAY* play, int type) { + switch (type) { + case 0x0: + aES2_think_init_proc((NPC_SONCHO2*)npc, play); + break; + case 0x1: + aES2_think_main_proc((NPC_SONCHO2*)npc, play); + break; + } +} + +void aES2_schedule_init_proc(NPC_ACTOR* npc, GAME_PLAY* play) { + NPC_SONCHO2* soncho = (NPC_SONCHO2*)npc; + soncho->npc_class.think.think_proc = aES2_think_proc; + CLIP(npc_clip)->think_proc(npc, play, aNPC_THINK_SPECIAL, 0); +} + +void aES2_schedule_main_proc(NPC_ACTOR* npc, GAME_PLAY* play) { + if (CLIP(npc_clip)->think_proc(npc, play, -1, 1) == FALSE) { + CLIP(npc_clip)->think_proc(npc, play, -1, 2); + } +} + +void aES2_schedule_proc(NPC_ACTOR* npc, GAME_PLAY* play, int type) { + switch (type) { + case 0x0: + aES2_schedule_init_proc(npc, play); + break; + case 0x1: + aES2_schedule_main_proc(npc, play); + break; + } +}