mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-23 06:34:18 -04:00
Implement & link ac_npc_rcn_guide2
This commit is contained in:
@@ -761,6 +761,10 @@ ac_npc_rcn_guide.c:
|
||||
.text: [0x8056EED0, 0x8056FFF0]
|
||||
.rodata: [0x806499C0, 0x806499E8]
|
||||
.data: [0x806BEE20, 0x806BF028]
|
||||
ac_npc_rcn_guide2.c:
|
||||
.text: [0x8056FFF0, 0x80572050]
|
||||
.rodata: [0x806499E8, 0x806499F0]
|
||||
.data: [0x806BF028, 0x806BF4F8]
|
||||
ac_npc_rtc.c:
|
||||
.text: [0x80573044, 0x80574134]
|
||||
.rodata: [0x80649A08, 0x80649A40]
|
||||
|
||||
+10
-1
@@ -160,7 +160,16 @@ typedef struct npc_draw_info_s {
|
||||
/* 0x548 */ u8 _548[0x580 - 0x548];
|
||||
/* 0x580 */ int animation_id;
|
||||
/* 0x584 */ int texture_bank_idx;
|
||||
/* 0x588 */ u8 _588[0x5B9 - 0x588];
|
||||
/* 0x588 */ u8 _588[0x5B0 - 0x588];
|
||||
/* 0x5B0 */ u8 draw_type;
|
||||
/* 0x5B1 */ u8 _5B1;
|
||||
/* 0x5B2 */ u8 _5B2;
|
||||
/* 0x5B3 */ u8 _5B3;
|
||||
/* 0x5B4 */ u8 _5B4;
|
||||
/* 0x5B5 */ u8 _5B5;
|
||||
/* 0x5B6 */ u8 _5B6;
|
||||
/* 0x5B7 */ u8 _5B7;
|
||||
/* 0x5B8 */ u8 _5B8;
|
||||
/* 0x5B9 */ u8 _5B9;
|
||||
/* 0x5BA */ u8 _5BA;
|
||||
/* 0x5BB */ u8 _5BB;
|
||||
|
||||
@@ -3,11 +3,32 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "m_actor.h"
|
||||
#include "ac_npc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct npc_rcn_guide2_s NPC_RCN_GUIDE2_ACTOR;
|
||||
|
||||
typedef void (*aNRG2_THINK_PROC)(NPC_RCN_GUIDE2_ACTOR*, GAME_PLAY*);
|
||||
typedef void (*aNRG2_TALK_PROC)(NPC_RCN_GUIDE2_ACTOR*);
|
||||
|
||||
/* sizeof(NPC_RCN_GUIDE2_ACTOR) == 0x9BC */
|
||||
struct npc_rcn_guide2_s {
|
||||
/* 0x000 */ NPC_ACTOR npc_class;
|
||||
/* 0x994 */ int _994;
|
||||
/* 0x998 */ int think_idx;
|
||||
/* 0x99C */ int next_think_idx;
|
||||
/* 0x9A0 */ aNRG2_THINK_PROC think_proc;
|
||||
/* 0x9A4 */ int talk_idx;
|
||||
/* 0x9A8 */ int talk_proc_idx;
|
||||
/* 0x9AC */ aNRG2_TALK_PROC talk_proc;
|
||||
/* 0x9B0 */ int counter;
|
||||
/* 0x9B4 */ int daily_speak_flag;
|
||||
/* 0x9B8 */ int can_ask_again_flag;
|
||||
};
|
||||
|
||||
extern ACTOR_PROFILE Npc_Rcn_Guide2_Profile;
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -15,4 +36,3 @@ extern ACTOR_PROFILE Npc_Rcn_Guide2_Profile;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -8,6 +8,25 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct shop_design_actor_s SHOP_DESIGN_ACTOR;
|
||||
|
||||
typedef mActor_name_t (*aSD_UNITNUM2ITEMNO_PROC)(int ut_x, int ut_z);
|
||||
typedef int (*aSD_REPORTGOODSSALE_PROC)(int ut_x, int ut_z);
|
||||
|
||||
typedef struct shop_design_clip_s {
|
||||
SHOP_DESIGN_ACTOR* design_actor;
|
||||
aSD_UNITNUM2ITEMNO_PROC unitNum2ItemNo_proc;
|
||||
aSD_REPORTGOODSSALE_PROC reportGoodsSale_proc;
|
||||
} aSD_Clip_c;
|
||||
|
||||
struct shop_design_actor_s {
|
||||
ACTOR actor_class;
|
||||
mActor_name_t* goods_list;
|
||||
int goods_list_count;
|
||||
int goods_list_max;
|
||||
aSD_Clip_c clip;
|
||||
};
|
||||
|
||||
extern ACTOR_PROFILE Shop_Design_Profile;
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -15,4 +34,3 @@ extern ACTOR_PROFILE Shop_Design_Profile;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+8
-1
@@ -24,6 +24,7 @@
|
||||
#include "ac_handOverItem.h"
|
||||
#include "ac_quest_manager_clip.h"
|
||||
#include "ac_shop_goods_h.h"
|
||||
#include "ac_shop_design.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -43,7 +44,13 @@ typedef struct clip_s {
|
||||
/* 0x038 */ void* _038;
|
||||
/* 0x03C */ void* _03C;
|
||||
/* 0x040 */ aNPC_Clip_c* npc_clip;
|
||||
/* 0x044 */ void* _044[(0x060 - 0x044) / sizeof(void*)];
|
||||
/* 0x044 */ void* _044;
|
||||
/* 0x048 */ void* _048;
|
||||
/* 0x04C */ void* _04C;
|
||||
/* 0x050 */ void* _050;
|
||||
/* 0x054 */ aSD_Clip_c* shop_design_clip;
|
||||
/* 0x058 */ void* _058;
|
||||
/* 0x05C */ void* _05C;
|
||||
/* 0x060 */ aSM_Clip_c* shop_manekin_clip;
|
||||
/* 0x064 */ void* _064;
|
||||
/* 0x068 */ CLIP_NONE_PROC _068;
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ enum {
|
||||
enum demo_type {
|
||||
mDemo_TYPE_NONE,
|
||||
mDemo_TYPE_SCROLL,
|
||||
mDemo_TYPE_2,
|
||||
mDemo_TYPE_EXITSCENE,
|
||||
mDemo_TYPE_DOOR,
|
||||
mDemo_TYPE_4,
|
||||
mDemo_TYPE_SCROLL2,
|
||||
|
||||
@@ -594,6 +594,10 @@ extern int mNT_check_unknown(mActor_name_t item_no);
|
||||
#define FTR_DRACAENA_NORTH 0x13B2
|
||||
#define FTR_DRACAENA_WEST 0x13B3
|
||||
|
||||
#define FTR_MANHOLE_COVER 0x1444
|
||||
|
||||
#define FTR_BATH_MAT 0x154C
|
||||
|
||||
#define HANIWA_START 0x15B0
|
||||
#define FTR_HANIWA000_SOUTH (HANIWA_START + 0)
|
||||
#define FTR_HANIWA000_EAST (HANIWA_START + 1)
|
||||
@@ -2174,6 +2178,7 @@ extern int mNT_check_unknown(mActor_name_t item_no);
|
||||
#define DOOR1 (DOOR0 + 1) /* 0x4001 */
|
||||
|
||||
#define EXIT_DOOR 0x4080
|
||||
#define EXIT_DOOR1 (EXIT_DOOR + 1) /* 0x4081 */
|
||||
|
||||
#define NPC_HOUSE_START 0x5000
|
||||
#define NPC_HOUSE000 NPC_HOUSE_START
|
||||
|
||||
+1
-1
@@ -1368,7 +1368,7 @@ struct player_actor_s {
|
||||
/* 0x138C */ int a_btn_pressed;
|
||||
/* 0x1390 */ int a_btn_triggers_submenu;
|
||||
/* 0x1394 */ mActor_name_t item_in_front; /* item directly in front of the player */
|
||||
/* 0x1398 */ xyz_t foward_ut_pos; /* wpos of unit in front of player */
|
||||
/* 0x1398 */ xyz_t forward_ut_pos; /* wpos of unit in front of player */
|
||||
/* 0x13A4 */ s8 update_scene_bg_mode;
|
||||
};
|
||||
|
||||
|
||||
+4
-4
@@ -223,13 +223,13 @@ extern void mQst_SetFirstJobStart(mQst_errand_c* errand);
|
||||
extern void mQst_SetFirstJobChangeCloth(mQst_errand_c* errand, mActor_name_t item);
|
||||
extern void mQst_SetFirstJobSeed(mQst_errand_c* errand);
|
||||
extern void mQst_SetFirstJobHello(mQst_errand_c* errand);
|
||||
extern void mQst_SetFirstJobFurniture(mQst_errand_c* errand, AnmPersonalID_c* pid, mActor_name_t item, u8 slot);
|
||||
extern void mQst_SetFirstJobFurniture(mQst_errand_c* errand, AnmPersonalID_c* pid, mActor_name_t item, int slot);
|
||||
extern void mQst_SetFirstJobLetter(mQst_errand_c* errand, AnmPersonalID_c* pid);
|
||||
extern void mQst_SetFirstJobLetter2(mQst_errand_c* errand, AnmPersonalID_c* pid);
|
||||
extern void mQst_SetFirstJobOpenQuest(mQst_errand_c* errand);
|
||||
extern void mQst_SetFirstJobCarpet(mQst_errand_c* errand, AnmPersonalID_c* pid, mActor_name_t item, u8 slot);
|
||||
extern void mQst_SetFirstJobAxe(mQst_errand_c* errand, AnmPersonalID_c* pid, mActor_name_t item, u8 slot);
|
||||
extern void mQst_SetFirstJobAxe2(mQst_errand_c* errand, AnmPersonalID_c* pid, mActor_name_t item, u8 slot);
|
||||
extern void mQst_SetFirstJobCarpet(mQst_errand_c* errand, AnmPersonalID_c* pid, mActor_name_t item, int slot);
|
||||
extern void mQst_SetFirstJobAxe(mQst_errand_c* errand, AnmPersonalID_c* pid, mActor_name_t item, int slot);
|
||||
extern void mQst_SetFirstJobAxe2(mQst_errand_c* errand, AnmPersonalID_c* pid, mActor_name_t item, int slot);
|
||||
extern void mQst_SetFirstJobNotice(mQst_errand_c* errand);
|
||||
extern int mQst_GetRandom(int max);
|
||||
extern void mQst_GetGoods_common(mActor_name_t* item, AnmPersonalID_c* pid, int category, mActor_name_t* exist_table,
|
||||
|
||||
@@ -0,0 +1,229 @@
|
||||
#include "ac_npc_rcn_guide2.h"
|
||||
|
||||
#include "m_common_data.h"
|
||||
#include "m_bgm.h"
|
||||
#include "m_player_lib.h"
|
||||
#include "m_font.h"
|
||||
#include "m_msg.h"
|
||||
#include "m_soncho.h"
|
||||
#include "ac_intro_demo.h"
|
||||
|
||||
enum {
|
||||
aNRG2_JOB1,
|
||||
aNRG2_JOB2,
|
||||
aNRG2_JOB3,
|
||||
aNRG2_JOB4,
|
||||
aNRG2_JOB5,
|
||||
aNRG2_JOB6,
|
||||
aNRG2_JOB7,
|
||||
aNRG2_JOB8,
|
||||
aNRG2_JOB9,
|
||||
aNRG2_JOB10,
|
||||
aNRG2_JOB11,
|
||||
|
||||
aNRG2_JOB_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aNRG2_NORM_TALK_JOB1_START,
|
||||
aNRG2_NORM_TALK_JOB2_START,
|
||||
aNRG2_NORM_TALK_JOB3_START,
|
||||
aNRG2_NORM_TALK_JOB4_START,
|
||||
aNRG2_NORM_TALK_JOB5_START,
|
||||
aNRG2_NORM_TALK_JOB5_2_START,
|
||||
aNRG2_NORM_TALK_JOB6_START,
|
||||
aNRG2_NORM_TALK_JOB7_START,
|
||||
aNRG2_NORM_TALK_JOB10_START,
|
||||
aNRG2_NORM_TALK_JOB11_START,
|
||||
|
||||
aNRG2_NORM_TALK_JOB1_REFUSE,
|
||||
aNRG2_NORM_TALK_JOB2_REFUSE,
|
||||
aNRG2_NORM_TALK_JOB3_REFUSE,
|
||||
aNRG2_NORM_TALK_JOB4_REFUSE,
|
||||
aNRG2_NORM_TALK_JOB5_REFUSE,
|
||||
aNRG2_NORM_TALK_JOB5_2_REFUSE,
|
||||
aNRG2_NORM_TALK_JOB6_REFUSE,
|
||||
aNRG2_NORM_TALK_JOB7_REFUSE,
|
||||
|
||||
aNRG2_NORM_TALK_J1_CONT1,
|
||||
aNRG2_NORM_TALK_J1_CONT2,
|
||||
aNRG2_NORM_TALK_J1_CONT3,
|
||||
|
||||
aNRG2_NORM_TALK_J2_CONT1,
|
||||
|
||||
aNRG2_NORM_TALK_J3_CONT1,
|
||||
aNRG2_NORM_TALK_J3_CONT2,
|
||||
|
||||
aNRG2_NORM_TALK_J4_CONT1,
|
||||
aNRG2_NORM_TALK_J4_CONT2,
|
||||
aNRG2_NORM_TALK_J5_CONT3,
|
||||
|
||||
aNRG2_NORM_TALK_J5_CONT1,
|
||||
aNRG2_NORM_TALK_J5_CONT2,
|
||||
|
||||
aNRG2_NORM_TALK_J6_CONT1,
|
||||
aNRG2_NORM_TALK_J6_CONT2,
|
||||
|
||||
aNRG2_NORM_TALK_J7_CONT1,
|
||||
|
||||
aNRG2_NORM_TALK_J10_CONT1,
|
||||
|
||||
aNRG2_NORM_TALK_J11_CONT1,
|
||||
|
||||
aNRG2_NORM_TALK_J1_END,
|
||||
aNRG2_NORM_TALK_J2_END,
|
||||
aNRG2_NORM_TALK_J3_END,
|
||||
aNRG2_NORM_TALK_J4_END,
|
||||
aNRG2_NORM_TALK_J5_END,
|
||||
aNRG2_NORM_TALK_J6_END,
|
||||
aNRG2_NORM_TALK_J7_END,
|
||||
aNRG2_NORM_TALK_J10_END,
|
||||
aNRG2_NORM_TALK_J11_END,
|
||||
|
||||
aNRG2_NORM_TALK_AGAIN,
|
||||
|
||||
aNRG2_NORM_TALK_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aNRG2_FORCE_TALK_SAY_HELLO,
|
||||
aNRG2_FORCE_TALK_SAY_HELLO2,
|
||||
aNRG2_FORCE_TALK_SAY_HELLO_SP,
|
||||
aNRG2_FORCE_TALK_CLOTH_CHK,
|
||||
aNRG2_FORCE_TALK_UPSTAIR_CHK,
|
||||
|
||||
aNRG2_FORCE_TALK_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aNRG2_THINK_SAY_HELLO,
|
||||
aNRG2_THINK_SAY_HELLO2,
|
||||
aNRG2_THINK_SAY_HELLO3,
|
||||
aNRG2_THINK_SEND_AWAY,
|
||||
aNRG2_THINK_TALK_START_WAIT,
|
||||
aNRG2_THINK_JOB_START_WAIT,
|
||||
aNRG2_THINK_ALL_JOB_END,
|
||||
|
||||
aNRG2_THINK_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aNRG2_TALK_SAY_HELLO,
|
||||
aNRG2_TALK_SAY_HELLO_SP,
|
||||
aNRG2_TALK_SAY_HELLO_SP2,
|
||||
aNRG2_TALK_CLOTH_CHK,
|
||||
aNRG2_TALK_TALK_END_WAIT,
|
||||
aNRG2_TALK_DEMO_START_WAIT,
|
||||
aNRG2_TALK_DEMO_END_WAIT,
|
||||
aNRG2_TALK_DEMO_END_WAIT2,
|
||||
aNRG2_TALK_JOB_START,
|
||||
aNRG2_TALK_JOB_END,
|
||||
aNRG2_TALK_3RD_JOB_END,
|
||||
aNRG2_TALK_DEMO2_START_WAIT,
|
||||
aNRG2_TALK_DEMO2_START_WAIT2,
|
||||
aNRG2_TALK_DEMO2_END,
|
||||
aNRG2_TALK_GIVE_NEW_PAPER,
|
||||
aNRG2_TALK_CHECK_MORE_PAPER,
|
||||
aNRG2_TALK_DECIDE_NEW_TARGET,
|
||||
aNRG2_TALK_DEMO3_START_WAIT,
|
||||
aNRG2_TALK_DEMO3_START_WAIT2,
|
||||
aNRG2_TALK_DEMO3_END_WAIT,
|
||||
aNRG2_TALK_ALL_JOB_END,
|
||||
|
||||
aNRG2_TALK_NUM
|
||||
};
|
||||
|
||||
typedef struct rcn_guide2_talk_info_s {
|
||||
int msg_no;
|
||||
aNRG2_TALK_PROC talk_proc;
|
||||
} aNRG2_talk_info_c;
|
||||
|
||||
static void aNRG2_actor_ct(ACTOR* actorx, GAME* game);
|
||||
static void aNRG2_actor_save(ACTOR* actorx, GAME* game);
|
||||
static void aNRG2_actor_dt(ACTOR* actorx, GAME* game);
|
||||
static void aNRG2_actor_init(ACTOR* actorx, GAME* game);
|
||||
static void aNRG2_actor_draw(ACTOR* actorx, GAME* game);
|
||||
static void aNRG2_actor_move(ACTOR* actorx, GAME* game);
|
||||
|
||||
// clang-format off
|
||||
ACTOR_PROFILE Npc_Rcn_Guide2_Profile = {
|
||||
mAc_PROFILE_NPC_RCN_GUIDE2,
|
||||
ACTOR_PART_NPC,
|
||||
ACTOR_STATE_NONE,
|
||||
SP_NPC_RCN_GUIDE2,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(NPC_RCN_GUIDE2_ACTOR),
|
||||
&aNRG2_actor_ct,
|
||||
&aNRG2_actor_dt,
|
||||
&aNRG2_actor_init,
|
||||
mActor_NONE_PROC1,
|
||||
&aNRG2_actor_save,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static void aNRG2_change_talk_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2, int talk_proc_idx);
|
||||
static void aNRG2_force_talk_request(ACTOR* actorx, GAME* game);
|
||||
static int aNRG2_talk_init(ACTOR* actorx, GAME* game);
|
||||
static int aNRG2_talk_end_chk(ACTOR* actorx, GAME* game);
|
||||
|
||||
static void aNRG2_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* game, int sched_idx);
|
||||
static void aNRG2_setup_think_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2, GAME_PLAY* play, int think_idx);
|
||||
|
||||
static void aNRG2_actor_ct(ACTOR* actorx, GAME* game) {
|
||||
// clang-format off
|
||||
static aNPC_ct_data_c ct_data = {
|
||||
&aNRG2_actor_move,
|
||||
&aNRG2_actor_draw,
|
||||
5,
|
||||
&aNRG2_force_talk_request,
|
||||
&aNRG2_talk_init,
|
||||
&aNRG2_talk_end_chk,
|
||||
1,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
NPC_RCN_GUIDE2_ACTOR* rcn_guide2 = (NPC_RCN_GUIDE2_ACTOR*)actorx;
|
||||
|
||||
if (Common_Get(clip).npc_clip->birth_check_proc(actorx, game) == TRUE) {
|
||||
int shop_type = 0;
|
||||
|
||||
switch (actorx->npc_id) {
|
||||
case SP_NPC_RCN_GUIDE2:
|
||||
shop_type = 0;
|
||||
break;
|
||||
case SP_NPC_RCN_GUIDE2_1:
|
||||
shop_type = 1;
|
||||
break;
|
||||
case SP_NPC_RCN_GUIDE2_2:
|
||||
shop_type = 2;
|
||||
break;
|
||||
case SP_NPC_RCN_GUIDE2_3:
|
||||
shop_type = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
rcn_guide2->npc_class.draw.draw_type = shop_type;
|
||||
rcn_guide2->npc_class.schedule.schedule_proc = &aNRG2_schedule_proc;
|
||||
Common_Get(clip).npc_clip->ct_proc(actorx, game, &ct_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_actor_save(ACTOR* actorx, GAME* game) {
|
||||
Common_Get(clip).npc_clip->save_proc(actorx, game);
|
||||
}
|
||||
|
||||
static void aNRG2_actor_dt(ACTOR* actorx, GAME* game) {
|
||||
Common_Get(clip).npc_clip->dt_proc(actorx, game);
|
||||
}
|
||||
|
||||
static void aNRG2_actor_init(ACTOR* actorx, GAME* game) {
|
||||
Common_Get(clip).npc_clip->init_proc(actorx, game);
|
||||
}
|
||||
|
||||
static void aNRG2_actor_draw(ACTOR* actorx, GAME* game) {
|
||||
Common_Get(clip).npc_clip->draw_proc(actorx, game);
|
||||
}
|
||||
|
||||
#include "../src/ac_npc_rcn_guide2_move.c_inc"
|
||||
#include "../src/ac_npc_rcn_guide2_talk.c_inc"
|
||||
#include "../src/ac_npc_rcn_guide2_schedule.c_inc"
|
||||
@@ -0,0 +1,30 @@
|
||||
static void aNRG2_set_exit_info(ACTOR* actorx) {
|
||||
GAME_PLAY* play = (GAME_PLAY*)gamePT;
|
||||
|
||||
if (goto_other_scene(play, Common_GetPointer(structure_exit_door_data), TRUE) != 1) {
|
||||
mDemo_End(actorx);
|
||||
} else {
|
||||
mBGMPsComp_scene_mode(14);
|
||||
mBGMPsComp_make_ps_wipe(0x195);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_exit_check(ACTOR* actorx, GAME_PLAY* play) {
|
||||
PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play);
|
||||
|
||||
if (player != NULL && player->item_in_front == EXIT_DOOR1 && play->fb_wipe_mode == 0) {
|
||||
mDemo_Request(mDemo_TYPE_EXITSCENE, actorx, &aNRG2_set_exit_info);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_actor_move(ACTOR* actorx, GAME* game) {
|
||||
NPC_RCN_GUIDE2_ACTOR* rcn_guide2 = (NPC_RCN_GUIDE2_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
|
||||
if (rcn_guide2->npc_class.action.idx == aNPC_ACT_WAIT) {
|
||||
rcn_guide2->npc_class.action.step = aNPC_ACTION_END_STEP;
|
||||
}
|
||||
|
||||
Common_Get(clip).npc_clip->move_proc(actorx, game);
|
||||
aNRG2_exit_check(actorx, play);
|
||||
}
|
||||
@@ -0,0 +1,374 @@
|
||||
static int aNRG2_setup_j1_cont(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
int talk_idx = aNRG2_NORM_TALK_J1_CONT1;
|
||||
|
||||
if (mPr_GetPossessionItemIdxWithCond(Now_Private, ITM_CLOTH016, mPr_ITEM_COND_NORMAL) == -1) {
|
||||
if (mPr_GetPossessionItemIdx(Now_Private, EMPTY_NO) == -1) {
|
||||
talk_idx = aNRG2_NORM_TALK_J1_CONT3;
|
||||
} else {
|
||||
talk_idx = aNRG2_NORM_TALK_J1_CONT2;
|
||||
}
|
||||
}
|
||||
|
||||
return talk_idx;
|
||||
}
|
||||
|
||||
static int aNRG2_setup_j2_cont(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
int talk_idx = aNRG2_NORM_TALK_J2_CONT1;
|
||||
|
||||
if (rcn_guide2->can_ask_again_flag == TRUE) {
|
||||
talk_idx = aNRG2_NORM_TALK_AGAIN;
|
||||
}
|
||||
|
||||
return talk_idx;
|
||||
}
|
||||
|
||||
static int aNRG2_setup_j3_cont(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
int talk_idx = aNRG2_NORM_TALK_J3_CONT1;
|
||||
|
||||
if (mQst_CheckRemoveTarget(errand_p) == TRUE) {
|
||||
talk_idx = aNRG2_NORM_TALK_J3_CONT2;
|
||||
} else if (rcn_guide2->can_ask_again_flag == TRUE) {
|
||||
talk_idx = aNRG2_NORM_TALK_AGAIN;
|
||||
}
|
||||
|
||||
return talk_idx;
|
||||
}
|
||||
|
||||
static int aNRG2_setup_j4_cont(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
int talk_idx = aNRG2_NORM_TALK_J4_CONT1;
|
||||
|
||||
if (rcn_guide2->can_ask_again_flag == TRUE) {
|
||||
talk_idx = aNRG2_NORM_TALK_AGAIN;
|
||||
} else if (mQst_CheckRemoveTarget(errand_p) == TRUE) {
|
||||
talk_idx = aNRG2_NORM_TALK_J4_CONT2;
|
||||
} else if (errand_p->base.progress == 3) {
|
||||
talk_idx = aNRG2_NORM_TALK_J5_CONT3;
|
||||
}
|
||||
|
||||
return talk_idx;
|
||||
}
|
||||
|
||||
static int aNRG2_setup_j5_cont(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
int talk_idx = aNRG2_NORM_TALK_J5_CONT1;
|
||||
|
||||
if (mQst_CheckRemoveTarget(errand_p) == TRUE) {
|
||||
talk_idx = aNRG2_NORM_TALK_J5_CONT2;
|
||||
}
|
||||
|
||||
return talk_idx;
|
||||
}
|
||||
|
||||
static int aNRG2_setup_j6_cont(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
int talk_idx = aNRG2_NORM_TALK_J6_CONT1;
|
||||
|
||||
if (mQst_CheckRemoveTarget(errand_p) == TRUE) {
|
||||
talk_idx = aNRG2_NORM_TALK_J6_CONT2;
|
||||
} else if (rcn_guide2->can_ask_again_flag == TRUE) {
|
||||
talk_idx = aNRG2_NORM_TALK_AGAIN;
|
||||
}
|
||||
|
||||
return talk_idx;
|
||||
}
|
||||
|
||||
static int aNRG2_setup_j7_cont(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
int talk_idx = aNRG2_NORM_TALK_J7_CONT1;
|
||||
|
||||
if (rcn_guide2->can_ask_again_flag == TRUE) {
|
||||
talk_idx = aNRG2_NORM_TALK_AGAIN;
|
||||
}
|
||||
|
||||
return talk_idx;
|
||||
}
|
||||
|
||||
static int aNRG2_setup_j10_cont(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
return aNRG2_NORM_TALK_J10_CONT1;
|
||||
}
|
||||
|
||||
static int aNRG2_setup_j11_cont(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
return aNRG2_NORM_TALK_J11_CONT1;
|
||||
}
|
||||
|
||||
typedef int (*aNRG2_SETUP_JOB_CONT_PROC)(NPC_RCN_GUIDE2_ACTOR*);
|
||||
|
||||
static void aNRG2_setup_job_cont(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
// clang-format off
|
||||
static aNRG2_SETUP_JOB_CONT_PROC setup_job_cont_proc[] = {
|
||||
&aNRG2_setup_j1_cont,
|
||||
&aNRG2_setup_j2_cont,
|
||||
&aNRG2_setup_j3_cont,
|
||||
&aNRG2_setup_j4_cont,
|
||||
&aNRG2_setup_j5_cont,
|
||||
&aNRG2_setup_j6_cont,
|
||||
&aNRG2_setup_j7_cont,
|
||||
&aNRG2_setup_j4_cont,
|
||||
&aNRG2_setup_j6_cont,
|
||||
&aNRG2_setup_j10_cont,
|
||||
&aNRG2_setup_j11_cont,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
int idx = errand_p->base.quest_kind - mQst_ERRAND_FIRSTJOB_CHANGE_CLOTH;
|
||||
|
||||
rcn_guide2->talk_idx = (*setup_job_cont_proc[idx])(rcn_guide2);
|
||||
}
|
||||
|
||||
static void aNRG2_talk_start_wait(NPC_RCN_GUIDE2_ACTOR* rcn_guide2, GAME_PLAY* play) {
|
||||
// clang-format off
|
||||
static int job_end_talk_idx[] = {
|
||||
aNRG2_NORM_TALK_J1_END,
|
||||
aNRG2_NORM_TALK_J2_END,
|
||||
aNRG2_NORM_TALK_J3_END,
|
||||
aNRG2_NORM_TALK_J4_END,
|
||||
aNRG2_NORM_TALK_J5_END,
|
||||
aNRG2_NORM_TALK_J6_END,
|
||||
aNRG2_NORM_TALK_J7_END,
|
||||
aNRG2_NORM_TALK_J4_END,
|
||||
aNRG2_NORM_TALK_J6_END,
|
||||
aNRG2_NORM_TALK_J10_END,
|
||||
aNRG2_NORM_TALK_J11_END,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
int idx = errand_p->base.quest_kind - mQst_ERRAND_FIRSTJOB_CHANGE_CLOTH;
|
||||
|
||||
if (mQst_CheckFirstJobFin(errand_p) == TRUE) {
|
||||
rcn_guide2->talk_idx = job_end_talk_idx[idx];
|
||||
rcn_guide2->can_ask_again_flag = FALSE;
|
||||
} else {
|
||||
aNRG2_setup_job_cont(rcn_guide2);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_job_start_wait(NPC_RCN_GUIDE2_ACTOR* rcn_guide2, GAME_PLAY* play) {
|
||||
// clang-format off
|
||||
static int job_start_talk_idx[] = {
|
||||
aNRG2_NORM_TALK_JOB1_START,
|
||||
aNRG2_NORM_TALK_JOB2_START,
|
||||
aNRG2_NORM_TALK_JOB3_START,
|
||||
aNRG2_NORM_TALK_JOB4_START,
|
||||
aNRG2_NORM_TALK_JOB5_START,
|
||||
aNRG2_NORM_TALK_JOB6_START,
|
||||
aNRG2_NORM_TALK_JOB7_START,
|
||||
aNRG2_NORM_TALK_JOB4_START,
|
||||
aNRG2_NORM_TALK_JOB6_START,
|
||||
aNRG2_NORM_TALK_JOB10_START,
|
||||
aNRG2_NORM_TALK_JOB11_START,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
// clang-format off
|
||||
static int job_start_refuse_talk_idx[] = {
|
||||
aNRG2_NORM_TALK_JOB1_REFUSE,
|
||||
aNRG2_NORM_TALK_JOB2_REFUSE,
|
||||
aNRG2_NORM_TALK_JOB3_REFUSE,
|
||||
aNRG2_NORM_TALK_JOB4_REFUSE,
|
||||
aNRG2_NORM_TALK_JOB5_REFUSE,
|
||||
aNRG2_NORM_TALK_JOB6_REFUSE,
|
||||
aNRG2_NORM_TALK_JOB7_REFUSE,
|
||||
aNRG2_NORM_TALK_JOB4_REFUSE,
|
||||
aNRG2_NORM_TALK_JOB6_REFUSE,
|
||||
-1,
|
||||
-1,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
int idx = errand_p->base.quest_kind - mQst_ERRAND_FIRSTJOB_CHANGE_CLOTH;
|
||||
|
||||
if (aNRG2_check_job_start() == TRUE) {
|
||||
rcn_guide2->talk_idx = job_start_talk_idx[idx];
|
||||
} else {
|
||||
rcn_guide2->talk_idx = job_start_refuse_talk_idx[idx];
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_all_job_end(NPC_RCN_GUIDE2_ACTOR* rcn_guide2, GAME_PLAY* play) {
|
||||
if (play->fb_wipe_mode == 0) {
|
||||
rcn_guide2->counter++;
|
||||
|
||||
if (rcn_guide2->counter > 60) {
|
||||
aNRG2_setup_think_proc(rcn_guide2, play, aNRG2_THINK_SEND_AWAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_think_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
NPC_RCN_GUIDE2_ACTOR* rcn_guide2 = (NPC_RCN_GUIDE2_ACTOR*)nactorx;
|
||||
|
||||
if (nactorx->action.step == aNPC_ACTION_END_STEP) {
|
||||
(*rcn_guide2->think_proc)(rcn_guide2, play);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_think_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
NPC_RCN_GUIDE2_ACTOR* rcn_guide2 = (NPC_RCN_GUIDE2_ACTOR*)nactorx;
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
int think_idx;
|
||||
|
||||
rcn_guide2->npc_class.condition_info.hide_request = FALSE;
|
||||
rcn_guide2->npc_class.actor_class.status_data.weight = 255;
|
||||
rcn_guide2->npc_class.actor_class.shape_info.rotation.y = rcn_guide2->npc_class.actor_class.player_angle_y;
|
||||
rcn_guide2->npc_class.actor_class.world.angle.y = rcn_guide2->npc_class.actor_class.player_angle_y;
|
||||
|
||||
if (Common_Get(quest).work == 0) {
|
||||
Common_Get(quest).work = 1;
|
||||
rcn_guide2->daily_speak_flag = TRUE;
|
||||
|
||||
if (errand_p->base.quest_kind == mQst_ERRAND_FIRSTJOB_START) {
|
||||
if (Now_Private->cloth.item == ITM_CLOTH016) {
|
||||
aNRG2_setup_job(aNRG2_JOB2);
|
||||
think_idx = aNRG2_THINK_SAY_HELLO3;
|
||||
} else {
|
||||
aNRG2_setup_job(aNRG2_JOB1);
|
||||
think_idx = aNRG2_THINK_SAY_HELLO;
|
||||
}
|
||||
} else {
|
||||
think_idx = aNRG2_THINK_SAY_HELLO2;
|
||||
}
|
||||
} else if (errand_p->base.progress == 1) {
|
||||
think_idx = aNRG2_THINK_JOB_START_WAIT;
|
||||
} else {
|
||||
think_idx = aNRG2_THINK_TALK_START_WAIT;
|
||||
}
|
||||
|
||||
if (Save_Get(scene_no) == SCENE_DEPART) {
|
||||
/* Replace the upstairs warps with reserve items */
|
||||
mFI_UtNumtoFGSet_common(RSV_POLICE_ITEM_0, 7, 1, FALSE);
|
||||
mFI_UtNumtoFGSet_common(RSV_POLICE_ITEM_0, 8, 1, FALSE);
|
||||
}
|
||||
|
||||
aNRG2_setup_think_proc(rcn_guide2, play, think_idx);
|
||||
}
|
||||
|
||||
static void aNRG2_send_away_init(NPC_RCN_GUIDE2_ACTOR* rcn_guide2, GAME_PLAY* play) {
|
||||
goto_other_scene(play, Common_GetPointer(structure_exit_door_data), 1);
|
||||
mBGMPsComp_scene_mode(14);
|
||||
}
|
||||
|
||||
static void aNRG2_talk_start_wait_init(NPC_RCN_GUIDE2_ACTOR* rcn_guide2, GAME_PLAY* play) {
|
||||
aNRG2_talk_start_wait(rcn_guide2, play);
|
||||
}
|
||||
|
||||
static void aNRG2_job_start_wait_init(NPC_RCN_GUIDE2_ACTOR* rcn_guide2, GAME_PLAY* play) {
|
||||
aNRG2_job_start_wait(rcn_guide2, play);
|
||||
}
|
||||
|
||||
static void aNRG2_all_job_end_init(NPC_RCN_GUIDE2_ACTOR* rcn_guide2, GAME_PLAY* play) {
|
||||
INTRO_DEMO_ACTOR* intro_demo;
|
||||
|
||||
mPlib_request_main_demo_wait_type1(&play->game, 0, NULL);
|
||||
intro_demo =
|
||||
(INTRO_DEMO_ACTOR*)Actor_info_name_search(&play->actor_info, mAc_PROFILE_INTRO_DEMO, ACTOR_PART_CONTROL);
|
||||
intro_demo->_1A8 = TRUE;
|
||||
}
|
||||
|
||||
typedef void (*aNRG2_THINK_INIT_PROC)(NPC_RCN_GUIDE2_ACTOR*, GAME_PLAY*);
|
||||
|
||||
typedef struct rcn_guide2_think_data_s {
|
||||
aNRG2_THINK_PROC think_proc;
|
||||
aNRG2_THINK_INIT_PROC think_init_proc;
|
||||
aNPC_TALK_REQUEST_PROC talk_request_proc;
|
||||
u8 talk_idx;
|
||||
u8 next_think_idx;
|
||||
} aNRG2_think_data_c;
|
||||
|
||||
static void aNRG2_setup_think_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2, GAME_PLAY* play, int think_idx) {
|
||||
// clang-format off
|
||||
static aNRG2_think_data_c dt_tbl[] = {
|
||||
{
|
||||
(aNRG2_THINK_PROC)&none_proc1,
|
||||
(aNRG2_THINK_INIT_PROC)&none_proc1,
|
||||
&aNRG2_force_talk_request,
|
||||
aNRG2_FORCE_TALK_SAY_HELLO,
|
||||
aNRG2_THINK_SEND_AWAY,
|
||||
},
|
||||
{
|
||||
(aNRG2_THINK_PROC)&none_proc1,
|
||||
(aNRG2_THINK_INIT_PROC)&none_proc1,
|
||||
&aNRG2_force_talk_request,
|
||||
aNRG2_FORCE_TALK_SAY_HELLO2,
|
||||
aNRG2_THINK_SEND_AWAY,
|
||||
},
|
||||
{
|
||||
(aNRG2_THINK_PROC)&none_proc1,
|
||||
(aNRG2_THINK_INIT_PROC)&none_proc1,
|
||||
&aNRG2_force_talk_request,
|
||||
aNRG2_FORCE_TALK_SAY_HELLO_SP,
|
||||
aNRG2_THINK_SEND_AWAY,
|
||||
},
|
||||
{
|
||||
(aNRG2_THINK_PROC)&none_proc1,
|
||||
&aNRG2_send_away_init,
|
||||
(aNPC_TALK_REQUEST_PROC)&none_proc1,
|
||||
0,
|
||||
aNRG2_THINK_SEND_AWAY,
|
||||
},
|
||||
{
|
||||
&aNRG2_talk_start_wait,
|
||||
&aNRG2_talk_start_wait_init,
|
||||
&aNRG2_norm_talk_request,
|
||||
aNRG2_NORM_TALK_JOB1_START,
|
||||
aNRG2_THINK_TALK_START_WAIT,
|
||||
},
|
||||
{
|
||||
&aNRG2_job_start_wait,
|
||||
&aNRG2_job_start_wait_init,
|
||||
&aNRG2_norm_talk_request,
|
||||
aNRG2_NORM_TALK_JOB1_START,
|
||||
aNRG2_THINK_JOB_START_WAIT,
|
||||
},
|
||||
{
|
||||
&aNRG2_all_job_end,
|
||||
&aNRG2_all_job_end_init,
|
||||
(aNPC_TALK_REQUEST_PROC)&none_proc1,
|
||||
0,
|
||||
aNRG2_THINK_ALL_JOB_END,
|
||||
},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
aNRG2_think_data_c* data = &dt_tbl[think_idx];
|
||||
static u16 arg_data[6] = { 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
rcn_guide2->think_idx = think_idx;
|
||||
rcn_guide2->think_proc = data->think_proc;
|
||||
rcn_guide2->npc_class.talk_info.talk_request_proc = data->talk_request_proc;
|
||||
rcn_guide2->talk_idx = data->talk_idx;
|
||||
rcn_guide2->next_think_idx = data->next_think_idx;
|
||||
rcn_guide2->npc_class.request.act_priority = 1;
|
||||
rcn_guide2->npc_class.request.act_idx = aNPC_ACT_WAIT;
|
||||
rcn_guide2->npc_class.request.act_type = aNPC_ACT_TYPE_DEFAULT;
|
||||
mem_copy((u8*)rcn_guide2->npc_class.request.act_args, (u8*)arg_data, sizeof(arg_data));
|
||||
(*data->think_init_proc)(rcn_guide2, play);
|
||||
}
|
||||
|
||||
static void aNRG2_think_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
static aNPC_SUB_PROC think_proc[] = { &aNRG2_think_init_proc, &aNRG2_think_main_proc };
|
||||
|
||||
(*think_proc[proc_type])(nactorx, play);
|
||||
}
|
||||
|
||||
static void aNRG2_schedule_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
nactorx->think.think_proc = &aNRG2_think_proc;
|
||||
Common_Get(clip).npc_clip->think_proc(nactorx, play, aNPC_THINK_IN_BLOCK, 0);
|
||||
}
|
||||
|
||||
static void aNRG2_schedule_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
int res = Common_Get(clip).npc_clip->think_proc(nactorx, play, -1, 1);
|
||||
|
||||
if (res == 0) {
|
||||
Common_Get(clip).npc_clip->think_proc(nactorx, play, -1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
static aNPC_SUB_PROC sche_proc[] = { &aNRG2_schedule_init_proc, &aNRG2_schedule_main_proc };
|
||||
|
||||
(*sche_proc[proc_type])(nactorx, play);
|
||||
}
|
||||
@@ -0,0 +1,912 @@
|
||||
static void aNRG2_set_str_j3(void) {
|
||||
static u8 choume_str[] = { 'Q', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
AnmPersonalID_c* to_id_p = &errand_p->recipient;
|
||||
int idx = mNpc_SearchAnimalinfo(Save_Get(animals), to_id_p->npc_id, ANIMAL_NUM_MAX);
|
||||
u8 str[ANIMAL_NAME_LEN];
|
||||
|
||||
if (idx != -1) {
|
||||
/* Set msg string 3 & 4 to acre Z & X respectively */
|
||||
Anmhome_c* home_p = &Save_Get(animals[idx]).home_info;
|
||||
|
||||
mMsg_Set_free_str(msg_p, mMsg_FREE_STR3, &choume_str[home_p->block_z], 1);
|
||||
mFont_UnintToString(str, sizeof(str), home_p->block_x, sizeof(str), TRUE, FALSE, TRUE);
|
||||
mMsg_Set_free_str(msg_p, mMsg_FREE_STR4, str, sizeof(str));
|
||||
}
|
||||
|
||||
mNpc_GetNpcWorldNameAnm(str, to_id_p);
|
||||
mMsg_Set_free_str_cl(msg_p, mMsg_FREE_STR5, str, sizeof(str), 1);
|
||||
}
|
||||
|
||||
static void aNRG2_set_str_j4(void) {
|
||||
int bx;
|
||||
int bz;
|
||||
u8 str[1];
|
||||
|
||||
/* Set recipient home acre */
|
||||
aNRG2_set_str_j3();
|
||||
/* Set post office acre string */
|
||||
mFI_BlockKind2BkNum(&bx, &bz, mRF_BLOCKKIND_POSTOFFICE);
|
||||
mFont_UnintToString(str, sizeof(str), bx, sizeof(str), TRUE, FALSE, TRUE);
|
||||
/* We only care about the X acre since the post office is always in the A row */
|
||||
mMsg_SET_FREE_STR(mMsg_FREE_STR6, str, sizeof(str));
|
||||
}
|
||||
|
||||
typedef void (*aNRG2_SET_STR_PROC)(void);
|
||||
|
||||
static void aNRG2_set_str_proc(void) {
|
||||
static aNRG2_SET_STR_PROC process[] = {
|
||||
(aNRG2_SET_STR_PROC)&none_proc1,
|
||||
(aNRG2_SET_STR_PROC)&none_proc1,
|
||||
&aNRG2_set_str_j3,
|
||||
&aNRG2_set_str_j4,
|
||||
&aNRG2_set_str_j3,
|
||||
&aNRG2_set_str_j3,
|
||||
(aNRG2_SET_STR_PROC)&none_proc1,
|
||||
&aNRG2_set_str_j4,
|
||||
&aNRG2_set_str_j3,
|
||||
(aNRG2_SET_STR_PROC)&none_proc1,
|
||||
(aNRG2_SET_STR_PROC)&none_proc1,
|
||||
};
|
||||
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
int idx = errand_p->base.quest_kind - mQst_ERRAND_FIRSTJOB_CHANGE_CLOTH;
|
||||
|
||||
/* Set the current job strings, index is job quest idx relative to first job */
|
||||
(*process[idx])();
|
||||
}
|
||||
|
||||
static void aNRG2_set_possession(void) {
|
||||
// clang-format off
|
||||
static mActor_name_t set_item[] = {
|
||||
ITM_CLOTH016,
|
||||
ITM_WHITE_PANSY_BAG,
|
||||
EMPTY_NO,
|
||||
ITM_PAPER55,
|
||||
EMPTY_NO,
|
||||
ITM_AXE,
|
||||
EMPTY_NO,
|
||||
ITM_PAPER55,
|
||||
ITM_AXE,
|
||||
EMPTY_NO,
|
||||
EMPTY_NO,
|
||||
};
|
||||
// clang-format on
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
u32 job_kind = errand_p->base.quest_kind - mQst_ERRAND_FIRSTJOB_CHANGE_CLOTH;
|
||||
|
||||
if (job_kind == aNRG2_JOB2) {
|
||||
int i;
|
||||
/* Give player 7 random flower bags */
|
||||
for (i = 0; i < 7; i++) {
|
||||
mActor_name_t item = ITM_WHITE_PANSY_BAG + RANDOM(9);
|
||||
|
||||
mPr_SetFreePossessionItem(Now_Private, item, mPr_ITEM_COND_NORMAL);
|
||||
}
|
||||
|
||||
/* Give player 3 saplings */
|
||||
for (i = 0; i < 3; i++) {
|
||||
mPr_SetFreePossessionItem(Now_Private, ITM_SAPLING, mPr_ITEM_COND_NORMAL);
|
||||
}
|
||||
} else {
|
||||
switch (job_kind) {
|
||||
case aNRG2_JOB3:
|
||||
case aNRG2_JOB5:
|
||||
/* Set the random errand item with quest condition */
|
||||
mPr_SetFreePossessionItem(Now_Private, errand_p->item, mPr_ITEM_COND_QUEST);
|
||||
break;
|
||||
case aNRG2_JOB1:
|
||||
case aNRG2_JOB4:
|
||||
case aNRG2_JOB7:
|
||||
case aNRG2_JOB8:
|
||||
/* Set the static job item with normal condition */
|
||||
mPr_SetFreePossessionItem(Now_Private, set_item[job_kind], mPr_ITEM_COND_NORMAL);
|
||||
break;
|
||||
case aNRG2_JOB2:
|
||||
case aNRG2_JOB6:
|
||||
case aNRG2_JOB9:
|
||||
default:
|
||||
/* Set the static job item with quest condition */
|
||||
mPr_SetFreePossessionItem(Now_Private, set_item[job_kind], mPr_ITEM_COND_QUEST);
|
||||
break;
|
||||
case aNRG2_JOB10:
|
||||
case aNRG2_JOB11:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int aNRG2_check_job_start(void) {
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
int res = FALSE;
|
||||
u32 free_slots = mPr_GetPossessionItemSum(Now_Private, EMPTY_NO);
|
||||
|
||||
switch (errand_p->base.quest_kind) {
|
||||
case mQst_ERRAND_FIRSTJOB_PLANT_FLOWER:
|
||||
/* Need at least 10 inventory slots free for the planting chore */
|
||||
if (free_slots >= 10) {
|
||||
res = TRUE;
|
||||
}
|
||||
break;
|
||||
case mQst_ERRAND_FIRSTJOB_POST_NOTICE:
|
||||
case mQst_ERRAND_FIRSTJOB_INTRODUCTIONS:
|
||||
case mQst_ERRAND_FIRSTJOB_OPEN:
|
||||
/* These chores have no items and thus can always be started */
|
||||
res = TRUE;
|
||||
break;
|
||||
default:
|
||||
/* Default requires at least one free inventory slot */
|
||||
if (free_slots > 0) {
|
||||
res = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Is this a typo of setup? */
|
||||
static void aNRG2_stepup_j1(u32 kind, NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
|
||||
/* Job 1: change into 'work clothes' */
|
||||
mQst_SetFirstJobChangeCloth(errand_p, ITM_CLOTH016);
|
||||
}
|
||||
|
||||
static void aNRG2_stepup_j2(u32 kind, NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
|
||||
/* Job 2: plant flower seeds & tree saplings */
|
||||
mQst_SetFirstJobSeed(errand_p);
|
||||
}
|
||||
|
||||
static void aNRG2_stepup_j3(u32 kind, NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
/* List of 'no good' furniture, seemingly only ones you can walk on? */
|
||||
static mActor_name_t ng_list[] = { FTR_MANHOLE_COVER, FTR_BATH_MAT };
|
||||
mQst_errand_c* errand_p;
|
||||
AnmPersonalID_c* anm_pid_p;
|
||||
mActor_name_t ftr;
|
||||
u32 free_idx;
|
||||
|
||||
/* Get first job quest data */
|
||||
errand_p = mQst_GetFirstJobData();
|
||||
|
||||
/* Get first free inventory slot index */
|
||||
free_idx = mPr_GetPossessionItemIdx(Now_Private, EMPTY_NO);
|
||||
|
||||
/* Get an unused target villager for delivery target */
|
||||
anm_pid_p = mNpc_GetOtherAnimalPersonalID(errand_p->info.first_job.used_ids, errand_p->info.first_job.used_num);
|
||||
|
||||
/* Roll random ABC list furniture to be delivered */
|
||||
mSP_SelectRandomItem_New(NULL, &ftr, 1, ng_list, ARRAY_COUNT(ng_list), mSP_KIND_FURNITURE, mSP_LISTTYPE_ABC, FALSE);
|
||||
|
||||
/* Job 3: deliver furniture */
|
||||
mQst_SetFirstJobFurniture(errand_p, anm_pid_p, ftr, free_idx);
|
||||
}
|
||||
|
||||
static void aNRG2_stepup_j4(u32 kind, NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
mQst_errand_c* errand_p;
|
||||
AnmPersonalID_c* anm_pid_p;
|
||||
|
||||
// Get first job quest data
|
||||
errand_p = mQst_GetFirstJobData();
|
||||
|
||||
// Get an unused target villager for letter recipient
|
||||
anm_pid_p = mNpc_GetOtherAnimalPersonalID(errand_p->info.first_job.used_ids, errand_p->info.first_job.used_num);
|
||||
|
||||
// Force a memory with the animal in the event the player hasn't spoken to them yet
|
||||
// This could happen if an animal moves in before the chore is started,
|
||||
// but after the introductions sequence is finished.
|
||||
// This prevents the case where the recipient would not be listed
|
||||
// in the recipient menu despite being assigned by Nook.
|
||||
mNpc_SetAnimalPersonalID2Memory(anm_pid_p);
|
||||
|
||||
// Job 4: send letter
|
||||
if (kind == aNRG2_JOB4) {
|
||||
mQst_SetFirstJobLetter(errand_p, anm_pid_p);
|
||||
} else {
|
||||
mQst_SetFirstJobLetter2(errand_p, anm_pid_p);
|
||||
}
|
||||
|
||||
// Allow Nook to remind the player about this chore
|
||||
rcn_guide2->can_ask_again_flag = TRUE;
|
||||
}
|
||||
|
||||
static void aNRG2_stepup_j5(u32 kind, NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
mQst_errand_c* errand_p;
|
||||
AnmPersonalID_c* anm_pid_p;
|
||||
mActor_name_t ftr;
|
||||
u32 free_idx;
|
||||
|
||||
/* Get first job quest data */
|
||||
errand_p = mQst_GetFirstJobData();
|
||||
|
||||
/* Get first free inventory slot index */
|
||||
free_idx = mPr_GetPossessionItemIdx(Now_Private, EMPTY_NO);
|
||||
|
||||
/* Get an unused target villager for delivery target */
|
||||
anm_pid_p = mNpc_GetOtherAnimalPersonalID(errand_p->info.first_job.used_ids, errand_p->info.first_job.used_num);
|
||||
|
||||
/* Roll random ABC list carpet to be delivered */
|
||||
mSP_SelectRandomItem_New(NULL, &ftr, 1, NULL, 0, mSP_KIND_CARPET, mSP_LISTTYPE_ABC, FALSE);
|
||||
|
||||
/* Job 5: deliver carpet */
|
||||
mQst_SetFirstJobCarpet(errand_p, anm_pid_p, ftr, free_idx);
|
||||
}
|
||||
|
||||
static void aNRG2_stepup_j6(u32 kind, NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
mQst_errand_c* errand_p;
|
||||
u32 free_idx;
|
||||
|
||||
// Get first job quest data
|
||||
errand_p = mQst_GetFirstJobData();
|
||||
|
||||
// Get the first free inventory slot
|
||||
free_idx = mPr_GetPossessionItemIdx(Now_Private, EMPTY_NO);
|
||||
|
||||
// Job 5: deliver axe
|
||||
if (kind == aNRG2_JOB6) {
|
||||
mQst_SetFirstJobAxe(errand_p, &errand_p->info.first_job.used_ids[1], ITM_AXE, free_idx);
|
||||
} else {
|
||||
mQst_SetFirstJobAxe2(errand_p, &errand_p->info.first_job.used_ids[1], ITM_AXE, free_idx);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_stepup_j7(u32 kind, NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
|
||||
/* Job 7: post on notice board */
|
||||
mQst_SetFirstJobNotice(errand_p);
|
||||
}
|
||||
|
||||
static void aNRG2_stepup_j10(u32 kind, NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
|
||||
/* Job 10: introductions */
|
||||
mQst_SetFirstJobHello(errand_p);
|
||||
}
|
||||
|
||||
static void aNRG2_stepup_j11(u32 kind, NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
|
||||
/* Job 11: open quest */
|
||||
mQst_SetFirstJobOpenQuest(errand_p);
|
||||
}
|
||||
|
||||
typedef void (*aNRG2_STEPUP_PROC)(u32, NPC_RCN_GUIDE2_ACTOR*);
|
||||
|
||||
static void aNRG2_stepup_job(NPC_RCN_GUIDE2_ACTOR* rcn_guide2, u32 job_kind) {
|
||||
// clang-format off
|
||||
static aNRG2_STEPUP_PROC stepup_job_proc[] = {
|
||||
&aNRG2_stepup_j1,
|
||||
&aNRG2_stepup_j2,
|
||||
&aNRG2_stepup_j3,
|
||||
&aNRG2_stepup_j4,
|
||||
&aNRG2_stepup_j5,
|
||||
&aNRG2_stepup_j6,
|
||||
&aNRG2_stepup_j7,
|
||||
&aNRG2_stepup_j4,
|
||||
&aNRG2_stepup_j6,
|
||||
&aNRG2_stepup_j10,
|
||||
&aNRG2_stepup_j11,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
|
||||
if (errand_p->base.progress == 1) {
|
||||
(*stepup_job_proc[job_kind])(job_kind, rcn_guide2);
|
||||
aNRG2_set_str_proc();
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_setup_job(int job_kind) {
|
||||
// clang-format off
|
||||
static u32 kind[] = {
|
||||
mQst_ERRAND_FIRSTJOB_CHANGE_CLOTH,
|
||||
mQst_ERRAND_FIRSTJOB_PLANT_FLOWER,
|
||||
mQst_ERRAND_FIRSTJOB_DELIVER_FTR,
|
||||
mQst_ERRAND_FIRSTJOB_SEND_LETTER,
|
||||
mQst_ERRAND_FIRSTJOB_DELIVER_CARPET,
|
||||
mQst_ERRAND_FIRSTJOB_DELIVER_AXE,
|
||||
mQst_ERRAND_FIRSTJOB_POST_NOTICE,
|
||||
mQst_ERRAND_FIRSTJOB_SEND_LETTER2,
|
||||
mQst_ERRAND_FIRSTJOB_DELIVER_AXE2,
|
||||
mQst_ERRAND_FIRSTJOB_INTRODUCTIONS,
|
||||
mQst_ERRAND_FIRSTJOB_OPEN,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
|
||||
errand_p->base.quest_kind = kind[job_kind];
|
||||
errand_p->base.progress = 1;
|
||||
}
|
||||
|
||||
static void aNRG2_say_hello_talk_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
// clang-format off
|
||||
static int job_start_msg_no[] = {
|
||||
0x07F1,
|
||||
0x07F6,
|
||||
0x07FB,
|
||||
0x0802,
|
||||
0x080C,
|
||||
0x0813,
|
||||
0x0818,
|
||||
0x0802,
|
||||
0x0813,
|
||||
0x0821,
|
||||
0x0827,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
// clang-format off
|
||||
static int job_start_refuse_msg_no[] = {
|
||||
0x07F0,
|
||||
0x07F5,
|
||||
0x07FA,
|
||||
0x07FA,
|
||||
0x07FA,
|
||||
0x07FA,
|
||||
0x0818,
|
||||
0x07FA,
|
||||
0x07FA,
|
||||
-1,
|
||||
-1,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static int next_talk_idx[] = { aNRG2_TALK_DEMO_START_WAIT, aNRG2_TALK_TALK_END_WAIT };
|
||||
|
||||
mMsg_Window_c* msg_p;
|
||||
mQst_errand_c* errand_p;
|
||||
int msg_no;
|
||||
int talk_idx;
|
||||
int job_kind;
|
||||
|
||||
msg_p = mMsg_Get_base_window_p();
|
||||
errand_p = mQst_GetFirstJobData();
|
||||
if (errand_p->base.progress == 1) {
|
||||
job_kind = errand_p->base.quest_kind - mQst_ERRAND_FIRSTJOB_CHANGE_CLOTH;
|
||||
if (aNRG2_check_job_start() == TRUE) {
|
||||
/* The next job can be started */
|
||||
|
||||
// Initial setup
|
||||
aNRG2_stepup_job(rcn_guide2, job_kind);
|
||||
// Set quest items if necessary
|
||||
aNRG2_set_possession();
|
||||
// Setup params
|
||||
msg_no = job_start_msg_no[job_kind];
|
||||
rcn_guide2->next_think_idx = aNRG2_THINK_TALK_START_WAIT;
|
||||
talk_idx = 0;
|
||||
} else {
|
||||
/* The next job can't be started */
|
||||
msg_no = job_start_refuse_msg_no[job_kind];
|
||||
rcn_guide2->next_think_idx = aNRG2_THINK_JOB_START_WAIT;
|
||||
talk_idx = 1;
|
||||
}
|
||||
|
||||
mMsg_Set_continue_msg_num(msg_p, msg_no);
|
||||
aNRG2_change_talk_proc(rcn_guide2, next_talk_idx[talk_idx]);
|
||||
} else {
|
||||
/* We're still in the middle of a job? */
|
||||
rcn_guide2->next_think_idx = aNRG2_THINK_TALK_START_WAIT;
|
||||
mMsg_Set_CancelNormalContinue(msg_p);
|
||||
aNRG2_change_talk_proc(rcn_guide2, aNRG2_TALK_TALK_END_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_say_hello_sp_talk_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
/* Special message on first meeting at shop if player is already wearing uniform */
|
||||
mMsg_SET_CONTINUE_MSG_NUM(0x0837);
|
||||
aNRG2_change_talk_proc(rcn_guide2, aNRG2_TALK_SAY_HELLO_SP2);
|
||||
}
|
||||
|
||||
static void aNRG2_say_hello_sp2_talk_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
if (mMsg_GET_MSG_NUM() == 0x0837) {
|
||||
aNRG2_say_hello_talk_proc(rcn_guide2);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_cloth_chk_talk_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
|
||||
if (errand_p->base.progress == 1) {
|
||||
rcn_guide2->next_think_idx = aNRG2_THINK_JOB_START_WAIT;
|
||||
} else {
|
||||
rcn_guide2->next_think_idx = aNRG2_THINK_TALK_START_WAIT;
|
||||
}
|
||||
|
||||
aNRG2_change_talk_proc(rcn_guide2, aNRG2_TALK_TALK_END_WAIT);
|
||||
}
|
||||
|
||||
static void aNRG2_demo_start_wait_talk_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
/* List of display items for each job */
|
||||
static mActor_name_t itemNo[] = {
|
||||
ITM_CLOTH016, /* work uniform */
|
||||
ITM_WHITE_PANSY_BAG, /* flower bag */
|
||||
FTR_FAN, /* furniture */
|
||||
ITM_PAPER55, /* simple paper */
|
||||
ITM_CARPET00, /* carpet */
|
||||
ITM_AXE, /* axe */
|
||||
EMPTY_NO, /* no item */
|
||||
ITM_PAPER55, /* simple paper */
|
||||
ITM_AXE, /* axe */
|
||||
EMPTY_NO, /* no item */
|
||||
EMPTY_NO, /* no item */
|
||||
};
|
||||
|
||||
int order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 1);
|
||||
|
||||
if (order == 4) {
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
u32 kind = errand_p->base.quest_kind - mQst_ERRAND_FIRSTJOB_CHANGE_CLOTH;
|
||||
|
||||
/* Set params for hand over item */
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 0, itemNo[kind]);
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 1, 7);
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 2, 0);
|
||||
/* Don't let the player continue dialog */
|
||||
mMsg_SET_LOCKCONTINUE();
|
||||
aNRG2_change_talk_proc(rcn_guide2, aNRG2_TALK_DEMO_END_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_demo_end_wait_talk_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
/* Wait for the hand over process item to start */
|
||||
if (rcn_guide2->npc_class.action.idx == 10 && Common_Get(clip).handOverItem_clip->master_actor != NULL) {
|
||||
aNRG2_change_talk_proc(rcn_guide2, aNRG2_TALK_DEMO_END_WAIT2);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_demo_end_wait2_talk_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
/* Wait for the hand over item process to finish */
|
||||
if (Common_Get(clip).handOverItem_clip->master_actor == NULL) {
|
||||
/* Allow player to continue dialog */
|
||||
mMsg_UNSET_LOCKCONTINUE();
|
||||
aNRG2_change_talk_proc(rcn_guide2, aNRG2_TALK_TALK_END_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_job_start_talk_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
int talk_proc_idx;
|
||||
|
||||
/* Setup job quest info */
|
||||
aNRG2_stepup_job(rcn_guide2, errand_p->base.quest_kind - mQst_ERRAND_FIRSTJOB_CHANGE_CLOTH);
|
||||
/* Give the player the necessary item(s) for the job */
|
||||
aNRG2_set_possession();
|
||||
|
||||
if (errand_p->base.quest_kind == mQst_ERRAND_FIRSTJOB_INTRODUCTIONS ||
|
||||
errand_p->base.quest_kind == mQst_ERRAND_FIRSTJOB_OPEN) {
|
||||
talk_proc_idx = aNRG2_TALK_TALK_END_WAIT;
|
||||
} else {
|
||||
talk_proc_idx = aNRG2_TALK_DEMO_START_WAIT;
|
||||
}
|
||||
|
||||
aNRG2_change_talk_proc(rcn_guide2, talk_proc_idx);
|
||||
rcn_guide2->next_think_idx = aNRG2_THINK_TALK_START_WAIT;
|
||||
}
|
||||
|
||||
static void aNRG2_job_end_talk_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
static int next_job_no[] = {
|
||||
aNRG2_JOB2, aNRG2_JOB3, aNRG2_JOB4, aNRG2_JOB11, aNRG2_JOB6, aNRG2_JOB7,
|
||||
aNRG2_JOB7, aNRG2_JOB9, aNRG2_JOB7, aNRG2_JOB3, aNRG2_JOB5,
|
||||
};
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
int next_job;
|
||||
|
||||
/* If the finished quest was the planting flowers & saplings job & the player hasn't spoken to all villagers &
|
||||
* Tortimer, then set the job to introductions.
|
||||
*/
|
||||
if (errand_p->base.quest_kind == mQst_ERRAND_FIRSTJOB_PLANT_FLOWER &&
|
||||
(mNpc_CheckFriendAllAnimal(&Now_Private->player_ID) == FALSE || mSC_check_ArbeitPlayer() == FALSE)) {
|
||||
next_job = aNRG2_JOB10;
|
||||
} else {
|
||||
next_job = next_job_no[errand_p->base.quest_kind - mQst_ERRAND_FIRSTJOB_CHANGE_CLOTH];
|
||||
}
|
||||
|
||||
aNRG2_setup_job(next_job);
|
||||
aNRG2_change_talk_proc(rcn_guide2, aNRG2_TALK_SAY_HELLO);
|
||||
}
|
||||
|
||||
static void aNRG2_3rd_job_end_talk_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
u16 order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
|
||||
/* Hand over the map */
|
||||
if (order != 0) {
|
||||
aNRG2_job_end_talk_proc(rcn_guide2);
|
||||
|
||||
/* Set params for hand over item */
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 1, 2);
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 0, ITM_TOWN_MAP);
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 1, 7);
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 2, 0);
|
||||
|
||||
/* Enable map flag */
|
||||
Common_Set(map_flag, TRUE);
|
||||
|
||||
/* Clear demo order */
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_demo2_start_wait_talk_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
u16 order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
|
||||
/* Take quest item back from player */
|
||||
if (order != 0) {
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
int idx = mPr_GetPossessionItemIdxWithCond(Now_Private, errand_p->item, mPr_ITEM_COND_QUEST);
|
||||
|
||||
// This is bad, if you somehow don't have the quest item, the first item in your inventory will be deleted
|
||||
if (idx == -1) {
|
||||
idx = 0;
|
||||
}
|
||||
|
||||
/* Clear item */
|
||||
mPr_SetPossessionItem(Now_Private, idx, 0, mPr_ITEM_COND_NORMAL);
|
||||
|
||||
/* Clear demo order */
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
|
||||
/* Prevent player from continuing dialogue */
|
||||
mMsg_SET_LOCKCONTINUE();
|
||||
|
||||
/* Tell the player to play hand over animation */
|
||||
mPlib_request_main_give_type1(gamePT, errand_p->item, 7, FALSE, FALSE);
|
||||
|
||||
aNRG2_setup_job(errand_p->base.quest_kind - mQst_ERRAND_FIRSTJOB_CHANGE_CLOTH);
|
||||
aNRG2_change_talk_proc(rcn_guide2, aNRG2_TALK_DEMO2_START_WAIT2);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_demo2_start_wait2_talk_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
/* Wait for hand over item request mode */
|
||||
if (Common_Get(clip).handOverItem_clip->request_mode == aHOI_REQUEST_TRANS_WAIT) {
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 1, 3);
|
||||
aNRG2_change_talk_proc(rcn_guide2, aNRG2_TALK_DEMO2_END);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_demo2_end_wait_talk_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
/* Wait for hand over item to finish */
|
||||
if (Common_Get(clip).handOverItem_clip->master_actor == NULL) {
|
||||
/* Allow player to continue the dialogue now */
|
||||
mMsg_UNSET_LOCKCONTINUE();
|
||||
aNRG2_job_start_talk_proc(rcn_guide2);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_give_new_paper_talk_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
|
||||
|
||||
if (aNRG2_check_job_start() == TRUE) {
|
||||
/* Give another piece of stationery to the player */
|
||||
mMsg_Set_continue_msg_num(msg_p, 0x0805); // 'Here! Here's another piece of paper.'
|
||||
aNRG2_job_start_talk_proc(rcn_guide2);
|
||||
rcn_guide2->can_ask_again_flag = TRUE;
|
||||
} else {
|
||||
/* Player has full pockets so tell them */
|
||||
mMsg_Set_continue_msg_num(msg_p, 0x07FA); // '...What have we here?'
|
||||
aNRG2_change_talk_proc(rcn_guide2, aNRG2_TALK_TALK_END_WAIT);
|
||||
rcn_guide2->can_ask_again_flag = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_check_more_paper_talk_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
u16 order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
mQst_errand_c* errand_p;
|
||||
|
||||
if (order != 0) {
|
||||
/* Clear the demo order */
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
|
||||
switch (mChoice_GET_CHOSENUM()) {
|
||||
case mChoice_CHOICE0:
|
||||
/* Player asked for more paper, so give them some if they have inv space */
|
||||
errand_p = mQst_GetFirstJobData();
|
||||
aNRG2_give_new_paper_talk_proc(rcn_guide2);
|
||||
errand_p->base.progress = 2;
|
||||
break;
|
||||
case mChoice_CHOICE1:
|
||||
/* Player said they don't need more paper */
|
||||
aNRG2_change_talk_proc(rcn_guide2, aNRG2_TALK_TALK_END_WAIT);
|
||||
rcn_guide2->can_ask_again_flag = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_decide_new_target_talk_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
u16 order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
mQst_errand_c* errand_p;
|
||||
|
||||
if (order != 0) {
|
||||
errand_p = mQst_GetFirstJobData();
|
||||
|
||||
/* Clear the demo order */
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
|
||||
aNRG2_setup_job(errand_p->base.quest_kind - mQst_ERRAND_FIRSTJOB_CHANGE_CLOTH);
|
||||
aNRG2_stepup_job(rcn_guide2, errand_p->base.quest_kind - mQst_ERRAND_FIRSTJOB_CHANGE_CLOTH);
|
||||
aNRG2_change_talk_proc(rcn_guide2, aNRG2_TALK_CHECK_MORE_PAPER);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_demo3_start_wait_talk_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
u16 order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
mQst_errand_c* errand_p;
|
||||
int idx;
|
||||
|
||||
if (order != 0) {
|
||||
errand_p = mQst_GetFirstJobData();
|
||||
idx = mPr_GetPossessionItemIdxWithCond(Now_Private, errand_p->item, mPr_ITEM_COND_QUEST);
|
||||
|
||||
if (idx == -1) {
|
||||
/* If the job's tool item can't be found then try the player's equipped item */
|
||||
if (Now_Private->equipment == errand_p->item) {
|
||||
Now_Private->equipment = EMPTY_NO;
|
||||
}
|
||||
} else {
|
||||
mPr_SetPossessionItem(Now_Private, idx, EMPTY_NO, mPr_ITEM_COND_NORMAL);
|
||||
}
|
||||
|
||||
/* Clear the demo order */
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
|
||||
mMsg_SET_LOCKCONTINUE();
|
||||
mPlib_request_main_give_type1(gamePT, errand_p->item, 7, FALSE, FALSE);
|
||||
aNRG2_setup_job(aNRG2_JOB8);
|
||||
aNRG2_change_talk_proc(rcn_guide2, aNRG2_TALK_DEMO3_START_WAIT2);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG2_all_job_end_talk_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2) {
|
||||
rcn_guide2->next_think_idx = aNRG2_THINK_ALL_JOB_END;
|
||||
aNRG2_change_talk_proc(rcn_guide2, aNRG2_TALK_TALK_END_WAIT);
|
||||
}
|
||||
|
||||
static void aNRG2_change_talk_proc(NPC_RCN_GUIDE2_ACTOR* rcn_guide2, int talk_proc_idx) {
|
||||
// clang-format off
|
||||
static aNRG2_TALK_PROC proc[] = {
|
||||
&aNRG2_say_hello_talk_proc,
|
||||
&aNRG2_say_hello_sp_talk_proc,
|
||||
&aNRG2_say_hello_sp2_talk_proc,
|
||||
&aNRG2_cloth_chk_talk_proc,
|
||||
(aNRG2_TALK_PROC)&none_proc1,
|
||||
&aNRG2_demo_start_wait_talk_proc,
|
||||
&aNRG2_demo_end_wait_talk_proc,
|
||||
&aNRG2_demo_end_wait2_talk_proc,
|
||||
&aNRG2_job_start_talk_proc,
|
||||
&aNRG2_job_end_talk_proc,
|
||||
&aNRG2_3rd_job_end_talk_proc,
|
||||
&aNRG2_demo2_start_wait_talk_proc,
|
||||
&aNRG2_demo2_start_wait2_talk_proc,
|
||||
&aNRG2_demo2_end_wait_talk_proc,
|
||||
&aNRG2_give_new_paper_talk_proc,
|
||||
&aNRG2_check_more_paper_talk_proc,
|
||||
&aNRG2_decide_new_target_talk_proc,
|
||||
&aNRG2_demo3_start_wait_talk_proc,
|
||||
&aNRG2_demo2_start_wait2_talk_proc,
|
||||
&aNRG2_demo2_end_wait_talk_proc,
|
||||
&aNRG2_all_job_end_talk_proc,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
rcn_guide2->talk_proc = proc[talk_proc_idx];
|
||||
}
|
||||
|
||||
static void aNRG2_set_goods_talk_info(ACTOR* actorx) {
|
||||
NPC_RCN_GUIDE2_ACTOR* rcn_guide2 = (NPC_RCN_GUIDE2_ACTOR*)actorx;
|
||||
int msg_no = 0x081C;
|
||||
|
||||
/* Check if it's a raffle day */
|
||||
if (Common_Get(tanuki_shop_status) == mSP_TANUKI_SHOP_STATUS_FUKUBIKI) {
|
||||
msg_no = 0x0833;
|
||||
}
|
||||
|
||||
mDemo_Set_msg_num(msg_no);
|
||||
mDemo_Set_talk_turn(TRUE);
|
||||
rcn_guide2->talk_proc = (aNRG2_TALK_PROC)&none_proc1;
|
||||
}
|
||||
|
||||
static int aNRG2_goods_talk_request(ACTOR* actorx, GAME* game) {
|
||||
PLAYER_ACTOR* player = GET_PLAYER_ACTOR_GAME(game);
|
||||
int res = FALSE;
|
||||
|
||||
if (player != NULL) {
|
||||
int ux;
|
||||
int uz;
|
||||
mActor_name_t item;
|
||||
|
||||
mFI_Wpos2UtNum(&ux, &uz, player->forward_ut_pos);
|
||||
item = Common_Get(clip).shop_design_clip->unitNum2ItemNo_proc(ux, uz);
|
||||
if (player->a_btn_pressed == TRUE && item != EXIT_DOOR1 && item != EMPTY_NO && item != RSV_WALL_NO &&
|
||||
item != RSV_NO && item != DOOR0) {
|
||||
/* Player interacted with shop goods, tell them they're inaccessible currently */
|
||||
NPC_RCN_GUIDE2_ACTOR* rcn_guide2 = (NPC_RCN_GUIDE2_ACTOR*)actorx;
|
||||
|
||||
mDemo_Request(mDemo_TYPE_SPEAK, actorx, &aNRG2_set_goods_talk_info);
|
||||
rcn_guide2->talk_proc_idx = 0;
|
||||
res = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int aNRG2_cloth_check(void) {
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
int res = FALSE;
|
||||
|
||||
if (errand_p->base.quest_kind > mQst_ERRAND_FIRSTJOB_CHANGE_CLOTH &&
|
||||
errand_p->info.first_job.wrong_cloth == FALSE && Now_Private->cloth.item != ITM_CLOTH016) {
|
||||
/* Player changed out of work uniform on the job, now they get a stern talking to! */
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int aNRG2_check_upstair(void) {
|
||||
PLAYER_ACTOR* player = GET_PLAYER_ACTOR_NOW();
|
||||
u16 angle_y = player->actor_class.shape_info.rotation.y;
|
||||
int res = FALSE;
|
||||
|
||||
if (angle_y > DEG2SHORT_ANGLE2(135.0f) && angle_y < DEG2SHORT_ANGLE2(225.0f) &&
|
||||
player->item_in_front == RSV_POLICE_ITEM_0) {
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void aNRG2_set_force_talk_info(ACTOR* actorx) {
|
||||
static aNRG2_talk_info_c dt_tbl[] = {
|
||||
{ 0x07EE, &aNRG2_say_hello_talk_proc }, /* 'Well, finally you arrive!' */
|
||||
{ 0x07EF, &aNRG2_say_hello_talk_proc }, /* 'So you're back again today?' */
|
||||
{ 0x07EE, &aNRG2_say_hello_sp_talk_proc }, /* 'Well, finally you arrive!' (already wearing work uniform) */
|
||||
{ 0x0832, &aNRG2_cloth_chk_talk_proc }, /* 'Why did you change out of your uniform, hm?' */
|
||||
{ 0x0834, (aNRG2_TALK_PROC)&none_proc1 }, /* 'Stop right there!' (Going up to 2nd floor) */
|
||||
};
|
||||
|
||||
aNRG2_talk_info_c* data;
|
||||
NPC_RCN_GUIDE2_ACTOR* rcn_guide2 = (NPC_RCN_GUIDE2_ACTOR*)actorx;
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
int talk_idx;
|
||||
|
||||
/* Figure out our talk state */
|
||||
if (aNRG2_cloth_check() == TRUE) {
|
||||
talk_idx = aNRG2_FORCE_TALK_CLOTH_CHK; // Player changed out of their work uniform
|
||||
errand_p->info.first_job.wrong_cloth = TRUE;
|
||||
} else if (aNRG2_check_upstair() == TRUE) {
|
||||
talk_idx = aNRG2_FORCE_TALK_UPSTAIR_CHK; // Player tried going upstairs in Nookington's
|
||||
} else {
|
||||
talk_idx = rcn_guide2->talk_idx;
|
||||
}
|
||||
data = &dt_tbl[talk_idx];
|
||||
|
||||
/* If assigning a new job then set the necessary text strings */
|
||||
if (mQst_CheckFirstJobFin(errand_p) == FALSE) {
|
||||
aNRG2_set_str_proc();
|
||||
}
|
||||
|
||||
/* Apply the relevant data */
|
||||
mDemo_Set_msg_num(data->msg_no);
|
||||
mDemo_Set_talk_turn(TRUE);
|
||||
rcn_guide2->talk_proc = data->talk_proc;
|
||||
}
|
||||
|
||||
static void aNRG2_force_talk_request(ACTOR* actorx, GAME* game) {
|
||||
NPC_RCN_GUIDE2_ACTOR* rcn_guide2 = (NPC_RCN_GUIDE2_ACTOR*)actorx;
|
||||
|
||||
mDemo_Request(mDemo_TYPE_SPEAK, actorx, &aNRG2_set_force_talk_info);
|
||||
rcn_guide2->talk_proc_idx = 0;
|
||||
}
|
||||
|
||||
static void aNRG2_set_norm_talk_info(ACTOR* actorx) {
|
||||
// clang-format off
|
||||
static aNRG2_talk_info_c dt_tbl[] = {
|
||||
{ 0x07F1, &aNRG2_job_start_talk_proc },
|
||||
{ 0x07F6, &aNRG2_job_start_talk_proc },
|
||||
{ 0x07FB, &aNRG2_job_start_talk_proc },
|
||||
{ 0x0802, &aNRG2_job_start_talk_proc },
|
||||
{ 0x080C, &aNRG2_job_start_talk_proc },
|
||||
{ 0x0830, &aNRG2_job_start_talk_proc },
|
||||
{ 0x0813, &aNRG2_job_start_talk_proc },
|
||||
{ 0x0818, &aNRG2_job_start_talk_proc },
|
||||
{ 0x0821, &aNRG2_job_start_talk_proc },
|
||||
{ 0x0827, &aNRG2_job_start_talk_proc },
|
||||
{ 0x07F0, (aNRG2_TALK_PROC)&none_proc1 },
|
||||
{ 0x07F5, (aNRG2_TALK_PROC)&none_proc1 },
|
||||
{ 0x07FA, (aNRG2_TALK_PROC)&none_proc1 },
|
||||
{ 0x07FA, (aNRG2_TALK_PROC)&none_proc1 },
|
||||
{ 0x07FA, (aNRG2_TALK_PROC)&none_proc1 },
|
||||
{ 0x0826, (aNRG2_TALK_PROC)&none_proc1 },
|
||||
{ 0x07FA, (aNRG2_TALK_PROC)&none_proc1 },
|
||||
{ 0x0818, (aNRG2_TALK_PROC)&none_proc1 },
|
||||
{ 0x07F3, (aNRG2_TALK_PROC)&none_proc1 },
|
||||
{ 0x081F, &aNRG2_job_start_talk_proc },
|
||||
{ 0x0835, (aNRG2_TALK_PROC)&none_proc1 },
|
||||
{ 0x07F8, (aNRG2_TALK_PROC)&none_proc1 },
|
||||
{ 0x07FE, (aNRG2_TALK_PROC)&none_proc1 },
|
||||
{ 0x07FF, &aNRG2_demo2_start_wait_talk_proc },
|
||||
{ 0x0807, &aNRG2_check_more_paper_talk_proc },
|
||||
{ 0x0808, &aNRG2_decide_new_target_talk_proc },
|
||||
{ 0x0804, &aNRG2_give_new_paper_talk_proc },
|
||||
{ 0x080F, (aNRG2_TALK_PROC)&none_proc1 },
|
||||
{ 0x0810, &aNRG2_demo2_start_wait_talk_proc },
|
||||
{ 0x0815, (aNRG2_TALK_PROC)&none_proc1 },
|
||||
{ 0x0816, &aNRG2_demo3_start_wait_talk_proc },
|
||||
{ 0x0819, (aNRG2_TALK_PROC)&none_proc1 },
|
||||
{ 0x0822, (aNRG2_TALK_PROC)&none_proc1 },
|
||||
{ 0x0829, (aNRG2_TALK_PROC)&none_proc1 },
|
||||
{ 0x07F4, &aNRG2_job_end_talk_proc },
|
||||
{ 0x07F9, &aNRG2_job_end_talk_proc },
|
||||
{ 0x0801, &aNRG2_3rd_job_end_talk_proc },
|
||||
{ 0x080B, &aNRG2_job_end_talk_proc },
|
||||
{ 0x0812, &aNRG2_job_end_talk_proc },
|
||||
{ 0x0818, &aNRG2_job_end_talk_proc },
|
||||
{ 0x081A, &aNRG2_all_job_end_talk_proc },
|
||||
{ 0x0828, &aNRG2_job_end_talk_proc },
|
||||
{ 0x0830, &aNRG2_job_end_talk_proc },
|
||||
{ 0x0836, (aNRG2_TALK_PROC)&none_proc1 },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
NPC_RCN_GUIDE2_ACTOR* rcn_guide2 = (NPC_RCN_GUIDE2_ACTOR*)actorx;
|
||||
int talk_idx = rcn_guide2->talk_idx;
|
||||
aNRG2_talk_info_c* data = &dt_tbl[talk_idx];
|
||||
mQst_errand_c* errand_p = mQst_GetFirstJobData();
|
||||
|
||||
if (talk_idx >= aNRG2_NORM_TALK_J1_CONT1 && talk_idx <= aNRG2_NORM_TALK_J11_CONT1) {
|
||||
rcn_guide2->can_ask_again_flag = TRUE;
|
||||
}
|
||||
|
||||
if (mQst_CheckFirstJobFin(errand_p) == FALSE) {
|
||||
aNRG2_set_str_proc();
|
||||
}
|
||||
|
||||
mDemo_Set_msg_num(data->msg_no);
|
||||
rcn_guide2->talk_proc = data->talk_proc;
|
||||
}
|
||||
|
||||
static void aNRG2_norm_talk_request(ACTOR* actorx, GAME* game) {
|
||||
NPC_RCN_GUIDE2_ACTOR* rcn_guide2 = (NPC_RCN_GUIDE2_ACTOR*)actorx;
|
||||
|
||||
if (aNRG2_goods_talk_request(actorx, game) == FALSE) {
|
||||
if (aNRG2_cloth_check() == TRUE) {
|
||||
aNRG2_force_talk_request(actorx, game);
|
||||
} else if (aNRG2_check_upstair() == TRUE) {
|
||||
aNRG2_force_talk_request(actorx, game);
|
||||
} else {
|
||||
mDemo_Request(mDemo_TYPE_TALK, actorx, &aNRG2_set_norm_talk_info);
|
||||
rcn_guide2->talk_proc_idx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int aNRG2_talk_init(ACTOR* actorx, GAME* game) {
|
||||
NPC_RCN_GUIDE2_ACTOR* rcn_guide2 = (NPC_RCN_GUIDE2_ACTOR*)actorx;
|
||||
|
||||
rcn_guide2->npc_class.talk_info.talk_request_proc = (aNPC_TALK_REQUEST_PROC)&none_proc1;
|
||||
mDemo_Set_ListenAble();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int aNRG2_talk_end_chk(ACTOR* actorx, GAME* game) {
|
||||
NPC_RCN_GUIDE2_ACTOR* rcn_guide2 = (NPC_RCN_GUIDE2_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
int res = FALSE;
|
||||
|
||||
(*rcn_guide2->talk_proc)(rcn_guide2);
|
||||
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, actorx) == FALSE && mDemo_Check(mDemo_TYPE_TALK, actorx) == FALSE) {
|
||||
aNRG2_setup_think_proc(rcn_guide2, play, rcn_guide2->next_think_idx);
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
+744
-785
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user