From 61a64fdf5156992280e2e97cc47eab54594ee0da Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Sat, 8 Feb 2025 01:45:20 -0500 Subject: [PATCH] Implement & link ac_ev_dozaemon --- configure.py | 2 +- include/ac_ev_dozaemon.h | 60 +++++- src/actor/npc/event/ac_ev_dozaemon.c | 146 ++++++++++++++ src/actor/npc/event/ac_ev_dozaemon_move.c_inc | 188 ++++++++++++++++++ .../npc/event/ac_ev_dozaemon_schedule.c_inc | 130 ++++++++++++ 5 files changed, 524 insertions(+), 2 deletions(-) create mode 100644 src/actor/npc/event/ac_ev_dozaemon.c create mode 100644 src/actor/npc/event/ac_ev_dozaemon_move.c_inc create mode 100644 src/actor/npc/event/ac_ev_dozaemon_schedule.c_inc diff --git a/configure.py b/configure.py index 0e6ddb6f..c1bffa84 100644 --- a/configure.py +++ b/configure.py @@ -1167,7 +1167,7 @@ config.libs = [ Object(Matching, "actor/npc/event/ac_ev_castaway.c"), Object(NonMatching, "actor/npc/event/ac_ev_designer.c"), Object(Matching, "actor/npc/event/ac_ev_dokutu.c"), - Object(NonMatching, "actor/npc/event/ac_ev_dozaemon.c"), + Object(Matching, "actor/npc/event/ac_ev_dozaemon.c"), Object(Matching, "actor/npc/event/ac_ev_ghost.c"), Object(Matching, "actor/npc/event/ac_ev_gypsy.c"), Object(Matching, "actor/npc/event/ac_ev_kabuPeddler.c"), diff --git a/include/ac_ev_dozaemon.h b/include/ac_ev_dozaemon.h index a5bf343b..3bf3df53 100644 --- a/include/ac_ev_dozaemon.h +++ b/include/ac_ev_dozaemon.h @@ -3,11 +3,70 @@ #include "types.h" #include "m_actor.h" +#include "ac_npc.h" #ifdef __cplusplus extern "C" { #endif +#define aEDZ_SAVE_FLAG_WAKEUP (1 << 0) +#define aEDZ_SAVE_FLAG_GIVE (1 << 1) +#define aEDZ_SAVE_FLAG_GAVE_FIRST (1 << 2) + +enum { + aEDZ_INIT_PROC_NONE, + aEDZ_INIT_PROC_NORMAL_WAIT, + aEDZ_INIT_PROC_TAORERU, + aEDZ_INIT_PROC_OKIAGARU, + aEDZ_INIT_PROC_WANDER, + + aEDZ_INIT_PROC_NUM +}; + +enum { + aEDZ_THINK_PROC_NONE, + aEDZ_THINK_PROC_ANIME_NEXT, + + aEDZ_THINK_PROC_NUM +}; + +enum { + aEDZ_TALK_PROC_NONE, + aEDZ_TALK_PROC_NORMAL, + aEDZ_TALK_PROC_FORCE, + + aEDZ_TALK_PROC_NUM +}; + +enum { + aEDZ_THINK_NORMAL_WAIT, + aEDZ_THINK_TAORERU, + aEDZ_THINK_OKIAGARU, + aEDZ_THINK_OKIAGARU_AFTER, + aEDZ_THINK_WANDER, + + aEDZ_THINK_NUM +}; + +typedef struct dozaemon_actor_s DOZAEMON_ACTOR; + +typedef void (*aEDZ_THINK_PROC)(DOZAEMON_ACTOR* actor, GAME_PLAY* play); +typedef void (*aEDZ_TALK_PROC)(DOZAEMON_ACTOR* actor, GAME_PLAY* play); + +struct dozaemon_actor_s { + NPC_ACTOR npc_class; + aEDZ_THINK_PROC think_proc; + aEDZ_TALK_PROC talk_proc; + s16 give_flag; + s16 _99E[2]; + u8 think_idx; + u8 next_think_idx; + u8 _9A4; + u8 _9A5; + u8 change_think; + u8 melody_backup; +}; + extern ACTOR_PROFILE Ev_Dozaemon_Profile; #ifdef __cplusplus @@ -15,4 +74,3 @@ extern ACTOR_PROFILE Ev_Dozaemon_Profile; #endif #endif - diff --git a/src/actor/npc/event/ac_ev_dozaemon.c b/src/actor/npc/event/ac_ev_dozaemon.c new file mode 100644 index 00000000..ab9edf47 --- /dev/null +++ b/src/actor/npc/event/ac_ev_dozaemon.c @@ -0,0 +1,146 @@ +#include "ac_ev_dozaemon.h" + +#include "m_common_data.h" +#include "libultra/libultra.h" +#include "m_msg.h" +#include "m_player_lib.h" + +enum { + aEDZ_TALK_END_WAIT, + aEDZ_TALK_STOP_PLAYER, + aEDZ_TALK_OKIAGARU, + aEDZ_TALK_GIVE, + + aEDZ_TALK_NUM +}; + +static void aEDZ_actor_ct(ACTOR* actorx, GAME* game); +static void aEDZ_actor_dt(ACTOR* actorx, GAME* game); +static void aEDZ_actor_move(ACTOR* actorx, GAME* game); +static void aEDZ_actor_init(ACTOR* actorx, GAME* game); +static void aEDZ_actor_draw(ACTOR* actorx, GAME* game); +static void aEDZ_actor_save(ACTOR* actorx, GAME* game); + +ACTOR_PROFILE Ev_Dozaemon_Profile = { + mAc_PROFILE_EV_DOZAEMON, + ACTOR_PART_NPC, + ACTOR_STATE_NONE, + SP_NPC_EV_DOZAEMON, + ACTOR_OBJ_BANK_KEEP, + sizeof(DOZAEMON_ACTOR), + aEDZ_actor_ct, + aEDZ_actor_dt, + aEDZ_actor_init, + mActor_NONE_PROC1, + aEDZ_actor_save, +}; + +static int aEDZ_talk_init(ACTOR* actorx, GAME* game); +static int aEDZ_talk_end_chk(ACTOR* actorx, GAME* game); + +static int aEDZ_change_talk_proc(DOZAEMON_ACTOR* dozaemon, int talk_act); + +static void aEDZ_setup_think_proc(DOZAEMON_ACTOR* dozaemon, GAME_PLAY* play, u8 think_idx); + +static void aEDZ_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int sched_type); + +static void aEDZ_actor_ct(ACTOR* actorx, GAME* game) { + static aNPC_ct_data_c ct_data = { + aEDZ_actor_move, + aEDZ_actor_draw, + aNPC_CT_SCHED_TYPE_SPECIAL, + mActor_NONE_PROC1, + aEDZ_talk_init, + aEDZ_talk_end_chk, + 0, + }; + + mEv_dozaemon_c* dozaemon_ev = (mEv_dozaemon_c*)mEv_get_save_area(mEv_EVENT_DOZAEMON, 13); + + if (CLIP(npc_clip)->birth_check_proc(actorx, game) == TRUE) { + DOZAEMON_ACTOR* dozaemon = (DOZAEMON_ACTOR*)actorx; + u32 attribute; + f32 pos_z; + f32 pos_x; + + dozaemon->npc_class.schedule.schedule_proc = aEDZ_schedule_proc; + CLIP(npc_clip)->ct_proc(actorx, game, &ct_data); + dozaemon->npc_class.palActorIgnoreTimer = -1; + dozaemon->change_think = 0; + dozaemon->melody_backup = 0; + + aNPC_SPNPC_BIT_SET(Common_Get(spnpc_first_talk_flags), aNPC_SPNPC_BIT_DOZAEMON); + + attribute = mCoBG_Wpos2BgAttribute_Original(actorx->world.position); + pos_z = actorx->world.position.z - 10.0f; + pos_x = actorx->world.position.x; + + if (attribute == mCoBG_ATTRIBUTE_25) { + pos_x -= 10.0f; + } else if (attribute == mCoBG_ATTRIBUTE_26) { + pos_x += 10.0f; + } + + CLIP(npc_clip)->set_dst_pos_proc(&dozaemon->npc_class, pos_x, pos_z); + actorx->shape_info.rotation.y = dozaemon->npc_class.movement.mv_angl; + actorx->world.angle.y = dozaemon->npc_class.movement.mv_angl; + + if (dozaemon_ev == NULL) { + dozaemon_ev = (mEv_dozaemon_c*)mEv_reserve_save_area(mEv_EVENT_DOZAEMON, 13); + dozaemon_ev->flags = 0; + } else if ((dozaemon_ev->flags & aEDZ_SAVE_FLAG_WAKEUP) != 0) { + Actor_delete(actorx); + } + + if (actorx->mv_proc != NULL && Save_Get(event_save_common).dozaemon_completed == TRUE) { + Actor_delete(actorx); + } + } +} + +static void aEDZ_actor_save(ACTOR* actorx, GAME* game) { + mNpc_RenewalSetNpc(actorx); +} + +static void aEDZ_actor_dt(ACTOR* actorx, GAME* game) { + if (mEv_check_status(mEv_EVENT_DOZAEMON, mEv_STATUS_SHOW) != FALSE) { + mEv_actor_dying_message(mEv_EVENT_DOZAEMON, actorx); + } + + CLIP(npc_clip)->dt_proc(actorx, game); +} + +static void aEDZ_actor_init(ACTOR* actorx, GAME* game) { + CLIP(npc_clip)->init_proc(actorx, game); +} + +static int aEDZ_set_request_act(DOZAEMON_ACTOR* dozaemon, u8 prio, u8 act_idx, u8 act_type, u16 act_obj, s16 move_x, s16 move_z) { + int ret = FALSE; + + if (prio >= dozaemon->npc_class.request.act_priority) { + u16 arg_data[aNPC_REQUEST_ARG_NUM]; + + bzero(arg_data, sizeof(arg_data)); + arg_data[0] = act_obj; + arg_data[2] = move_x; + arg_data[3] = move_z; + dozaemon->npc_class.request.act_priority = prio; + dozaemon->npc_class.request.act_idx = act_idx; + dozaemon->npc_class.request.act_type = act_type; + mem_copy((u8*)dozaemon->npc_class.request.act_args, (u8*)arg_data, sizeof(arg_data)); + ret = TRUE; + } + + return ret; +} + +static void aEDZ_actor_move(ACTOR* actorx, GAME* game) { + CLIP(npc_clip)->move_proc(actorx, game); +} + +static void aEDZ_actor_draw(ACTOR* actorx, GAME* game) { + CLIP(npc_clip)->draw_proc(actorx, game); +} + +#include "../src/actor/npc/event/ac_ev_dozaemon_move.c_inc" +#include "../src/actor/npc/event/ac_ev_dozaemon_schedule.c_inc" diff --git a/src/actor/npc/event/ac_ev_dozaemon_move.c_inc b/src/actor/npc/event/ac_ev_dozaemon_move.c_inc new file mode 100644 index 00000000..cf61e419 --- /dev/null +++ b/src/actor/npc/event/ac_ev_dozaemon_move.c_inc @@ -0,0 +1,188 @@ +static void aEDZ_to_ageru(DOZAEMON_ACTOR* dozaemon) { + mEv_dozaemon_c* dozaemon_ev = (mEv_dozaemon_c*)mEv_get_save_area(mEv_EVENT_DOZAEMON, 13); + + if (mPr_GetPossessionItemSumWithCond(Now_Private, EMPTY_NO, mPr_ITEM_COND_NORMAL) == 0) { + mMsg_SET_CONTINUE_MSG_NUM(0x2408); + aEDZ_change_talk_proc(dozaemon, aEDZ_TALK_END_WAIT); + } else { + mMsg_SET_CONTINUE_MSG_NUM(0x2404); + aEDZ_change_talk_proc(dozaemon, aEDZ_TALK_GIVE); + dozaemon->give_flag = TRUE; + dozaemon_ev->flags |= aEDZ_SAVE_FLAG_GAVE_FIRST; + } +} + +static void aEDZ_to_ageru2(DOZAEMON_ACTOR* dozaemon) { + mEv_dozaemon_c* dozaemon_ev = (mEv_dozaemon_c*)mEv_get_save_area(mEv_EVENT_DOZAEMON, 13); + + if (mPr_GetPossessionItemSumWithCond(Now_Private, EMPTY_NO, mPr_ITEM_COND_NORMAL) == 0) { + mDemo_Set_msg_num(0x2409); + aEDZ_change_talk_proc(dozaemon, aEDZ_TALK_END_WAIT); + } else { + mDemo_Set_msg_num(0x2405); + aEDZ_change_talk_proc(dozaemon, aEDZ_TALK_GIVE); + dozaemon->give_flag = TRUE; + dozaemon_ev->flags &= ~aEDZ_SAVE_FLAG_GAVE_FIRST; + } +} + +static void aEDZ_ageru(void) { + mActor_name_t item; + + mSP_SelectRandomItem_New(NULL, &item, 1, NULL, 0, mSP_KIND_FURNITURE, mSP_LISTTYPE_JONASON, FALSE); + mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 1, 2); + mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 0, item); + mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 1, aHOI_REQUEST_PUTAWAY); + mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 2, FALSE); + mPr_SetFreePossessionItem(Now_Private, item, mPr_ITEM_COND_NORMAL); +} + +static void aEDZ_talk_stop_player(DOZAEMON_ACTOR* dozaemon, GAME_PLAY* play) { + if (!mDemo_Check(mDemo_TYPE_TALK, (ACTOR*)dozaemon) && !mDemo_Check(mDemo_TYPE_SPEAK, (ACTOR*)dozaemon)) { + if (mPlib_get_player_actor_main_index((GAME*)play) != mPlayer_INDEX_DEMO_WAIT) { + mPlib_request_main_demo_wait_type1((GAME*)play, FALSE, NULL); + } else { + aEDZ_change_talk_proc(dozaemon, aEDZ_TALK_END_WAIT); + } + } +} + +static void aEDZ_talk_okiagaru(DOZAEMON_ACTOR* dozaemon, GAME_PLAY* play) { + if (mMsg_CHECK_MAINNORMALCONTINUE()) { + aEDZ_to_ageru(dozaemon); + } +} + +static void aEDZ_talk_give(DOZAEMON_ACTOR* dozaemon, GAME_PLAY* play) { + mEv_dozaemon_c* dozaemon_ev = (mEv_dozaemon_c*)mEv_get_save_area(mEv_EVENT_DOZAEMON, 13); + + if (dozaemon->give_flag) { + if (mMsg_CHECK_MAINNORMALCONTINUE() == FALSE) { + dozaemon->give_flag = FALSE; + } + } else if (mMsg_CHECK_MAINNORMALCONTINUE()) { + aEDZ_ageru(); + dozaemon_ev->flags |= aEDZ_SAVE_FLAG_GIVE; + Save_Get(event_save_common).dozaemon_completed = TRUE; + if ((dozaemon_ev->flags & aEDZ_SAVE_FLAG_GAVE_FIRST) != 0) { + mMsg_SET_CONTINUE_MSG_NUM(0x2406); + } else { + mMsg_SET_CONTINUE_MSG_NUM(0x2407); + } + + aEDZ_change_talk_proc(dozaemon, aEDZ_TALK_END_WAIT); + } +} + +static int aEDZ_change_talk_proc(DOZAEMON_ACTOR* dozaemon, int talk_act) { + static aEDZ_TALK_PROC proc[] = { + (aEDZ_TALK_PROC)none_proc1, + aEDZ_talk_stop_player, + aEDZ_talk_okiagaru, + aEDZ_talk_give, + }; + + dozaemon->talk_proc = proc[talk_act]; + return TRUE; +} + +static void aEDZ_set_force_talk_info(ACTOR* actorx) { + DOZAEMON_ACTOR* dozaemon = (DOZAEMON_ACTOR*)actorx; + mEv_dozaemon_c* dozaemon_ev = (mEv_dozaemon_c*)mEv_get_save_area(mEv_EVENT_DOZAEMON, 13); + + mDemo_Set_msg_num(0x23FE + RANDOM(6)); + mDemo_Set_talk_turn(TRUE); + mDemo_Set_camera(CAMERA2_PROCESS_TALK); + dozaemon->talk_proc = aEDZ_talk_okiagaru; + dozaemon_ev->flags |= aEDZ_SAVE_FLAG_WAKEUP; + if (dozaemon->npc_class.talk_info.melody_inst != 0) { + dozaemon->melody_backup = dozaemon->npc_class.talk_info.melody_inst; + } + + dozaemon->npc_class.talk_info.melody_inst = 0; +} + +static void aEDZ_force_talk_request(ACTOR* actorx, GAME* game) { + DOZAEMON_ACTOR* dozaemon = (DOZAEMON_ACTOR*)actorx; + + if (dozaemon->change_think == FALSE) { + mDemo_Request(mDemo_TYPE_SPEAK, actorx, aEDZ_set_force_talk_info); + } else { + dozaemon->change_think = FALSE; + } +} + +static void aEDZ_set_norm_talk_info(ACTOR* actorx) { + DOZAEMON_ACTOR* dozaemon = (DOZAEMON_ACTOR*)actorx; + + mDemo_Set_talk_turn(TRUE); + mDemo_Set_camera(CAMERA2_PROCESS_TALK); + + if (RANDOM_F(1.0f) < 0.35f) { + mDemo_Set_msg_num(0x23F8); + dozaemon->talk_proc = aEDZ_talk_stop_player; + dozaemon->next_think_idx = aEDZ_THINK_OKIAGARU; + mDemo_Set_talk_return_demo_wait(TRUE); + mPlib_Set_able_force_speak_label(actorx); + } else { + mDemo_Set_msg_num(0x23F9 + RANDOM(5)); + dozaemon->talk_proc = (aEDZ_TALK_PROC)none_proc1; + } +} + +static void aEDZ_norm_talk_request(ACTOR* actorx, GAME* game) { + DOZAEMON_ACTOR* dozaemon = (DOZAEMON_ACTOR*)actorx; + + if (dozaemon->change_think == FALSE) { + mDemo_Request(mDemo_TYPE_TALK, actorx, aEDZ_set_norm_talk_info); + } else { + dozaemon->change_think = FALSE; + } +} + +static void aEDZ_set_wander_talk_info(ACTOR* actorx) { + DOZAEMON_ACTOR* dozaemon = (DOZAEMON_ACTOR*)actorx; + mEv_dozaemon_c* dozaemon_ev = (mEv_dozaemon_c*)mEv_get_save_area(mEv_EVENT_DOZAEMON, 13); + + mDemo_Set_camera(CAMERA2_PROCESS_TALK); + mDemo_Set_talk_turn(TRUE); + + if ((dozaemon_ev->flags & aEDZ_SAVE_FLAG_GIVE) == 0) { + aEDZ_to_ageru2(dozaemon); + } else { + mDemo_Set_msg_num(0x240A + RANDOM(6)); + dozaemon->talk_proc = (aEDZ_TALK_PROC)none_proc1; + } +} + +static void aEDZ_wander_talk_request(ACTOR* actorx, GAME* game) { + mDemo_Request(mDemo_TYPE_TALK, actorx, aEDZ_set_wander_talk_info); +} + +static int aEDZ_talk_init(ACTOR* actorx, GAME* game) { + DOZAEMON_ACTOR* dozaemon = (DOZAEMON_ACTOR*)actorx; + + dozaemon->npc_class.talk_info.talk_request_proc = (aNPC_TALK_REQUEST_PROC)none_proc1; + mDemo_Set_ListenAble(); + mDemo_Start(actorx); + return TRUE; +} + +static int aEDZ_talk_end_chk(ACTOR* actorx, GAME* game) { + DOZAEMON_ACTOR* dozaemon = (DOZAEMON_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + int ret = FALSE; + + (*dozaemon->talk_proc)(dozaemon, play); + if (mDemo_CAN_ACTOR_TALK(actorx)) { + aEDZ_setup_think_proc(dozaemon, play, dozaemon->next_think_idx); + if (dozaemon->melody_backup != 0) { + dozaemon->npc_class.talk_info.melody_inst = dozaemon->melody_backup; + dozaemon->melody_backup = 0; + } + + ret = TRUE; + } + + return ret; +} diff --git a/src/actor/npc/event/ac_ev_dozaemon_schedule.c_inc b/src/actor/npc/event/ac_ev_dozaemon_schedule.c_inc new file mode 100644 index 00000000..ab5e2e51 --- /dev/null +++ b/src/actor/npc/event/ac_ev_dozaemon_schedule.c_inc @@ -0,0 +1,130 @@ +static void aEDZ_anime_next(DOZAEMON_ACTOR* dozaemon, GAME_PLAY* play) { + if (cKF_FrameControl_stop_proc(&dozaemon->npc_class.draw.main_animation.keyframe.frame_control) == cKF_STATE_STOPPED) { + aEDZ_setup_think_proc(dozaemon, play, (u8)++dozaemon->think_idx); + } +} + +static void aEDZ_think_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) { + DOZAEMON_ACTOR* dozaemon = (DOZAEMON_ACTOR*)nactorx; + + (*dozaemon->think_proc)(dozaemon, play); +} + +static void aEDZ_think_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) { + DOZAEMON_ACTOR* dozaemon = (DOZAEMON_ACTOR*)nactorx; + + dozaemon->npc_class.actor_class.status_data.weight = MASSTYPE_IMMOVABLE; + dozaemon->npc_class.condition_info.hide_request = FALSE; + aEDZ_setup_think_proc(dozaemon, play, aEDZ_THINK_TAORERU); +} + +static void aEDZ_normal_wait_init(DOZAEMON_ACTOR* dozaemon, GAME_PLAY* play) { + aEDZ_set_request_act(dozaemon, 4, aNPC_ACT_WAIT, aNPC_ACT_TYPE_DEFAULT, aNPC_ACT_OBJ_DEFAULT, 0, 0); +} + +static void aEDZ_taoreru_init(DOZAEMON_ACTOR* dozaemon, GAME_PLAY* play) { + dozaemon->npc_class.action.idx = aNPC_ACT_WAIT; + CLIP(npc_clip)->animation_init_proc((ACTOR*)dozaemon, aNPC_ANIM_GETUP_WAIT_SEG1, FALSE); + aEDZ_normal_wait_init(dozaemon, play); + dozaemon->npc_class.head.lock_flag = TRUE; + dozaemon->npc_class.talk_info.turn = aNPC_TALK_TURN_NONE; + dozaemon->npc_class.talk_info.default_animation = aNPC_ANIM_PIKU_SEG1; +} + +static void aEDZ_okiagaru_init(DOZAEMON_ACTOR* dozaemon, GAME_PLAY* play) { + dozaemon->npc_class.action.idx = aNPC_ACT_WAIT; + CLIP(npc_clip)->animation_init_proc((ACTOR*)dozaemon, aNPC_ANIM_GETUP_SEG1, FALSE); + dozaemon->npc_class.draw.main_animation.keyframe.frame_control.mode = cKF_FRAMECONTROL_STOP; + aEDZ_normal_wait_init(dozaemon, play); + dozaemon->npc_class.head.lock_flag = FALSE; + dozaemon->npc_class.talk_info.turn = aNPC_TALK_TURN_NORMAL; + dozaemon->npc_class.talk_info.default_animation = aNPC_ANIM_TALK1; + dozaemon->npc_class.actor_class.status_data.weight = 50; +} + +static void aEDZ_wander_init(DOZAEMON_ACTOR* dozaemon, GAME_PLAY* play) { + CLIP(npc_clip)->chg_schedule_proc((NPC_ACTOR*)dozaemon, play, aNPC_SCHEDULE_TYPE_WANDER); + dozaemon->npc_class.talk_info.talk_request_proc = aEDZ_wander_talk_request; +} + +typedef struct dozaemon_think_data_s { + u8 think_proc; + u8 think_init; + u8 talk_request; + u8 _03; + u8 think_idx_after_talk; +} aEDZ_think_data_c; + +static aEDZ_think_data_c dt_tbl[] = { + { aEDZ_THINK_PROC_NONE, aEDZ_INIT_PROC_NORMAL_WAIT, aEDZ_TALK_PROC_NONE, 0, aEDZ_THINK_NORMAL_WAIT}, + { aEDZ_THINK_PROC_NONE, aEDZ_INIT_PROC_TAORERU, aEDZ_TALK_PROC_NORMAL, 0, aEDZ_THINK_TAORERU}, + {aEDZ_THINK_PROC_ANIME_NEXT, aEDZ_INIT_PROC_OKIAGARU, aEDZ_TALK_PROC_NONE, 0, aEDZ_THINK_OKIAGARU}, + { aEDZ_THINK_PROC_NONE, aEDZ_INIT_PROC_NONE, aEDZ_TALK_PROC_FORCE, 0, aEDZ_THINK_WANDER}, + { aEDZ_THINK_PROC_NONE, aEDZ_INIT_PROC_WANDER, aEDZ_TALK_PROC_NONE, 0, aEDZ_THINK_WANDER}, +}; + +static aEDZ_THINK_PROC proc_table[] = { + (aEDZ_THINK_PROC)none_proc1, + aEDZ_anime_next, +}; + +typedef void (*aEDZ_THINK_INIT_PROC)(DOZAEMON_ACTOR* dozaemon, GAME_PLAY* play); + +static aEDZ_THINK_INIT_PROC init_table[] = { + (aEDZ_THINK_INIT_PROC)none_proc1, + aEDZ_normal_wait_init, + aEDZ_taoreru_init, + aEDZ_okiagaru_init, + aEDZ_wander_init, +}; + +static void aEDZ_setup_think_proc(DOZAEMON_ACTOR* dozaemon, GAME_PLAY* play, u8 idx) { + aEDZ_think_data_c* dt = &dt_tbl[idx]; + static aNPC_TALK_REQUEST_PROC talk_request_table[] = { + (aNPC_TALK_REQUEST_PROC)none_proc1, + aEDZ_norm_talk_request, + aEDZ_force_talk_request, + }; + + dozaemon->think_idx = idx; + dozaemon->think_proc = proc_table[dt->think_proc]; + dozaemon->npc_class.talk_info.talk_request_proc = talk_request_table[dt->talk_request]; + dozaemon->_9A5 = dt->_03; + dozaemon->next_think_idx = dt->think_idx_after_talk; + + (*init_table[dt->think_init])(dozaemon, play); + dozaemon->change_think = TRUE; +} + +static void aEDZ_think_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int think_type) { + switch (think_type) { + case aNPC_THINK_PROC_INIT: + aEDZ_think_init_proc(nactorx, play); + break; + case aNPC_THINK_PROC_MAIN: + aEDZ_think_main_proc(nactorx, play); + break; + } +} + +static void aEDZ_schedule_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) { + nactorx->think.think_proc = aEDZ_think_proc; + CLIP(npc_clip)->think_proc(nactorx, play, aNPC_THINK_SPECIAL, aNPC_THINK_TYPE_INIT); +} + +static void aEDZ_schedule_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) { + if (CLIP(npc_clip)->think_proc(nactorx, play, -1, aNPC_THINK_TYPE_CHK_INTERRUPT) == FALSE) { + CLIP(npc_clip)->think_proc(nactorx, play, -1, aNPC_THINK_TYPE_MAIN); + } +} + +static void aEDZ_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) { + switch (proc_type) { + case aNPC_SCHEDULE_PROC_INIT: + aEDZ_schedule_init_proc(nactorx, play); + break; + case aNPC_SCHEDULE_PROC_MAIN: + aEDZ_schedule_main_proc(nactorx, play); + break; + } +}