Implement & link ac_npc_shop_mastersp

This commit is contained in:
Cuyler36
2024-12-28 19:25:33 -05:00
parent 6a945e159f
commit eedc9646b4
10 changed files with 1026 additions and 3 deletions
+1 -1
View File
@@ -1130,7 +1130,7 @@ config.libs = [
Object(Matching, "actor/npc/ac_npc_sendo.c"),
Object(NonMatching, "actor/npc/ac_npc_shasho.c"),
Object(Matching, "actor/npc/ac_npc_shop_master.c"),
Object(NonMatching, "actor/npc/ac_npc_shop_mastersp.c"),
Object(Matching, "actor/npc/ac_npc_shop_mastersp.c"),
Object(NonMatching, "actor/npc/ac_npc_sleep_obaba.c"),
Object(NonMatching, "actor/npc/ac_npc_soncho.c"),
Object(NonMatching, "actor/npc/ac_npc_station_master.c"),
+3 -1
View File
@@ -352,11 +352,13 @@ typedef struct npc_action_s {
aNPC_ACTION_PROC act_proc;
} aNPC_action_c;
#define aNPC_REQUEST_ARG_NUM 6
typedef struct npc_request_s {
u8 act_priority;
u8 act_idx;
u8 act_type;
u16 act_args[6];
u16 act_args[aNPC_REQUEST_ARG_NUM];
u8 umb_flag;
u8 _11;
u8 head_priority;
+33 -1
View File
@@ -3,11 +3,44 @@
#include "types.h"
#include "m_actor.h"
#include "ac_npc.h"
#include "m_shop.h"
#include "m_player_lib.h"
#ifdef __cplusplus
extern "C" {
#endif
#define aSHM_REQ_TICKET_NUM 5
#define aSHM_FIRST_PLACE_PERCENT 5
#define aSHM_SECOND_PLACE_PERCENT (10 + aSHM_FIRST_PLACE_PERCENT)
#define aSHM_THIRD_PLACE_PERCENT (20 + aSHM_SECOND_PLACE_PERCENT)
typedef struct npc_shop_mastersp_actor_s NPC_SHOP_MASTERSP_ACTOR;
typedef void (*aSHM_THINK_PROC)(NPC_SHOP_MASTERSP_ACTOR*, GAME_PLAY*);
typedef void (*aSHM_TALK_PROC)(NPC_SHOP_MASTERSP_ACTOR*, GAME_PLAY*);
struct npc_shop_mastersp_actor_s {
NPC_ACTOR npc_class;
int think_idx;
int next_think_idx;
int move_think_idx;
aSHM_THINK_PROC think_proc;
int talk_idx;
aSHM_TALK_PROC talk_proc;
s16 result;
s16 timer;
s16 root;
s16 root_idx;
s16 now_idx;
int month;
int ut[2];
int melody_bak;
s16 base_pos[11][2];
};
extern ACTOR_PROFILE Npc_Shop_Mastersp_Profile;
#ifdef __cplusplus
@@ -15,4 +48,3 @@ extern ACTOR_PROFILE Npc_Shop_Mastersp_Profile;
#endif
#endif
+2
View File
@@ -111,6 +111,8 @@ typedef enum audio_sound_effects {
NA_SE_STONECOIN_ROLL = 0x7D,
NA_SE_STONECOIN_DRAG = 0x7E,
NA_SE_7F = 0x7F,
NA_SE_TRAIN_RIDE = 0x8D,
NA_SE_GOKI_MOVE = 0xA8,
+2
View File
@@ -206,6 +206,8 @@ extern int mDemo_Check_ListenAble();
extern int mDemo_Check_DiffAngle_forTalk(s16 diff_angle);
extern void mDemo_KeepCamera(int camera_type);
#define mDemo_CAN_ACTOR_TALK(actor) (!mDemo_Check(mDemo_TYPE_SPEAK, (actor)) && !mDemo_Check(mDemo_TYPE_TALK, (actor)))
#ifdef __cplusplus
}
#endif
+3
View File
@@ -209,6 +209,9 @@ extern int mNT_check_unknown(mActor_name_t item_no);
#define TICKET_MONTH(n) (1 + (((n) >> 3) & 0xF))
#define TICKET_COUNT(n) (1 + ((n) & 7))
#define TICKET_TO_MONTH(month) (((month) - 1) << 3)
#define TICKET_TO_COUNT(cnt) ((cnt) & 7)
#define TICKET_GET_ITEM(month, cnt) (ITM_TICKET_START | (((month) - 1) << 3) | ((cnt) & 7))
#define WISP_COUNT(n) (ITEM_IS_WISP(n) ? (1 + (n) - ITM_SPIRIT0) : 0)
#define ITEM_IS_INSECT(n) ((n) >= ITM_INSECT_START && (n) < ITM_INSECT_END)
+135
View File
@@ -0,0 +1,135 @@
#include "ac_npc_shop_mastersp.h"
#include "m_common_data.h"
#include "libultra/libultra.h"
#include "m_item_name.h"
#include "m_msg.h"
#include "m_bgm.h"
enum {
aSHM_WON_FIRST_PLACE,
aSHM_WON_SECOND_PLACE,
aSHM_WON_THIRD_PLACE,
aSHM_DIDNT_WIN,
aSHM_WIN_NUM
};
enum {
aSHM_TALK_TALK_TRY,
aSHM_TALK_TALK_HAZURE,
aSHM_TALK_TALK_RETRY,
aSHM_TALK_STOP_PLAYER,
aSHM_TALK_GIVE_PLAYER,
aSHM_TALK_TALK_TAMAKESI,
aSHM_TALK_END_WAIT,
aSHM_TALK_SAY_GOODBYE,
aSHM_TALK_EXIT_WAIT,
aSHM_TALK_NUM
};
enum {
aSHM_THINK_NORMAL_WAIT,
aSHM_THINK_NORMAL_WAIT2,
aSHM_THINK_NORMAL_WAIT3,
aSHM_THINK_NORMAL_TURN,
aSHM_THINK_4,
aSHM_THINK_5,
aSHM_THINK_WIN1,
aSHM_THINK_WIN2,
aSHM_THINK_WIN3,
aSHM_THINK_LOSE,
aSHM_THINK_10,
aSHM_THINK_11,
aSHM_THINK_12,
aSHM_THINK_MOVE,
aSHM_THINK_MOVE_TURN,
aSHM_THINK_FADE_OUT,
aSHM_THINK_MOVE_PLAYER,
aSHM_THINK_WAIT_PLAYER,
aSHM_THINK_WAIT_PLAYER2,
aSHM_THINK_WAIT_PLAYER3,
aSHM_THINK_WAIT_PLAYER4,
aSHM_THINK_HIROU,
aSHM_THINK_HAPPY_ACADEMY,
aSHM_THINK_HAPPY_ACADEMY2,
aSHM_THINK_HAPPY_ACADEMY3,
aSHM_THINK_NUM
};
static void aSHM_actor_ct(ACTOR* actorx, GAME* game);
static void aSHM_actor_dt(ACTOR* actorx, GAME* game);
static void aSHM_actor_move(ACTOR* actorx, GAME* game);
static void aSHM_actor_init(ACTOR* actorx, GAME* game);
static void aSHM_actor_draw(ACTOR* actorx, GAME* game);
static void aSHM_actor_save(ACTOR* actorx, GAME* game);
// clang-format off
ACTOR_PROFILE Npc_Shop_Mastersp_Profile = {
mAc_PROFILE_NPC_SHOP_MASTERSP,
ACTOR_PART_NPC,
ACTOR_STATE_NONE,
SP_NPC_SHOP_MASTERSP,
ACTOR_OBJ_BANK_KEEP,
sizeof(NPC_SHOP_MASTERSP_ACTOR),
&aSHM_actor_ct,
&aSHM_actor_dt,
&aSHM_actor_init,
mActor_NONE_PROC1,
&aSHM_actor_save,
};
// clang-format on
static int aSHM_talk_init(ACTOR* actorx, GAME* game);
static int aSHM_talk_end_chk(ACTOR* actorx, GAME* game);
static void aSHM_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int type);
static int aSHM_change_talk_proc(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, int talk_proc_idx);
static void aSHM_setup_think_proc(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play, int think_idx);
static void aSHM_set_base_position(ACTOR* actorx, GAME_PLAY* play);
static void aSHM_actor_ct(ACTOR* actorx, GAME* game) {
// clang-format off
static aNPC_ct_data_c ct_data = {
&aSHM_actor_move,
&aSHM_actor_draw,
5,
(aNPC_TALK_REQUEST_PROC)&none_proc1,
&aSHM_talk_init,
&aSHM_talk_end_chk,
0,
};
// clang-format on
if (CLIP(npc_clip)->birth_check_proc(actorx, game) == TRUE) {
NPC_SHOP_MASTERSP_ACTOR* shop_mastersp = (NPC_SHOP_MASTERSP_ACTOR*)actorx;
shop_mastersp->npc_class.schedule.schedule_proc = &aSHM_schedule_proc;
CLIP(npc_clip)->ct_proc(actorx, game, &ct_data);
aSHM_set_base_position(actorx, (GAME_PLAY*)game);
shop_mastersp->melody_bak = 0;
}
}
static void aSHM_actor_save(ACTOR* actorx, GAME* game) {
mNpc_RenewalSetNpc(actorx);
}
static void aSHM_actor_dt(ACTOR* actorx, GAME* game) {
CLIP(npc_clip)->dt_proc(actorx, game);
}
static void aSHM_actor_init(ACTOR* actorx, GAME* game) {
CLIP(npc_clip)->init_proc(actorx, game);
}
static void aSHM_actor_draw(ACTOR* actorx, GAME* game) {
CLIP(npc_clip)->draw_proc(actorx, game);
}
#include "../src/actor/npc/ac_npc_shop_mastersp_move.c_inc"
#include "../src/actor/npc/ac_npc_shop_mastersp_talk.c_inc"
#include "../src/actor/npc/ac_npc_shop_mastersp_schedule.c_inc"
@@ -0,0 +1,123 @@
static s16 aSHM_ftr_revise_x(mActor_name_t item) {
if (mRmTp_ItemNo2FtrSize(item) == mRmTp_FTRSIZE_1x1) {
return -(mFI_UT_WORLDSIZE_X / 2);
}
return 0;
}
static s16 aSHM_ftr_revise_z(mActor_name_t item) {
if (mRmTp_ItemNo2FtrSize(item) == mRmTp_FTRSIZE_2x2) {
return 0;
}
return -mFI_UT_WORLDSIZE_Z;
}
static void aSHM_set_base_position(ACTOR* actorx, GAME_PLAY* play) {
NPC_SHOP_MASTERSP_ACTOR* shop_mastersp = (NPC_SHOP_MASTERSP_ACTOR*)actorx;
int level = mSP_GetShopLevel();
mActor_name_t* item_p = Save_Get(shop).lottery_items;
static s16 base_table_x[] = { 160, 240, 240, 240 };
static s16 base_table_z[] = { 140, 140, 300, 300 };
ACTOR* player = GET_PLAYER_ACTOR_ACTOR(play);
shop_mastersp->base_pos[0][0] = base_table_x[level];
shop_mastersp->base_pos[0][1] = base_table_z[level];
actorx->world.position.x = shop_mastersp->base_pos[0][0];
actorx->world.position.z = shop_mastersp->base_pos[0][1];
shop_mastersp->base_pos[1][0] = base_table_x[level];
shop_mastersp->base_pos[1][1] = base_table_z[level] - 2;
shop_mastersp->base_pos[1][0] += aSHM_ftr_revise_x(item_p[0]);
shop_mastersp->base_pos[1][1] += aSHM_ftr_revise_z(item_p[0]);
shop_mastersp->base_pos[2][0] = base_table_x[level] + 80;
shop_mastersp->base_pos[2][1] = base_table_z[level] - 2;
shop_mastersp->base_pos[2][0] += aSHM_ftr_revise_x(item_p[1]);
shop_mastersp->base_pos[2][1] += aSHM_ftr_revise_z(item_p[1]);
shop_mastersp->base_pos[3][0] = base_table_x[level] - 80;
shop_mastersp->base_pos[3][1] = base_table_z[level] - 2;
shop_mastersp->base_pos[3][0] += aSHM_ftr_revise_x(item_p[2]);
shop_mastersp->base_pos[3][1] += aSHM_ftr_revise_z(item_p[2]);
shop_mastersp->base_pos[4][0] = shop_mastersp->base_pos[0][0] - 80;
shop_mastersp->base_pos[4][1] = shop_mastersp->base_pos[0][1];
shop_mastersp->base_pos[5][0] = shop_mastersp->base_pos[4][0];
shop_mastersp->base_pos[5][1] = shop_mastersp->base_pos[4][1] + 80;
shop_mastersp->base_pos[6][0] = shop_mastersp->base_pos[5][0] + 40;
shop_mastersp->base_pos[6][1] = shop_mastersp->base_pos[5][1];
shop_mastersp->base_pos[7][0] = shop_mastersp->base_pos[0][0] + 80;
shop_mastersp->base_pos[7][1] = shop_mastersp->base_pos[0][1];
shop_mastersp->base_pos[8][0] = shop_mastersp->base_pos[7][0];
shop_mastersp->base_pos[8][1] = shop_mastersp->base_pos[7][1] + 80;
shop_mastersp->base_pos[9][0] = shop_mastersp->base_pos[8][0] - 40;
shop_mastersp->base_pos[9][1] = shop_mastersp->base_pos[8][1];
shop_mastersp->base_pos[10][0] = player->world.position.x;
shop_mastersp->base_pos[10][1] = player->world.position.z - 60.0f;
}
static void aSHM_set_avoid_pos(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp) {
static u8 root1[1] = { 1 };
static u8 root2[3] = { 4, 5, 6 };
static u8 root3[3] = { 5, 4, 0 };
static u8 root4[2] = { 7, 2 };
static u8 root5[2] = { 8, 9 };
static u8 root6[3] = { 8, 7, 0 };
static u8 root7[2] = { 4, 3 };
static u8 root8[2] = { 5, 6 };
static u8 root10[3] = { 7, 8, 10 };
static u8* root_table[10] = { root1, root2, root3, root4, root5, root6, root7, root8, root3, root10 };
shop_mastersp->now_idx = root_table[shop_mastersp->root][shop_mastersp->root_idx];
}
static void aSHM_set_start_avoid_pos(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, s16 root) {
shop_mastersp->root = root;
shop_mastersp->root_idx = 0;
aSHM_set_avoid_pos(shop_mastersp);
}
static int aSHM_set_next_avoid_pos(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp) {
static s16 root_max[] = { 1, 3, 3, 2, 2, 3, 2, 2, 3, 3 };
shop_mastersp->root_idx++;
if (shop_mastersp->root_idx < root_max[shop_mastersp->root]) {
aSHM_set_avoid_pos(shop_mastersp);
return FALSE;
}
return TRUE;
}
static int aSHM_set_request_act(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, u8 prio, u8 act_idx, u8 act_type, u16 act_obj, s16 pos_x, s16 pos_z) {
int ret = FALSE;
if (prio >= shop_mastersp->npc_class.request.act_priority) {
u16 args[aNPC_REQUEST_ARG_NUM];
bzero(args, sizeof(args));
args[0] = act_obj;
args[2] = pos_x;
args[3] = pos_z;
shop_mastersp->npc_class.request.act_priority = prio;
shop_mastersp->npc_class.request.act_idx = act_idx;
shop_mastersp->npc_class.request.act_type = act_type;
mem_copy((u8*)shop_mastersp->npc_class.request.act_args, (u8*)args, sizeof(args));
ret = TRUE;
}
return ret;
}
static void aSHM_actor_move(ACTOR* actorx, GAME* game) {
CLIP(npc_clip)->move_proc(actorx, game);
}
@@ -0,0 +1,303 @@
static void aSHM_set_start_think(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
int think_idx;
ACTOR* actorx = (ACTOR*)shop_mastersp;
if (!mLd_PlayerManKindCheck() && mEv_CheckEvent(mEv_SAVED_HRATALK_PLR0 + Common_Get(player_no)) == TRUE) {
think_idx = aSHM_THINK_HAPPY_ACADEMY;
} else {
actorx->talk_distance = 55.0f;
if (check_null_lottery()) {
think_idx = aSHM_THINK_NORMAL_WAIT2;
} else if (ABS(actorx->player_angle_y) < 4000) {
actorx->talk_distance = 100.0f;
think_idx = aSHM_THINK_NORMAL_WAIT;
} else {
think_idx = aSHM_THINK_NORMAL_WAIT3;
}
}
aSHM_setup_think_proc(shop_mastersp, play, think_idx);
}
static void aSHM_normal_wait_common(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
if (player_go_away(play)) {
aSHM_setup_think_proc(shop_mastersp, play, aSHM_THINK_4);
} else if (player_buy(shop_mastersp, play)) {
aSHM_setup_think_proc(shop_mastersp, play, aSHM_THINK_5);
}
}
static void aSHM_normal_wait(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
ACTOR* actorx = (ACTOR*)shop_mastersp;
if (ABS(actorx->player_angle_y) > 4000) {
aSHM_setup_think_proc(shop_mastersp, play, aSHM_THINK_NORMAL_WAIT3);
actorx->talk_distance = 55.0f;
}
aSHM_normal_wait_common(shop_mastersp, play);
}
static void aSHM_normal_wait2(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
ACTOR* actorx = (ACTOR*)shop_mastersp;
if (ABS(actorx->player_angle_y) > 4000) {
actorx->talk_distance = 55.0f;
} else {
actorx->talk_distance = 100.0f;
}
aSHM_normal_wait_common(shop_mastersp, play);
}
static void aSHM_normal_wait3(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
ACTOR* actorx = (ACTOR*)shop_mastersp;
if (ABS(actorx->player_angle_y) < 4000) {
aSHM_setup_think_proc(shop_mastersp, play, aSHM_THINK_NORMAL_WAIT);
actorx->talk_distance = 100.0f;
}
aSHM_normal_wait_common(shop_mastersp, play);
}
static void aSHM_normal_turn(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
NPC_ACTOR* nactorx = (NPC_ACTOR*)shop_mastersp;
if (nactorx->action.idx == aNPC_ACT_TURN) {
aSHM_set_start_think(shop_mastersp, play);
}
}
static void aSHM_move(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
if (shop_mastersp->npc_class.action.idx == aNPC_ACT_WALK2 || shop_mastersp->npc_class.action.idx == aNPC_ACT_WAIT) {
if (aSHM_set_next_avoid_pos(shop_mastersp)) {
aSHM_setup_think_proc(shop_mastersp, play, shop_mastersp->move_think_idx);
} else {
aSHM_setup_think_proc(shop_mastersp, play, aSHM_THINK_MOVE);
}
}
}
static void aSHM_move_turn(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
if (shop_mastersp->npc_class.action.idx == aNPC_ACT_TURN) {
aSHM_setup_think_proc(shop_mastersp, play, aSHM_THINK_MOVE);
}
}
static void aSHM_move_player(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
if (mPlib_get_player_actor_main_index((GAME*)play) != mPlayer_INDEX_DEMO_WALK) {
mPlib_request_main_demo_walk_type1((GAME*)play, shop_mastersp->base_pos[0][0],
shop_mastersp->base_pos[0][1] + 2 * mFI_UT_WORLDSIZE_Z, 2.0f, FALSE);
} else {
aSHM_setup_think_proc(shop_mastersp, play, aSHM_THINK_WAIT_PLAYER);
}
}
static void aSHM_wait_player(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
if (mPlib_get_player_actor_main_index((GAME*)play) != mPlayer_INDEX_DEMO_WALK) {
aSHM_setup_think_proc(shop_mastersp, play, aSHM_THINK_WAIT_PLAYER2);
}
}
static void aSHM_wait_player2(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
xyz_t pos;
ACTOR* actorx = (ACTOR*)shop_mastersp;
if (mPlib_get_player_actor_main_index((GAME*)play) != mPlayer_INDEX_ROTATE_OCTAGON) {
pos.x = shop_mastersp->base_pos[0][0];
pos.y = actorx->world.position.y;
pos.z = shop_mastersp->base_pos[0][1] + 2 * mFI_UT_WORLDSIZE_Z - 2;
mPlib_request_main_rotate_octagon_type1((GAME*)play, &pos, DEG2SHORT_ANGLE2(180.0f));
} else {
aSHM_setup_think_proc(shop_mastersp, play, aSHM_THINK_WAIT_PLAYER3);
}
}
static void aSHM_wait_player3(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
if (mPlib_Check_RotateOctagon()) {
aSHM_setup_think_proc(shop_mastersp, play, aSHM_THINK_WAIT_PLAYER4);
if (CLIP(garagara_clip) != NULL) {
CLIP(garagara_clip)->garagara_anime_start_proc(shop_mastersp->result);
}
}
}
static void aSHM_wait_player4(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
if (!mPlib_Check_RotateOctagon()) {
aSHM_setup_think_proc(shop_mastersp, play, aSHM_THINK_WIN1 + shop_mastersp->result);
}
}
static void aSHM_hirou(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
mActor_name_t* item_p = Save_Get(shop).lottery_items;
if (shop_mastersp->timer == 10) {
aSHM_remove_gift(shop_mastersp, item_p[shop_mastersp->result]);
}
if (shop_mastersp->timer > 0) {
shop_mastersp->timer--;
return;
}
mFI_UtNumtoFGSet_common(RSV_SHOP_SOLD_FTR, shop_mastersp->ut[0], shop_mastersp->ut[1], FALSE);
aSHM_set_start_avoid_pos(shop_mastersp, shop_mastersp->root + 1);
shop_mastersp->move_think_idx = aSHM_THINK_10;
aSHM_setup_think_proc(shop_mastersp, play, aSHM_THINK_MOVE_TURN);
}
static void aSHM_happy_academy3(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
GAME* game = (GAME*)play;
if (mPlib_get_player_actor_main_index(game) == mPlayer_INDEX_DEMO_WAIT) {
mPlib_request_main_wait_type3(game);
} else {
aSHM_setup_think_proc(shop_mastersp, play, aSHM_THINK_NORMAL_TURN);
}
}
static void aSHM_think_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
NPC_SHOP_MASTERSP_ACTOR* shop_mastersp = (NPC_SHOP_MASTERSP_ACTOR*)nactorx;
if (shop_mastersp->think_idx == aSHM_THINK_HAPPY_ACADEMY3) {
(*shop_mastersp->think_proc)(shop_mastersp, play);
} else if (shop_mastersp->think_idx == aSHM_THINK_NORMAL_WAIT ||
shop_mastersp->think_idx == aSHM_THINK_NORMAL_WAIT2 ||
shop_mastersp->think_idx == aSHM_THINK_NORMAL_WAIT3) {
(*shop_mastersp->think_proc)(shop_mastersp, play);
} else if (shop_mastersp->npc_class.action.step == aNPC_ACTION_END_STEP) {
(*shop_mastersp->think_proc)(shop_mastersp, play);
} else if (shop_mastersp->npc_class.action.idx == aNPC_ACT_WALK2) {
shop_mastersp->npc_class.movement.mv_add_angl = DEG2SHORT_ANGLE2(22.5f);
}
}
static void aSHM_think_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
NPC_SHOP_MASTERSP_ACTOR* shop_mastersp = (NPC_SHOP_MASTERSP_ACTOR*)nactorx;
lbRTC_time_c rtc_time = Common_Get(time.rtc_time);
shop_mastersp->npc_class.actor_class.status_data.weight = MASSTYPE_HEAVY;
shop_mastersp->npc_class.condition_info.hide_request = FALSE;
aSHM_set_start_think(shop_mastersp, play);
shop_mastersp->month = rtc_time.month;
}
static void aSHM_normal_wait_init(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
aSHM_set_request_act(shop_mastersp, 4, aNPC_ACT_WAIT, aNPC_ACT_TYPE_SEARCH, aNPC_ACT_OBJ_PLAYER, 0, 0);
}
static void aSHM_normal_turn_init(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
ACTOR* actorx = (ACTOR*)shop_mastersp;
aSHM_set_request_act(shop_mastersp, 4, aNPC_ACT_TURN, aNPC_ACT_TYPE_TO_POINT, aNPC_ACT_OBJ_DEFAULT,
actorx->world.position.x, actorx->world.position.z + 10);
}
static void aSHM_move_init(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
aSHM_set_request_act(shop_mastersp, 4, aNPC_ACT_WALK2, aNPC_ACT_TYPE_TO_POINT, aNPC_ACT_OBJ_DEFAULT,
shop_mastersp->base_pos[shop_mastersp->now_idx][0],
shop_mastersp->base_pos[shop_mastersp->now_idx][1]);
}
static void aSHM_move_turn_init(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
aSHM_set_request_act(shop_mastersp, 4, aNPC_ACT_TURN, aNPC_ACT_TYPE_TO_POINT, aNPC_ACT_OBJ_DEFAULT,
shop_mastersp->base_pos[shop_mastersp->now_idx][0],
shop_mastersp->base_pos[shop_mastersp->now_idx][1]);
}
static void aSHM_fade_out_init(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
// nothing
}
static void aSHM_hirou_init(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
aSHM_set_request_act(shop_mastersp, 4, aNPC_ACT_TURN, aNPC_ACT_TYPE_TO_POINT, aNPC_ACT_OBJ_DEFAULT,
shop_mastersp->base_pos[shop_mastersp->now_idx][0],
shop_mastersp->base_pos[shop_mastersp->now_idx][1] - 10);
shop_mastersp->timer = 20;
}
static void aSHM_happy_academy_init(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
shop_mastersp->move_think_idx = aSHM_THINK_HAPPY_ACADEMY2;
aSHM_set_start_avoid_pos(shop_mastersp, 9);
}
static void aSHM_happy_academy2_init(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
mEv_EventOFF(mEv_SAVED_HRATALK_PLR0 + Common_Get(player_no));
shop_mastersp->move_think_idx = aSHM_THINK_HAPPY_ACADEMY3;
aSHM_set_start_avoid_pos(shop_mastersp, 5);
}
typedef struct {
aSHM_THINK_PROC think_proc;
aSHM_THINK_PROC think_init_proc;
aNPC_TALK_REQUEST_PROC talk_request_proc;
u8 talk_idx;
u8 next_think_idx;
} aSHM_think_data_c;
static void aSHM_setup_think_proc(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play, int think_idx) {
// clang-format off
static aSHM_think_data_c dt_tbl[aSHM_THINK_NUM] = {
{aSHM_normal_wait, aSHM_normal_wait_init, aSHM_norm_talk_request, 0x00, aSHM_THINK_NORMAL_TURN},
{aSHM_normal_wait2, aSHM_normal_wait_init, aSHM_norm_talk_request, 0x01, aSHM_THINK_NORMAL_TURN},
{aSHM_normal_wait3, aSHM_normal_wait_init, aSHM_norm_talk_request, 0x02, aSHM_THINK_NORMAL_TURN},
{aSHM_normal_turn, aSHM_normal_turn_init, (aNPC_TALK_REQUEST_PROC)none_proc1, 0x00, aSHM_THINK_NORMAL_TURN},
{(aSHM_THINK_PROC)none_proc1, aSHM_normal_wait_init, aSHM_force_talk_request, 0x00, aSHM_THINK_FADE_OUT},
{(aSHM_THINK_PROC)none_proc1, aSHM_normal_wait_init, aSHM_force_talk_request, 0x01, aSHM_THINK_NORMAL_TURN},
{(aSHM_THINK_PROC)none_proc1, aSHM_normal_wait_init, aSHM_force_talk_request, 0x02, aSHM_THINK_MOVE_TURN},
{(aSHM_THINK_PROC)none_proc1, aSHM_normal_wait_init, aSHM_force_talk_request, 0x03, aSHM_THINK_MOVE_TURN},
{(aSHM_THINK_PROC)none_proc1, aSHM_normal_wait_init, aSHM_force_talk_request, 0x04, aSHM_THINK_MOVE_TURN},
{(aSHM_THINK_PROC)none_proc1, aSHM_normal_wait_init, aSHM_force_talk_request, 0x05, aSHM_THINK_NORMAL_TURN},
{(aSHM_THINK_PROC)none_proc1, aSHM_normal_wait_init, aSHM_force_talk_request, 0x06, aSHM_THINK_MOVE_TURN},
{(aSHM_THINK_PROC)none_proc1, aSHM_normal_wait_init, aSHM_force_talk_request, 0x07, aSHM_THINK_NORMAL_TURN},
{(aSHM_THINK_PROC)none_proc1, aSHM_normal_wait_init, aSHM_force_talk_request, 0x08, aSHM_THINK_NORMAL_TURN},
{aSHM_move, aSHM_move_init, (aNPC_TALK_REQUEST_PROC)none_proc1, 0x00, aSHM_THINK_MOVE_TURN},
{aSHM_move_turn, aSHM_move_turn_init, (aNPC_TALK_REQUEST_PROC)none_proc1, 0x00, aSHM_THINK_MOVE},
{(aSHM_THINK_PROC)none_proc1, aSHM_fade_out_init, (aNPC_TALK_REQUEST_PROC)none_proc1, 0x00, aSHM_THINK_FADE_OUT},
{aSHM_move_player, (aSHM_THINK_PROC)none_proc1, (aNPC_TALK_REQUEST_PROC)none_proc1, 0x00, aSHM_THINK_MOVE_PLAYER},
{aSHM_wait_player, (aSHM_THINK_PROC)none_proc1, (aNPC_TALK_REQUEST_PROC)none_proc1, 0x00, aSHM_THINK_WAIT_PLAYER},
{aSHM_wait_player2, (aSHM_THINK_PROC)none_proc1, (aNPC_TALK_REQUEST_PROC)none_proc1, 0x00, aSHM_THINK_WAIT_PLAYER2},
{aSHM_wait_player3, (aSHM_THINK_PROC)none_proc1, (aNPC_TALK_REQUEST_PROC)none_proc1, 0x00, aSHM_THINK_WAIT_PLAYER3},
{aSHM_wait_player4, (aSHM_THINK_PROC)none_proc1, (aNPC_TALK_REQUEST_PROC)none_proc1, 0x00, aSHM_THINK_WAIT_PLAYER4},
{aSHM_hirou, aSHM_hirou_init, (aNPC_TALK_REQUEST_PROC)none_proc1, 0x00, aSHM_THINK_HIROU},
{(aSHM_THINK_PROC)none_proc1, aSHM_happy_academy_init, aSHM_force_talk_request, 0x09, aSHM_THINK_MOVE_TURN},
{(aSHM_THINK_PROC)none_proc1, aSHM_happy_academy2_init, aSHM_force_talk_request, 0x0A, aSHM_THINK_MOVE_TURN},
{aSHM_happy_academy3, aSHM_normal_wait_init, (aNPC_TALK_REQUEST_PROC)none_proc1, 0x00, aSHM_THINK_HAPPY_ACADEMY3},
};
// clang-format on
aSHM_think_data_c* data_p = &dt_tbl[think_idx];
shop_mastersp->think_idx = think_idx;
shop_mastersp->think_proc = data_p->think_proc;
shop_mastersp->npc_class.talk_info.talk_request_proc = data_p->talk_request_proc;
shop_mastersp->talk_idx = data_p->talk_idx;
shop_mastersp->next_think_idx = data_p->next_think_idx;
(*data_p->think_init_proc)(shop_mastersp, play);
}
static void aSHM_think_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int type) {
static aNPC_SUB_PROC think_proc[] = { aSHM_think_init_proc, aSHM_think_main_proc };
(*think_proc[type])(nactorx, play);
}
static void aSHM_schedule_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
nactorx->think.think_proc = aSHM_think_proc;
CLIP(npc_clip)->think_proc(nactorx, play, aNPC_THINK_IN_BLOCK, 0);
}
static void aSHM_schedule_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
if (!CLIP(npc_clip)->think_proc(nactorx, play, -1, 1)) {
CLIP(npc_clip)->think_proc(nactorx, play, -1, 2);
}
}
static void aSHM_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int type) {
static aNPC_SUB_PROC sche_proc[] = { aSHM_schedule_init_proc, aSHM_schedule_main_proc };
(*sche_proc[type])(nactorx, play);
}
@@ -0,0 +1,421 @@
static int player_go_away(GAME_PLAY* play) {
ACTOR* playerx = GET_PLAYER_ACTOR_ACTOR(play);
if (playerx != NULL && CLIP(shop_design_clip) != NULL) {
PLAYER_ACTOR* player = (PLAYER_ACTOR*)playerx;
mActor_name_t front_item = player->item_in_front;
if (front_item == EXIT_DOOR1) {
return TRUE;
}
}
return FALSE;
}
static int player_buy(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
ACTOR* playerx = GET_PLAYER_ACTOR_ACTOR(play);
int ux;
int uz;
mActor_name_t item;
if (shop_mastersp->timer > 0) {
shop_mastersp->timer--;
return FALSE;
}
if (playerx != NULL) {
PLAYER_ACTOR* player = (PLAYER_ACTOR*)playerx;
if (player->a_btn_pressed == TRUE) {
mFI_Wpos2UtNum(&ux, &uz, player->forward_ut_pos);
item = CLIP(shop_design_clip)->unitNum2ItemNo_proc(ux, uz);
if (item != EMPTY_NO && item != RSV_SHOP_SOLD_FTR && item != RSV_NO) {
shop_mastersp->timer = 10;
return TRUE;
}
}
}
return FALSE;
}
static int check_null_lottery(void) {
mActor_name_t* item_p = Save_Get(shop).lottery_items;
int i;
for (i = 0; i < mSP_LOTTERY_ITEM_COUNT; i++) {
if (item_p[i] != EMPTY_NO && item_p[i] != RSV_SHOP_SOLD_FTR) {
return FALSE;
}
}
return TRUE;
}
static int search_lottery_ticket(int idx, int month) {
mActor_name_t item = Now_Private->inventory.pockets[idx];
if (NowPrivate_GetItemCond(idx) == mPr_ITEM_COND_NORMAL && ITEM_NAME_GET_TYPE(item) == NAME_TYPE_ITEM1 &&
ITEM_NAME_GET_CAT(item - ITEM1_NO_START) == ITEM1_CAT_TICKET && TICKET_MONTH(item) == month) {
return TICKET_COUNT(item);
}
return 0;
}
static int check_lottery_ticket(int month) {
int i;
int count = 0;
for (i = 0; i < mPr_POCKETS_SLOT_COUNT && count < aSHM_REQ_TICKET_NUM; i++) {
count += search_lottery_ticket(i, month);
}
return count >= aSHM_REQ_TICKET_NUM;
}
static void uketori_lottery_ticket_amari(int idx, int count, int month) {
mActor_name_t item = Now_Private->inventory.pockets[idx];
mPr_SetPossessionItem(Now_Private, idx, ITM_TICKET_START | TICKET_TO_MONTH(month) | (TICKET_TO_COUNT(item) - count),
mPr_ITEM_COND_NORMAL);
}
static void uketori_lottery_ticket(int month) {
int i;
int count;
int req = aSHM_REQ_TICKET_NUM;
for (i = 0; i < mPr_POCKETS_SLOT_COUNT && req > 0; i++) {
count = search_lottery_ticket(i, month);
if (count != 0) {
if (count <= req) {
mPr_SetPossessionItem(Now_Private, i, EMPTY_NO, mPr_ITEM_COND_NORMAL);
} else {
uketori_lottery_ticket_amari(i, req, month);
}
req -= count;
}
}
}
static void aSHM_get_Fgitem_pos(mActor_name_t item, int* ux, int* uz) {
mActor_name_t* fg_p = mFI_BkNumtoUtFGTop(0, 0);
int i;
for (i = 0; i < UT_TOTAL_NUM; i++) {
if (item == *fg_p) {
*ux = i % UT_X_NUM;
*uz = i / UT_X_NUM;
break;
}
fg_p++;
}
}
static void aSHM_remove_gift(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, mActor_name_t item) {
int ux;
int uz;
int ftrID;
aSHM_get_Fgitem_pos(item, &ux, &uz);
if (aMR_CLIP != NULL && aMR_CLIP->unitNum2ftrItemNoftrId_proc(NULL, &ftrID, ux, uz, mCoBG_LAYER0)) {
aMR_CLIP->ftrId2extinguishFtr_proc(ftrID);
}
shop_mastersp->ut[0] = ux;
shop_mastersp->ut[1] = uz;
}
static int to_atari(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp) {
u8 name_str[mIN_ITEM_NAME_LEN];
mActor_name_t* item_p = Save_Get(shop).lottery_items;
if (item_p[shop_mastersp->result] == RSV_SHOP_SOLD_FTR || item_p[shop_mastersp->result] == EMPTY_NO) {
return FALSE;
}
mIN_copy_name_str(name_str, item_p[shop_mastersp->result]);
mMsg_SET_ITEM_STR_ART(mMsg_FREE_STR0, name_str, mIN_ITEM_NAME_LEN, item_p[shop_mastersp->result]);
mPr_SetFreePossessionItem(Now_Private, item_p[shop_mastersp->result], mPr_ITEM_COND_PRESENT);
aSHM_set_start_avoid_pos(shop_mastersp, shop_mastersp->result * 3);
shop_mastersp->move_think_idx = aSHM_THINK_HIROU;
return TRUE;
}
static void fukubiki_before_process(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp) {
int rng = RANDOM(100);
uketori_lottery_ticket(shop_mastersp->month);
aSHM_change_talk_proc(shop_mastersp, aSHM_TALK_STOP_PLAYER);
shop_mastersp->next_think_idx = aSHM_THINK_MOVE_PLAYER;
if (rng < aSHM_FIRST_PLACE_PERCENT) {
shop_mastersp->result = aSHM_WON_FIRST_PLACE;
} else if (rng < aSHM_SECOND_PLACE_PERCENT) {
shop_mastersp->result = aSHM_WON_SECOND_PLACE;
} else if (rng < aSHM_THIRD_PLACE_PERCENT) {
shop_mastersp->result = aSHM_WON_THIRD_PLACE;
} else {
shop_mastersp->result = aSHM_DIDNT_WIN;
}
// If the prize was already won then we change to didn't win
if (shop_mastersp->result != aSHM_DIDNT_WIN && !to_atari(shop_mastersp)) {
shop_mastersp->result = aSHM_DIDNT_WIN;
}
}
static void aSHM_talk_try(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
if (mMsg_CHECK_MAINNORMALCONTINUE()) {
shop_mastersp->result = mChoice_GET_CHOSENUM();
switch (shop_mastersp->result) {
case mChoice_CHOICE0:
if (check_lottery_ticket(shop_mastersp->month)) {
mMsg_SET_CONTINUE_MSG_NUM(0x10D4);
fukubiki_before_process(shop_mastersp);
} else {
mMsg_SET_CONTINUE_MSG_NUM(0x10D3);
aSHM_change_talk_proc(shop_mastersp, aSHM_TALK_END_WAIT);
}
break;
case mChoice_CHOICE1:
aSHM_change_talk_proc(shop_mastersp, aSHM_TALK_END_WAIT);
break;
}
}
}
static void aSHM_talk_hazure(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
int order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
if (order == 3) {
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
if (check_lottery_ticket(shop_mastersp->month)) {
mMsg_SET_CONTINUE_MSG_NUM(0x10D7);
aSHM_change_talk_proc(shop_mastersp, aSHM_TALK_TALK_RETRY);
} else {
mMsg_SET_CONTINUE_MSG_NUM(0x10D6);
aSHM_change_talk_proc(shop_mastersp, aSHM_TALK_TALK_TAMAKESI);
}
}
}
static void aSHM_talk_retry(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
int order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
if (order == 2) {
if (CLIP(garagara_clip) != NULL) {
CLIP(garagara_clip)->delete_ball_proc();
}
shop_mastersp->result = mChoice_GET_CHOSENUM();
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
switch (shop_mastersp->result) {
case mChoice_CHOICE0:
fukubiki_before_process(shop_mastersp);
break;
case mChoice_CHOICE1:
aSHM_change_talk_proc(shop_mastersp, aSHM_TALK_END_WAIT);
break;
}
}
}
static void aSHM_stop_player(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
ACTOR* actorx = (ACTOR*)shop_mastersp;
int order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
if (order == 1) {
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
sAdo_OngenTrgStart(NA_SE_7F, &actorx->world.position);
}
if (!mDemo_Check(mDemo_TYPE_TALK, actorx) && !mDemo_Check(mDemo_TYPE_SPEAK, actorx)) {
if (mPlib_get_player_actor_main_index((GAME*)play) != mPlayer_INDEX_DEMO_WAIT) {
mPlib_request_main_demo_wait_type1((GAME*)play, FALSE, NULL);
} else {
aSHM_change_talk_proc(shop_mastersp, aSHM_TALK_END_WAIT);
}
}
}
static void aSHM_give_player(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
mActor_name_t* item_p = Save_Get(shop).lottery_items;
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 1, 2);
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 0, item_p[shop_mastersp->result]);
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 1, aHOI_REQUEST_PUTAWAY);
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 2, FALSE);
item_p[shop_mastersp->result] = RSV_SHOP_SOLD_FTR;
aSHM_change_talk_proc(shop_mastersp, aSHM_TALK_STOP_PLAYER);
aSHM_set_start_avoid_pos(shop_mastersp, shop_mastersp->root + 1);
if (check_null_lottery() || !check_lottery_ticket(shop_mastersp->month)) {
shop_mastersp->move_think_idx = aSHM_THINK_11;
} else {
shop_mastersp->move_think_idx = aSHM_THINK_12;
}
}
static void aSHM_talk_tamakesi(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
ACTOR* actorx = (ACTOR*)shop_mastersp;
if (!mDemo_Check(mDemo_TYPE_SPEAK, actorx) && !mDemo_Check(mDemo_TYPE_TALK, actorx)) {
if (CLIP(garagara_clip) != NULL) {
CLIP(garagara_clip)->delete_ball_proc();
}
}
}
static void aSHM_say_goodbye(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
if (mMsg_Check_idling_now(msg_p) == TRUE) {
mMsg_request_main_disappear_wait_type1(msg_p);
aSHM_change_talk_proc(shop_mastersp, aSHM_TALK_EXIT_WAIT);
}
}
static void aSHM_exit_wait(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, GAME_PLAY* play) {
if (mMsg_CHECK_MAIN_WAIT() == TRUE) {
goto_other_scene(play, Common_GetPointer(structure_exit_door_data), TRUE);
if (play->fb_wipe_mode == 0) {
mBGMPsComp_scene_mode(14);
mBGMPsComp_volume_talk_end();
mBGMPsComp_make_ps_wipe(0x195);
}
}
}
static int aSHM_change_talk_proc(NPC_SHOP_MASTERSP_ACTOR* shop_mastersp, int talk_proc) {
// clang-format off
static aSHM_TALK_PROC proc[aSHM_TALK_NUM] = {
&aSHM_talk_try,
&aSHM_talk_hazure,
&aSHM_talk_retry,
&aSHM_stop_player,
&aSHM_give_player,
&aSHM_talk_tamakesi,
(aSHM_TALK_PROC)&none_proc1,
&aSHM_say_goodbye,
&aSHM_exit_wait,
};
// clang-format on
int ret = TRUE;
shop_mastersp->talk_proc = proc[talk_proc];
if (talk_proc == aSHM_TALK_STOP_PLAYER) {
mDemo_Set_talk_return_demo_wait(TRUE);
}
if (talk_proc == aSHM_TALK_SAY_GOODBYE) {
mMsg_SET_IDLING_REQ();
}
return ret;
}
typedef struct {
int msg_no;
int talk_proc;
u8 turn;
u8 cam_type;
} aSHM_talk_data_c;
static void aSHM_set_force_talk_info(ACTOR* actorx) {
// clang-format off
static aSHM_talk_data_c dt_tbl[] = {
{0x109E, aSHM_TALK_SAY_GOODBYE, FALSE, CAMERA2_PROCESS_NORMAL},
{0x10E0, aSHM_TALK_END_WAIT, TRUE, CAMERA2_PROCESS_NORMAL},
{0x10D9, aSHM_TALK_STOP_PLAYER, TRUE, CAMERA2_PROCESS_TALK},
{0x10DA, aSHM_TALK_STOP_PLAYER, TRUE, CAMERA2_PROCESS_TALK},
{0x10DB, aSHM_TALK_STOP_PLAYER, TRUE, CAMERA2_PROCESS_TALK},
{0x10D5, aSHM_TALK_TALK_HAZURE, TRUE, CAMERA2_PROCESS_TALK},
{0x10E3, aSHM_TALK_GIVE_PLAYER, TRUE, CAMERA2_PROCESS_TALK},
{0x10DC, aSHM_TALK_TALK_TAMAKESI, TRUE, CAMERA2_PROCESS_TALK},
{0x10DD, aSHM_TALK_TALK_RETRY, TRUE, CAMERA2_PROCESS_TALK},
{0x10E6, aSHM_TALK_STOP_PLAYER, TRUE, CAMERA2_PROCESS_NORMAL},
{0x082A, aSHM_TALK_STOP_PLAYER, TRUE, CAMERA2_PROCESS_TALK},
};
// clang-format on
NPC_SHOP_MASTERSP_ACTOR* shop_mastersp = (NPC_SHOP_MASTERSP_ACTOR*)actorx;
aSHM_talk_data_c* data_p = &dt_tbl[shop_mastersp->talk_idx];
mDemo_Set_msg_num(data_p->msg_no);
mDemo_Set_talk_turn(data_p->turn);
mDemo_Set_camera(data_p->cam_type);
aSHM_change_talk_proc(shop_mastersp, data_p->talk_proc);
if (shop_mastersp->talk_idx != 0 && shop_mastersp->talk_idx != 1) {
if (shop_mastersp->npc_class.talk_info.melody_inst != 0) {
shop_mastersp->melody_bak = shop_mastersp->npc_class.talk_info.melody_inst;
}
shop_mastersp->npc_class.talk_info.melody_inst = 0;
}
}
static void aSHM_force_talk_request(ACTOR* actorx, GAME* game) {
mDemo_Request(mDemo_TYPE_SPEAK, actorx, &aSHM_set_force_talk_info);
}
static void aSHM_set_norm_talk_info(ACTOR* actorx) {
// clang-format off
static aSHM_talk_data_c dt_tbl[] = {
{0x10D1, aSHM_TALK_TALK_TRY, TRUE, CAMERA2_PROCESS_TALK},
{0x10DF, aSHM_TALK_END_WAIT, TRUE, CAMERA2_PROCESS_TALK},
{0x10E4, aSHM_TALK_END_WAIT, TRUE, CAMERA2_PROCESS_TALK},
};
// clang-format on
NPC_SHOP_MASTERSP_ACTOR* shop_mastersp = (NPC_SHOP_MASTERSP_ACTOR*)actorx;
aSHM_talk_data_c* data_p = &dt_tbl[shop_mastersp->talk_idx];
mDemo_Set_msg_num(data_p->msg_no);
mDemo_Set_talk_turn(data_p->turn);
mDemo_Set_camera(data_p->cam_type);
aSHM_change_talk_proc(shop_mastersp, data_p->talk_proc);
}
static void aSHM_norm_talk_request(ACTOR* actorx, GAME* game) {
mDemo_Request(mDemo_TYPE_TALK, actorx, &aSHM_set_norm_talk_info);
}
static int aSHM_talk_init(ACTOR* actorx, GAME* game) {
NPC_SHOP_MASTERSP_ACTOR* shop_mastersp = (NPC_SHOP_MASTERSP_ACTOR*)actorx;
shop_mastersp->npc_class.talk_info.talk_request_proc = (aNPC_TALK_REQUEST_PROC)&none_proc1;
mDemo_Set_ListenAble();
mDemo_Start(actorx);
return TRUE;
}
static int aSHM_talk_end_chk(ACTOR* actorx, GAME* game) {
NPC_SHOP_MASTERSP_ACTOR* shop_mastersp = (NPC_SHOP_MASTERSP_ACTOR*)actorx;
GAME_PLAY* play = (GAME_PLAY*)game;
int ret = FALSE;
(*shop_mastersp->talk_proc)(shop_mastersp, play);
if (mDemo_CAN_ACTOR_TALK(actorx)) {
aSHM_setup_think_proc(shop_mastersp, play, shop_mastersp->next_think_idx);
ret = TRUE;
if (shop_mastersp->melody_bak != 0) {
shop_mastersp->npc_class.talk_info.melody_inst = shop_mastersp->melody_bak;
}
}
return ret;
}