From a7ae788c3914d14dedd7ff40724a4c14124549d3 Mon Sep 17 00:00:00 2001 From: roeming Date: Fri, 13 Jun 2025 16:31:26 -0400 Subject: [PATCH 1/2] link ac_harvest_npc0 --- configure.py | 2 +- src/actor/npc/ac_harvest_npc0.c | 110 +++++++++++++++ src/actor/npc/ac_harvest_npc0.c_inc | 200 ++++++++++++++++++++++++++++ 3 files changed, 311 insertions(+), 1 deletion(-) create mode 100644 src/actor/npc/ac_harvest_npc0.c create mode 100644 src/actor/npc/ac_harvest_npc0.c_inc diff --git a/configure.py b/configure.py index 8fd7cad7..f1cbe2e2 100644 --- a/configure.py +++ b/configure.py @@ -1103,7 +1103,7 @@ config.libs = [ Object(Matching, "actor/npc/ac_hanabi_npc1.c"), Object(Matching, "actor/npc/ac_hanami_npc0.c"), Object(Matching, "actor/npc/ac_hanami_npc1.c"), - Object(NonMatching, "actor/npc/ac_harvest_npc0.c"), + Object(Matching, "actor/npc/ac_harvest_npc0.c"), Object(NonMatching, "actor/npc/ac_harvest_npc1.c"), Object(Matching, "actor/npc/ac_hatumode_npc0.c"), Object(Matching, "actor/npc/ac_kamakura_npc0.c"), diff --git a/src/actor/npc/ac_harvest_npc0.c b/src/actor/npc/ac_harvest_npc0.c new file mode 100644 index 00000000..f16c2fd6 --- /dev/null +++ b/src/actor/npc/ac_harvest_npc0.c @@ -0,0 +1,110 @@ +#include "ac_harvest_npc0.h" +#include "m_name_table.h" +#include "ac_npc.h" +#include "ac_npc_h.h" +#include "m_common_data.h" +#include "m_msg.h" +#include "m_soncho.h" +#include "ac_shrine.h" + +typedef struct npc_harvest_npc0_actor_s NPC_HARVEST_NPC0_ACTOR; + +typedef void (*aHT0_PROC)(NPC_HARVEST_NPC0_ACTOR* actor, GAME_PLAY* play); + +typedef struct npc_harvest_npc0_actor_s { + NPC_ACTOR actor; + int _994; + int _998; + int _99C; + aHT0_PROC _9A0; + int _9A4; + u8 _9A8; +} NPC_HARVEST_NPC0_ACTOR; + +static void aHT0_actor_ct(ACTOR* actorx, GAME* game); +static void aHT0_actor_dt(ACTOR* actorx, GAME* game); +static void aHT0_actor_init(ACTOR* actorx, GAME* game); +static void aHT0_actor_save(ACTOR* actorx, GAME* game); +static void aHT0_actor_move(ACTOR* actorx, GAME* game); +static void aHT0_actor_draw(ACTOR* actorx, GAME* game); +static BOOL aHT0_talk_init(ACTOR* actorx, GAME* game); +static BOOL aHT0_talk_end_chk(ACTOR* actorx, GAME* game); +static void aHT0_schedule_proc(NPC_ACTOR*, GAME_PLAY*, int); +static void aHT0_talk_request(ACTOR* actorx, GAME* game); +static void aHT0_change_talk_proc(NPC_HARVEST_NPC0_ACTOR*, int); + +// clang-format off +ACTOR_PROFILE Harvest_Npc0_Profile = { + mAc_PROFILE_HARVEST_NPC0, + ACTOR_PART_NPC, + ACTOR_STATE_NONE, + EMPTY_NO, + ACTOR_OBJ_BANK_KEEP, + sizeof(NPC_HARVEST_NPC0_ACTOR), + aHT0_actor_ct, + aHT0_actor_dt, + aHT0_actor_init, + mActor_NONE_PROC1, + aHT0_actor_save +}; +// clang-format on + +static int aHT0_GetMyIdx(NPC_HARVEST_NPC0_ACTOR* actor) { + return (actor->actor.actor_class.npc_id - SP_NPC_EV_HARVEST_0) & 3; +} + +static s16 aHT0_GetDefaultAngle(NPC_HARVEST_NPC0_ACTOR* actor) { + static s16 first_angle[] = { + DEG2SHORT_ANGLE2(45), + DEG2SHORT_ANGLE2(270), + DEG2SHORT_ANGLE2(315), + DEG2SHORT_ANGLE2(90), + }; + return first_angle[aHT0_GetMyIdx(actor)]; +} + +static void aHT0_actor_ct(ACTOR* actorx, GAME* game) { + // clang-format off + static aNPC_ct_data_c ct_data = { + aHT0_actor_move, + aHT0_actor_draw, + aNPC_CT_SCHED_TYPE_SPECIAL, + aHT0_talk_request, + aHT0_talk_init, + aHT0_talk_end_chk + }; + // clang-format on + + NPC_HARVEST_NPC0_ACTOR* actor = (NPC_HARVEST_NPC0_ACTOR*)actorx; + if (NPC_CLIP->birth_check_proc(actorx, game) == TRUE) { + actor->actor.schedule.schedule_proc = aHT0_schedule_proc; + NPC_CLIP->ct_proc(actorx, game, &ct_data); + } +} + +static void aHT0_actor_save(ACTOR* actorx, GAME* game) { + NPC_CLIP->save_proc(actorx, game); +} + +static void aHT0_actor_dt(ACTOR* actorx, GAME* game) { + NPC_CLIP->dt_proc(actorx, game); +} + +static void aHT0_actor_init(ACTOR* actorx, GAME* game) { + NPC_CLIP->init_proc(actorx, game); +} + +static void aHT0_set_animation(ACTOR* actorx, int index) { + static int animeSeqNo[] = { 72, 74, 73, 1 }; + NPC_CLIP->animation_init_proc(actorx, animeSeqNo[index], FALSE); +} + +static void aHT0_actor_move(ACTOR* actorx, GAME* game) { + NPC_CLIP->move_proc(actorx, game); +} + +static void aHT0_actor_draw(ACTOR* actorx, GAME* game) { + NPC_CLIP->draw_proc(actorx, game); +} + +#include "../../actor/npc/ac_harvest_npc0.c_inc" diff --git a/src/actor/npc/ac_harvest_npc0.c_inc b/src/actor/npc/ac_harvest_npc0.c_inc new file mode 100644 index 00000000..046763d6 --- /dev/null +++ b/src/actor/npc/ac_harvest_npc0.c_inc @@ -0,0 +1,200 @@ + +static void aHT0_set_request_act(NPC_ACTOR* actorx) { + NPC_HARVEST_NPC0_ACTOR* actor = (NPC_HARVEST_NPC0_ACTOR*)actorx; + actor->actor.request.act_priority = 4; + actor->actor.request.act_idx = aNPC_ACT_SPECIAL; + actor->actor.request.act_type = aNPC_ACT_TYPE_SEARCH; +} + +static void aHT0_make_tumbler(NPC_ACTOR* actorx, GAME_PLAY* play) { + NPC_HARVEST_NPC0_ACTOR* actor = (NPC_HARVEST_NPC0_ACTOR*)actorx; + if ((actor->_9A4 & 1) == 1 && actor->actor.right_hand.item_actor_p == NULL) { + ACTOR* pActor = CLIP(tools_clip) + ->aTOL_birth_proc(TOOL_TUMBLER, aTOL_ACTION_S_TAKEOUT, &actor->actor.actor_class, + &play->game, -1, NULL); + if (pActor) { + actor->actor.right_hand.item_actor_p = pActor; + } + } +} + +static void aHT0_wait(NPC_HARVEST_NPC0_ACTOR* actor, GAME_PLAY* play) { + if (actor->actor.draw.main_animation_state == cKF_STATE_CONTINUE) { + if (actor->actor.draw.loop_flag == FALSE) { + actor->actor.action.step = -1; + } else { + actor->actor.draw.loop_flag--; + } + } +} + +static void aHT0_merry(NPC_HARVEST_NPC0_ACTOR* actor, GAME_PLAY* play) { + if (actor->actor.draw.main_animation_state == cKF_STATE_CONTINUE) { + if (actor->actor.draw.loop_flag == FALSE) { + actor->actor.action.step = -1; + } else { + actor->actor.draw.loop_flag--; + } + } + sAdo_OngenPos((u32)actor, actor->_9A8, &actor->actor.actor_class.world.position); +} + +static void aHT0_drink(NPC_HARVEST_NPC0_ACTOR* actor, GAME_PLAY* play) { + if (actor->actor.draw.main_animation_state == cKF_STATE_STOPPED) { + actor->actor.action.step = -1; + } +} + +static void aHT0_to_default(NPC_HARVEST_NPC0_ACTOR* actor, GAME_PLAY* play) { + if (actor->actor.actor_class.shape_info.rotation.y == aHT0_GetDefaultAngle(actor)) { + actor->_998 = 0; + actor->actor.action.step = -1; + } + actor->actor.actor_class.world.angle.y = actor->actor.actor_class.shape_info.rotation.y; +} + +static void aHT0_setupAction(NPC_ACTOR* actorx, int index) { + static aHT0_PROC process[] = { aHT0_wait, aHT0_merry, aHT0_drink, aHT0_to_default }; + static int anm_loop_base[] = { 1, 2, 1, 1 }; + static f32 anm_loop_rnd[] = { 0.f, 3.f, 1.f, 0.f }; + NPC_HARVEST_NPC0_ACTOR* actor = (NPC_HARVEST_NPC0_ACTOR*)actorx; + actor->actor.action.step = 0; + actor->_994 = index; + actor->_9A0 = process[index]; + actor->actor.draw.loop_flag = anm_loop_base[index] + RANDOM(anm_loop_rnd[index]); + aHT0_set_animation(&actorx->actor_class, index); + if (index == 1) { + static u8 clap_se_no[] = { 0x2f, 0x31, 0x32, 0x33 }; + actor->_9A8 = clap_se_no[RANDOM(ARRAY_COUNT(clap_se_no))]; + } +} + +static void aHT0_act_chg_data_proc(NPC_HARVEST_NPC0_ACTOR* actor, GAME_PLAY* play) { + actor->actor.action.act_obj = aNPC_ACT_OBJ_PLAYER; +} + +static void aHT0_act_init_proc(NPC_HARVEST_NPC0_ACTOR* actor, GAME_PLAY* play) { + aHT0_setupAction(&actor->actor, 3); +} + +static void aHT0_act_main_proc(NPC_HARVEST_NPC0_ACTOR* actor, GAME_PLAY* play) { + actor->_9A0(actor, play); +} + +static void aHT0_act_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int index) { + NPC_HARVEST_NPC0_ACTOR* actor = (NPC_HARVEST_NPC0_ACTOR*)actorx; + static aHT0_PROC act_proc[] = { aHT0_act_init_proc, aHT0_act_chg_data_proc, aHT0_act_main_proc }; + act_proc[index](actor, play); +} + +static void aHT0_think_main_proc(NPC_HARVEST_NPC0_ACTOR* actor, GAME_PLAY* play) { + if (actor->actor.action.step == (u8)-1) { + switch (actor->actor.action.idx) { + case 22: { + static int action[] = { 0, 1, 2, 3 }; + if (actor->_998 != -1) { + aHT0_setupAction(&actor->actor, action[actor->_998]); + actor->_998 = -1; + } else { + int temp = RANDOM(2); + temp <<= (actor->_9A4 & 1); + aHT0_setupAction(&actor->actor, action[temp]); + } + actor->actor.condition_info.demo_flg = aNPC_COND_DEMO_SKIP_HEAD_LOOKAT | + aNPC_COND_DEMO_SKIP_FORWARD_CHECK | aNPC_COND_DEMO_SKIP_BGCHECK | + aNPC_COND_DEMO_SKIP_MOVE_RANGE_CHECK | + aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV | aNPC_COND_DEMO_SKIP_MOVE_Y; + actor->actor.collision.check_kind = aNPC_BG_CHECK_TYPE_ONLY_GROUND; + } break; + case 8: { + actor->actor.movement.mv_angl = aHT0_GetDefaultAngle(actor); + aHT0_set_request_act(&actor->actor); + actor->actor.condition_info.demo_flg = aNPC_COND_DEMO_SKIP_HEAD_LOOKAT | + aNPC_COND_DEMO_SKIP_FORWARD_CHECK | aNPC_COND_DEMO_SKIP_BGCHECK | + aNPC_COND_DEMO_SKIP_MOVE_RANGE_CHECK | + aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV | aNPC_COND_DEMO_SKIP_MOVE_Y; + actor->actor.collision.check_kind = aNPC_BG_CHECK_TYPE_ONLY_GROUND; + } break; + } + } +} + +static void aHT0_think_init_proc(NPC_HARVEST_NPC0_ACTOR* actor, GAME_PLAY* play) { + actor->actor.think.interrupt_flags = 0; + actor->actor.action.act_proc = aHT0_act_proc; + aHT0_set_request_act(&actor->actor); +} + +static void aHT0_think_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int index) { + NPC_HARVEST_NPC0_ACTOR* actor = (NPC_HARVEST_NPC0_ACTOR*)actorx; + static aHT0_PROC think_proc[] = { aHT0_think_init_proc, aHT0_think_main_proc }; + think_proc[index](actor, play); +} + +static void aHT0_schedule_init_proc(NPC_ACTOR* actorx, GAME_PLAY* play) { + NPC_HARVEST_NPC0_ACTOR* actor = (NPC_HARVEST_NPC0_ACTOR*)actorx; + int id = actor->actor.actor_class.npc_id - SP_NPC_EV_HARVEST_0; + actor->actor.think.think_proc = aHT0_think_proc; + actor->actor.condition_info.hide_request = 0; + actor->actor.palActorIgnoreTimer = -1; + actor->actor.talk_info.turn = 1; + actor->actor.talk_info.default_animation = 72; + actor->_9A4 = id; + actor->actor.condition_info.demo_flg = aNPC_COND_DEMO_SKIP_HEAD_LOOKAT | aNPC_COND_DEMO_SKIP_FORWARD_CHECK | + aNPC_COND_DEMO_SKIP_BGCHECK | aNPC_COND_DEMO_SKIP_MOVE_RANGE_CHECK | + aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV | aNPC_COND_DEMO_SKIP_MOVE_Y; + actor->actor.collision.check_kind = aNPC_BG_CHECK_TYPE_ONLY_GROUND; + actor->actor.actor_class.status_data.weight = MASSTYPE_HEAVY; + actor->_998 = -1; + actor->actor.movement.mv_angl = actor->actor.actor_class.world.angle.y = + actor->actor.actor_class.shape_info.rotation.y = aHT0_GetDefaultAngle(actor); + NPC_CLIP->think_proc(actorx, play, 9, 0); +} + +static void aHT0_schedule_main_proc(NPC_ACTOR* actorx, GAME_PLAY* play) { + if (NPC_CLIP->think_proc(actorx, play, -1, aNPC_THINK_TYPE_CHK_INTERRUPT) == FALSE) { + NPC_CLIP->think_proc(actorx, play, -1, aNPC_THINK_TYPE_MAIN); + } + aHT0_make_tumbler(actorx, play); +} + +static void unused_stripped() { + static s16 def_angle[] = { + DEG2SHORT_ANGLE2(45), + DEG2SHORT_ANGLE2(270), + DEG2SHORT_ANGLE2(315), + DEG2SHORT_ANGLE2(90), + }; +} + +static void aHT0_schedule_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int proc) { + static aNPC_SUB_PROC sche_proc[] = { aHT0_schedule_init_proc, aHT0_schedule_main_proc }; + sche_proc[proc](actorx, play); +} + +static void aHT0_set_talk_info(ACTOR* actorx) { + NPC_HARVEST_NPC0_ACTOR* actor = (NPC_HARVEST_NPC0_ACTOR*)actorx; + static int msg_base[] = { 0x3c98, 0x3cb7, 0x3c3b, 0x3c5a, 0x3c79, 0x3cd6 }; + int looks = mNpc_GetNpcLooks(&actor->actor.actor_class); + int msg_no = msg_base[looks] + actor->_9A4 * 3; + mDemo_Set_msg_num(msg_no + RANDOM(3)); +} + +static void aHT0_talk_request(ACTOR* actorx, GAME* game) { + mDemo_Request(7, actorx, aHT0_set_talk_info); +} + +static BOOL aHT0_talk_init(ACTOR* actorx, GAME* game) { + mDemo_Set_ListenAble(); + return TRUE; +} + +static BOOL aHT0_talk_end_chk(ACTOR* actorx, GAME* game) { + NPC_HARVEST_NPC0_ACTOR* actor = (NPC_HARVEST_NPC0_ACTOR*)actorx; + BOOL ret = FALSE; + if (mDemo_Check(7, actorx) == FALSE) { + actor->_99C = 1; + ret = TRUE; + } + return ret; +} From c52a70b40ca1527c35cd073443030ff03ff5bfda Mon Sep 17 00:00:00 2001 From: roeming Date: Fri, 13 Jun 2025 16:52:07 -0400 Subject: [PATCH 2/2] link ac_harvest_npc1 --- configure.py | 2 +- src/actor/npc/ac_harvest_npc1.c | 97 +++++++++++++++++++ src/actor/npc/ac_harvest_npc1.c_inc | 138 ++++++++++++++++++++++++++++ 3 files changed, 236 insertions(+), 1 deletion(-) create mode 100644 src/actor/npc/ac_harvest_npc1.c create mode 100644 src/actor/npc/ac_harvest_npc1.c_inc diff --git a/configure.py b/configure.py index f1cbe2e2..9e70ce5b 100644 --- a/configure.py +++ b/configure.py @@ -1104,7 +1104,7 @@ config.libs = [ Object(Matching, "actor/npc/ac_hanami_npc0.c"), Object(Matching, "actor/npc/ac_hanami_npc1.c"), Object(Matching, "actor/npc/ac_harvest_npc0.c"), - Object(NonMatching, "actor/npc/ac_harvest_npc1.c"), + Object(Matching, "actor/npc/ac_harvest_npc1.c"), Object(Matching, "actor/npc/ac_hatumode_npc0.c"), Object(Matching, "actor/npc/ac_kamakura_npc0.c"), Object(Matching, "actor/npc/ac_normal_npc.c"), diff --git a/src/actor/npc/ac_harvest_npc1.c b/src/actor/npc/ac_harvest_npc1.c new file mode 100644 index 00000000..a0a18d6d --- /dev/null +++ b/src/actor/npc/ac_harvest_npc1.c @@ -0,0 +1,97 @@ +#include "ac_harvest_npc1.h" +#include "m_name_table.h" +#include "ac_npc.h" +#include "ac_npc_h.h" +#include "m_common_data.h" +#include "m_msg.h" +#include "m_soncho.h" +#include "ac_shrine.h" + +typedef struct npc_harvest_npc1_actor_s NPC_HARVEST_NPC1_ACTOR; + +typedef void (*aHT1_PROC)(NPC_HARVEST_NPC1_ACTOR* actor, GAME_PLAY* play); + +typedef struct npc_harvest_npc1_actor_s { + NPC_ACTOR actor; + int _994; + int _998; + aHT1_PROC _99C; +} NPC_HARVEST_NPC1_ACTOR; + +static void aHT1_actor_ct(ACTOR* actorx, GAME* game); +static void aHT1_actor_dt(ACTOR* actorx, GAME* game); +static void aHT1_actor_init(ACTOR* actorx, GAME* game); +static void aHT1_actor_save(ACTOR* actorx, GAME* game); +static void aHT1_actor_move(ACTOR* actorx, GAME* game); +static void aHT1_actor_draw(ACTOR* actorx, GAME* game); +static BOOL aHT1_talk_init(ACTOR* actorx, GAME* game); +static BOOL aHT1_talk_end_chk(ACTOR* actorx, GAME* game); +static void aHT1_schedule_proc(NPC_ACTOR*, GAME_PLAY*, int); +static void aHT1_talk_request(ACTOR* actorx, GAME* game); + +// clang-format off +ACTOR_PROFILE Harvest_Npc1_Profile = { + mAc_PROFILE_HARVEST_NPC1, + ACTOR_PART_NPC, + ACTOR_STATE_NONE, + EMPTY_NO, + ACTOR_OBJ_BANK_KEEP, + sizeof(NPC_HARVEST_NPC1_ACTOR), + aHT1_actor_ct, + aHT1_actor_dt, + aHT1_actor_init, + mActor_NONE_PROC1, + aHT1_actor_save +}; +// clang-format on + +static void aHT1_actor_ct(ACTOR* actorx, GAME* game) { + // clang-format off + static aNPC_ct_data_c ct_data = { + aHT1_actor_move, + aHT1_actor_draw, + aNPC_CT_SCHED_TYPE_SPECIAL, + aHT1_talk_request, + aHT1_talk_init, + aHT1_talk_end_chk + }; + // clang-format on + + NPC_HARVEST_NPC1_ACTOR* actor = (NPC_HARVEST_NPC1_ACTOR*)actorx; + if (NPC_CLIP->birth_check_proc(actorx, game) == TRUE) { + actor->actor.actor_class.world.position.x += 20.f; + actor->actor.schedule.schedule_proc = aHT1_schedule_proc; + NPC_CLIP->ct_proc(actorx, game, &ct_data); + } +} + +static void aHT1_actor_save(ACTOR* actorx, GAME* game) { + NPC_CLIP->save_proc(actorx, game); +} + +static void aHT1_actor_dt(ACTOR* actorx, GAME* game) { + NPC_CLIP->dt_proc(actorx, game); +} + +static void aHT1_actor_init(ACTOR* actorx, GAME* game) { + NPC_CLIP->init_proc(actorx, game); +} + +static void aHT1_set_animation(ACTOR* actorx, int index) { + static int animeSeqNo[] = { 5, 1 }; + NPC_CLIP->animation_init_proc(actorx, animeSeqNo[index], FALSE); +} + +static void aHT1_actor_move(ACTOR* actorx, GAME* game) { + NPC_CLIP->move_proc(actorx, game); +} + +static s16 aHT1_GetDefaultAngle() { + return 0; +} + +static void aHT1_actor_draw(ACTOR* actorx, GAME* game) { + NPC_CLIP->draw_proc(actorx, game); +} + +#include "../../actor/npc/ac_harvest_npc1.c_inc" diff --git a/src/actor/npc/ac_harvest_npc1.c_inc b/src/actor/npc/ac_harvest_npc1.c_inc new file mode 100644 index 00000000..d3b8d880 --- /dev/null +++ b/src/actor/npc/ac_harvest_npc1.c_inc @@ -0,0 +1,138 @@ + +static void aHT1_set_request_act(NPC_ACTOR* actorx) { + NPC_HARVEST_NPC1_ACTOR* actor = (NPC_HARVEST_NPC1_ACTOR*)actorx; + actor->actor.request.act_priority = 4; + actor->actor.request.act_idx = aNPC_ACT_SPECIAL; + actor->actor.request.act_type = aNPC_ACT_TYPE_SEARCH; +} + +static void aHT1_wait(NPC_HARVEST_NPC1_ACTOR* actor, GAME_PLAY* play) { + if (actor->actor.draw.main_animation_state == cKF_STATE_CONTINUE) { + if (actor->actor.draw.loop_flag == FALSE) { + actor->actor.action.step = -1; + } else { + actor->actor.draw.loop_flag--; + } + } +} + +static void aHT1_to_default(NPC_HARVEST_NPC1_ACTOR* actor, GAME_PLAY* play) { + if (actor->actor.actor_class.shape_info.rotation.y == aHT1_GetDefaultAngle(actor)) { + actor->_998 = 0; + actor->actor.action.step = -1; + } + actor->actor.actor_class.world.angle.y = actor->actor.actor_class.shape_info.rotation.y; +} + +static void aHT1_setupAction(NPC_ACTOR* actorx, int index) { + static aHT1_PROC process[] = { aHT1_wait, aHT1_to_default }; + NPC_HARVEST_NPC1_ACTOR* actor = (NPC_HARVEST_NPC1_ACTOR*)actorx; + actor->actor.action.step = 0; + actor->_994 = index; + actor->_99C = process[index]; + aHT1_set_animation(&actorx->actor_class, index); +} + +static void aHT1_act_chg_data_proc(NPC_HARVEST_NPC1_ACTOR* actor, GAME_PLAY* play) { + actor->actor.action.act_obj = aNPC_ACT_OBJ_PLAYER; +} + +static void aHT1_act_init_proc(NPC_HARVEST_NPC1_ACTOR* actor, GAME_PLAY* play) { + aHT1_setupAction(&actor->actor, 1); +} + +static void aHT1_act_main_proc(NPC_HARVEST_NPC1_ACTOR* actor, GAME_PLAY* play) { + actor->_99C(actor, play); +} + +static void aHT1_act_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int index) { + NPC_HARVEST_NPC1_ACTOR* actor = (NPC_HARVEST_NPC1_ACTOR*)actorx; + static aHT1_PROC act_proc[] = { aHT1_act_init_proc, aHT1_act_chg_data_proc, aHT1_act_main_proc }; + act_proc[index](actor, play); +} + +static void aHT1_think_main_proc(NPC_HARVEST_NPC1_ACTOR* actor, GAME_PLAY* play) { + if (actor->actor.action.step == (u8)-1) { + switch (actor->actor.action.idx) { + case 22: { + if (actor->_998 != -1) { + aHT1_setupAction(&actor->actor, actor->_998); + actor->_998 = -1; + } + actor->actor.condition_info.demo_flg = + aNPC_COND_DEMO_SKIP_MOVE_RANGE_CHECK | aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV; + actor->actor.collision.check_kind = aNPC_BG_CHECK_TYPE_ONLY_GROUND; + } break; + case 8: { + actor->actor.movement.mv_angl = aHT1_GetDefaultAngle(actor); + aHT1_set_request_act(&actor->actor); + actor->actor.condition_info.demo_flg = + aNPC_COND_DEMO_SKIP_MOVE_RANGE_CHECK | aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV; + actor->actor.collision.check_kind = aNPC_BG_CHECK_TYPE_ONLY_GROUND; + } break; + } + } +} + +static void aHT1_think_init_proc(NPC_HARVEST_NPC1_ACTOR* actor, GAME_PLAY* play) { + actor->actor.think.interrupt_flags = 0; + actor->actor.action.act_proc = aHT1_act_proc; + aHT1_set_request_act(&actor->actor); +} + +static void aHT1_think_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int index) { + NPC_HARVEST_NPC1_ACTOR* actor = (NPC_HARVEST_NPC1_ACTOR*)actorx; + static aHT1_PROC think_proc[] = { aHT1_think_init_proc, aHT1_think_main_proc }; + think_proc[index](actor, play); +} + +static void aHT1_schedule_init_proc(NPC_ACTOR* actorx, GAME_PLAY* play) { + NPC_HARVEST_NPC1_ACTOR* actor = (NPC_HARVEST_NPC1_ACTOR*)actorx; + int id = actor->actor.actor_class.npc_id - SP_NPC_EV_HARVEST_0; + actor->actor.think.think_proc = aHT1_think_proc; + actor->actor.condition_info.hide_request = 0; + actor->actor.palActorIgnoreTimer = -1; + actor->_998 = -1; + actor->actor.condition_info.demo_flg = aNPC_COND_DEMO_SKIP_MOVE_RANGE_CHECK | aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV; + actor->actor.actor_class.status_data.weight = MASSTYPE_HEAVY; + actor->actor.actor_class.shape_info.rotation.y = aHT1_GetDefaultAngle(); + actor->actor.actor_class.world.angle.y = aHT1_GetDefaultAngle(); + actor->actor.movement.mv_angl = aHT1_GetDefaultAngle(); + NPC_CLIP->think_proc(actorx, play, 9, 0); +} + +static void aHT1_schedule_main_proc(NPC_ACTOR* actorx, GAME_PLAY* play) { + if (NPC_CLIP->think_proc(actorx, play, -1, aNPC_THINK_TYPE_CHK_INTERRUPT) == FALSE) { + NPC_CLIP->think_proc(actorx, play, -1, aNPC_THINK_TYPE_MAIN); + } +} + +static void aHT1_schedule_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int proc) { + static aNPC_SUB_PROC sche_proc[] = { aHT1_schedule_init_proc, aHT1_schedule_main_proc }; + sche_proc[proc](actorx, play); +} + +static void aHT1_set_talk_info(ACTOR* actorx) { + NPC_HARVEST_NPC1_ACTOR* actor = (NPC_HARVEST_NPC1_ACTOR*)actorx; + static int msg_base[] = { 0x3CA4, 0x3CC3, 0x3C47, 0x3C66, 0x3C85, 0x3CE2 }; + int looks = mNpc_GetNpcLooks(actorx); + mDemo_Set_msg_num(RANDOM(3) + msg_base[looks]); +} + +static void aHT1_talk_request(ACTOR* actorx, GAME* game) { + mDemo_Request(7, actorx, aHT1_set_talk_info); +} + +static BOOL aHT1_talk_init(ACTOR* actorx, GAME* game) { + mDemo_Set_ListenAble(); + return TRUE; +} + +static BOOL aHT1_talk_end_chk(ACTOR* actorx, GAME* game) { + NPC_HARVEST_NPC1_ACTOR* actor = (NPC_HARVEST_NPC1_ACTOR*)actorx; + BOOL ret = FALSE; + if (mDemo_Check(7, actorx) == FALSE) { + ret = TRUE; + } + return ret; +}