Merge pull request #469 from SamuraiOndo/master

Implement and link ac_halloween_npc.c
This commit is contained in:
Cuyler36
2025-05-15 22:04:21 -04:00
committed by GitHub
6 changed files with 607 additions and 1 deletions
+1 -1
View File
@@ -1098,7 +1098,7 @@ config.libs = [
Object(NonMatching, "actor/npc/ac_countdown_npc1.c"),
Object(Matching, "actor/npc/ac_go_home_npc.c"),
Object(NonMatching, "actor/npc/ac_groundhog_npc0.c"),
Object(NonMatching, "actor/npc/ac_halloween_npc.c"),
Object(Matching, "actor/npc/ac_halloween_npc.c"),
Object(NonMatching, "actor/npc/ac_hanabi_npc0.c"),
Object(NonMatching, "actor/npc/ac_hanabi_npc1.c"),
Object(NonMatching, "actor/npc/ac_hanami_npc0.c"),
+34
View File
@@ -3,11 +3,45 @@
#include "types.h"
#include "m_actor.h"
#include "ac_npc.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct halloween_npc_s NPC_HALLOWEEN_ACTOR;
typedef void (*aHWN_TALK_PROC)(NPC_HALLOWEEN_ACTOR*, GAME_PLAY*);
// has to be _P because a function is already defined as aHWN_think_proc
typedef void (*aHWN_THINK_PROC_P)(NPC_ACTOR*, GAME_PLAY*);
/* sizeof(halloween_npc_s) == 0x9AC*/
struct halloween_npc_s {
/* 0x000 */ NPC_ACTOR npc_class;
/* 0x994 */ int dt_tbl_idx;
/* 0x998 */ aHWN_THINK_PROC_P think_proc;
/* 0x99C */ int _99C;
/* 0x9A0 */ aHWN_TALK_PROC talk_proc;
/* 0x9A4 */ mActor_name_t item;
/* 0x9A8 */ BOOL _9A0;
};
enum {
aHWN_TALK_FIRST_CALL_TALK_PROC, // 0
aHWN_TALK_TRICK_OR_TREAT_TALK_PROC, // 1
aHWN_TALK_MENU_OPEN_WAIT_TALK_PROC, // 2
aHWN_TALK_MENU_CLOSE_WAIT_TALK_PROC, // 3
aHWN_TALK_GET_OTHER_ITEM_WAIT_TALK_PROC, // 4
aHWN_TALK_RECEIVE_TOOL_ITEM_START_WAIT_TALK_PROC, // 5
aHWN_TALK_RECEIVE_TOOL_ITEM_END_WAIT_TALK_PROC, // 6
aHWN_TALK_TRICK_TIMING_WAIT_TALK_PROC, // 7
aHWN_TALK_TRICK_CHG_CLOTH_TALK_PROC, // 8
aHWN_TALK_TRICK_CHG_CLOTH_END_WAIT_TALK_PROC, // 9
aHWN_TALK_GET_AME_WAIT_TALK_PROC, // 10
aHWN_TALK_GET_AME_TALK_PROC, // 11
aHWN_TALK_PL_DEMO_CODE_END_WAIT_TALK_PROC, // 12
aHWN_TALK_NONE_PROC1, // 13
};
extern ACTOR_PROFILE Halloween_Npc_Profile;
#ifdef __cplusplus
+129
View File
@@ -0,0 +1,129 @@
#include "ac_halloween_npc.h"
#include "ac_npc.h"
#include "ac_npc_h.h"
#include "dolphin/os/OSRtc.h"
#include "libc64/qrand.h"
#include "libultra/libultra.h"
#include "m_actor_type.h"
#include "m_bgm.h"
#include "m_card.h"
#include "m_choice.h"
#include "m_common_data.h"
#include "m_config.h"
#include "m_demo.h"
#include "m_lib.h"
#include "m_msg.h"
#include "m_npc.h"
#include "m_play.h"
#include "m_play_h.h"
#include "m_player.h"
#include "m_player_lib.h"
#include "m_room_type.h"
#include "m_soncho.h"
#include "m_vibctl.h"
#include "types.h"
static void aHWN_actor_ct(ACTOR* actorx, GAME* game);
static void aHWN_actor_dt(ACTOR* actorx, GAME* game);
static void aHWN_actor_save(ACTOR* actorx, GAME* game);
static void aHWN_actor_init(ACTOR* actorx, GAME* game);
static void aHWN_actor_draw(ACTOR* actorx, GAME* game);
static BOOL aHWN_set_request_act(NPC_HALLOWEEN_ACTOR* actorx, u8 prio, u8 idx, u8 type, u16 obj, s16 move_x,
s16 move_z);
static void aHWN_actor_move(ACTOR* actorx, GAME* game);
static int aHWN_get_trick_type();
static void aHWN_restart_msg_win(NPC_HALLOWEEN_ACTOR* actorx, int msg_idx);
static void aHWN_first_call_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_trick_or_treat_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_menu_open_wait_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_menu_close_wait_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_get_other_item_wait_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_receive_tool_item_start_wait_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_receive_tool_item_end_wait_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_trick_timing_wait_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_trick_chg_cloth_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_trick_chg_cloth_end_wait_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_get_ame_wait_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_get_ame_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_pl_demo_code_end_wait_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_change_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, int talk_proc_idx);
static void aHWN_set_force_talk_info(ACTOR* actorx);
static void aHWN_force_talk_request(ACTOR* actorx, GAME* game);
static void aHWN_set_norm_talk_info(NPC_HALLOWEEN_ACTOR* actorx);
static void aHWN_norm_talk_request(NPC_HALLOWEEN_ACTOR* actorx);
static int aHWN_talk_init();
static BOOL aHWN_talk_end_chk(ACTOR* actorx, GAME* game);
static void aHWN_approach(NPC_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_approach_wait(NPC_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_think_main_proc(NPC_ACTOR* actorx, GAME_PLAY* playe);
static void aHWN_think_init_proc(NPC_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_approach_init(NPC_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_approach_wait_init(NPC_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_setup_think_proc(ACTOR* actorx, GAME* game, int dt_tbl_idx);
static void aHWN_think_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int think_proc_idx);
static void aHWN_schedule_think_init(NPC_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_schedule_init_proc(NPC_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_schedule_main_proc(NPC_ACTOR* actorx, GAME_PLAY* play);
static void aHWN_schedule_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int sche_proc_idx);
// clang-format off
ACTOR_PROFILE Halloween_Npc_Profile = {
mAc_PROFILE_HALLOWEEN_NPC,
ACTOR_PART_NPC,
ACTOR_STATE_NONE,
0,
ACTOR_OBJ_BANK_KEEP,
sizeof(NPC_HALLOWEEN_ACTOR),
aHWN_actor_ct,
aHWN_actor_dt,
aHWN_actor_init,
mActor_NONE_PROC1,
aHWN_actor_save,
};
// clang-format on
static void aHWN_actor_ct(ACTOR* actorx, GAME* game) {
// clang-format off
static aNPC_ct_data_c ct_data = {
&aHWN_actor_move,
&aHWN_actor_draw,
aNPC_CT_SCHED_TYPE_SPECIAL,
&aHWN_force_talk_request,
&aHWN_talk_init,
&aHWN_talk_end_chk,
0,
};
// clang-format on
NPC_HALLOWEEN_ACTOR* hwn_actor = (NPC_HALLOWEEN_ACTOR*)actorx;
if (NPC_CLIP->birth_check_proc(actorx, game) == TRUE) {
hwn_actor->npc_class.schedule.schedule_proc = &aHWN_schedule_proc;
NPC_CLIP->ct_proc(actorx, game, &ct_data);
hwn_actor->npc_class.palActorIgnoreTimer = -1;
}
}
static void aHWN_actor_dt(ACTOR* actorx, GAME* game) {
NPC_CLIP->dt_proc(actorx, game);
}
static void aHWN_actor_save(ACTOR* actorx, GAME* game) {
NPC_CLIP->save_proc(actorx, game);
}
static void aHWN_actor_init(ACTOR* actorx, GAME* game) {
NPC_CLIP->init_proc(actorx, game);
}
static void aHWN_actor_draw(ACTOR* actorx, GAME* game) {
NPC_CLIP->draw_proc(actorx, game);
}
#include "../src/actor/npc/ac_halloween_npc_move.c_inc"
#include "../src/actor/npc/ac_halloween_npc_talk.c_inc"
#include "../src/actor/npc/ac_halloween_npc_schedule.c_inc"
+22
View File
@@ -0,0 +1,22 @@
static BOOL aHWN_set_request_act(NPC_HALLOWEEN_ACTOR* actorx, u8 prio, u8 idx, u8 type, u16 obj, s16 move_x,
s16 move_z) {
BOOL res = FALSE;
if (prio >= actorx->npc_class.request.act_priority) {
u16 args[aNPC_REQUEST_ARG_NUM];
bzero(args, sizeof(args));
args[0] = obj;
args[2] = move_x;
args[3] = move_z;
args[5] = 70;
actorx->npc_class.request.act_priority = prio;
actorx->npc_class.request.act_idx = idx;
actorx->npc_class.request.act_type = type;
mem_copy((u8*)actorx->npc_class.request.act_args, (u8*)args, sizeof(args));
res = TRUE;
}
return res;
}
static void aHWN_actor_move(ACTOR* actorx, GAME* game) {
NPC_CLIP->move_proc(actorx, game);
}
@@ -0,0 +1,120 @@
static void aHWN_approach(NPC_ACTOR* actorx, GAME_PLAY* play) {
NPC_HALLOWEEN_ACTOR* hwn_actor = (NPC_HALLOWEEN_ACTOR*)actorx;
ACTOR* talk_actor = mDemo_Get_talk_actor();
if ((talk_actor != NULL && talk_actor != &actorx->actor_class) ||
(hwn_actor->npc_class.actor_class.block_x != play->block_table.block_x ||
hwn_actor->npc_class.actor_class.block_z != play->block_table.block_z)) {
aHWN_setup_think_proc(&actorx->actor_class, &play->game, 1);
} else if (hwn_actor->npc_class.action.step == aNPC_ACTION_END_STEP) {
aHWN_setup_think_proc(&actorx->actor_class, &play->game, 0);
}
}
static void aHWN_approach_wait(NPC_ACTOR* actorx, GAME_PLAY* play) {
NPC_HALLOWEEN_ACTOR* hwn_actor = (NPC_HALLOWEEN_ACTOR*)actorx;
if (((mDemo_Get_talk_actor() == 0) && (hwn_actor->npc_class.actor_class.block_x == (play->block_table).block_x)) &&
(hwn_actor->npc_class.actor_class.block_z == (play->block_table).block_z)) {
aHWN_setup_think_proc(&actorx->actor_class, &play->game, 0);
} else if (hwn_actor->npc_class.action.step == aNPC_ACTION_END_STEP) {
aHWN_setup_think_proc(&actorx->actor_class, &play->game, 1);
}
}
static void aHWN_think_main_proc(NPC_ACTOR* actorx, GAME_PLAY* play) {
NPC_HALLOWEEN_ACTOR* hwn_actor = (NPC_HALLOWEEN_ACTOR*)actorx;
hwn_actor->think_proc(actorx, play);
}
static void aHWN_think_init_proc(NPC_ACTOR* actorx, GAME_PLAY* play) {
NPC_HALLOWEEN_ACTOR* hwn_actor = (NPC_HALLOWEEN_ACTOR*)actorx;
aHWN_setup_think_proc(&actorx->actor_class, &play->game, 0);
hwn_actor->npc_class.condition_info.hide_request = 0;
hwn_actor->npc_class.think.interrupt_flags = aNPC_THINK_INTERRUPT_ENTRANCE | aNPC_THINK_INTERRUPT_OBSTACLE;
hwn_actor->npc_class.condition_info.demo_flg = aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV;
}
static void aHWN_approach_init(NPC_ACTOR* actorx, GAME_PLAY* play) {
aHWN_set_request_act((NPC_HALLOWEEN_ACTOR*)actorx, 4, aNPC_ACT_RUN, aNPC_ACT_TYPE_SEARCH, aNPC_ACT_OBJ_PLAYER, 0,
0);
}
static void aHWN_approach_wait_init(NPC_ACTOR* actorx, GAME_PLAY* play) {
aHWN_set_request_act((NPC_HALLOWEEN_ACTOR*)actorx, 4, aNPC_ACT_WAIT, aNPC_ACT_TYPE_SEARCH, aNPC_ACT_OBJ_PLAYER, 0,
0);
}
typedef struct {
aHWN_THINK_PROC_P approach_proc;
aHWN_THINK_PROC_P approach_init_proc;
aNPC_TALK_REQUEST_PROC talk_request_proc;
u8 unk;
} aHWN_talk_data_c;
static void aHWN_setup_think_proc(ACTOR* actorx, GAME* game, int dt_tbl_idx) {
NPC_HALLOWEEN_ACTOR* hwn_actor = (NPC_HALLOWEEN_ACTOR*)actorx;
aHWN_talk_data_c* data;
// clang-format off
static aHWN_talk_data_c dt_tbl[] = {
{ &aHWN_approach, &aHWN_approach_init, &aHWN_force_talk_request, 0 },
{ &aHWN_approach_wait, &aHWN_approach_wait_init, (aNPC_TALK_REQUEST_PROC)&none_proc1, 0 },
};
// clang-format on
hwn_actor->dt_tbl_idx = dt_tbl_idx;
data = &dt_tbl[dt_tbl_idx];
hwn_actor->think_proc = data->approach_proc;
hwn_actor->npc_class.talk_info.talk_request_proc = data->talk_request_proc;
hwn_actor->_99C = data->unk;
data->approach_init_proc((NPC_ACTOR*)actorx, (GAME_PLAY*)game);
}
static void aHWN_think_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int think_proc_idx) {
static aHWN_THINK_PROC_P think_proc[] = { aHWN_think_init_proc, aHWN_think_main_proc };
think_proc[think_proc_idx](actorx, play);
}
static void aHWN_schedule_think_init(NPC_ACTOR* actorx, GAME_PLAY* play) {
static int think_idx[] = { 5, 9, 1 };
NPC_CLIP->think_proc(actorx, play, think_idx[actorx->schedule.step], 0);
}
static void aHWN_schedule_init_proc(NPC_ACTOR* actorx, GAME_PLAY* play) {
int step = 1;
actorx->think.think_proc = aHWN_think_proc;
if (actorx->npc_info.animal->is_home == TRUE) {
step = 0;
}
actorx->schedule.step = step;
aHWN_schedule_think_init(actorx, play);
}
static void aHWN_schedule_main_proc(NPC_ACTOR* actorx, GAME_PLAY* play) {
NPC_HALLOWEEN_ACTOR* hwn_actor = (NPC_HALLOWEEN_ACTOR*)actorx;
if (actorx->think.end_flag == TRUE) {
if (actorx->schedule.step != 2) {
actorx->schedule.step += 1;
}
aHWN_schedule_think_init(actorx, play);
} else if (hwn_actor->_9A0 == TRUE) {
if (NPC_CLIP->think_proc(actorx, play, -1, 1) == 0) {
if (actorx->action.step == aNPC_ACTION_END_STEP) {
hwn_actor->_9A0 = FALSE;
aHWN_schedule_think_init(actorx, play);
}
} else {
actorx->request.act_priority = 4;
}
} else {
if (NPC_CLIP->think_proc(actorx, play, -1, 1) == 0) {
NPC_CLIP->think_proc(actorx, play, -1, 2);
} else {
actorx->request.act_priority = 4;
hwn_actor->_9A0 = TRUE;
}
}
}
static void aHWN_schedule_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int sche_proc_idx) {
static aNPC_SUB_PROC sche_proc[] = { aHWN_schedule_init_proc, aHWN_schedule_main_proc };
sche_proc[sche_proc_idx](actorx, play);
}
+301
View File
@@ -0,0 +1,301 @@
static int aHWN_get_trick_type(void) {
int count = 0;
int idx[mPr_POCKETS_SLOT_COUNT];
mActor_name_t* pockets_p = Now_Private->inventory.pockets;
int i;
int ret = 0; // trick type enum/define
for (i = 0; i < mPr_POCKETS_SLOT_COUNT; i++) {
switch (ITEM_NAME_GET_TYPE(*pockets_p)) {
case NAME_TYPE_FTR0:
case NAME_TYPE_FTR1:
if ((NowPrivate_GetItemCond(i) & mPr_ITEM_COND_QUEST) == 0) {
int ftr_idx = mRmTp_FtrItemNo2FtrIdx(*pockets_p);
// check furniture is not jack-o'-lantern nor jack-in-the-box
if (ftr_idx != 0x127 && ftr_idx != 0x131) {
idx[count++] = i;
}
}
break;
case NAME_TYPE_ITEM1:
if (ITEM_NAME_GET_CAT(*pockets_p) != ITEM1_CAT_TOOL &&
(NowPrivate_GetItemCond(i) & mPr_ITEM_COND_QUEST) == 0) {
idx[count++] = i;
}
break;
}
pockets_p++;
}
if (count > 0 && RANDOM_F(1.0f) < 0.5f) {
mActor_name_t new_item;
mSP_SelectRandomItem_New(NULL, &new_item, 1, NULL, 0, mSP_KIND_FURNITURE, mSP_LISTTYPE_HALLOWEEN2, FALSE);
mPr_SetPossessionItem(Now_Private, idx[RANDOM(count)], new_item, mPr_ITEM_COND_NORMAL);
mDemo_Set_OrderValue(mDemo_ORDER_PLAYER, 0, 0xFD); // play trick animation
ret = 1;
}
return ret;
}
static void aHWN_restart_msg_win(NPC_HALLOWEEN_ACTOR* actorx, int msg_idx) {
int msg_data;
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
int look = mNpc_GetLooks(actorx->npc_class.npc_info.event->npc_id);
mMsg_request_main_appear_wait_type1(msg_p);
mMsg_ChangeMsgData(msg_p, ((look & 0xFF) * 6 + msg_idx));
mMsg_Set_ForceNext(msg_p);
mMsg_Unset_LockContinue(msg_p);
}
static void aHWN_first_call_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play) {
int look = mNpc_GetLooks(actorx->npc_class.npc_info.event->npc_id);
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
mMsg_Set_continue_msg_num(msg_p, ((look & 0xFF) * 6) + 0x98b);
aHWN_change_talk_proc(actorx, aHWN_TALK_TRICK_OR_TREAT_TALK_PROC);
}
static void aHWN_trick_or_treat_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play) {
int talk_proc_idx;
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
int order_value = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
if (order_value && mMsg_Check_MainNormalContinue(msg_p) == TRUE) {
if (mChoice_GET_CHOSENUM() == 0) {
mMsg_request_main_disappear_wait_type1(msg_p);
talk_proc_idx = aHWN_TALK_MENU_OPEN_WAIT_TALK_PROC;
} else {
talk_proc_idx = aHWN_TALK_TRICK_TIMING_WAIT_TALK_PROC;
}
aHWN_change_talk_proc(actorx, talk_proc_idx);
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
}
}
static void aHWN_menu_open_wait_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play) {
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
if (mMsg_Check_main_wait(msg_p) == TRUE) {
mSM_open_submenu(&play->submenu, mSM_OVL_INVENTORY, 6, 0);
mMsg_Set_LockContinue(msg_p);
aHWN_change_talk_proc(actorx, aHWN_TALK_MENU_CLOSE_WAIT_TALK_PROC);
}
}
static void aHWN_menu_close_wait_talk_proc(NPC_HALLOWEEN_ACTOR* actor, GAME_PLAY* play) {
Submenu_Item_c* item_p;
int talk_proc_idx;
BOOL shouldSetPosessionItem;
mActor_name_t item;
if (play->submenu.open_flag == FALSE) {
item_p = play->submenu.item_p;
shouldSetPosessionItem = TRUE;
item = item_p->item;
actor->item = item;
if (item == EMPTY_NO) {
talk_proc_idx = aHWN_TALK_TRICK_TIMING_WAIT_TALK_PROC;
aHWN_restart_msg_win(actor, 0x98c);
shouldSetPosessionItem = FALSE;
} else if (item != ITM_FOOD_CANDY) {
if ((item >= ITM_NET && item <= ITM_ROD) || (item >= ITM_GOLDEN_NET && item <= ITM_GOLDEN_ROD)) {
shouldSetPosessionItem = FALSE;
}
talk_proc_idx = aHWN_TALK_GET_OTHER_ITEM_WAIT_TALK_PROC;
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 1, 3);
} else {
talk_proc_idx = aHWN_TALK_GET_AME_WAIT_TALK_PROC;
aHWN_restart_msg_win(actor, 0x98f);
}
if (shouldSetPosessionItem == TRUE) {
mPr_SetPossessionItem(Now_Private, item_p->slot_no, 0, 0);
}
aHWN_change_talk_proc(actor, talk_proc_idx);
}
}
static void aHWN_get_other_item_wait_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play) {
mActor_name_t item;
int talk_proc_idx;
int msg_idx;
if (CLIP(handOverItem_clip)->master_actor == 0) {
item = actorx->item;
talk_proc_idx = aHWN_TALK_TRICK_TIMING_WAIT_TALK_PROC;
msg_idx = 0x98e;
if ((item >= ITM_NET && item <= ITM_ROD) || (item >= ITM_GOLDEN_NET && item <= ITM_GOLDEN_ROD)) {
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 1, 0);
msg_idx = 0x990;
talk_proc_idx = aHWN_TALK_RECEIVE_TOOL_ITEM_START_WAIT_TALK_PROC;
}
aHWN_restart_msg_win(actorx, msg_idx);
aHWN_change_talk_proc(actorx, talk_proc_idx);
}
}
static void aHWN_receive_tool_item_start_wait_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play) {
int OrderValue = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 1);
if (OrderValue == 2) {
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 0, actorx->item);
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 1, 7);
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 2, 0);
mMsg_SET_LOCKCONTINUE();
aHWN_change_talk_proc(actorx, aHWN_TALK_RECEIVE_TOOL_ITEM_END_WAIT_TALK_PROC);
}
}
static void aHWN_receive_tool_item_end_wait_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play) {
int OrderValue = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 1);
if ((OrderValue == 0) && (CLIP(handOverItem_clip)->master_actor == 0)) {
mMsg_UNSET_LOCKCONTINUE();
aHWN_change_talk_proc(actorx, aHWN_TALK_TRICK_TIMING_WAIT_TALK_PROC);
}
}
static void aHWN_trick_timing_wait_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play) {
int trick_type;
int talk_proc_idx;
int OrderValue = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
mMsg_Window_c* msg_p;
if (OrderValue != 0) {
msg_p = mMsg_Get_base_window_p();
trick_type = aHWN_get_trick_type();
talk_proc_idx = aHWN_TALK_PL_DEMO_CODE_END_WAIT_TALK_PROC;
if (trick_type == 0) {
talk_proc_idx = aHWN_TALK_TRICK_CHG_CLOTH_TALK_PROC;
}
mMsg_Set_LockContinue(msg_p);
aHWN_change_talk_proc(actorx, talk_proc_idx);
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
}
}
static void aHWN_trick_chg_cloth_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play) {
int player_actor_main_index = mPlib_get_player_actor_main_index(&play->game);
if (player_actor_main_index == mPlayer_INDEX_CHANGE_CLOTH) {
aHWN_change_talk_proc(actorx, aHWN_TALK_TRICK_CHG_CLOTH_END_WAIT_TALK_PROC);
} else {
mPlib_request_main_change_cloth_forNPC_type1(&play->game, ITM_CLOTH017, 0x11, 0);
}
}
static void aHWN_trick_chg_cloth_end_wait_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play) {
mMsg_Window_c* msg_p;
int looks;
int player_actor_main_index = mPlib_get_player_actor_main_index(&play->game);
if (player_actor_main_index != mPlayer_INDEX_CHANGE_CLOTH) {
msg_p = mMsg_Get_base_window_p();
looks = mNpc_GetLooks(actorx->npc_class.npc_info.event->npc_id);
mMsg_Unset_LockContinue(msg_p);
mMsg_Set_ForceNext(msg_p);
mMsg_ChangeMsgData(msg_p, (looks * 6 + 0x98d));
aHWN_change_talk_proc(actorx, aHWN_TALK_NONE_PROC1);
}
}
static void aHWN_get_ame_wait_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play) {
int OrderValue = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 1);
if ((OrderValue == 3) && (CLIP(handOverItem_clip)->master_actor != 0)) {
mMsg_SET_LOCKCONTINUE();
aHWN_change_talk_proc(actorx, aHWN_TALK_GET_AME_TALK_PROC);
}
}
static void aHWN_get_ame_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play) {
if (CLIP(handOverItem_clip)->master_actor == 0) {
mMsg_UNSET_LOCKCONTINUE();
aHWN_change_talk_proc(actorx, aHWN_TALK_NONE_PROC1);
}
}
static void aHWN_pl_demo_code_end_wait_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, GAME_PLAY* play) {
mMsg_Window_c* msg_p;
int look;
int OrderValue = mDemo_Get_OrderValue(mDemo_ORDER_PLAYER, 0);
if (OrderValue == 0) {
msg_p = mMsg_Get_base_window_p();
look = mNpc_GetLooks(actorx->npc_class.npc_info.event->npc_id);
mMsg_Unset_LockContinue(msg_p);
mMsg_Set_ForceNext(msg_p);
mMsg_ChangeMsgData(msg_p, ((look & 0xFF) * 6 + 0x98d));
aHWN_change_talk_proc(actorx, aHWN_TALK_NONE_PROC1);
}
}
static void aHWN_change_talk_proc(NPC_HALLOWEEN_ACTOR* actorx, int talk_proc_idx) {
// clang-format off
static aHWN_TALK_PROC talk_proc[] = {
&aHWN_first_call_talk_proc,
&aHWN_trick_or_treat_talk_proc,
&aHWN_menu_open_wait_talk_proc,
&aHWN_menu_close_wait_talk_proc,
&aHWN_get_other_item_wait_talk_proc,
&aHWN_receive_tool_item_start_wait_talk_proc,
&aHWN_receive_tool_item_end_wait_talk_proc,
&aHWN_trick_timing_wait_talk_proc,
&aHWN_trick_chg_cloth_talk_proc,
&aHWN_trick_chg_cloth_end_wait_talk_proc,
&aHWN_get_ame_wait_talk_proc,
&aHWN_get_ame_talk_proc,
&aHWN_pl_demo_code_end_wait_talk_proc,
(aHWN_TALK_PROC)&none_proc1,
};
// clang-format on
actorx->talk_proc = talk_proc[talk_proc_idx];
}
static void aHWN_set_force_talk_info(ACTOR* actorx) {
mDemo_Set_msg_num(0x98a);
mDemo_Set_talk_turn(1);
aHWN_change_talk_proc((NPC_HALLOWEEN_ACTOR*)actorx, aHWN_TALK_FIRST_CALL_TALK_PROC);
}
static void aHWN_force_talk_request(ACTOR* actorx, GAME* game) {
int bx;
int bz;
ACTOR* player_actorx = GET_PLAYER_ACTOR_ACTOR((GAME_PLAY*)game);
if (player_actorx != NULL) {
if (!mFI_Wpos2BlockNum(&bx, &bz, player_actorx->world.position)) {
bx = 0;
bz = 0;
}
} else {
bx = 0;
bz = 0;
}
if (actorx->player_distance_xz < 70.0f) {
if ((ABS(actorx->player_distance_y) < 20.0f) && (actorx->block_x == bx) && (actorx->block_z == bz)) {
mDemo_Request(mDemo_TYPE_SPEAK, actorx, aHWN_set_force_talk_info);
}
}
}
static void aHWN_set_norm_talk_info(NPC_HALLOWEEN_ACTOR* actorx) {
int looks = mNpc_GetLooks(actorx->npc_class.npc_info.event->npc_id);
mDemo_Set_msg_num((looks & 0xFF) + 0x9af);
aHWN_change_talk_proc(actorx, aHWN_TALK_NONE_PROC1);
}
static void aHWN_norm_talk_request(NPC_HALLOWEEN_ACTOR* actorx) {
mDemo_Request(mDemo_TYPE_TALK, &actorx->npc_class.actor_class, (mDemo_REQUEST_PROC)aHWN_set_norm_talk_info);
}
static int aHWN_talk_init() {
mDemo_Set_ListenAble();
return 1;
}
static BOOL aHWN_talk_end_chk(ACTOR* actorx, GAME* game) {
BOOL res = FALSE;
NPC_HALLOWEEN_ACTOR* hwn_actor = (NPC_HALLOWEEN_ACTOR*)actorx;
hwn_actor->talk_proc((NPC_HALLOWEEN_ACTOR*)actorx, (GAME_PLAY*)game);
if ((mDemo_Check(mDemo_TYPE_SPEAK, &hwn_actor->npc_class.actor_class) == FALSE) &&
(mDemo_Check(mDemo_TYPE_TALK, &hwn_actor->npc_class.actor_class) == FALSE)) {
if (hwn_actor->npc_class.schedule.step == 1) {
hwn_actor->npc_class.think.end_flag = TRUE;
}
res = TRUE;
hwn_actor->npc_class.talk_info.talk_request_proc = (aNPC_TALK_REQUEST_PROC)aHWN_norm_talk_request;
}
return res;
}