mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-09-11 03:13:22 -04:00
Add a few more rel groups
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
#include "ac_npc_curator.h"
|
||||
|
||||
#include "m_common_data.h"
|
||||
#include "m_item_name.h"
|
||||
#include "m_msg.h"
|
||||
|
||||
enum {
|
||||
aCR_ACTION_WAIT,
|
||||
aCR_ACTION_SLEEP_WAIT,
|
||||
aCR_ACTION_SLEEP,
|
||||
|
||||
aCR_ACTION_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aCR_TALK_END_WAIT,
|
||||
aCR_TALK_AFTER_TALK_START_WAIT,
|
||||
aCR_TALK_CHK_REQUEST,
|
||||
aCR_TALK_CHK_DECIDE_TO_DONATE,
|
||||
aCR_TALK_CHK_DECIDE_TO_DONATE2,
|
||||
aCR_TALK_MENU_OPEN_WAIT,
|
||||
aCR_TALK_MSG_WIN_CLOSE_WAIT,
|
||||
aCR_TALK_MENU_CLOSE_WAIT,
|
||||
aCR_TALK_GET_DEMO_START_WAIT,
|
||||
aCR_TALK_GET_DEMO_END_WAIT,
|
||||
aCR_TALK_MSG_WIN_OPEN_WAIT,
|
||||
aCR_TALK_RETURN_DEMO_START_WAIT,
|
||||
aCR_TALK_RETURN_DEMO_START_WAIT2,
|
||||
aCR_TALK_RETURN_DEMO_END_WAIT,
|
||||
aCR_TALK_RETURN_DEMO_END_WAIT2,
|
||||
aCR_TALK_CHK_CONTINUE_TO_DONATE,
|
||||
aCR_TALK_CHK_CONTINUE_TO_DONATE2,
|
||||
aCR_TALK_CHK_CONTINUE_TO_DONATE3,
|
||||
aCR_TALK_PUTAWAY_DEMO_START_WAIT,
|
||||
aCR_TALK_PUTAWAY_DEMO_START_WAIT2,
|
||||
aCR_TALK_PUTAWAY_DEMO_START_WAIT3,
|
||||
aCR_TALK_PUTAWAY_DEMO_START_WAIT4,
|
||||
aCR_TALK_PUTAWAY_DEMO_START_WAIT5,
|
||||
aCR_TALK_PUTAWAY_DEMO_START_WAIT6,
|
||||
aCR_TALK_PUTAWAY_DEMO_START_WAIT5_2,
|
||||
aCR_TALK_PUTAWAY_DEMO_END_WAIT,
|
||||
aCR_TALK_PUTAWAY_DEMO_END_WAIT2,
|
||||
aCR_TALK_PUTAWAY_DEMO_END_WAIT3,
|
||||
aCR_TALK_PUTAWAY_DEMO_END_WAIT4,
|
||||
aCR_TALK_PUTAWAY_DEMO_END_WAIT5,
|
||||
aCR_TALK_PUTAWAY_DEMO_END_WAIT6,
|
||||
aCR_TALK_AFTER_EXPLAIN_INSECT,
|
||||
aCR_TALK_THANKS_FOSSIL_MSG_END_WAIT,
|
||||
aCR_TALK_CHK_ALL_COMPLETE,
|
||||
|
||||
aCR_TALK_NUM
|
||||
};
|
||||
|
||||
static void aCR_actor_ct(ACTOR* actorx, GAME* game);
|
||||
static void aCR_actor_dt(ACTOR* actorx, GAME* game);
|
||||
static void aCR_actor_move(ACTOR* actorx, GAME* game);
|
||||
static void aCR_actor_draw(ACTOR* actorx, GAME* game);
|
||||
static void aCR_actor_init(ACTOR* actorx, GAME* game);
|
||||
static void aCR_actor_save(ACTOR* actorx, GAME* game);
|
||||
|
||||
ACTOR_PROFILE Npc_Curator_Profile = {
|
||||
mAc_PROFILE_NPC_CURATOR,
|
||||
ACTOR_PART_NPC,
|
||||
ACTOR_STATE_NONE,
|
||||
SP_NPC_CURATOR,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(NPC_CURATOR_ACTOR),
|
||||
&aCR_actor_ct,
|
||||
&aCR_actor_dt,
|
||||
&aCR_actor_init,
|
||||
mActor_NONE_PROC1,
|
||||
&aCR_actor_save
|
||||
};
|
||||
|
||||
static void aCR_talk_request(ACTOR* actorx, GAME* game);
|
||||
static int aCR_talk_init(ACTOR* actorx, GAME* game);
|
||||
static int aCR_talk_end_chk(ACTOR* actorx, GAME* game);
|
||||
|
||||
static void aCR_schedule_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int sched_idx);
|
||||
static void aCR_setupTalkAction(NPC_CURATOR_ACTOR* curator, GAME_PLAY* play, int talk_act_idx);
|
||||
static void aCR_setupAction(NPC_CURATOR_ACTOR* curator, GAME_PLAY* play, int action);
|
||||
|
||||
static void aCR_actor_ct(ACTOR* actorx, GAME* game) {
|
||||
static aNPC_ct_data_c ct_data = {
|
||||
&aCR_actor_move,
|
||||
&aCR_actor_draw,
|
||||
5,
|
||||
&aCR_talk_request,
|
||||
&aCR_talk_init,
|
||||
&aCR_talk_end_chk,
|
||||
0
|
||||
};
|
||||
|
||||
NPC_CURATOR_ACTOR* curator = (NPC_CURATOR_ACTOR*)actorx;
|
||||
|
||||
if ((*Common_Get(clip).npc_clip->birth_check_proc)(actorx, game) == TRUE) {
|
||||
curator->npc_class.schedule.schedule_proc = &aCR_schedule_proc;
|
||||
(*Common_Get(clip).npc_clip->ct_proc)(actorx, game, &ct_data);
|
||||
actorx->status_data.weight = 255;
|
||||
actorx->world.position.x += 20.0f;
|
||||
curator->setupTalkAction_proc = &aCR_setupTalkAction;
|
||||
|
||||
/* Clear 'first talk' flag if entering from a scene outside the museum */
|
||||
if (Common_Get(last_scene_no) >= SCENE_MY_ROOM_LL1 || Common_Get(last_scene_no) < SCENE_MUSEUM_ROOM_PAINTING) {
|
||||
aNPC_SPNPC_BIT_CLR(Common_Get(spnpc_first_talk_flags), aNPC_SPNPC_BIT_CURATOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aCR_actor_save(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->save_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aCR_actor_dt(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->dt_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aCR_actor_init(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->init_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aCR_actor_draw(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->draw_proc)(actorx, game);
|
||||
}
|
||||
|
||||
#include "../src/actor/ac_npc_curator_move.c_inc"
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,72 @@
|
||||
#include "ac_npc_engineer.h"
|
||||
#include "m_name_table.h"
|
||||
#include "m_common_data.h"
|
||||
|
||||
extern void aNEG_actor_ct(ACTOR* actor, GAME* game);
|
||||
extern void aNEG_actor_dt(ACTOR* actor, GAME* game);
|
||||
extern void aNEG_actor_init(ACTOR* actor, GAME* game);
|
||||
extern void aNEG_actor_save(ACTOR* actor, GAME* game);
|
||||
|
||||
ACTOR_PROFILE Npc_Engineer_Profile = {
|
||||
mAc_PROFILE_NPC_ENGINEER,
|
||||
ACTOR_PART_NPC,
|
||||
ACTOR_STATE_CAN_MOVE_IN_DEMO_SCENES | ACTOR_STATE_NO_MOVE_WHILE_CULLED,
|
||||
EMPTY_NO,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(NPCENGINEER_ACTOR),
|
||||
aNEG_actor_ct,
|
||||
aNEG_actor_dt,
|
||||
aNEG_actor_init,
|
||||
mActor_NONE_PROC1,
|
||||
aNEG_actor_save,
|
||||
};
|
||||
|
||||
void aNEG_actor_move(ACTOR*, GAME*);
|
||||
void aNEG_actor_draw(ACTOR*, GAME*);
|
||||
|
||||
void aNEG_actor_ct(ACTOR* actor, GAME* game){
|
||||
static aNPC_ct_data_c ct_data = {
|
||||
&aNEG_actor_move,
|
||||
&aNEG_actor_draw,
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
};
|
||||
NPCENGINEER_ACTOR* engineer = (NPCENGINEER_ACTOR*)actor;
|
||||
if(Common_Get(clip.npc_clip)->birth_check_proc(actor,game) == TRUE){
|
||||
engineer->npc_class.schedule.schedule_proc = (aNPC_SCHEDULE_PROC)mActor_NONE_PROC1;
|
||||
Common_Get(clip.npc_clip)->ct_proc(actor,game,&ct_data);
|
||||
engineer->npc_class.condition_info.demo_flg = -1;
|
||||
engineer->npc_class.condition_info.hide_request = 0;
|
||||
engineer->npc_class.palActorIgnoreTimer = -1;
|
||||
engineer->npc_class.actor_class.status_data.weight = MASSTYPE_HEAVY;
|
||||
engineer->npc_class.actor_class.shape_info.rotation.y = 0x4000;
|
||||
engineer->npc_class.actor_class.world.angle.y = 0x4000;
|
||||
engineer->npc_class.movement.mv_angl = 0x4000;
|
||||
engineer->npc_class.request.act_priority = 4;
|
||||
engineer->npc_class.request.act_idx = 0;
|
||||
engineer->npc_class.request.act_type = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void aNEG_actor_save(ACTOR* actor, GAME* game) {
|
||||
Common_Get(clip.npc_clip)->save_proc(actor,game);
|
||||
}
|
||||
|
||||
void aNEG_actor_dt(ACTOR* actor, GAME* game) {
|
||||
Common_Get(clip.npc_clip)->dt_proc(actor,game);
|
||||
}
|
||||
|
||||
void aNEG_actor_init(ACTOR* actor, GAME* game) {
|
||||
Common_Get(clip.npc_clip)->init_proc(actor,game);
|
||||
}
|
||||
|
||||
void aNEG_actor_move(ACTOR* actor, GAME* game){
|
||||
Common_Get(clip.npc_clip)->move_proc(actor,game);
|
||||
}
|
||||
|
||||
void aNEG_actor_draw(ACTOR* actor, GAME* game) {
|
||||
Common_Get(clip.npc_clip)->draw_proc(actor,game);
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
#include "ac_npc_guide.h"
|
||||
|
||||
#include "m_play.h"
|
||||
#include "m_common_data.h"
|
||||
#include "ac_train_door.h"
|
||||
#include "m_player_lib.h"
|
||||
#include "m_font.h"
|
||||
#include "m_msg.h"
|
||||
#include "m_timeIn_ovl.h"
|
||||
#include "m_ledit_ovl.h"
|
||||
#include "libultra/libultra.h"
|
||||
#include "m_bgm.h"
|
||||
#include "m_soncho.h"
|
||||
|
||||
enum {
|
||||
aNGD_ACTION_ENTER,
|
||||
aNGD_ACTION_APPROACH,
|
||||
aNGD_ACTION_TALK_START_WAIT,
|
||||
aNGD_ACTION_TIME_CHECK,
|
||||
aNGD_ACTION_SDON_AND_PB_WAIT,
|
||||
aNGD_ACTION_TIME_MENU_OPEN_WAIT,
|
||||
aNGD_ACTION_TIME_MENU_CLOSE_WAIT,
|
||||
aNGD_ACTION_MSG_WIN_OPEN_WAIT,
|
||||
aNGD_ACTION_CONFIRM_INPUT_DATA,
|
||||
aNGD_ACTION_WAIT_PERMISSION,
|
||||
aNGD_ACTION_SITDOWN,
|
||||
aNGD_ACTION_PNAME_MENU_OPEN_WAIT,
|
||||
aNGD_ACTION_PNAME_MENU_CLOSE_WAIT,
|
||||
aNGD_ACTION_SEX_SELECT_WAIT,
|
||||
aNGD_ACTION_SEX_SELECT_WAIT2,
|
||||
aNGD_ACTION_SEX_SELECT_AFTER,
|
||||
aNGD_ACTION_CNAME_MENU_OPEN_WAIT,
|
||||
aNGD_ACTION_CNAME_MENU_CLOSE_WAIT,
|
||||
aNGD_ACTION_STANDUP_START_WAIT,
|
||||
aNGD_ACTION_STANDUP,
|
||||
aNGD_ACTION_MOVE_READY,
|
||||
aNGD_ACTION_MOVE_TO_AISLE,
|
||||
aNGD_ACTION_MOVE_TO_DOOR,
|
||||
aNGD_ACTION_MOVE_TO_DECK,
|
||||
aNGD_ACTION_KEITAI_ON,
|
||||
aNGD_ACTION_KEITAI_TALK,
|
||||
aNGD_ACTION_KEITAI_OFF,
|
||||
aNGD_ACTION_OPEN_DOOR,
|
||||
aNGD_ACTION_RETURN_APPROACH,
|
||||
aNGD_ACTION_LAST_TALK_START_WAIT,
|
||||
aNGD_ACTION_SITDOWN2_START_WAIT,
|
||||
aNGD_ACTION_SITDOWN2,
|
||||
aNGD_ACTION_LAST_TALK_END_WAIT,
|
||||
aNGD_ACTION_SCENE_CHANGE_WAIT,
|
||||
|
||||
aNGD_ACTION_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aNGD_OBJ_LOOK_TYPE_NORMAL,
|
||||
aNGD_OBJ_LOOK_TYPE_TALK,
|
||||
|
||||
aNGD_OBJ_LOOK_TYPE_NUM
|
||||
};
|
||||
|
||||
static void aNGD_actor_ct(ACTOR* actorx, GAME* game);
|
||||
static void aNGD_actor_dt(ACTOR* actorx, GAME* game);
|
||||
static void aNGD_actor_init(ACTOR* actorx, GAME* game);
|
||||
static void aNGD_actor_save(ACTOR* actorx, GAME* game);
|
||||
|
||||
// clang-format off
|
||||
ACTOR_PROFILE Npc_Guide_Profile = {
|
||||
mAc_PROFILE_NPC_GUIDE,
|
||||
ACTOR_PART_NPC,
|
||||
ACTOR_STATE_NO_DRAW_WHILE_CULLED | ACTOR_STATE_NO_MOVE_WHILE_CULLED,
|
||||
SP_NPC_GUIDE,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(NPC_GUIDE_ACTOR),
|
||||
&aNGD_actor_ct,
|
||||
&aNGD_actor_dt,
|
||||
&aNGD_actor_init,
|
||||
mActor_NONE_PROC1,
|
||||
&aNGD_actor_save,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static void aNGD_actor_move(ACTOR* actorx, GAME* game);
|
||||
static void aNGD_actor_draw(ACTOR* actorx, GAME* game);
|
||||
|
||||
static void aNGD_setupAction(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play, int action);
|
||||
|
||||
static void aNGD_actor_ct(ACTOR* actorx, GAME* game) {
|
||||
static aNPC_ct_data_c ct_data = { &aNGD_actor_move, &aNGD_actor_draw, 0, NULL, NULL, NULL, 0 };
|
||||
NPC_GUIDE_ACTOR* guide = (NPC_GUIDE_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
PLAYER_ACTOR* player;
|
||||
|
||||
Common_Get(clip).npc_clip->ct_proc(actorx, game, &ct_data);
|
||||
guide->npc_class.condition_info.hide_flg = FALSE; // show guide actor
|
||||
guide->npc_class.condition_info.demo_flg =
|
||||
aNPC_COND_DEMO_SKIP_ENTRANCE_CHECK | aNPC_COND_DEMO_SKIP_HEAD_LOOKAT | aNPC_COND_DEMO_SKIP_TALK_CHECK |
|
||||
aNPC_COND_DEMO_SKIP_ITEM | aNPC_COND_DEMO_SKIP_FORWARD_CHECK | aNPC_COND_DEMO_SKIP_BGCHECK |
|
||||
aNPC_COND_DEMO_SKIP_OBJ_COL_CHECK | aNPC_COND_DEMO_SKIP_MOVE_Y | aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV |
|
||||
aNPC_COND_DEMO_SKIP_MOVE_RANGE_CHECK;
|
||||
guide->camera_morph_counter = 40;
|
||||
guide->obj_look_type = aNGD_OBJ_LOOK_TYPE_NORMAL;
|
||||
guide->npc_class.eye_y = 30.0f;
|
||||
guide->camera_move_set_counter = 1;
|
||||
guide->npc_class.palActorIgnoreTimer = -1;
|
||||
guide->train_door_actor = Actor_info_fgName_search(&play->actor_info, TRAIN_DOOR, ACTOR_PART_BG);
|
||||
guide->npc_class.actor_class.shape_info.draw_shadow = TRUE;
|
||||
guide->npc_class.actor_class.world.position.z = 130.0f;
|
||||
|
||||
/* Put the player into demo wait state */
|
||||
mPlib_request_main_demo_wait_type1(game, 0, NULL);
|
||||
player = GET_PLAYER_ACTOR(play);
|
||||
if (player != NULL) {
|
||||
/* Make the player invisible during the intro train ride */
|
||||
player->actor_class.state_bitfield |= ACTOR_STATE_INVISIBLE;
|
||||
}
|
||||
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_ENTER);
|
||||
|
||||
/* Play train noises sfx repeatedly */
|
||||
sAdo_SysLevStart(NA_SE_TRAIN_RIDE);
|
||||
|
||||
/* Disable sunlight */
|
||||
Common_Set(sunlight_flag, FALSE);
|
||||
|
||||
/* Turn on echo for sound effects */
|
||||
sAdo_TrgSeEcho(TRUE);
|
||||
sAdo_LevSeEcho(TRUE);
|
||||
}
|
||||
|
||||
static void aNGD_actor_save(ACTOR* actorx, GAME* game) {
|
||||
Common_Get(clip).npc_clip->save_proc(actorx, game);
|
||||
}
|
||||
|
||||
static void aNGD_actor_dt(ACTOR* actorx, GAME* game) {
|
||||
/* Update all animals in town to have this town's info */
|
||||
mNpc_SetAnimalThisLand(Save_Get(animals), ANIMAL_NUM_MAX);
|
||||
Common_Get(clip).npc_clip->dt_proc(actorx, game);
|
||||
|
||||
/* Stop train noise sfx */
|
||||
sAdo_SysLevStop(NA_SE_TRAIN_RIDE);
|
||||
}
|
||||
|
||||
static void aNGD_actor_init(ACTOR* actorx, GAME* game) {
|
||||
Common_Get(clip).npc_clip->init_proc(actorx, game);
|
||||
}
|
||||
|
||||
static void aNGD_actor_draw(ACTOR* actorx, GAME* game) {
|
||||
Common_Get(clip).npc_clip->draw_proc(actorx, game);
|
||||
}
|
||||
|
||||
#include "../src/actor/ac_npc_guide_animation.c_inc"
|
||||
#include "../src/actor/ac_npc_guide_move.c_inc"
|
||||
@@ -0,0 +1,138 @@
|
||||
#include "ac_npc_guide2.h"
|
||||
|
||||
#include "m_play.h"
|
||||
#include "m_common_data.h"
|
||||
#include "ac_train_door.h"
|
||||
#include "m_player_lib.h"
|
||||
#include "m_font.h"
|
||||
#include "m_msg.h"
|
||||
#include "m_timeIn_ovl.h"
|
||||
#include "m_ledit_ovl.h"
|
||||
#include "libultra/libultra.h"
|
||||
#include "m_bgm.h"
|
||||
#include "m_soncho.h"
|
||||
|
||||
enum {
|
||||
aNG2_ACTION_ENTER,
|
||||
aNG2_ACTION_APPROACH,
|
||||
aNG2_ACTION_TALK_START_WAIT,
|
||||
aNG2_ACTION_WAIT_PERMISSION,
|
||||
aNG2_ACTION_SITDOWN,
|
||||
aNG2_ACTION_SDON_AND_PB_WAIT,
|
||||
aNG2_ACTION_PNAME_MENU_OPEN_WAIT,
|
||||
aNG2_ACTION_PNAME_MENU_CLOSE_WAIT,
|
||||
aNG2_ACTION_MSG_WIN_OPEN_WAIT,
|
||||
aNG2_ACTION_PNAME_NG,
|
||||
aNG2_ACTION_SEX_SELECT_WAIT,
|
||||
aNG2_ACTION_SEX_SELECT_WAIT2,
|
||||
aNG2_ACTION_SEX_SELECT_AFTER,
|
||||
aNG2_ACTION_STANDUP_START_WAIT,
|
||||
aNG2_ACTION_STANDUP,
|
||||
aNG2_ACTION_MOVE_READY,
|
||||
aNG2_ACTION_MOVE_TO_AISLE,
|
||||
aNG2_ACTION_MOVE_TO_DOOR,
|
||||
aNG2_ACTION_MOVE_TO_DECK,
|
||||
aNG2_ACTION_KEITAI_ON,
|
||||
aNG2_ACTION_KEITAI_TALK,
|
||||
aNG2_ACTION_KEITAI_OFF,
|
||||
aNG2_ACTION_OPEN_DOOR,
|
||||
aNG2_ACTION_RETURN_APPROACH,
|
||||
aNG2_ACTION_LAST_TALK_START_WAIT,
|
||||
aNG2_ACTION_SITDOWN2_START_WAIT,
|
||||
aNG2_ACTION_SITDOWN2,
|
||||
aNG2_ACTION_LAST_TALK_END_WAIT,
|
||||
aNG2_ACTION_SCENE_CHANGE_WAIT,
|
||||
|
||||
aNG2_ACTION_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aNG2_OBJ_LOOK_TYPE_NORMAL,
|
||||
aNG2_OBJ_LOOK_TYPE_TALK,
|
||||
|
||||
aNG2_OBJ_LOOK_TYPE_NUM
|
||||
};
|
||||
|
||||
static void aNG2_actor_ct(ACTOR* actorx, GAME* game);
|
||||
static void aNG2_actor_dt(ACTOR* actorx, GAME* game);
|
||||
static void aNG2_actor_init(ACTOR* actorx, GAME* game);
|
||||
static void aNG2_actor_save(ACTOR* actorx, GAME* game);
|
||||
|
||||
// clang-format off
|
||||
ACTOR_PROFILE Npc_Guide2_Profile = {
|
||||
mAc_PROFILE_NPC_GUIDE2,
|
||||
ACTOR_PART_NPC,
|
||||
ACTOR_STATE_NO_DRAW_WHILE_CULLED | ACTOR_STATE_NO_MOVE_WHILE_CULLED,
|
||||
SP_NPC_GUIDE2,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(NPC_GUIDE2_ACTOR),
|
||||
&aNG2_actor_ct,
|
||||
&aNG2_actor_dt,
|
||||
&aNG2_actor_init,
|
||||
mActor_NONE_PROC1,
|
||||
&aNG2_actor_save,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static void aNG2_actor_move(ACTOR* actorx, GAME* game);
|
||||
static void aNG2_actor_draw(ACTOR* actorx, GAME* game);
|
||||
|
||||
static void aNG2_setupAction(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play, int action);
|
||||
|
||||
static void aNG2_actor_ct(ACTOR* actorx, GAME* game) {
|
||||
static aNPC_ct_data_c ct_data = { &aNG2_actor_move, &aNG2_actor_draw, 0, NULL, NULL, NULL, 0 };
|
||||
NPC_GUIDE2_ACTOR* guide2 = (NPC_GUIDE2_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
PLAYER_ACTOR* player;
|
||||
|
||||
Common_Get(clip).npc_clip->ct_proc(actorx, game, &ct_data);
|
||||
guide2->npc_class.condition_info.hide_flg = FALSE; // show guide2 actor
|
||||
guide2->npc_class.condition_info.demo_flg =
|
||||
aNPC_COND_DEMO_SKIP_ENTRANCE_CHECK | aNPC_COND_DEMO_SKIP_HEAD_LOOKAT | aNPC_COND_DEMO_SKIP_TALK_CHECK |
|
||||
aNPC_COND_DEMO_SKIP_ITEM | aNPC_COND_DEMO_SKIP_FORWARD_CHECK | aNPC_COND_DEMO_SKIP_BGCHECK |
|
||||
aNPC_COND_DEMO_SKIP_OBJ_COL_CHECK | aNPC_COND_DEMO_SKIP_MOVE_Y | aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV |
|
||||
aNPC_COND_DEMO_SKIP_MOVE_RANGE_CHECK;
|
||||
guide2->camera_morph_counter = 40;
|
||||
guide2->obj_look_type = aNG2_OBJ_LOOK_TYPE_NORMAL;
|
||||
guide2->npc_class.eye_y = 30.0f;
|
||||
guide2->camera_move_set_counter = 1;
|
||||
guide2->npc_class.palActorIgnoreTimer = -1;
|
||||
guide2->train_door_actor = Actor_info_fgName_search(&play->actor_info, TRAIN_DOOR, ACTOR_PART_BG);
|
||||
guide2->npc_class.actor_class.shape_info.draw_shadow = TRUE;
|
||||
guide2->npc_class.actor_class.world.position.z = 130.0f;
|
||||
|
||||
/* Put the player into demo wait state */
|
||||
mPlib_request_main_demo_wait_type1(game, 0, NULL);
|
||||
player = GET_PLAYER_ACTOR(play);
|
||||
if (player != NULL) {
|
||||
/* Make the player invisible during the intro train ride */
|
||||
player->actor_class.state_bitfield |= ACTOR_STATE_INVISIBLE;
|
||||
}
|
||||
|
||||
aNG2_setupAction(guide2, play, aNG2_ACTION_ENTER);
|
||||
|
||||
/* Play train noises sfx repeatedly */
|
||||
sAdo_SysLevStart(NA_SE_TRAIN_RIDE);
|
||||
}
|
||||
|
||||
static void aNG2_actor_save(ACTOR* actorx, GAME* game) {
|
||||
Common_Get(clip).npc_clip->save_proc(actorx, game);
|
||||
}
|
||||
|
||||
static void aNG2_actor_dt(ACTOR* actorx, GAME* game) {
|
||||
Common_Get(clip).npc_clip->dt_proc(actorx, game);
|
||||
|
||||
/* Stop train noise sfx */
|
||||
sAdo_SysLevStop(NA_SE_TRAIN_RIDE);
|
||||
}
|
||||
|
||||
static void aNG2_actor_init(ACTOR* actorx, GAME* game) {
|
||||
Common_Get(clip).npc_clip->init_proc(actorx, game);
|
||||
}
|
||||
|
||||
static void aNG2_actor_draw(ACTOR* actorx, GAME* game) {
|
||||
Common_Get(clip).npc_clip->draw_proc(actorx, game);
|
||||
}
|
||||
|
||||
#include "../src/actor/ac_npc_guide2_animation.c_inc"
|
||||
#include "../src/actor/ac_npc_guide2_move.c_inc"
|
||||
@@ -0,0 +1,45 @@
|
||||
typedef struct npc_guide_animation_s {
|
||||
int anim_id;
|
||||
int talk_flag;
|
||||
} aNG2_anime_c;
|
||||
|
||||
static void aNG2_set_animation(NPC_GUIDE2_ACTOR* guide2, int action) {
|
||||
// clang-format off
|
||||
static aNG2_anime_c anime[] = {
|
||||
{ aNPC_ANIM_OPEN_D1, FALSE },
|
||||
{ aNPC_ANIM_WALK1, FALSE },
|
||||
{ aNPC_ANIM_WAIT1, TRUE },
|
||||
{ aNPC_ANIM_WAIT1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, TRUE },
|
||||
{ aNPC_ANIM_STANDUP_D1, FALSE },
|
||||
{ aNPC_ANIM_WAIT1, FALSE },
|
||||
{ aNPC_ANIM_WALK1, FALSE },
|
||||
{ aNPC_ANIM_WALK1, FALSE },
|
||||
{ aNPC_ANIM_TO_DECK_D1, FALSE },
|
||||
{ aNPC_ANIM_KEITAI_ON1, FALSE },
|
||||
{ aNPC_ANIM_KEITAI_TALK1, TRUE },
|
||||
{ aNPC_ANIM_KEITAI_OFF1, FALSE },
|
||||
{ aNPC_ANIM_OPEN_D2, FALSE },
|
||||
{ aNPC_ANIM_WALK1, FALSE },
|
||||
{ aNPC_ANIM_WAIT1, FALSE },
|
||||
{ aNPC_ANIM_WAIT1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, FALSE },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
aNG2_anime_c* anime_info = &anime[action];
|
||||
|
||||
Common_Get(clip).npc_clip->animation_init_proc(&guide2->npc_class.actor_class, anime_info->anim_id,
|
||||
anime_info->talk_flag);
|
||||
}
|
||||
@@ -0,0 +1,823 @@
|
||||
static void aNG2_set_camera(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
static s8 mov_def_cnt[] = { 3, 0 };
|
||||
static f32 obj_look_y_max[] = { 30.0f, 20.0f };
|
||||
static f32 obj_look_y_spd[] = { 0.5f, 2.5f };
|
||||
|
||||
xyz_t eye;
|
||||
xyz_t pos;
|
||||
xyz_t ground;
|
||||
s16 move;
|
||||
f32 moveX;
|
||||
f32 moveY;
|
||||
int obj_look_type = guide2->obj_look_type;
|
||||
s16 cur_angle;
|
||||
f32 inter;
|
||||
f32 sin;
|
||||
f32 ground_y;
|
||||
s16 angle;
|
||||
|
||||
move = guide2->camera_move;
|
||||
guide2->camera_move += 0xE20;
|
||||
angle = move;
|
||||
angle += 0xE20;
|
||||
moveX = cos_s(angle) * 0.1f;
|
||||
angle = move;
|
||||
angle += 0xE20;
|
||||
moveY = sin_s(angle) * guide2->camera_move_range;
|
||||
|
||||
if (guide2->camera_move_y <= 0.0f && moveY >= 0.0f) {
|
||||
s8 cnt = guide2->camera_move_cnt;
|
||||
|
||||
cnt--;
|
||||
if (cnt < 0) {
|
||||
s8 set_cnt = guide2->camera_move_set_counter;
|
||||
|
||||
set_cnt--;
|
||||
if (set_cnt < 0) {
|
||||
set_cnt = ARRAY_COUNT(mov_def_cnt) - 1;
|
||||
}
|
||||
|
||||
guide2->camera_move_set_counter = set_cnt;
|
||||
cnt = mov_def_cnt[set_cnt];
|
||||
guide2->camera_move_range = 0.3f;
|
||||
} else {
|
||||
guide2->camera_move_range *= 0.35f;
|
||||
}
|
||||
|
||||
guide2->camera_move_cnt = cnt;
|
||||
}
|
||||
|
||||
guide2->camera_move_y = moveY;
|
||||
cur_angle = guide2->camera_tilt_cur_angle;
|
||||
chase_angle(&cur_angle, guide2->camera_tilt_goal_angle, guide2->camera_tilt_add);
|
||||
guide2->camera_tilt_cur_angle = cur_angle;
|
||||
sin = sin_s(cur_angle);
|
||||
|
||||
/* Set camera eye pos */
|
||||
eye.x = moveX + sin * 20.0f + 100.0f;
|
||||
eye.y = moveY + sin * -5.0f + 80.0f;
|
||||
eye.z = 400.0f;
|
||||
|
||||
/* Move NPC head to current target */
|
||||
chase_f(&guide2->npc_class.eye_y, obj_look_y_max[obj_look_type], obj_look_y_spd[obj_look_type] * 0.5f);
|
||||
|
||||
/* Set ground pos */
|
||||
ground.x = guide2->npc_class.draw.shadow_pos.x;
|
||||
ground.z = guide2->npc_class.draw.shadow_pos.z;
|
||||
if (obj_look_type == aNG2_OBJ_LOOK_TYPE_TALK) {
|
||||
/* Use the guide2's NPC shadow position for Y */
|
||||
ground_y = guide2->npc_class.draw.shadow_pos.y;
|
||||
} else {
|
||||
/* Get the ground position for Y */
|
||||
ground_y = mCoBG_GetBgY_OnlyCenter_FromWpos2(ground, 0.0f);
|
||||
}
|
||||
|
||||
chase_f(&guide2->obj_dist_ground, ground_y, 0.5f);
|
||||
ground.y = guide2->obj_dist_ground;
|
||||
|
||||
/* Set camera center pos */
|
||||
if (guide2->lock_camera_flag == TRUE) {
|
||||
pos.x = ground.x;
|
||||
pos.y = ground.y + guide2->npc_class.eye_y;
|
||||
pos.z = ground.z;
|
||||
} else if (mDemo_Check(mDemo_TYPE_SPEAK, &guide2->npc_class.actor_class) == TRUE) {
|
||||
int morph_counter = guide2->camera_morph_counter;
|
||||
f32 r;
|
||||
|
||||
guide2->camera_morph_counter = morph_counter - 1;
|
||||
if ((morph_counter - 1) == 0) {
|
||||
guide2->lock_camera_flag = TRUE;
|
||||
}
|
||||
|
||||
r = (40.0f - (f32)(morph_counter - 1)) / 40.0f;
|
||||
inter = cKF_HermitCalc(r, 1.0f, 0.0f, 1.0f, 3.2f, 0.0f);
|
||||
|
||||
pos.x = (ground.x - 90.0f) * inter + 90.0f;
|
||||
pos.y = ((ground.y + guide2->npc_class.eye_y) - 80.0f) * inter + 80.0f;
|
||||
pos.z = (ground.z - 280.0f) * inter + 280.0f;
|
||||
} else {
|
||||
/* Default position */
|
||||
pos.x = 90.0f;
|
||||
pos.y = 80.0f;
|
||||
pos.z = 280.0f;
|
||||
}
|
||||
|
||||
pos.x += moveX;
|
||||
pos.y += moveY;
|
||||
|
||||
Camera2_change_priority(play, 0);
|
||||
Camera2_request_main_lock(play, &pos, &eye, 40.0f, 0, 60.0f, 800.0f, 5);
|
||||
}
|
||||
|
||||
static void aNG2_set_camera_eyes(NPC_GUIDE2_ACTOR* guide2) {
|
||||
if (guide2->camera_eyes_flag == TRUE) {
|
||||
guide2->npc_class.request.head_pos.x = 100.0f;
|
||||
guide2->npc_class.request.head_pos.y = guide2->npc_class.actor_class.eye.position.y;
|
||||
guide2->npc_class.request.head_pos.z = 400.0f;
|
||||
guide2->npc_class.request.head_priority = 3;
|
||||
guide2->npc_class.request.head_type = 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_set_walk_spd(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
guide2->npc_class.movement.max_speed = 1.0f;
|
||||
guide2->npc_class.movement.acceleration = 0.1f;
|
||||
guide2->npc_class.movement.deceleration = 0.2f;
|
||||
}
|
||||
|
||||
static void aNG2_set_walk_spd2(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
guide2->npc_class.movement.max_speed = 1.5f;
|
||||
guide2->npc_class.movement.acceleration = 0.15f;
|
||||
guide2->npc_class.movement.deceleration = 0.3f;
|
||||
}
|
||||
|
||||
static void aNG2_set_stop_spd(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
guide2->npc_class.actor_class.speed = 0.0f;
|
||||
guide2->npc_class.movement.max_speed = 0.0f;
|
||||
guide2->npc_class.movement.acceleration = 0.0f;
|
||||
guide2->npc_class.movement.deceleration = 0.0f;
|
||||
}
|
||||
|
||||
static int aNG2_make_keitai(NPC_GUIDE2_ACTOR* guide2, GAME* game) {
|
||||
int res = FALSE;
|
||||
|
||||
if (guide2->npc_class.right_hand.item_actor_p == NULL) {
|
||||
if (Common_Get(clip).tools_clip != NULL) {
|
||||
ACTOR* keitai = Common_Get(clip).tools_clip->aTOL_birth_proc(
|
||||
TOOL_KEITAI, aTOL_ACTION_TAKEOUT, &guide2->npc_class.actor_class, game, -1, NULL);
|
||||
|
||||
if (keitai != NULL) {
|
||||
guide2->npc_class.right_hand.item_actor_p = keitai;
|
||||
res = TRUE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int aNG2_chg_cond_keitai(NPC_GUIDE2_ACTOR* guide2, int cond) {
|
||||
int res = FALSE;
|
||||
|
||||
if (Common_Get(clip).tools_clip != NULL) {
|
||||
if (Common_Get(clip).tools_clip->aTOL_chg_request_mode_proc(
|
||||
&guide2->npc_class.actor_class, guide2->npc_class.right_hand.item_actor_p, cond) == TRUE) {
|
||||
res = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void aNG2_talk_demo_proc(ACTOR* actorx) {
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, actorx) == TRUE) {
|
||||
Common_Get(clip).npc_clip->talk_demo_proc(actorx);
|
||||
}
|
||||
}
|
||||
|
||||
static u8* aNG2_getP_other_pl_name(void) {
|
||||
Private_c* priv;
|
||||
u32 player_no;
|
||||
int i;
|
||||
|
||||
player_no = Common_Get(player_no);
|
||||
priv = Save_Get(private_data) + player_no;
|
||||
|
||||
/* Search for players before this one's player no */
|
||||
for (i = player_no; i != 0; i--) {
|
||||
priv--;
|
||||
if (mPr_NullCheckPersonalID(&priv->player_ID) != TRUE) {
|
||||
return priv->player_ID.player_name;
|
||||
}
|
||||
}
|
||||
|
||||
priv = Save_Get(private_data) + player_no;
|
||||
/* Search for players after this one's player no */
|
||||
for (i = (PLAYER_NUM - 1) - player_no; i != 0; i--) {
|
||||
priv++;
|
||||
if (mPr_NullCheckPersonalID(&priv->player_ID) != TRUE) {
|
||||
return priv->player_ID.player_name;
|
||||
}
|
||||
}
|
||||
|
||||
/* No other players to reference */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int aNG2_check_pname(void) {
|
||||
int ok = TRUE;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PLAYER_NUM; i++) {
|
||||
Private_c* priv = Save_GetPointer(private_data[i]);
|
||||
|
||||
if (i != Common_Get(player_no)) {
|
||||
if (mem_cmp(Now_Private->player_ID.player_name, priv->player_ID.player_name, PLAYER_NAME_LEN) == TRUE) {
|
||||
/* Another player has the same name in this town */
|
||||
ok = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static void aNG2_check_talk_msg_no(NPC_GUIDE2_ACTOR* guide2) {
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, &guide2->npc_class.actor_class) == TRUE) {
|
||||
int msg_no = mMsg_GET_MSG_NUM();
|
||||
int flags;
|
||||
|
||||
switch (msg_no) {
|
||||
case 0x2AC9:
|
||||
flags = (1 << 3);
|
||||
break;
|
||||
case 0x2ADB:
|
||||
flags = (1 << 2);
|
||||
break;
|
||||
case 0x2ADD:
|
||||
flags = (1 << 1);
|
||||
break;
|
||||
case 0x2AD3:
|
||||
flags = (1 << 0);
|
||||
break;
|
||||
default:
|
||||
flags = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
guide2->answer_flags |= flags;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_set_pl_face_type(NPC_GUIDE2_ACTOR* guide2) {
|
||||
static int face_type_table[mPr_SEX_NUM][mPr_FACE_TYPE_NUM] = {
|
||||
/* Male faces */
|
||||
{
|
||||
mPr_FACE_TYPE5,
|
||||
mPr_FACE_TYPE6,
|
||||
mPr_FACE_TYPE1,
|
||||
mPr_FACE_TYPE4,
|
||||
mPr_FACE_TYPE0,
|
||||
mPr_FACE_TYPE2,
|
||||
mPr_FACE_TYPE7,
|
||||
mPr_FACE_TYPE3,
|
||||
},
|
||||
/* Female faces */
|
||||
{
|
||||
mPr_FACE_TYPE0,
|
||||
mPr_FACE_TYPE5,
|
||||
mPr_FACE_TYPE2,
|
||||
mPr_FACE_TYPE6,
|
||||
mPr_FACE_TYPE4,
|
||||
mPr_FACE_TYPE7,
|
||||
mPr_FACE_TYPE3,
|
||||
mPr_FACE_TYPE1,
|
||||
},
|
||||
};
|
||||
|
||||
int answer_flags = guide2->answer_flags;
|
||||
int face_type;
|
||||
|
||||
if ((answer_flags & 1) == 0) {
|
||||
/* Select a random face for the player */
|
||||
face_type = RANDOM(mPr_FACE_TYPE_NUM);
|
||||
} else {
|
||||
/* Select a face based on choices */
|
||||
face_type = face_type_table[Now_Private->gender][answer_flags >> 1];
|
||||
}
|
||||
|
||||
Now_Private->face = face_type;
|
||||
}
|
||||
|
||||
static void aNG2_calc_body_angl(NPC_GUIDE2_ACTOR* guide2, f32 pos_x, f32 pos_z) {
|
||||
f32 dX = pos_x - guide2->npc_class.actor_class.world.position.x;
|
||||
f32 dZ = pos_z - guide2->npc_class.actor_class.world.position.z;
|
||||
s16 angl = atans_table(dZ, dX);
|
||||
|
||||
chase_angle(&guide2->npc_class.actor_class.shape_info.rotation.y, angl, DEG2SHORT_ANGLE2(11.25f));
|
||||
guide2->npc_class.actor_class.world.angle.y = guide2->npc_class.actor_class.shape_info.rotation.y;
|
||||
}
|
||||
|
||||
static void aNG2_set_default_talk_info(void) {
|
||||
mDemo_Set_camera(CAMERA2_PROCESS_NUM);
|
||||
mDemo_Set_talk_change_player(FALSE);
|
||||
mDemo_Set_use_zoom_sound(TRUE);
|
||||
}
|
||||
|
||||
static void aNG2_enter(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
if (guide2->npc_class.draw.main_animation_state == cKF_STATE_STOPPED) {
|
||||
guide2->camera_eyes_flag = TRUE;
|
||||
aNG2_setupAction(guide2, play, aNG2_ACTION_APPROACH);
|
||||
} else if (cKF_FrameControl_passCheck_now(&guide2->npc_class.draw.main_animation.keyframe.frame_control, 20.0f) ==
|
||||
TRUE) {
|
||||
TRAINDOOR_ACTOR* train_door = (TRAINDOOR_ACTOR*)guide2->train_door_actor;
|
||||
|
||||
train_door->open_flag = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_approach(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
if (guide2->npc_class.actor_class.world.position.z >= 290.0f) {
|
||||
guide2->npc_class.actor_class.world.position.z = 290.0f;
|
||||
aNG2_setupAction(guide2, play, aNG2_ACTION_TALK_START_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_set_talk_info_talk_start_wait(ACTOR* actorx) {
|
||||
mMsg_SET_FREE_STR(mMsg_FREE_STR0, aNG2_getP_other_pl_name(), PLAYER_NAME_LEN);
|
||||
mDemo_Set_msg_num(0x2AD5);
|
||||
aNG2_set_default_talk_info();
|
||||
((NPC_GUIDE2_ACTOR*)actorx)->obj_look_type = aNG2_OBJ_LOOK_TYPE_TALK;
|
||||
}
|
||||
|
||||
static void aNG2_talk_start_wait(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
ACTOR* actorx = (ACTOR*)guide2;
|
||||
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, actorx) == TRUE) {
|
||||
if (mDemo_Check_ListenAble() == FALSE &&
|
||||
chase_angle(&actorx->shape_info.rotation.y, actorx->player_angle_y, 0x400) == TRUE) {
|
||||
guide2->camera_eyes_flag = FALSE;
|
||||
aNG2_setupAction(guide2, play, aNG2_ACTION_WAIT_PERMISSION);
|
||||
mDemo_Set_ListenAble();
|
||||
}
|
||||
} else {
|
||||
mDemo_Request(mDemo_TYPE_SPEAK, actorx, &aNG2_set_talk_info_talk_start_wait);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_wait_permission(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
if (mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) {
|
||||
aNG2_setupAction(guide2, play, aNG2_ACTION_SITDOWN);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_sitdown(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
guide2->npc_class.actor_class.world.position.x = 100.0f;
|
||||
guide2->npc_class.actor_class.world.position.z = 280.0f;
|
||||
guide2->npc_class.actor_class.shape_info.rotation.y = 0;
|
||||
|
||||
/* Wait for the sit animation to finish before continuing */
|
||||
if (guide2->npc_class.draw.main_animation_state == cKF_STATE_STOPPED) {
|
||||
mMsg_UNSET_LOCKCONTINUE();
|
||||
guide2->next_action = aNG2_ACTION_PNAME_MENU_OPEN_WAIT;
|
||||
aNG2_setupAction(guide2, play, aNG2_ACTION_SDON_AND_PB_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_sdon_and_pb_wait(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
u16 order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
|
||||
if (order != 0 && mMsg_CHECK_MAINNORMALCONTINUE()) {
|
||||
aNG2_setupAction(guide2, play, guide2->next_action);
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_pname_menu_open_wait(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
if (mMsg_CHECK_MAIN_WAIT() == TRUE) {
|
||||
aNG2_setupAction(guide2, play, 7);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_pname_menu_close_wait(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
if (play->submenu.open_flag == FALSE) {
|
||||
aNG2_setupAction(guide2, play, 8);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_msg_win_open_wait(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
static int msg_no[] = { 0x2ACA, 0x2AE2 };
|
||||
static int next_act_idx[] = { 10, 9 };
|
||||
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
|
||||
|
||||
if (mMsg_Check_not_series_main_wait(msg_p) == TRUE) {
|
||||
int idx = 0;
|
||||
|
||||
mMsg_Unset_LockContinue(msg_p);
|
||||
|
||||
/* Check if the player's name already exists in town */
|
||||
if (aNG2_check_pname() == FALSE) {
|
||||
idx = 1;
|
||||
}
|
||||
|
||||
mMsg_Set_continue_msg_num(msg_p, msg_no[idx]);
|
||||
mMsg_Set_ForceNext(msg_p);
|
||||
aNG2_setupAction(guide2, play, next_act_idx[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_sex_select_wait(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
if (mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) {
|
||||
switch (mChoice_GET_CHOSENUM()) {
|
||||
case mChoice_CHOICE0: // male
|
||||
case mChoice_CHOICE1: // female
|
||||
aNG2_setupAction(guide2, play, aNG2_ACTION_SEX_SELECT_WAIT2);
|
||||
break;
|
||||
case mChoice_CHOICE2: // 'That's not right'
|
||||
guide2->next_action = aNG2_ACTION_PNAME_MENU_OPEN_WAIT;
|
||||
aNG2_setupAction(guide2, play, aNG2_ACTION_SDON_AND_PB_WAIT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_sex_select_wait2(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
static int next_act_idx[] = { aNG2_ACTION_STANDUP_START_WAIT, aNG2_ACTION_SEX_SELECT_AFTER };
|
||||
int order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
|
||||
if (order != 0) {
|
||||
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
|
||||
|
||||
if (mMsg_Check_MainNormalContinue(msg_p) == TRUE) {
|
||||
int idx = -1;
|
||||
|
||||
switch (mChoice_GET_CHOSENUM()) {
|
||||
case mChoice_CHOICE0: // male
|
||||
switch (order) {
|
||||
case 1: // That's right
|
||||
Now_Private->gender = mPr_SEX_MALE;
|
||||
break;
|
||||
case 2: // I'm not a boy
|
||||
Now_Private->gender = mPr_SEX_FEMALE;
|
||||
break;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
mMsg_Set_continue_msg_num(msg_p, 0x2AD9);
|
||||
mMsg_Set_ForceNext(msg_p);
|
||||
break;
|
||||
case mChoice_CHOICE1: // female
|
||||
switch (order) {
|
||||
case 1: // That's right
|
||||
Now_Private->gender = mPr_SEX_FEMALE;
|
||||
break;
|
||||
case 2: // I'm not a girl
|
||||
Now_Private->gender = mPr_SEX_MALE;
|
||||
break;
|
||||
}
|
||||
idx = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (idx != -1) {
|
||||
aNG2_setupAction(guide2, play, next_act_idx[idx]);
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_sex_select_after(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
|
||||
u16 order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
|
||||
if (order != 0 && mMsg_Check_MainNormalContinue(msg_p)) {
|
||||
aNG2_setupAction(guide2, play, aNG2_ACTION_STANDUP_START_WAIT);
|
||||
mMsg_Set_continue_msg_num(msg_p, 0x2AD9);
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_standup_start_wait(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
/* Wait for guide2 to stop speaking to us */
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, &guide2->npc_class.actor_class) == FALSE) {
|
||||
guide2->obj_look_type = aNG2_OBJ_LOOK_TYPE_NORMAL;
|
||||
aNG2_setupAction(guide2, play, aNG2_ACTION_STANDUP);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_standup(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
/* Wait for animation to finish */
|
||||
if (guide2->npc_class.draw.main_animation_state == cKF_STATE_STOPPED) {
|
||||
aNG2_setupAction(guide2, play, guide2->next_action);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_move_ready(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
guide2->npc_class.actor_class.world.position.x = 100.0f;
|
||||
guide2->npc_class.actor_class.world.position.z = 300.0f;
|
||||
aNG2_setupAction(guide2, play, aNG2_ACTION_MOVE_TO_AISLE);
|
||||
}
|
||||
|
||||
static void aNG2_move_to_aisle(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
aNG2_calc_body_angl(guide2, 140.0f, 290.0f);
|
||||
if (guide2->npc_class.actor_class.world.position.x > 140.0f) {
|
||||
aNG2_setupAction(guide2, play, aNG2_ACTION_MOVE_TO_DOOR);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_move_to_door(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
aNG2_calc_body_angl(guide2, 140.0f, 130.0f);
|
||||
/* Check if we reached the door */
|
||||
if (guide2->npc_class.actor_class.world.position.z < 130.0f) {
|
||||
aNG2_setupAction(guide2, play, aNG2_ACTION_MOVE_TO_DECK);
|
||||
}
|
||||
|
||||
/* Check if we should start rotating */
|
||||
if (guide2->npc_class.draw.shadow_pos.z < 140.0f) {
|
||||
guide2->camera_tilt_goal_angle = DEG2SHORT_ANGLE2(90.0f);
|
||||
guide2->camera_tilt_add = DEG2SHORT_ANGLE2(2.8125f);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_move_to_deck(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
if (cKF_FrameControl_passCheck_now(&guide2->npc_class.draw.main_animation.keyframe.frame_control, 9.0f) == TRUE) {
|
||||
TRAINDOOR_ACTOR* train_door = (TRAINDOOR_ACTOR*)guide2->train_door_actor;
|
||||
|
||||
train_door->open_flag = TRUE;
|
||||
}
|
||||
|
||||
/* Reuse standup state to wait for animation to finish */
|
||||
aNG2_standup(guide2, play);
|
||||
}
|
||||
|
||||
static void aNG2_set_talk_info_keitai_on(ACTOR* actorx) {
|
||||
mDemo_Set_msg_num(0x2ADE);
|
||||
aNG2_set_default_talk_info();
|
||||
}
|
||||
|
||||
static void aNG2_keitai_on(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
static f32 anmSpd[] = { 0.0f, 0.5f };
|
||||
int idx = aNG2_make_keitai(guide2, &play->game);
|
||||
|
||||
guide2->npc_class.draw.main_animation.keyframe.frame_control.speed = anmSpd[idx];
|
||||
if (idx != 0) {
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, (ACTOR*)guide2) == TRUE) {
|
||||
if (mDemo_Check_ListenAble() == FALSE) {
|
||||
mDemo_Set_ListenAble();
|
||||
}
|
||||
} else {
|
||||
/* Request to start speaking */
|
||||
mDemo_Request(mDemo_TYPE_SPEAK, (ACTOR*)guide2, &aNG2_set_talk_info_keitai_on);
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for animation to finish */
|
||||
if (guide2->npc_class.draw.main_animation_state == cKF_STATE_STOPPED) {
|
||||
aNG2_setupAction(guide2, play, aNG2_ACTION_KEITAI_TALK);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_keitai_talk(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, &guide2->npc_class.actor_class) == FALSE) {
|
||||
aNG2_setupAction(guide2, play, aNG2_ACTION_KEITAI_OFF);
|
||||
} else if (guide2->npc_class.draw.main_animation_state == cKF_STATE_STOPPED) {
|
||||
Common_Get(clip).npc_clip->animation_init_proc(&guide2->npc_class.actor_class, aNPC_ANIM_KEITAI_TALK2, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_open_door(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
chase_angle(&guide2->npc_class.actor_class.shape_info.rotation.y, DEG2SHORT_ANGLE2(-180.0f),
|
||||
DEG2SHORT_ANGLE2(0.703125f));
|
||||
if (cKF_FrameControl_passCheck_now(&guide2->npc_class.draw.main_animation.keyframe.frame_control, 22.0f) == TRUE) {
|
||||
TRAINDOOR_ACTOR* train_door = (TRAINDOOR_ACTOR*)guide2->train_door_actor;
|
||||
|
||||
train_door->open_flag = TRUE;
|
||||
if (guide2->npc_class.draw.shadow_pos.z < 140.0f) {
|
||||
guide2->camera_tilt_goal_angle = 0;
|
||||
guide2->camera_tilt_add = 0x600;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reuse standup state to wait for animation to finish */
|
||||
aNG2_standup(guide2, play);
|
||||
}
|
||||
|
||||
static void aNG2_return_approach(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
guide2->npc_class.actor_class.world.position.x = 140.0f;
|
||||
guide2->npc_class.actor_class.world.angle.y = 0;
|
||||
guide2->npc_class.actor_class.shape_info.rotation.y = 0;
|
||||
if (guide2->npc_class.actor_class.world.position.z > 290.0f) {
|
||||
aNG2_setupAction(guide2, play, aNG2_ACTION_LAST_TALK_START_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_set_talk_info_last_talk_start_wait(ACTOR* actorx) {
|
||||
mDemo_Set_msg_num(0x2AD1);
|
||||
aNG2_set_default_talk_info();
|
||||
((NPC_GUIDE2_ACTOR*)actorx)->obj_look_type = aNG2_OBJ_LOOK_TYPE_TALK;
|
||||
}
|
||||
|
||||
static void aNG2_last_talk_start_wait(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
ACTOR* actorx = (ACTOR*)guide2;
|
||||
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, actorx) == TRUE) {
|
||||
if (mDemo_Check_ListenAble() == FALSE &&
|
||||
chase_angle(&actorx->shape_info.rotation.y, actorx->player_angle_y, 0x400) == TRUE) {
|
||||
guide2->camera_eyes_flag = FALSE;
|
||||
aNG2_setupAction(guide2, play, aNG2_ACTION_SITDOWN2_START_WAIT);
|
||||
mDemo_Set_ListenAble();
|
||||
}
|
||||
} else {
|
||||
mDemo_Request(mDemo_TYPE_SPEAK, actorx, &aNG2_set_talk_info_last_talk_start_wait);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_sitdown2_start_wait(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
u16 order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
|
||||
if (order != 0) {
|
||||
aNG2_setupAction(guide2, play, aNG2_ACTION_SITDOWN2);
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNG2_sitdown2(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
guide2->npc_class.actor_class.world.position.x = 100.0f;
|
||||
guide2->npc_class.actor_class.world.position.z = 280.0f;
|
||||
guide2->npc_class.actor_class.shape_info.rotation.y = 0;
|
||||
|
||||
/* Wait for animation to finish */
|
||||
aNG2_standup(guide2, play);
|
||||
}
|
||||
|
||||
static void aNG2_last_talk_end_wait(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, &guide2->npc_class.actor_class) == FALSE) {
|
||||
aNG2_setupAction(guide2, play, aNG2_ACTION_SCENE_CHANGE_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
/* Init procs */
|
||||
|
||||
static void aNG2_sitdown_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
mMsg_SET_LOCKCONTINUE();
|
||||
}
|
||||
|
||||
static void aNG2_pname_menu_open_wait_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
|
||||
|
||||
mMsg_Set_LockContinue(msg_p);
|
||||
mMsg_request_main_disappear_wait_type1(msg_p);
|
||||
}
|
||||
|
||||
static void aNG2_pname_menu_close_wait_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
Submenu* submenu = &play->submenu;
|
||||
|
||||
mSM_open_submenu(submenu, mSM_OVL_LEDIT, mLE_TYPE_PLAYER_NAME, 0);
|
||||
}
|
||||
|
||||
static void aNG2_msg_win_open_wait_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
mMsg_REQUEST_MAIN_APPEAR_WAIT_TYPE1();
|
||||
}
|
||||
|
||||
static void aNG2_pname_ng_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
guide2->next_action = 6;
|
||||
}
|
||||
|
||||
static void aNG2_standup_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
guide2->next_action = aNG2_ACTION_MOVE_READY;
|
||||
}
|
||||
|
||||
static void aNG2_move_ready_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
guide2->npc_class.draw.main_animation.keyframe.morph_counter = 0.0f;
|
||||
}
|
||||
|
||||
static void aNG2_move_to_aisle_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
aNG2_set_walk_spd2(guide2, play);
|
||||
}
|
||||
|
||||
static void aNG2_move_to_deck_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
aNG2_set_stop_spd(guide2, play);
|
||||
guide2->npc_class.actor_class.world.position.x = 140.0f;
|
||||
guide2->npc_class.actor_class.world.position.z = 130.0f;
|
||||
guide2->next_action = aNG2_ACTION_KEITAI_ON;
|
||||
}
|
||||
|
||||
static void aNG2_keitai_off_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
aNG2_chg_cond_keitai(guide2, aTOL_ACTION_PUTAWAY);
|
||||
guide2->next_action = aNG2_ACTION_OPEN_DOOR;
|
||||
}
|
||||
|
||||
static void aNG2_open_door_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
guide2->next_action = aNG2_ACTION_RETURN_APPROACH;
|
||||
}
|
||||
|
||||
static void aNG2_return_approach_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
guide2->camera_eyes_flag = TRUE;
|
||||
aNG2_set_walk_spd2(guide2, play);
|
||||
guide2->npc_class.draw.main_animation.keyframe.morph_counter = 0.0f;
|
||||
}
|
||||
|
||||
static void aNG2_sitdown2_start_wait_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
}
|
||||
|
||||
static void aNG2_sitdown2_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
guide2->npc_class.draw.main_animation.keyframe.morph_counter = 0.0f;
|
||||
guide2->next_action = aNG2_ACTION_LAST_TALK_END_WAIT;
|
||||
}
|
||||
|
||||
static void aNG2_last_talk_end_wait_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
aNG2_chg_cond_keitai(guide2, aTOL_ACTION_DESTRUCT);
|
||||
guide2->npc_class.right_hand.item_actor_p = NULL;
|
||||
}
|
||||
|
||||
static void aNG2_scene_change_wait_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
|
||||
/* Init next scene transition */
|
||||
goto_next_scene(play, 0, 1);
|
||||
play->fb_wipe_type = 3;
|
||||
Common_Get(transition).wipe_type = 4;
|
||||
|
||||
mEv_SetFirstJob();
|
||||
mEv_SetFirstIntro();
|
||||
mEnv_DecideWeather_NormalGameStart();
|
||||
aNG2_set_pl_face_type(guide2);
|
||||
mPr_SetNowPrivateCloth();
|
||||
Common_Set(submenu_disabled, TRUE);
|
||||
mBGMPsComp_make_ps_wipe(0x41C2);
|
||||
mBGMPsComp_scene_mode(18);
|
||||
}
|
||||
|
||||
typedef void (*aNG2_INIT_PROC)(NPC_GUIDE2_ACTOR*, GAME_PLAY*);
|
||||
|
||||
static void aNG2_init_proc(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play, int action) {
|
||||
static aNG2_INIT_PROC init_proc[] = {
|
||||
(aNG2_INIT_PROC)&none_proc1,
|
||||
&aNG2_set_walk_spd,
|
||||
&aNG2_set_stop_spd,
|
||||
(aNG2_INIT_PROC)&none_proc1,
|
||||
&aNG2_sitdown_init,
|
||||
(aNG2_INIT_PROC)&none_proc1,
|
||||
&aNG2_pname_menu_open_wait_init,
|
||||
&aNG2_pname_menu_close_wait_init,
|
||||
&aNG2_msg_win_open_wait_init,
|
||||
&aNG2_pname_ng_init,
|
||||
(aNG2_INIT_PROC)&none_proc1,
|
||||
(aNG2_INIT_PROC)&none_proc1,
|
||||
(aNG2_INIT_PROC)&none_proc1,
|
||||
(aNG2_INIT_PROC)&none_proc1,
|
||||
&aNG2_standup_init,
|
||||
&aNG2_move_ready_init,
|
||||
&aNG2_move_to_aisle_init,
|
||||
(aNG2_INIT_PROC)&none_proc1,
|
||||
&aNG2_move_to_deck_init,
|
||||
(aNG2_INIT_PROC)&none_proc1,
|
||||
(aNG2_INIT_PROC)&none_proc1,
|
||||
&aNG2_keitai_off_init,
|
||||
&aNG2_open_door_init,
|
||||
&aNG2_return_approach_init,
|
||||
&aNG2_set_stop_spd,
|
||||
&aNG2_sitdown2_start_wait_init,
|
||||
&aNG2_sitdown2_init,
|
||||
&aNG2_last_talk_end_wait_init,
|
||||
&aNG2_scene_change_wait_init,
|
||||
};
|
||||
|
||||
(*init_proc[action])(guide2, play);
|
||||
}
|
||||
|
||||
static void aNG2_setupAction(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play, int action) {
|
||||
static aNG2_PROC process[] = {
|
||||
&aNG2_enter,
|
||||
&aNG2_approach,
|
||||
&aNG2_talk_start_wait,
|
||||
&aNG2_wait_permission,
|
||||
&aNG2_sitdown,
|
||||
&aNG2_sdon_and_pb_wait,
|
||||
&aNG2_pname_menu_open_wait,
|
||||
&aNG2_pname_menu_close_wait,
|
||||
&aNG2_msg_win_open_wait,
|
||||
&aNG2_sdon_and_pb_wait,
|
||||
&aNG2_sex_select_wait,
|
||||
&aNG2_sex_select_wait2,
|
||||
&aNG2_sex_select_after,
|
||||
&aNG2_standup_start_wait,
|
||||
&aNG2_standup,
|
||||
&aNG2_move_ready,
|
||||
&aNG2_move_to_aisle,
|
||||
&aNG2_move_to_door,
|
||||
&aNG2_move_to_deck,
|
||||
&aNG2_keitai_on,
|
||||
&aNG2_keitai_talk,
|
||||
&aNG2_standup,
|
||||
&aNG2_open_door,
|
||||
&aNG2_return_approach,
|
||||
&aNG2_last_talk_start_wait,
|
||||
&aNG2_sitdown2_start_wait,
|
||||
&aNG2_sitdown2,
|
||||
&aNG2_last_talk_end_wait,
|
||||
(aNG2_PROC)&none_proc1,
|
||||
};
|
||||
|
||||
guide2->action = action;
|
||||
guide2->proc = process[action];
|
||||
aNG2_set_animation(guide2, action);
|
||||
aNG2_init_proc(guide2, play, action);
|
||||
}
|
||||
|
||||
static void aNG2_actor_move(ACTOR* actorx, GAME* game) {
|
||||
NPC_GUIDE2_ACTOR* guide2 = (NPC_GUIDE2_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
|
||||
Common_Get(clip).npc_clip->move_before_proc(actorx, game);
|
||||
aNG2_talk_demo_proc(actorx);
|
||||
aNG2_check_talk_msg_no(guide2);
|
||||
(*guide2->proc)(guide2, play);
|
||||
Common_Get(clip).npc_clip->move_after_proc(actorx, game);
|
||||
aNG2_set_camera(guide2, play);
|
||||
aNG2_set_camera_eyes(guide2);
|
||||
mSC_change_player_freeze(play);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
typedef struct npc_guide_animation_s {
|
||||
int anim_id;
|
||||
int talk_flag;
|
||||
} aNGD_anime_c;
|
||||
|
||||
static void aNGD_set_animation(NPC_GUIDE_ACTOR* guide, int action) {
|
||||
// clang-format off
|
||||
static aNGD_anime_c anime[] = {
|
||||
{ aNPC_ANIM_OPEN_D1, FALSE },
|
||||
{ aNPC_ANIM_WALK1, FALSE },
|
||||
{ aNPC_ANIM_WAIT1, TRUE },
|
||||
{ aNPC_ANIM_WAIT1, TRUE },
|
||||
{ aNPC_ANIM_WAIT1, TRUE },
|
||||
{ aNPC_ANIM_WAIT1, TRUE },
|
||||
{ aNPC_ANIM_WAIT1, TRUE },
|
||||
{ aNPC_ANIM_WAIT1, TRUE },
|
||||
{ aNPC_ANIM_WAIT1, TRUE },
|
||||
{ aNPC_ANIM_WAIT1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, TRUE },
|
||||
{ aNPC_ANIM_STANDUP_D1, FALSE },
|
||||
{ aNPC_ANIM_WAIT1, FALSE },
|
||||
{ aNPC_ANIM_WALK1, FALSE },
|
||||
{ aNPC_ANIM_WALK1, FALSE },
|
||||
{ aNPC_ANIM_TO_DECK_D1, FALSE },
|
||||
{ aNPC_ANIM_KEITAI_ON1, FALSE },
|
||||
{ aNPC_ANIM_KEITAI_TALK1, TRUE },
|
||||
{ aNPC_ANIM_KEITAI_OFF1, FALSE },
|
||||
{ aNPC_ANIM_OPEN_D2, FALSE },
|
||||
{ aNPC_ANIM_WALK1, FALSE },
|
||||
{ aNPC_ANIM_WAIT1, FALSE },
|
||||
{ aNPC_ANIM_WAIT1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, TRUE },
|
||||
{ aNPC_ANIM_SITDOWN_WAIT_D1, FALSE },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
aNGD_anime_c* anime_info = &anime[action];
|
||||
int anim_id = anime_info->anim_id;
|
||||
int talk_flag = anime_info->talk_flag;
|
||||
|
||||
if ((action == aNGD_ACTION_SDON_AND_PB_WAIT || action == aNGD_ACTION_MSG_WIN_OPEN_WAIT ||
|
||||
action == aNGD_ACTION_CONFIRM_INPUT_DATA) &&
|
||||
guide->next_action != aNGD_ACTION_TIME_MENU_OPEN_WAIT &&
|
||||
guide->next_action != aNGD_ACTION_TIME_MENU_CLOSE_WAIT) {
|
||||
anim_id = aNPC_ANIM_SITDOWN_WAIT_D1;
|
||||
talk_flag = TRUE;
|
||||
}
|
||||
|
||||
Common_Get(clip).npc_clip->animation_init_proc(&guide->npc_class.actor_class, anim_id, talk_flag);
|
||||
}
|
||||
@@ -0,0 +1,908 @@
|
||||
static void aNGD_set_camera(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
static s8 mov_def_cnt[] = { 3, 0 };
|
||||
static f32 obj_look_y_max[] = { 30.0f, 20.0f };
|
||||
static f32 obj_look_y_spd[] = { 0.5f, 2.5f };
|
||||
|
||||
xyz_t eye;
|
||||
xyz_t pos;
|
||||
xyz_t ground;
|
||||
s16 move;
|
||||
f32 moveX;
|
||||
f32 moveY;
|
||||
int obj_look_type = guide->obj_look_type;
|
||||
s16 cur_angle;
|
||||
f32 inter;
|
||||
f32 sin;
|
||||
f32 ground_y;
|
||||
s16 angle;
|
||||
|
||||
move = guide->camera_move;
|
||||
guide->camera_move += 0xE20;
|
||||
angle = move;
|
||||
angle += 0xE20;
|
||||
moveX = cos_s(angle) * 0.1f;
|
||||
angle = move;
|
||||
angle += 0xE20;
|
||||
moveY = sin_s(angle) * guide->camera_move_range;
|
||||
|
||||
if (guide->camera_move_y <= 0.0f && moveY >= 0.0f) {
|
||||
s8 cnt = guide->camera_move_cnt;
|
||||
|
||||
cnt--;
|
||||
if (cnt < 0) {
|
||||
s8 set_cnt = guide->camera_move_set_counter;
|
||||
|
||||
set_cnt--;
|
||||
if (set_cnt < 0) {
|
||||
set_cnt = ARRAY_COUNT(mov_def_cnt) - 1;
|
||||
}
|
||||
|
||||
guide->camera_move_set_counter = set_cnt;
|
||||
cnt = mov_def_cnt[set_cnt];
|
||||
guide->camera_move_range = 0.3f;
|
||||
} else {
|
||||
guide->camera_move_range *= 0.35f;
|
||||
}
|
||||
|
||||
guide->camera_move_cnt = cnt;
|
||||
}
|
||||
|
||||
guide->camera_move_y = moveY;
|
||||
cur_angle = guide->camera_tilt_cur_angle;
|
||||
chase_angle(&cur_angle, guide->camera_tilt_goal_angle, guide->camera_tilt_add);
|
||||
guide->camera_tilt_cur_angle = cur_angle;
|
||||
sin = sin_s(cur_angle);
|
||||
|
||||
/* Set camera eye pos */
|
||||
eye.x = moveX + sin * 20.0f + 100.0f;
|
||||
eye.y = moveY + sin * -5.0f + 80.0f;
|
||||
eye.z = 400.0f;
|
||||
|
||||
/* Move NPC head to current target */
|
||||
chase_f(&guide->npc_class.eye_y, obj_look_y_max[obj_look_type], obj_look_y_spd[obj_look_type] * 0.5f);
|
||||
|
||||
/* Set ground pos */
|
||||
ground.x = guide->npc_class.draw.shadow_pos.x;
|
||||
ground.z = guide->npc_class.draw.shadow_pos.z;
|
||||
if (obj_look_type == aNGD_OBJ_LOOK_TYPE_TALK) {
|
||||
/* Use the guide's NPC shadow position for Y */
|
||||
ground_y = guide->npc_class.draw.shadow_pos.y;
|
||||
} else {
|
||||
/* Get the ground position for Y */
|
||||
ground_y = mCoBG_GetBgY_OnlyCenter_FromWpos2(ground, 0.0f);
|
||||
}
|
||||
|
||||
chase_f(&guide->obj_dist_ground, ground_y, 0.5f);
|
||||
ground.y = guide->obj_dist_ground;
|
||||
|
||||
/* Set camera center pos */
|
||||
if (guide->lock_camera_flag == TRUE) {
|
||||
pos.x = ground.x;
|
||||
pos.y = ground.y + guide->npc_class.eye_y;
|
||||
pos.z = ground.z;
|
||||
} else if (mDemo_Check(mDemo_TYPE_SPEAK, &guide->npc_class.actor_class) == TRUE) {
|
||||
int morph_counter = guide->camera_morph_counter;
|
||||
f32 r;
|
||||
|
||||
guide->camera_morph_counter = morph_counter - 1;
|
||||
if ((morph_counter - 1) == 0) {
|
||||
guide->lock_camera_flag = TRUE;
|
||||
}
|
||||
|
||||
r = (40.0f - (f32)(morph_counter - 1)) / 40.0f;
|
||||
inter = cKF_HermitCalc(r, 1.0f, 0.0f, 1.0f, 3.2f, 0.0f);
|
||||
|
||||
pos.x = (ground.x - 90.0f) * inter + 90.0f;
|
||||
pos.y = ((ground.y + guide->npc_class.eye_y) - 80.0f) * inter + 80.0f;
|
||||
pos.z = (ground.z - 280.0f) * inter + 280.0f;
|
||||
} else {
|
||||
/* Default position */
|
||||
pos.x = 90.0f;
|
||||
pos.y = 80.0f;
|
||||
pos.z = 280.0f;
|
||||
}
|
||||
|
||||
pos.x += moveX;
|
||||
pos.y += moveY;
|
||||
|
||||
Camera2_change_priority(play, 0);
|
||||
Camera2_request_main_lock(play, &pos, &eye, 40.0f, 0, 60.0f, 800.0f, 5);
|
||||
}
|
||||
|
||||
static void aNGD_set_camera_eyes(NPC_GUIDE_ACTOR* guide) {
|
||||
if (guide->camera_eyes_flag == TRUE) {
|
||||
guide->npc_class.request.head_pos.x = 100.0f;
|
||||
guide->npc_class.request.head_pos.y = guide->npc_class.actor_class.eye.position.y;
|
||||
guide->npc_class.request.head_pos.z = 400.0f;
|
||||
guide->npc_class.request.head_priority = 3;
|
||||
guide->npc_class.request.head_type = 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_set_walk_spd(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
guide->npc_class.movement.max_speed = 1.0f;
|
||||
guide->npc_class.movement.acceleration = 0.1f;
|
||||
guide->npc_class.movement.deceleration = 0.2f;
|
||||
}
|
||||
|
||||
static void aNGD_set_walk_spd2(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
guide->npc_class.movement.max_speed = 1.5f;
|
||||
guide->npc_class.movement.acceleration = 0.15f;
|
||||
guide->npc_class.movement.deceleration = 0.3f;
|
||||
}
|
||||
|
||||
static void aNGD_set_stop_spd(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
guide->npc_class.actor_class.speed = 0.0f;
|
||||
guide->npc_class.movement.max_speed = 0.0f;
|
||||
guide->npc_class.movement.acceleration = 0.0f;
|
||||
guide->npc_class.movement.deceleration = 0.0f;
|
||||
}
|
||||
|
||||
static int aNGD_make_keitai(NPC_GUIDE_ACTOR* guide, GAME* game) {
|
||||
int res = FALSE;
|
||||
|
||||
if (guide->npc_class.right_hand.item_actor_p == NULL) {
|
||||
if (Common_Get(clip).tools_clip != NULL) {
|
||||
ACTOR* keitai = Common_Get(clip).tools_clip->aTOL_birth_proc(TOOL_KEITAI, aTOL_ACTION_TAKEOUT,
|
||||
&guide->npc_class.actor_class, game, -1, NULL);
|
||||
|
||||
if (keitai != NULL) {
|
||||
guide->npc_class.right_hand.item_actor_p = keitai;
|
||||
res = TRUE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int aNGD_chg_cond_keitai(NPC_GUIDE_ACTOR* guide, int cond) {
|
||||
int res = FALSE;
|
||||
|
||||
if (Common_Get(clip).tools_clip != NULL) {
|
||||
if (Common_Get(clip).tools_clip->aTOL_chg_request_mode_proc(
|
||||
&guide->npc_class.actor_class, guide->npc_class.right_hand.item_actor_p, cond) == TRUE) {
|
||||
res = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void aNGD_talk_demo_proc(ACTOR* actorx) {
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, actorx) == TRUE) {
|
||||
Common_Get(clip).npc_clip->talk_demo_proc(actorx);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_check_talk_msg_no(NPC_GUIDE_ACTOR* guide) {
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, &guide->npc_class.actor_class) == TRUE) {
|
||||
int msg_no = mMsg_GET_MSG_NUM();
|
||||
int flags;
|
||||
|
||||
switch (msg_no) {
|
||||
case 0x2AC9:
|
||||
flags = (1 << 3);
|
||||
break;
|
||||
case 0x2ACD:
|
||||
flags = (1 << 2);
|
||||
break;
|
||||
case 0x2ACF:
|
||||
flags = (1 << 1);
|
||||
break;
|
||||
case 0x2AD3:
|
||||
flags = (1 << 0);
|
||||
break;
|
||||
default:
|
||||
flags = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
guide->answer_flags |= flags;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_set_pl_face_type(NPC_GUIDE_ACTOR* guide) {
|
||||
static int face_type_table[mPr_SEX_NUM][mPr_FACE_TYPE_NUM] = {
|
||||
/* Male faces */
|
||||
{
|
||||
mPr_FACE_TYPE5,
|
||||
mPr_FACE_TYPE6,
|
||||
mPr_FACE_TYPE1,
|
||||
mPr_FACE_TYPE4,
|
||||
mPr_FACE_TYPE0,
|
||||
mPr_FACE_TYPE2,
|
||||
mPr_FACE_TYPE7,
|
||||
mPr_FACE_TYPE3,
|
||||
},
|
||||
/* Female faces */
|
||||
{
|
||||
mPr_FACE_TYPE0,
|
||||
mPr_FACE_TYPE5,
|
||||
mPr_FACE_TYPE2,
|
||||
mPr_FACE_TYPE6,
|
||||
mPr_FACE_TYPE4,
|
||||
mPr_FACE_TYPE7,
|
||||
mPr_FACE_TYPE3,
|
||||
mPr_FACE_TYPE1,
|
||||
},
|
||||
};
|
||||
|
||||
int answer_flags = guide->answer_flags;
|
||||
int face_type;
|
||||
|
||||
if ((answer_flags & 1) == 0) {
|
||||
/* Select a random face for the player */
|
||||
face_type = RANDOM(mPr_FACE_TYPE_NUM);
|
||||
} else {
|
||||
/* Select a face based on choices */
|
||||
face_type = face_type_table[Now_Private->gender][answer_flags >> 1];
|
||||
}
|
||||
|
||||
Now_Private->face = face_type;
|
||||
}
|
||||
|
||||
static void aNGD_calc_body_angl(NPC_GUIDE_ACTOR* guide, f32 pos_x, f32 pos_z) {
|
||||
f32 dX = pos_x - guide->npc_class.actor_class.world.position.x;
|
||||
f32 dZ = pos_z - guide->npc_class.actor_class.world.position.z;
|
||||
s16 angl = atans_table(dZ, dX);
|
||||
|
||||
chase_angle(&guide->npc_class.actor_class.shape_info.rotation.y, angl, DEG2SHORT_ANGLE2(11.25f));
|
||||
guide->npc_class.actor_class.world.angle.y = guide->npc_class.actor_class.shape_info.rotation.y;
|
||||
}
|
||||
|
||||
static void aNGD_set_default_talk_info(void) {
|
||||
mDemo_Set_camera(CAMERA2_PROCESS_NUM);
|
||||
mDemo_Set_talk_change_player(FALSE);
|
||||
mDemo_Set_use_zoom_sound(TRUE);
|
||||
}
|
||||
|
||||
static void aNGD_enter(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
if (guide->npc_class.draw.main_animation_state == cKF_STATE_STOPPED) {
|
||||
guide->camera_eyes_flag = TRUE;
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_APPROACH);
|
||||
} else if (cKF_FrameControl_passCheck_now(&guide->npc_class.draw.main_animation.keyframe.frame_control, 20.0f) ==
|
||||
TRUE) {
|
||||
TRAINDOOR_ACTOR* train_door = (TRAINDOOR_ACTOR*)guide->train_door_actor;
|
||||
|
||||
train_door->open_flag = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_approach(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
if (guide->npc_class.actor_class.world.position.z >= 290.0f) {
|
||||
guide->npc_class.actor_class.world.position.z = 290.0f;
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_TALK_START_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_set_talk_info_talk_start_wait(ACTOR* actorx) {
|
||||
mDemo_Set_msg_num(0x2AC6);
|
||||
aNGD_set_default_talk_info();
|
||||
((NPC_GUIDE_ACTOR*)actorx)->obj_look_type = aNGD_OBJ_LOOK_TYPE_TALK;
|
||||
}
|
||||
|
||||
static void aNGD_talk_start_wait(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
ACTOR* actorx = (ACTOR*)guide;
|
||||
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, actorx) == TRUE) {
|
||||
if (mDemo_Check_ListenAble() == FALSE &&
|
||||
chase_angle(&actorx->shape_info.rotation.y, actorx->player_angle_y, 0x400) == TRUE) {
|
||||
guide->camera_eyes_flag = FALSE;
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_TIME_CHECK);
|
||||
mDemo_Set_ListenAble();
|
||||
}
|
||||
} else {
|
||||
mDemo_Request(mDemo_TYPE_SPEAK, actorx, &aNGD_set_talk_info_talk_start_wait);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_time_check(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
if (mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) {
|
||||
switch (mChoice_GET_CHOSENUM()) {
|
||||
case mChoice_CHOICE0:
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_WAIT_PERMISSION);
|
||||
break;
|
||||
case mChoice_CHOICE1:
|
||||
guide->next_action = aNGD_ACTION_TIME_MENU_OPEN_WAIT;
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_SDON_AND_PB_WAIT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_sdon_and_pb_wait(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
u16 order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
|
||||
if (order != 0 && mMsg_CHECK_MAINNORMALCONTINUE()) {
|
||||
aNGD_setupAction(guide, play, guide->next_action);
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_time_menu_open_wait(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
if (mMsg_CHECK_MAIN_WAIT() == TRUE) {
|
||||
aNGD_setupAction(guide, play, guide->action + 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_time_menu_close_wait(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
if (play->submenu.open_flag == FALSE) {
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_MSG_WIN_OPEN_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_msg_win_open_wait(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
static int msg_no[] = { 0x2AE5, 0x2ACA, 0x2AE4 };
|
||||
static int next_act_idx[] = {
|
||||
aNGD_ACTION_CONFIRM_INPUT_DATA,
|
||||
aNGD_ACTION_SEX_SELECT_WAIT,
|
||||
aNGD_ACTION_CONFIRM_INPUT_DATA,
|
||||
};
|
||||
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
|
||||
|
||||
if (mMsg_Check_not_series_main_wait(msg_p) == TRUE) {
|
||||
int idx = -1;
|
||||
|
||||
switch (guide->next_action) {
|
||||
case aNGD_ACTION_TIME_MENU_CLOSE_WAIT:
|
||||
idx = 0;
|
||||
break;
|
||||
case aNGD_ACTION_PNAME_MENU_CLOSE_WAIT:
|
||||
idx = 1;
|
||||
break;
|
||||
case aNGD_ACTION_CNAME_MENU_CLOSE_WAIT:
|
||||
idx = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (idx >= 0) {
|
||||
mMsg_Unset_LockContinue(msg_p);
|
||||
mMsg_Set_continue_msg_num(msg_p, msg_no[idx]);
|
||||
mMsg_Set_ForceNext(msg_p);
|
||||
aNGD_setupAction(guide, play, next_act_idx[idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_confirm_input_data(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
if (mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) {
|
||||
switch (mChoice_GET_CHOSENUM()) {
|
||||
case mChoice_CHOICE0:
|
||||
switch (guide->next_action) {
|
||||
case aNGD_ACTION_TIME_MENU_CLOSE_WAIT:
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_WAIT_PERMISSION);
|
||||
break;
|
||||
case aNGD_ACTION_CNAME_MENU_CLOSE_WAIT:
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_STANDUP_START_WAIT);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case mChoice_CHOICE1:
|
||||
switch (guide->next_action) {
|
||||
case aNGD_ACTION_TIME_MENU_CLOSE_WAIT:
|
||||
guide->next_action = aNGD_ACTION_TIME_MENU_OPEN_WAIT;
|
||||
break;
|
||||
case aNGD_ACTION_CNAME_MENU_CLOSE_WAIT:
|
||||
guide->next_action = aNGD_ACTION_CNAME_MENU_OPEN_WAIT;
|
||||
break;
|
||||
}
|
||||
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_SDON_AND_PB_WAIT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_wait_permission(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
if (mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) {
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_SITDOWN);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_sitdown(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
guide->npc_class.actor_class.world.position.x = 100.0f;
|
||||
guide->npc_class.actor_class.world.position.z = 280.0f;
|
||||
guide->npc_class.actor_class.shape_info.rotation.y = 0;
|
||||
|
||||
/* Wait for the sit animation to finish before continuing */
|
||||
if (guide->npc_class.draw.main_animation_state == cKF_STATE_STOPPED) {
|
||||
mMsg_UNSET_LOCKCONTINUE();
|
||||
guide->next_action = aNGD_ACTION_PNAME_MENU_OPEN_WAIT;
|
||||
Common_Set(sunlight_flag, TRUE); // turn on the sunlight as we exit tunnel
|
||||
/* Turn off echoes since we exited the tunnel */
|
||||
sAdo_TrgSeEcho(FALSE);
|
||||
sAdo_LevSeEcho(FALSE);
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_SDON_AND_PB_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_sex_select_wait(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
if (mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) {
|
||||
switch (mChoice_GET_CHOSENUM()) {
|
||||
case mChoice_CHOICE0: // male
|
||||
case mChoice_CHOICE1: // female
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_SEX_SELECT_WAIT2);
|
||||
break;
|
||||
case mChoice_CHOICE2: // 'That's not right'
|
||||
guide->next_action = aNGD_ACTION_PNAME_MENU_OPEN_WAIT;
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_SDON_AND_PB_WAIT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_sex_select_wait2(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
int order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
|
||||
if (order != 0 && mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) {
|
||||
switch (mChoice_GET_CHOSENUM()) {
|
||||
case mChoice_CHOICE0: // male
|
||||
switch (order) {
|
||||
case 1: // That's right
|
||||
Now_Private->gender = mPr_SEX_MALE;
|
||||
break;
|
||||
case 2: // I'm not a boy
|
||||
Now_Private->gender = mPr_SEX_FEMALE;
|
||||
break;
|
||||
}
|
||||
|
||||
guide->next_action = aNGD_ACTION_CNAME_MENU_OPEN_WAIT;
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_SDON_AND_PB_WAIT);
|
||||
break;
|
||||
case mChoice_CHOICE1: // female
|
||||
switch (order) {
|
||||
case 1: // That's right
|
||||
Now_Private->gender = mPr_SEX_FEMALE;
|
||||
break;
|
||||
case 2: // I'm not a girl
|
||||
Now_Private->gender = mPr_SEX_MALE;
|
||||
break;
|
||||
}
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_SEX_SELECT_AFTER);
|
||||
break;
|
||||
}
|
||||
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_sex_select_after(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
|
||||
u16 order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
|
||||
if (order != 0 && mMsg_Check_MainNormalContinue(msg_p)) {
|
||||
mMsg_Set_continue_msg_num(msg_p, 0x2AD8);
|
||||
mMsg_Set_ForceNext(msg_p);
|
||||
guide->next_action = aNGD_ACTION_CNAME_MENU_OPEN_WAIT;
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_SDON_AND_PB_WAIT);
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_standup_start_wait(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
/* Wait for guide to stop speaking to us */
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, &guide->npc_class.actor_class) == FALSE) {
|
||||
guide->obj_look_type = aNGD_OBJ_LOOK_TYPE_NORMAL;
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_STANDUP);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_standup(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
/* Wait for animation to finish */
|
||||
if (guide->npc_class.draw.main_animation_state == cKF_STATE_STOPPED) {
|
||||
aNGD_setupAction(guide, play, guide->next_action);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_move_ready(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
guide->npc_class.actor_class.world.position.x = 100.0f;
|
||||
guide->npc_class.actor_class.world.position.z = 300.0f;
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_MOVE_TO_AISLE);
|
||||
}
|
||||
|
||||
static void aNGD_move_to_aisle(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
aNGD_calc_body_angl(guide, 140.0f, 290.0f);
|
||||
if (guide->npc_class.actor_class.world.position.x > 140.0f) {
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_MOVE_TO_DOOR);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_move_to_door(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
aNGD_calc_body_angl(guide, 140.0f, 130.0f);
|
||||
/* Check if we reached the door */
|
||||
if (guide->npc_class.actor_class.world.position.z < 130.0f) {
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_MOVE_TO_DECK);
|
||||
}
|
||||
|
||||
/* Check if we should start rotating */
|
||||
if (guide->npc_class.draw.shadow_pos.z < 140.0f) {
|
||||
guide->camera_tilt_goal_angle = DEG2SHORT_ANGLE2(90.0f);
|
||||
guide->camera_tilt_add = DEG2SHORT_ANGLE2(2.8125f);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_move_to_deck(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
if (cKF_FrameControl_passCheck_now(&guide->npc_class.draw.main_animation.keyframe.frame_control, 9.0f) == TRUE) {
|
||||
TRAINDOOR_ACTOR* train_door = (TRAINDOOR_ACTOR*)guide->train_door_actor;
|
||||
|
||||
train_door->open_flag = TRUE;
|
||||
}
|
||||
|
||||
/* Reuse standup state to wait for animation to finish */
|
||||
aNGD_standup(guide, play);
|
||||
}
|
||||
|
||||
static void aNGD_set_talk_info_keitai_on(ACTOR* actorx) {
|
||||
mDemo_Set_msg_num(0x2AD0);
|
||||
aNGD_set_default_talk_info();
|
||||
}
|
||||
|
||||
static void aNGD_keitai_on(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
static f32 anmSpd[] = { 0.0f, 0.5f };
|
||||
int idx = aNGD_make_keitai(guide, &play->game);
|
||||
|
||||
guide->npc_class.draw.main_animation.keyframe.frame_control.speed = anmSpd[idx];
|
||||
if (idx != 0) {
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, (ACTOR*)guide) == TRUE) {
|
||||
if (mDemo_Check_ListenAble() == FALSE) {
|
||||
mDemo_Set_ListenAble();
|
||||
}
|
||||
} else {
|
||||
/* Request to start speaking */
|
||||
mDemo_Request(mDemo_TYPE_SPEAK, (ACTOR*)guide, &aNGD_set_talk_info_keitai_on);
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for animation to finish */
|
||||
if (guide->npc_class.draw.main_animation_state == cKF_STATE_STOPPED) {
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_KEITAI_TALK);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_keitai_talk(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, &guide->npc_class.actor_class) == FALSE) {
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_KEITAI_OFF);
|
||||
} else if (guide->npc_class.draw.main_animation_state == cKF_STATE_STOPPED) {
|
||||
Common_Get(clip).npc_clip->animation_init_proc(&guide->npc_class.actor_class, aNPC_ANIM_KEITAI_TALK2, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_open_door(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
chase_angle(&guide->npc_class.actor_class.shape_info.rotation.y, DEG2SHORT_ANGLE2(-180.0f),
|
||||
DEG2SHORT_ANGLE2(0.703125f));
|
||||
if (cKF_FrameControl_passCheck_now(&guide->npc_class.draw.main_animation.keyframe.frame_control, 22.0f) == TRUE) {
|
||||
TRAINDOOR_ACTOR* train_door = (TRAINDOOR_ACTOR*)guide->train_door_actor;
|
||||
|
||||
train_door->open_flag = TRUE;
|
||||
if (guide->npc_class.draw.shadow_pos.z < 140.0f) {
|
||||
guide->camera_tilt_goal_angle = 0;
|
||||
guide->camera_tilt_add = 0x600;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reuse standup state to wait for animation to finish */
|
||||
aNGD_standup(guide, play);
|
||||
}
|
||||
|
||||
static void aNGD_return_approach(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
guide->npc_class.actor_class.world.position.x = 140.0f;
|
||||
guide->npc_class.actor_class.world.angle.y = 0;
|
||||
guide->npc_class.actor_class.shape_info.rotation.y = 0;
|
||||
if (guide->npc_class.actor_class.world.position.z > 290.0f) {
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_LAST_TALK_START_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_set_talk_info_last_talk_start_wait(ACTOR* actorx) {
|
||||
mDemo_Set_msg_num(0x2AD1);
|
||||
aNGD_set_default_talk_info();
|
||||
((NPC_GUIDE_ACTOR*)actorx)->obj_look_type = aNGD_OBJ_LOOK_TYPE_TALK;
|
||||
}
|
||||
|
||||
static void aNGD_last_talk_start_wait(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
ACTOR* actorx = (ACTOR*)guide;
|
||||
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, actorx) == TRUE) {
|
||||
if (mDemo_Check_ListenAble() == FALSE &&
|
||||
chase_angle(&actorx->shape_info.rotation.y, actorx->player_angle_y, 0x400) == TRUE) {
|
||||
guide->camera_eyes_flag = FALSE;
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_SITDOWN2_START_WAIT);
|
||||
mDemo_Set_ListenAble();
|
||||
}
|
||||
} else {
|
||||
mDemo_Request(mDemo_TYPE_SPEAK, actorx, &aNGD_set_talk_info_last_talk_start_wait);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_sitdown2_start_wait(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
u16 order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
|
||||
if (order != 0) {
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_SITDOWN2);
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_sitdown2(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
guide->npc_class.actor_class.world.position.x = 100.0f;
|
||||
guide->npc_class.actor_class.world.position.z = 280.0f;
|
||||
guide->npc_class.actor_class.shape_info.rotation.y = 0;
|
||||
|
||||
/* Wait for animation to finish */
|
||||
aNGD_standup(guide, play);
|
||||
}
|
||||
|
||||
static void aNGD_last_talk_end_wait(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, &guide->npc_class.actor_class) == FALSE) {
|
||||
aNGD_setupAction(guide, play, aNGD_ACTION_SCENE_CHANGE_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
/* Init procs */
|
||||
|
||||
static void aNGD_time_menu_open_wait_init(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
|
||||
|
||||
mMsg_Set_LockContinue(msg_p);
|
||||
mMsg_request_main_disappear_wait_type1(msg_p);
|
||||
guide->next_action = aNGD_ACTION_TIME_MENU_CLOSE_WAIT;
|
||||
}
|
||||
|
||||
static void aNGD_time_menu_close_wait_init(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
Submenu* submenu = &play->submenu;
|
||||
|
||||
switch (guide->next_action) {
|
||||
case aNGD_ACTION_TIME_MENU_CLOSE_WAIT:
|
||||
mSM_open_submenu(submenu, mSM_OVL_TIMEIN, mTI_OVL_OPEN_INITIAL, 0);
|
||||
break;
|
||||
case aNGD_ACTION_PNAME_MENU_CLOSE_WAIT:
|
||||
mSM_open_submenu(submenu, mSM_OVL_LEDIT, mLE_TYPE_PLAYER_NAME, 0);
|
||||
break;
|
||||
case aNGD_ACTION_CNAME_MENU_CLOSE_WAIT:
|
||||
mSM_open_submenu(submenu, mSM_OVL_LEDIT, mLE_TYPE_COUNTRY_NAME, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNGD_msg_win_open_wait_init(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
mMsg_REQUEST_MAIN_APPEAR_WAIT_TYPE1();
|
||||
}
|
||||
|
||||
static void aNGD_sitdown_init(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
mMsg_SET_LOCKCONTINUE();
|
||||
}
|
||||
|
||||
static void aNGD_pname_menu_open_wait_init(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
|
||||
|
||||
mMsg_Set_LockContinue(msg_p);
|
||||
mMsg_request_main_disappear_wait_type1(msg_p);
|
||||
guide->next_action = aNGD_ACTION_PNAME_MENU_CLOSE_WAIT;
|
||||
}
|
||||
|
||||
static void aNGD_cname_menu_open_wait_init(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
|
||||
|
||||
mMsg_Set_LockContinue(msg_p);
|
||||
mMsg_request_main_disappear_wait_type1(msg_p);
|
||||
guide->next_action = aNGD_ACTION_CNAME_MENU_CLOSE_WAIT;
|
||||
}
|
||||
|
||||
static void aNGD_standup_init(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
guide->next_action = aNGD_ACTION_MOVE_READY;
|
||||
}
|
||||
|
||||
static void aNGD_move_ready_init(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
guide->npc_class.draw.main_animation.keyframe.morph_counter = 0.0f;
|
||||
}
|
||||
|
||||
static void aNGD_move_to_aisle_init(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
aNGD_set_walk_spd2(guide, play);
|
||||
}
|
||||
|
||||
static void aNGD_move_to_deck_init(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
aNGD_set_stop_spd(guide, play);
|
||||
guide->npc_class.actor_class.world.position.x = 140.0f;
|
||||
guide->npc_class.actor_class.world.position.z = 130.0f;
|
||||
guide->next_action = aNGD_ACTION_KEITAI_ON;
|
||||
}
|
||||
|
||||
static void aNGD_keitai_off_init(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
aNGD_chg_cond_keitai(guide, aTOL_ACTION_PUTAWAY);
|
||||
guide->next_action = aNGD_ACTION_OPEN_DOOR;
|
||||
}
|
||||
|
||||
static void aNGD_open_door_init(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
guide->next_action = aNGD_ACTION_RETURN_APPROACH;
|
||||
}
|
||||
|
||||
static void aNGD_return_approach_init(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
guide->camera_eyes_flag = TRUE;
|
||||
aNGD_set_walk_spd2(guide, play);
|
||||
guide->npc_class.draw.main_animation.keyframe.morph_counter = 0.0f;
|
||||
}
|
||||
|
||||
static void aNGD_sitdown2_start_wait_init(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
}
|
||||
|
||||
static void aNGD_sitdown2_init(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
guide->npc_class.draw.main_animation.keyframe.morph_counter = 0.0f;
|
||||
guide->next_action = aNGD_ACTION_LAST_TALK_END_WAIT;
|
||||
}
|
||||
|
||||
static void aNGD_last_talk_end_wait_init(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
aNGD_chg_cond_keitai(guide, aTOL_ACTION_DESTRUCT);
|
||||
guide->npc_class.right_hand.item_actor_p = NULL;
|
||||
}
|
||||
|
||||
static void aNGD_scene_change_wait_init(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play) {
|
||||
u8 term;
|
||||
int town_day;
|
||||
|
||||
/* Init next scene transition */
|
||||
goto_next_scene(play, 0, 1);
|
||||
play->fb_wipe_type = 3;
|
||||
Common_Get(transition).wipe_type = 4;
|
||||
|
||||
/* Clear plant growth renew time */
|
||||
Save_Set(all_grow_renew_time, mTM_rtcTime_clear_code);
|
||||
|
||||
/* Update player ID town info */
|
||||
if (Now_Private != NULL) {
|
||||
mLd_CopyLandName(Now_Private->player_ID.land_name, Save_Get(land_info).name);
|
||||
}
|
||||
|
||||
/* Init island */
|
||||
bcopy(Save_GetPointer(land_info), &Save_Get(island).landinfo, sizeof(mLd_land_info_c)); // Copy the town's land info
|
||||
mNpc_DecideIslandNpc(&Save_Get(island).animal); // Pick islander
|
||||
|
||||
/* Update some renew time values to current rtc time */
|
||||
lbRTC_TimeCopy(Save_GetPointer(last_grow_time), Common_GetPointer(time.rtc_time));
|
||||
mTM_set_renew_time(Save_GetPointer(renew_time), Common_GetPointer(time.rtc_time));
|
||||
mTM_set_season(); // initialize the season
|
||||
|
||||
/* Initialize first Stalk Market info */
|
||||
Kabu_decide_price_schedule();
|
||||
|
||||
/* Init Post Office */
|
||||
mPO_post_office_init();
|
||||
|
||||
/* Set insect term info */
|
||||
Save_Set(insect_term, Common_Get(time.rtc_time.month));
|
||||
Save_Set(insect_term_transition_offset, RANDOM(6));
|
||||
|
||||
/* Set fish term info */
|
||||
term = Common_Get(time.rtc_time.month) * 2;
|
||||
if (Common_Get(time.rtc_time.day) > 15) {
|
||||
term++;
|
||||
}
|
||||
Save_Set(gyoei_term, term);
|
||||
Save_Set(gyoei_term_transition_offset, RANDOM(6));
|
||||
|
||||
/* Decide Town Day date */
|
||||
town_day = 1 + RANDOM(30);
|
||||
if (town_day >= 4) {
|
||||
town_day++; // add one to prevent conflict with Fireworks Festival (4th of July)
|
||||
}
|
||||
Save_Set(town_day, town_day);
|
||||
|
||||
mSP_ShopGameStartCt(NULL);
|
||||
mNtc_SetInitData();
|
||||
mPr_SetNowPrivateCloth();
|
||||
mEv_SetFirstJob();
|
||||
mEv_SetFirstIntro();
|
||||
mEnv_DecideWeather_FirstGameStart();
|
||||
mCD_calendar_clear(-1);
|
||||
mCD_calendar_wellcome_on();
|
||||
mNpc_SetParentNameAllAnimal();
|
||||
aNGD_set_pl_face_type(guide);
|
||||
Common_Set(submenu_disabled, TRUE);
|
||||
mRmTp_SetDefaultLightSwitchData(1);
|
||||
mBGMPsComp_make_ps_wipe(0x41C2);
|
||||
mBGMPsComp_scene_mode(18);
|
||||
}
|
||||
|
||||
typedef void (*aNGD_INIT_PROC)(NPC_GUIDE_ACTOR*, GAME_PLAY*);
|
||||
|
||||
static void aNGD_init_proc(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play, int action) {
|
||||
static aNGD_INIT_PROC init_proc[] = {
|
||||
(aNGD_INIT_PROC)&none_proc1,
|
||||
&aNGD_set_walk_spd,
|
||||
&aNGD_set_stop_spd,
|
||||
(aNGD_INIT_PROC)&none_proc1,
|
||||
(aNGD_INIT_PROC)&none_proc1,
|
||||
&aNGD_time_menu_open_wait_init,
|
||||
&aNGD_time_menu_close_wait_init,
|
||||
&aNGD_msg_win_open_wait_init,
|
||||
(aNGD_INIT_PROC)&none_proc1,
|
||||
(aNGD_INIT_PROC)&none_proc1,
|
||||
&aNGD_sitdown_init,
|
||||
&aNGD_pname_menu_open_wait_init,
|
||||
&aNGD_time_menu_close_wait_init,
|
||||
(aNGD_INIT_PROC)&none_proc1,
|
||||
(aNGD_INIT_PROC)&none_proc1,
|
||||
(aNGD_INIT_PROC)&none_proc1,
|
||||
&aNGD_cname_menu_open_wait_init,
|
||||
&aNGD_time_menu_close_wait_init,
|
||||
(aNGD_INIT_PROC)&none_proc1,
|
||||
&aNGD_standup_init,
|
||||
&aNGD_move_ready_init,
|
||||
&aNGD_move_to_aisle_init,
|
||||
(aNGD_INIT_PROC)&none_proc1,
|
||||
&aNGD_move_to_deck_init,
|
||||
(aNGD_INIT_PROC)&none_proc1,
|
||||
(aNGD_INIT_PROC)&none_proc1,
|
||||
&aNGD_keitai_off_init,
|
||||
&aNGD_open_door_init,
|
||||
&aNGD_return_approach_init,
|
||||
&aNGD_set_stop_spd,
|
||||
&aNGD_sitdown2_start_wait_init,
|
||||
&aNGD_sitdown2_init,
|
||||
&aNGD_last_talk_end_wait_init,
|
||||
&aNGD_scene_change_wait_init,
|
||||
};
|
||||
|
||||
(*init_proc[action])(guide, play);
|
||||
}
|
||||
|
||||
static void aNGD_setupAction(NPC_GUIDE_ACTOR* guide, GAME_PLAY* play, int action) {
|
||||
static aNGD_PROC process[] = {
|
||||
&aNGD_enter,
|
||||
&aNGD_approach,
|
||||
&aNGD_talk_start_wait,
|
||||
&aNGD_time_check,
|
||||
&aNGD_sdon_and_pb_wait,
|
||||
&aNGD_time_menu_open_wait,
|
||||
&aNGD_time_menu_close_wait,
|
||||
&aNGD_msg_win_open_wait,
|
||||
&aNGD_confirm_input_data,
|
||||
&aNGD_wait_permission,
|
||||
&aNGD_sitdown,
|
||||
&aNGD_time_menu_open_wait,
|
||||
&aNGD_time_menu_close_wait,
|
||||
&aNGD_sex_select_wait,
|
||||
&aNGD_sex_select_wait2,
|
||||
&aNGD_sex_select_after,
|
||||
&aNGD_time_menu_open_wait,
|
||||
&aNGD_time_menu_close_wait,
|
||||
&aNGD_standup_start_wait,
|
||||
&aNGD_standup,
|
||||
&aNGD_move_ready,
|
||||
&aNGD_move_to_aisle,
|
||||
&aNGD_move_to_door,
|
||||
&aNGD_move_to_deck,
|
||||
&aNGD_keitai_on,
|
||||
&aNGD_keitai_talk,
|
||||
&aNGD_standup,
|
||||
&aNGD_open_door,
|
||||
&aNGD_return_approach,
|
||||
&aNGD_last_talk_start_wait,
|
||||
&aNGD_sitdown2_start_wait,
|
||||
&aNGD_sitdown2,
|
||||
&aNGD_last_talk_end_wait,
|
||||
(aNGD_PROC)&none_proc1,
|
||||
};
|
||||
|
||||
guide->action = action;
|
||||
guide->proc = process[action];
|
||||
aNGD_set_animation(guide, action);
|
||||
aNGD_init_proc(guide, play, action);
|
||||
}
|
||||
|
||||
static void aNGD_actor_move(ACTOR* actorx, GAME* game) {
|
||||
NPC_GUIDE_ACTOR* guide = (NPC_GUIDE_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
|
||||
Common_Get(clip).npc_clip->move_before_proc(actorx, game);
|
||||
aNGD_talk_demo_proc(actorx);
|
||||
aNGD_check_talk_msg_no(guide);
|
||||
(*guide->proc)(guide, play);
|
||||
Common_Get(clip).npc_clip->move_after_proc(actorx, game);
|
||||
aNGD_set_camera(guide, play);
|
||||
aNGD_set_camera_eyes(guide);
|
||||
mSC_change_player_freeze(play);
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
#include "ac_npc_p_sel.h"
|
||||
|
||||
#include "m_config.h"
|
||||
#include "m_common_data.h"
|
||||
#include "m_player_lib.h"
|
||||
#include "m_soncho.h"
|
||||
#include "m_play.h"
|
||||
#include "m_card.h"
|
||||
#include "m_bgm.h"
|
||||
#include "m_choice.h"
|
||||
#include "m_msg.h"
|
||||
#include "m_vibctl.h"
|
||||
#include "libultra/libultra.h"
|
||||
#include "dolphin/os/OSRtc.h"
|
||||
|
||||
enum {
|
||||
aNPS_TALK_CHK_SETUP_SOUND,
|
||||
aNPS_TALK_SETUP_SOUND,
|
||||
aNPS_TALK_SETUP_VOICE,
|
||||
aNPS_TALK_CONFIRM_INPUT_DATA,
|
||||
aNPS_TALK_CONFIRM_INPUT_DATA2,
|
||||
aNPS_TALK_SETUP_YURE,
|
||||
aNPS_TALK_WAIT,
|
||||
|
||||
aNPS_TALK_NUM
|
||||
};
|
||||
|
||||
typedef void (*aNPS_THINK_PROC)(NPC_ACTOR*, GAME_PLAY*);
|
||||
|
||||
static void aNPS_actor_ct(ACTOR* actorx, GAME* game);
|
||||
static void aNPS_actor_dt(ACTOR* actorx, GAME* game);
|
||||
static void aNPS_actor_init(ACTOR* actorx, GAME* game);
|
||||
static void aNPS_actor_save(ACTOR* actorx, GAME* game);
|
||||
static void aNPS_actor_move(ACTOR* actorx, GAME* game);
|
||||
static void aNPS_actor_draw(ACTOR* actorx, GAME* game);
|
||||
|
||||
static void aNPS_talk_request(ACTOR* actorx, GAME* game);
|
||||
static void aNPS_change_talk_proc(NPC_P_SEL_ACTOR* p_sel, int talk_idx);
|
||||
static int aNPS_talk_init(ACTOR* actorx, GAME* game);
|
||||
static int aNPS_talk_end_chk(ACTOR* actorx, GAME* game);
|
||||
static void aNPS_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int type);
|
||||
|
||||
// clang-format off
|
||||
ACTOR_PROFILE Npc_P_Sel_Profile = {
|
||||
mAc_PROFILE_NPC_P_SEL,
|
||||
ACTOR_PART_NPC,
|
||||
ACTOR_STATE_NONE,
|
||||
SP_NPC_P_SEL,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(NPC_P_SEL_ACTOR),
|
||||
&aNPS_actor_ct,
|
||||
&aNPS_actor_dt,
|
||||
&aNPS_actor_init,
|
||||
mActor_NONE_PROC1,
|
||||
&aNPS_actor_save,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static u8 aNPS_sound_mode[] = { Config_SOUND_MODE_STEREO, Config_SOUND_MODE_MONO, Config_SOUND_MODE_HEADPHONES };
|
||||
static u8 aNPS_voice_mode[] = { Config_VOICE_MODE_ANIMALESE, Config_VOICE_MODE_CLICK, Config_VOICE_MODE_SILENT };
|
||||
|
||||
static void aNPS_actor_ct(ACTOR* actorx, GAME* game) {
|
||||
// clang-format off
|
||||
static aNPC_ct_data_c ct_data = {
|
||||
&aNPS_actor_move,
|
||||
&aNPS_actor_draw,
|
||||
5,
|
||||
(aNPC_TALK_REQUEST_PROC)&none_proc1,
|
||||
&aNPS_talk_init,
|
||||
&aNPS_talk_end_chk,
|
||||
0,
|
||||
};
|
||||
// clang-format off
|
||||
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
NPC_P_SEL_ACTOR* p_sel = (NPC_P_SEL_ACTOR*)actorx;
|
||||
PLAYER_ACTOR* player;
|
||||
xyz_t center;
|
||||
xyz_t eye;
|
||||
|
||||
if (CLIP(npc_clip)->birth_check_proc(actorx, game) == TRUE) {
|
||||
p_sel->npc_class.schedule.schedule_proc = &aNPS_schedule_proc;
|
||||
CLIP(npc_clip)->ct_proc(actorx, game, &ct_data);
|
||||
actorx->status_data.weight = MASSTYPE_IMMOVABLE;
|
||||
mPlib_request_main_demo_wait_type1(game, FALSE, NULL);
|
||||
|
||||
player = GET_PLAYER_ACTOR(play);
|
||||
if (player != NULL) {
|
||||
player->actor_class.state_bitfield |= ACTOR_STATE_INVISIBLE;
|
||||
}
|
||||
|
||||
center.x = 100.0f;
|
||||
center.y = 60.0f;
|
||||
center.z = 60.0f;
|
||||
|
||||
eye.x = 100.0f;
|
||||
eye.y = 130.0f;
|
||||
eye.z = 210.0f;
|
||||
|
||||
Camera2_change_priority(play, 0);
|
||||
Camera2_request_main_lock(play, ¢er, &eye, 40.0f, 0, 100.0f, 400.0f, 5);
|
||||
if (OSGetSoundMode() == OS_SOUND_MODE_MONO) {
|
||||
Save_Get(config).sound_mode = Config_SOUND_MODE_MONO;
|
||||
} else {
|
||||
Save_Get(config).sound_mode = Config_SOUND_MODE_STEREO;
|
||||
}
|
||||
|
||||
sAdo_SetOutMode(aNPS_sound_mode[Save_Get(config).sound_mode]);
|
||||
Save_Get(config).voice_mode = Config_VOICE_MODE_ANIMALESE;
|
||||
sAdo_SetVoiceMode(aNPS_voice_mode[Save_Get(config).voice_mode]);
|
||||
|
||||
p_sel->npc_class.condition_info.hide_request = FALSE;
|
||||
p_sel->npc_class.talk_info.default_act = aNPC_ACT_INTO_HOUSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPS_actor_save(ACTOR* actorx, GAME* game) {
|
||||
CLIP(npc_clip)->save_proc(actorx, game);
|
||||
}
|
||||
|
||||
static void aNPS_actor_dt(ACTOR* actorx, GAME* game) {
|
||||
CLIP(npc_clip)->dt_proc(actorx, game);
|
||||
}
|
||||
|
||||
static void aNPS_actor_init(ACTOR* actorx, GAME* game) {
|
||||
CLIP(npc_clip)->init_proc(actorx, game);
|
||||
}
|
||||
|
||||
static void aNPS_actor_move(ACTOR* actorx, GAME* game) {
|
||||
NPC_P_SEL_ACTOR* p_sel;
|
||||
cKF_FrameControl_c* fc_p;
|
||||
f32 speed;
|
||||
u8 arm_flag;
|
||||
StaffRollInfo_c staffroll_info;
|
||||
|
||||
p_sel = (NPC_P_SEL_ACTOR*)actorx;
|
||||
fc_p = &p_sel->npc_class.draw.main_animation.keyframe.frame_control;
|
||||
speed = 0.5f;
|
||||
arm_flag = TRUE;
|
||||
|
||||
if (p_sel->npc_class.draw.animation_id == aNPC_ANIM_4HAKU_E1) {
|
||||
sAdos_GetStaffRollInfo(&staffroll_info);
|
||||
|
||||
if (staffroll_info.staffroll_part != STAFFROLL_PART_FINISH) {
|
||||
speed = 0.0f;
|
||||
arm_flag = FALSE;
|
||||
fc_p->current_frame = 1.0f + 64.0f * (f32)staffroll_info.percent;
|
||||
}
|
||||
}
|
||||
|
||||
fc_p->speed = speed;
|
||||
sAdos_TTKK_ARM(arm_flag);
|
||||
CLIP(npc_clip)->move_proc(actorx, game);
|
||||
mSC_change_player_freeze((GAME_PLAY*)game); // TODO: mSC_change_player_freeze almost certainly takes a GAME*
|
||||
}
|
||||
|
||||
static void aNPS_actor_draw(ACTOR* actorx, GAME* game) {
|
||||
CLIP(npc_clip)->draw_proc(actorx, game);
|
||||
}
|
||||
|
||||
#include "../src/actor/ac_npc_p_sel_schedule.c_inc"
|
||||
#include "../src/actor/ac_npc_p_sel_talk.c_inc"
|
||||
@@ -0,0 +1,88 @@
|
||||
static int aNPS_setup_game_start(GAME_PLAY* play) {
|
||||
static Door_data_c door_data = {
|
||||
SCENE_START_DEMO, mSc_DIRECT_NORTH, 0, 0, { 120, 0, 340 }, EMPTY_NO, 3, { 0, 0, 0 }
|
||||
};
|
||||
s32 chan;
|
||||
int res = FALSE;
|
||||
|
||||
if (mCD_InitGameStart_bg(0, -1, 0, &chan) == 0) {
|
||||
goto_other_scene(play, &door_data, TRUE);
|
||||
Common_Set(transition.wipe_type, 3);
|
||||
Common_Set(map_flag, FALSE);
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void aNPS_think_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
NPC_P_SEL_ACTOR* p_sel = (NPC_P_SEL_ACTOR*)nactorx;
|
||||
u32 alpha;
|
||||
|
||||
if (!p_sel->talk_end_flag) {
|
||||
if (p_sel->strum_timer == 0) {
|
||||
nactorx->talk_info.talk_request_proc = &aNPS_talk_request;
|
||||
} else {
|
||||
p_sel->strum_timer--;
|
||||
}
|
||||
} else {
|
||||
if (p_sel->strum_timer == 0) {
|
||||
if (aNPS_setup_game_start(play) == TRUE) {
|
||||
p_sel->strum_timer = -1;
|
||||
play->fade_color_value.c.a = 255;
|
||||
}
|
||||
} else if (p_sel->strum_timer > 0) {
|
||||
if (p_sel->strum_timer < 70) {
|
||||
alpha = 255 * (1.0f - p_sel->strum_timer / 70.0f);
|
||||
play->fade_color_value.c.a = (u8)alpha;
|
||||
}
|
||||
|
||||
p_sel->strum_timer--;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_sel->bgm_stop_timer == 0) {
|
||||
mBGMPsComp_make_ps_wipe(0x421C);
|
||||
p_sel->bgm_stop_timer = -1;
|
||||
} else if (p_sel->bgm_stop_timer > 0) {
|
||||
p_sel->bgm_stop_timer--;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPS_think_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
NPC_P_SEL_ACTOR* p_sel = (NPC_P_SEL_ACTOR*)nactorx;
|
||||
|
||||
nactorx->request.act_priority = 4;
|
||||
nactorx->request.act_idx = aNPC_ACT_TALK;
|
||||
nactorx->request.act_type = aNPC_ACT_TYPE_DEFAULT;
|
||||
}
|
||||
|
||||
static void aNPS_think_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int type) {
|
||||
static aNPS_THINK_PROC think_proc[] = { &aNPS_think_init_proc, &aNPS_think_main_proc };
|
||||
|
||||
(*think_proc[type])(nactorx, play);
|
||||
}
|
||||
|
||||
static void aNPS_schedule_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
NPC_P_SEL_ACTOR* p_sel = (NPC_P_SEL_ACTOR*)nactorx;
|
||||
|
||||
nactorx->draw._5BE = 1;
|
||||
nactorx->think.think_proc = &aNPS_think_proc;
|
||||
nactorx->talk_info.default_animation = aNPC_ANIM_4HAKU_E1;
|
||||
p_sel->strum_timer = 440;
|
||||
p_sel->bgm_stop_timer = -1;
|
||||
|
||||
CLIP(npc_clip)->think_proc(nactorx, play, aNPC_THINK_IN_BLOCK, 0);
|
||||
}
|
||||
|
||||
static void aNPS_schedule_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
if (CLIP(npc_clip)->think_proc(nactorx, play, -1, 1) == 0) {
|
||||
CLIP(npc_clip)->think_proc(nactorx, play, -1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPS_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int type) {
|
||||
static aNPC_SUB_PROC sche_proc[] = { &aNPS_schedule_init_proc, &aNPS_schedule_main_proc };
|
||||
|
||||
(*sche_proc[type])(nactorx, play);
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
static int aNPS_setup_sound_option(void) {
|
||||
static u8 sound_mode[] = { Config_SOUND_MODE_STEREO, Config_SOUND_MODE_MONO, Config_SOUND_MODE_HEADPHONES };
|
||||
int order;
|
||||
int res;
|
||||
int idx;
|
||||
|
||||
order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
res = FALSE;
|
||||
|
||||
if (order != 0) {
|
||||
idx = 0;
|
||||
|
||||
switch (mChoice_GET_CHOSENUM()) {
|
||||
case mChoice_CHOICE0:
|
||||
idx = 0;
|
||||
break;
|
||||
case mChoice_CHOICE1:
|
||||
idx = 1;
|
||||
break;
|
||||
case mChoice_CHOICE2:
|
||||
idx = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
OSSetSoundMode(sound_mode[idx] == Config_SOUND_MODE_MONO ? OS_SOUND_MODE_MONO : OS_SOUND_MODE_STEREO);
|
||||
Save_Get(config).sound_mode = sound_mode[idx];
|
||||
sAdo_SetOutMode(aNPS_sound_mode[idx]);
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int aNPS_setup_voice_option(void) {
|
||||
static u8 voice_mode[] = { Config_VOICE_MODE_ANIMALESE, Config_VOICE_MODE_CLICK, Config_VOICE_MODE_SILENT };
|
||||
int order;
|
||||
int res;
|
||||
int idx;
|
||||
|
||||
order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
res = FALSE;
|
||||
|
||||
if (order != 0) {
|
||||
idx = 0;
|
||||
|
||||
switch (mChoice_GET_CHOSENUM()) {
|
||||
case mChoice_CHOICE0:
|
||||
idx = 0;
|
||||
break;
|
||||
case mChoice_CHOICE1:
|
||||
idx = 1;
|
||||
break;
|
||||
case mChoice_CHOICE2:
|
||||
idx = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
Save_Get(config).voice_mode = voice_mode[idx];
|
||||
sAdo_SetVoiceMode(aNPS_voice_mode[idx]);
|
||||
mMsg_sound_spec_change_voice_force(mMsg_Get_base_window_p());
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int aNPS_setup_yure_option(void) {
|
||||
int order;
|
||||
int res;
|
||||
int disabled;
|
||||
|
||||
order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
res = FALSE;
|
||||
|
||||
if (order != 0) {
|
||||
disabled = TRUE;
|
||||
|
||||
switch (mChoice_GET_CHOSENUM()) {
|
||||
case mChoice_CHOICE0:
|
||||
disabled = FALSE;
|
||||
mVibctl_entry(75, mVibctl_VIB_PROG_NON, mVibctl_VIB_PROG_FFF, mVibctl_VIB_PROG_P, 0, 16, 45, 0.0f);
|
||||
break;
|
||||
case mChoice_CHOICE1:
|
||||
disabled = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
Save_Get(config).vibration_disabled = disabled;
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void aNPS_chk_setup_sound(NPC_P_SEL_ACTOR* p_sel, GAME_PLAY* play) {
|
||||
if (mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) {
|
||||
int next_talk_idx = -1;
|
||||
|
||||
switch (mChoice_GET_CHOSENUM()) {
|
||||
case mChoice_CHOICE0:
|
||||
next_talk_idx = aNPS_TALK_WAIT;
|
||||
break;
|
||||
case mChoice_CHOICE1:
|
||||
next_talk_idx = aNPS_TALK_SETUP_YURE;
|
||||
p_sel->next_talk_idx = aNPS_TALK_CONFIRM_INPUT_DATA;
|
||||
break;
|
||||
}
|
||||
|
||||
if (next_talk_idx != -1) {
|
||||
aNPS_change_talk_proc(p_sel, next_talk_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPS_setup_sound(NPC_P_SEL_ACTOR* p_sel, GAME_PLAY* play) {
|
||||
if (aNPS_setup_sound_option() == TRUE) {
|
||||
aNPS_change_talk_proc(p_sel, aNPS_TALK_SETUP_VOICE);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPS_setup_yure(NPC_P_SEL_ACTOR* p_sel, GAME_PLAY* play) {
|
||||
if (aNPS_setup_yure_option() == TRUE) {
|
||||
aNPS_change_talk_proc(p_sel, aNPS_TALK_SETUP_SOUND);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPS_setup_voice(NPC_P_SEL_ACTOR* p_sel, GAME_PLAY* play) {
|
||||
if (aNPS_setup_voice_option() == TRUE) {
|
||||
aNPS_change_talk_proc(p_sel, p_sel->next_talk_idx);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPS_confirm_input_data(NPC_P_SEL_ACTOR* p_sel, GAME_PLAY* play) {
|
||||
if (mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) {
|
||||
switch (mChoice_GET_CHOSENUM()) {
|
||||
case mChoice_CHOICE0:
|
||||
aNPS_change_talk_proc(p_sel, aNPS_TALK_CONFIRM_INPUT_DATA2);
|
||||
break;
|
||||
default:
|
||||
aNPS_change_talk_proc(p_sel, aNPS_TALK_SETUP_VOICE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPS_confirm_input_data2(NPC_P_SEL_ACTOR* p_sel, GAME_PLAY* play) {
|
||||
if (mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) {
|
||||
switch (mChoice_GET_CHOSENUM()) {
|
||||
case mChoice_CHOICE0:
|
||||
aNPS_change_talk_proc(p_sel, aNPS_TALK_WAIT);
|
||||
break;
|
||||
default:
|
||||
aNPS_change_talk_proc(p_sel, aNPS_TALK_SETUP_YURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNPS_change_talk_proc(NPC_P_SEL_ACTOR* p_sel, int talk_idx) {
|
||||
static aNPS_TALK_PROC process[] = {
|
||||
&aNPS_chk_setup_sound, &aNPS_setup_sound, &aNPS_setup_voice, &aNPS_confirm_input_data,
|
||||
&aNPS_confirm_input_data2, &aNPS_setup_yure, (aNPS_TALK_PROC)&none_proc1,
|
||||
};
|
||||
|
||||
p_sel->talk_idx = talk_idx;
|
||||
p_sel->talk_proc = process[talk_idx];
|
||||
}
|
||||
|
||||
static void aNPS_set_talk_info_talk_request(ACTOR* actorx) {
|
||||
int msg_no = !mFRm_CheckSaveData() ? 0x09C7 : 0x09CA;
|
||||
|
||||
mDemo_Set_msg_num(msg_no);
|
||||
mDemo_Set_camera(CAMERA2_PROCESS_NORMAL);
|
||||
}
|
||||
|
||||
static void aNPS_talk_request(ACTOR* actorx, GAME* game) {
|
||||
mDemo_Request(mDemo_TYPE_SPEAK, actorx, &aNPS_set_talk_info_talk_request);
|
||||
}
|
||||
|
||||
static int aNPS_talk_init(ACTOR* actorx, GAME* game) {
|
||||
NPC_P_SEL_ACTOR* p_sel = (NPC_P_SEL_ACTOR*)actorx;
|
||||
|
||||
mDemo_Set_ListenAble();
|
||||
aNPS_change_talk_proc(p_sel, aNPS_TALK_CHK_SETUP_SOUND);
|
||||
p_sel->npc_class.talk_info.talk_request_proc = (aNPC_TALK_REQUEST_PROC)&none_proc1;
|
||||
mMsg_SET_IDLING_REQ();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int aNPS_talk_end_chk(ACTOR* actorx, GAME* game) {
|
||||
NPC_P_SEL_ACTOR* p_sel = (NPC_P_SEL_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
|
||||
int res = FALSE;
|
||||
|
||||
(*p_sel->talk_proc)(p_sel, play);
|
||||
if (mMsg_Check_idling_now(msg_p) == TRUE) {
|
||||
mMsg_request_main_disappear_wait_type1(msg_p);
|
||||
p_sel->strum_timer = 150;
|
||||
p_sel->bgm_stop_timer = 80;
|
||||
bzero(&play->fade_color_value, sizeof(rgba8888));
|
||||
aNPS_think_init_proc(&p_sel->npc_class, play);
|
||||
p_sel->talk_end_flag = TRUE;
|
||||
res = TRUE;
|
||||
} else {
|
||||
int silent_counter = p_sel->silent_counter;
|
||||
|
||||
if (mMsg_Check_MainNormal(msg_p) == TRUE || mChoice_CHECK_MAIN_NORMAL() == TRUE) {
|
||||
silent_counter++;
|
||||
if (silent_counter > 600) {
|
||||
silent_counter = 600;
|
||||
}
|
||||
} else {
|
||||
silent_counter = 0;
|
||||
}
|
||||
|
||||
if (mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 0) == 0) {
|
||||
if (silent_counter >= 600) {
|
||||
if (p_sel->npc_class.draw.animation_id != aNPC_ANIM_4HAKU_E1) {
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 0, 255);
|
||||
}
|
||||
} else {
|
||||
if (p_sel->npc_class.draw.animation_id == aNPC_ANIM_4HAKU_E1) {
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 0, 253);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p_sel->silent_counter = silent_counter;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
#include "ac_npc_rcn_guide.h"
|
||||
|
||||
#include "m_play.h"
|
||||
#include "m_name_table.h"
|
||||
#include "libultra/libultra.h"
|
||||
#include "m_common_data.h"
|
||||
#include "m_player_lib.h"
|
||||
#include "m_bgm.h"
|
||||
#include "m_msg.h"
|
||||
#include "m_font.h"
|
||||
#include "m_house.h"
|
||||
#include "ac_intro_demo.h"
|
||||
|
||||
/* sizeof(aNRG_talk_data_c) == 0x0C */
|
||||
typedef struct rcn_guide_talk_data_s {
|
||||
/* 0x00 */ int msg_no;
|
||||
/* 0x04 */ u8 turn_flag;
|
||||
/* 0x05 */ u8 camera_type;
|
||||
/* 0x06 */ u8 melody_flag;
|
||||
/* 0x08 */ aNRG_TALK_PROC talk_proc;
|
||||
} aNRG_talk_data_c;
|
||||
|
||||
enum {
|
||||
aNRC_THINK_CALL,
|
||||
aNRC_THINK_APPROACH,
|
||||
aNRG_THINK_INTRODUCE,
|
||||
aNRC_THINK_TURN,
|
||||
aNRC_THINK_TAKE_WITH,
|
||||
aNRC_THINK_EXPLAIN,
|
||||
aNRC_THINK_DECIDE_HOUSE_WAIT,
|
||||
aNRC_THINK_STOP_WADE,
|
||||
aNRC_THINK_BEFORE_OPEN_DOOR_TALK,
|
||||
aNRC_THINK_BEFORE_OPEN_DOOR_TALK2,
|
||||
aNRC_THINK_ENTER_WAIT,
|
||||
aNRC_THINK_RESTART_WAIT,
|
||||
aNRC_THINK_RESTART_TALK,
|
||||
aNRC_THINK_DECIDE_HOUSE,
|
||||
aNRC_THINK_EXIT_TURN,
|
||||
aNRC_THINK_EXIT,
|
||||
aNRC_THINK_WAIT,
|
||||
|
||||
aNRC_THINK_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aNRG_FORCE_TALK_CALL,
|
||||
aNRG_FORCE_TALK_INTRODUCE,
|
||||
aNRG_FORCE_TALK_EXPLAIN,
|
||||
aNRG_FORCE_TALK_STOP_WADE,
|
||||
aNRG_FORCE_TALK_BEFORE_OPEN_DOOR_TALK,
|
||||
aNRG_FORCE_TALK_BEFORE_OPEN_DOOR2_TALK,
|
||||
aNRG_FORCE_TALK_HOUSE_TAKEN,
|
||||
aNRG_FORCE_TALK_HOUSE_VACANT,
|
||||
|
||||
aNRG_FORCE_TALK_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aNRG_NORM_TALK_DECIDE_HOUSE,
|
||||
|
||||
aNRG_NORM_TALK_NUM
|
||||
};
|
||||
|
||||
static void aNRG_actor_ct(ACTOR* actorx, GAME* game);
|
||||
static void aNRG_actor_save(ACTOR* actorx, GAME* game);
|
||||
static void aNRG_actor_dt(ACTOR* actorx, GAME* game);
|
||||
static void aNRG_actor_init(ACTOR* actorx, GAME* game);
|
||||
static void aNRG_actor_draw(ACTOR* actorx, GAME* game);
|
||||
static void aNRG_actor_move(ACTOR* actorx, GAME* game);
|
||||
|
||||
// clang-format off
|
||||
ACTOR_PROFILE Npc_Rcn_Guide_Profile = {
|
||||
mAc_PROFILE_NPC_RCN_GUIDE,
|
||||
ACTOR_PART_NPC,
|
||||
ACTOR_STATE_CAN_MOVE_IN_DEMO_SCENES | ACTOR_STATE_NO_MOVE_WHILE_CULLED,
|
||||
SP_NPC_RCN_GUIDE,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(NPC_RCN_GUIDE_ACTOR),
|
||||
&aNRG_actor_ct,
|
||||
&aNRG_actor_dt,
|
||||
&aNRG_actor_init,
|
||||
mActor_NONE_PROC1,
|
||||
&aNRG_actor_save,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static void aNRG_force_talk_request(ACTOR* actorx, GAME* game);
|
||||
static int aNRG_talk_init(ACTOR* actorx, GAME* game);
|
||||
static int aNRG_talk_end_chk(ACTOR* actorx, GAME* game);
|
||||
|
||||
static void aNRG_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* game, int sched_idx);
|
||||
static void aNRG_setup_think_proc(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play, int think_idx);
|
||||
|
||||
static void aNRG_actor_ct(ACTOR* actorx, GAME* game) {
|
||||
// clang-format off
|
||||
static aNPC_ct_data_c ct_data = {
|
||||
&aNRG_actor_move,
|
||||
&aNRG_actor_draw,
|
||||
5,
|
||||
&aNRG_force_talk_request,
|
||||
&aNRG_talk_init,
|
||||
&aNRG_talk_end_chk,
|
||||
0,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
NPC_RCN_GUIDE_ACTOR* rcn_guide = (NPC_RCN_GUIDE_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
PLAYER_ACTOR* player;
|
||||
s16 angle_y;
|
||||
|
||||
if (Common_Get(clip).npc_clip->birth_check_proc(actorx, &play->game) == TRUE) {
|
||||
rcn_guide->npc_class.schedule.schedule_proc = &aNRG_schedule_proc;
|
||||
Common_Get(clip).npc_clip->ct_proc(actorx, &play->game, &ct_data);
|
||||
rcn_guide->npc_class.collision.priority = 2;
|
||||
rcn_guide->melody_copy = rcn_guide->npc_class.talk_info.melody_inst;
|
||||
|
||||
/* Set shop acre */
|
||||
mFI_BlockKind2BkNum(&rcn_guide->shop_bx, &rcn_guide->shop_bz, mRF_BLOCKKIND_SHOP);
|
||||
|
||||
rcn_guide->npc_class.draw.main_animation.keyframe.morph_counter = 0.0f;
|
||||
rcn_guide->npc_class.actor_class.status_data.weight = 255;
|
||||
|
||||
player = GET_PLAYER_ACTOR(play);
|
||||
if (player != NULL) {
|
||||
angle_y = search_position_angleY(&rcn_guide->npc_class.actor_class.world.position,
|
||||
&player->actor_class.world.position);
|
||||
} else {
|
||||
angle_y = 0;
|
||||
}
|
||||
|
||||
rcn_guide->npc_class.actor_class.shape_info.rotation.y = angle_y;
|
||||
rcn_guide->npc_class.actor_class.world.angle.y = angle_y;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG_actor_save(ACTOR* actorx, GAME* game) {
|
||||
Common_Get(clip).npc_clip->save_proc(actorx, game);
|
||||
}
|
||||
|
||||
static void aNRG_actor_dt(ACTOR* actorx, GAME* game) {
|
||||
NPC_RCN_GUIDE_ACTOR* rcn_guide = (NPC_RCN_GUIDE_ACTOR*)actorx;
|
||||
|
||||
/* Stop playing the initial intro music when destruct due to entering a house */
|
||||
if (rcn_guide->think_idx == aNRC_THINK_WAIT) {
|
||||
mBGMPsComp_delete_ps_demo(BGM_INTRO_RCN_GUIDE, 0x168);
|
||||
}
|
||||
|
||||
Common_Get(clip).npc_clip->dt_proc(actorx, game);
|
||||
}
|
||||
|
||||
static void aNRG_actor_init(ACTOR* actorx, GAME* game) {
|
||||
Common_Get(clip).npc_clip->init_proc(actorx, game);
|
||||
}
|
||||
|
||||
static void aNRG_actor_draw(ACTOR* actorx, GAME* game) {
|
||||
Common_Get(clip).npc_clip->draw_proc(actorx, game);
|
||||
}
|
||||
|
||||
#include "../src/actor/ac_npc_rcn_guide_move.c_inc"
|
||||
#include "../src/actor/ac_npc_rcn_guide_talk.c_inc"
|
||||
#include "../src/actor/ac_npc_rcn_guide_schedule.c_inc"
|
||||
@@ -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/actor/ac_npc_rcn_guide2_move.c_inc"
|
||||
#include "../src/actor/ac_npc_rcn_guide2_talk.c_inc"
|
||||
#include "../src/actor/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_itemNo[] = {
|
||||
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_itemNo[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_itemNo[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;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
static int aNRG_set_request_act(NPC_RCN_GUIDE_ACTOR* rcn_guide, u8 act_prio, u8 act_idx, u8 act_type, u16 obj, int x,
|
||||
int z) {
|
||||
u16 args[6];
|
||||
int res = FALSE;
|
||||
|
||||
if (act_prio >= rcn_guide->npc_class.request.act_priority) {
|
||||
bzero(args, sizeof(args));
|
||||
args[0] = obj;
|
||||
args[2] = x;
|
||||
args[3] = z;
|
||||
rcn_guide->npc_class.request.act_priority = act_prio;
|
||||
rcn_guide->npc_class.request.act_idx = act_idx;
|
||||
rcn_guide->npc_class.request.act_type = act_type;
|
||||
mem_copy((u8*)rcn_guide->npc_class.request.act_args, (u8*)args, sizeof(args));
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void aNRG_set_house_master_name(int house_idx) {
|
||||
mMsg_SET_FREE_STR(mMsg_FREE_STR0, Save_Get(private_data[mHS_get_pl_no(house_idx)]).player_ID.player_name,
|
||||
PLAYER_NAME_LEN);
|
||||
}
|
||||
|
||||
static void aNRG_set_shop_address(NPC_RCN_GUIDE_ACTOR* rcn_guide) {
|
||||
static u8 choume_str[] = { 'Q', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
u8 str[1];
|
||||
|
||||
/* Set the row (Z) string */
|
||||
mMsg_SET_FREE_STR(mMsg_FREE_STR1, &choume_str[rcn_guide->shop_bz], 1);
|
||||
/* Set the column (X) string */
|
||||
mFont_UnintToString(str, sizeof(str), rcn_guide->shop_bx, sizeof(str), TRUE, FALSE, TRUE);
|
||||
mMsg_SET_FREE_STR(mMsg_FREE_STR2, str, sizeof(str));
|
||||
}
|
||||
|
||||
static void aNRG_actor_move(ACTOR* actorx, GAME* game) {
|
||||
Common_Get(clip).npc_clip->move_proc(actorx, game);
|
||||
}
|
||||
@@ -0,0 +1,407 @@
|
||||
typedef void (*aNRG_THINK_INIT_PROC)(NPC_RCN_GUIDE_ACTOR*, GAME_PLAY*);
|
||||
|
||||
typedef struct npc_rcn_guide_setup_think_s {
|
||||
aNRG_THINK_PROC think_proc;
|
||||
aNRG_THINK_INIT_PROC think_init_proc;
|
||||
aNPC_TALK_REQUEST_PROC talk_request_proc;
|
||||
u8 talk_idx;
|
||||
u8 next_think_idx;
|
||||
} aNRG_setup_think_c;
|
||||
|
||||
static void aNRG_approach(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) {
|
||||
if (rcn_guide->npc_class.action.step == aNPC_ACTION_END_STEP && rcn_guide->npc_class.action.idx == 2) {
|
||||
aNRG_setup_think_proc(rcn_guide, play, aNRG_THINK_INTRODUCE);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG_turn(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) {
|
||||
if (rcn_guide->npc_class.action.step == aNPC_ACTION_END_STEP && rcn_guide->npc_class.action.idx == 3) {
|
||||
aNRG_setup_think_proc(rcn_guide, play, rcn_guide->next_think_idx);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG_take_with(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) {
|
||||
if (rcn_guide->npc_class.action.step == aNPC_ACTION_END_STEP && rcn_guide->npc_class.action.idx == 2) {
|
||||
int path = rcn_guide->path;
|
||||
|
||||
if (path >= 1) {
|
||||
aNRG_setup_think_proc(rcn_guide, play, aNRC_THINK_EXPLAIN);
|
||||
} else {
|
||||
aNRG_set_request_act(rcn_guide, 4, aNPC_ACT_WALK2, aNPC_ACT_TYPE_TO_POINT, aNPC_ACT_OBJ_DEFAULT, 2240,
|
||||
1500);
|
||||
path++;
|
||||
}
|
||||
|
||||
rcn_guide->path = path;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG_decide_house_wait(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) {
|
||||
int next_think_idx = -1;
|
||||
|
||||
if (GET_PLAYER_ACTOR_NOW()->excute_cancel_wade) {
|
||||
/* Player is trying to leave the acre, so let them know they can't */
|
||||
next_think_idx = aNRC_THINK_STOP_WADE;
|
||||
} else if (Common_Get(clip).demo_clip != NULL && Common_Get(clip).demo_clip->type == mDemo_CLIP_TYPE_INTRO_DEMO) {
|
||||
ACTOR* demo_actor = (ACTOR*)Common_Get(clip).demo_clip->demo_class;
|
||||
|
||||
if (demo_actor != NULL) {
|
||||
INTRO_DEMO_ACTOR* intro_demo = (INTRO_DEMO_ACTOR*)demo_actor;
|
||||
|
||||
switch (intro_demo->player_intro_demo_state) {
|
||||
case 1:
|
||||
next_think_idx = aNRC_THINK_BEFORE_OPEN_DOOR_TALK;
|
||||
break;
|
||||
case 2:
|
||||
next_think_idx = aNRC_THINK_BEFORE_OPEN_DOOR_TALK2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (next_think_idx >= 0) {
|
||||
aNRG_setup_think_proc(rcn_guide, play, next_think_idx);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG_enter_wait(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) {
|
||||
if (Common_Get(clip).demo_clip != NULL && Common_Get(clip).demo_clip->type == mDemo_CLIP_TYPE_INTRO_DEMO) {
|
||||
ACTOR* demo_actor = (ACTOR*)Common_Get(clip).demo_clip->demo_class;
|
||||
|
||||
if (demo_actor != NULL) {
|
||||
INTRO_DEMO_ACTOR* intro_demo = (INTRO_DEMO_ACTOR*)demo_actor;
|
||||
|
||||
intro_demo->player_in_house = TRUE;
|
||||
aNRG_setup_think_proc(rcn_guide, play, aNRC_THINK_WAIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG_exit(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) {
|
||||
static s16 moveX[] = { 2240, 2240, 2240, 2240 };
|
||||
static s16 moveZ[] = { 1900, 1980, 1300, 1220 };
|
||||
|
||||
if (rcn_guide->npc_class.action.step == aNPC_ACTION_END_STEP) {
|
||||
f32 posZ = rcn_guide->npc_class.actor_class.world.position.z;
|
||||
int idx;
|
||||
|
||||
if (posZ < 1540.0f) {
|
||||
if (posZ <= 1220.0f) {
|
||||
idx = -1;
|
||||
} else if (posZ <= 1300.0f) {
|
||||
idx = 3;
|
||||
} else {
|
||||
idx = 2;
|
||||
}
|
||||
} else {
|
||||
if (posZ >= 1980.0f) {
|
||||
idx = -1;
|
||||
} else if (posZ >= 1900.0f) {
|
||||
idx = 1;
|
||||
} else {
|
||||
idx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (idx == -1) {
|
||||
if (Common_Get(clip).demo_clip != NULL && Common_Get(clip).demo_clip->type == mDemo_CLIP_TYPE_INTRO_DEMO) {
|
||||
ACTOR* demo_actor = (ACTOR*)Common_Get(clip).demo_clip->demo_class;
|
||||
|
||||
if (demo_actor != NULL) {
|
||||
INTRO_DEMO_ACTOR* intro_demo = (INTRO_DEMO_ACTOR*)demo_actor;
|
||||
|
||||
intro_demo->rcn_guide_actor_p = NULL;
|
||||
Actor_delete(&rcn_guide->npc_class.actor_class);
|
||||
play->submenu.start_refuse = FALSE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
aNRG_set_request_act(rcn_guide, 4, aNPC_ACT_WALK2, aNPC_ACT_TYPE_TO_POINT, aNPC_ACT_OBJ_DEFAULT, moveX[idx],
|
||||
moveZ[idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG_restart_wait(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) {
|
||||
int think_idx;
|
||||
|
||||
if (mPlib_check_player_actor_main_index_OutDoorMove2(&play->game) == FALSE) {
|
||||
switch (rcn_guide->npc_class.actor_class.actor_specific) {
|
||||
case 1:
|
||||
think_idx = aNRC_THINK_DECIDE_HOUSE;
|
||||
break;
|
||||
default:
|
||||
think_idx = aNRC_THINK_RESTART_TALK;
|
||||
break;
|
||||
}
|
||||
|
||||
aNRG_setup_think_proc(rcn_guide, play, think_idx);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG_think_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
NPC_RCN_GUIDE_ACTOR* rcn_guide = (NPC_RCN_GUIDE_ACTOR*)nactorx;
|
||||
|
||||
(*rcn_guide->think_proc)(rcn_guide, play);
|
||||
}
|
||||
|
||||
static void aNRG_think_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
NPC_RCN_GUIDE_ACTOR* rcn_guide = (NPC_RCN_GUIDE_ACTOR*)nactorx;
|
||||
int think_idx;
|
||||
|
||||
switch (rcn_guide->npc_class.actor_class.actor_specific) {
|
||||
case 1:
|
||||
case 2:
|
||||
think_idx = aNRC_THINK_RESTART_WAIT;
|
||||
break;
|
||||
default:
|
||||
think_idx = aNRC_THINK_CALL;
|
||||
break;
|
||||
}
|
||||
|
||||
aNRG_setup_think_proc(rcn_guide, play, think_idx);
|
||||
rcn_guide->npc_class.condition_info.hide_request = FALSE;
|
||||
}
|
||||
|
||||
static void aNRG_call_init(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) {
|
||||
s16 angle_y = atans_table(980.0f - rcn_guide->npc_class.actor_class.world.position.z,
|
||||
2320.0f - rcn_guide->npc_class.actor_class.world.position.x);
|
||||
|
||||
rcn_guide->npc_class.actor_class.shape_info.rotation.y = angle_y;
|
||||
rcn_guide->npc_class.actor_class.world.angle.y = angle_y;
|
||||
}
|
||||
|
||||
static void aNRG_approach_init(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) {
|
||||
PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play);
|
||||
f32 x;
|
||||
f32 z;
|
||||
|
||||
/* Player cannot open the start menu */
|
||||
play->submenu.start_refuse = TRUE;
|
||||
/* Make the player stand around waiting */
|
||||
mPlib_request_main_demo_wait_type1(&play->game, 0, NULL);
|
||||
|
||||
if (player != NULL) {
|
||||
/* Move to a bit below where the player is */
|
||||
x = player->actor_class.world.position.x;
|
||||
z = player->actor_class.world.position.z + 70.0f;
|
||||
} else {
|
||||
/* Move to a predefined position -- how would the player even be NULL? */
|
||||
x = 2320.0f;
|
||||
z = 1050.0f;
|
||||
}
|
||||
|
||||
/* Request action to move to desired location */
|
||||
aNRG_set_request_act(rcn_guide, 4, aNPC_ACT_WALK2, aNPC_ACT_TYPE_TO_POINT, aNPC_ACT_OBJ_DEFAULT, x, z);
|
||||
}
|
||||
|
||||
static void aNRG_introduce_init(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) {
|
||||
aNRG_set_request_act(rcn_guide, 4, aNPC_ACT_WAIT, aNPC_ACT_TYPE_DEFAULT, aNPC_ACT_OBJ_DEFAULT, 0, 0);
|
||||
}
|
||||
|
||||
static void aNRG_turn_init(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) {
|
||||
mPlib_request_main_demo_wait_type1(&play->game, 0, NULL);
|
||||
aNRG_set_request_act(rcn_guide, 4, aNPC_ACT_TURN, aNPC_ACT_TYPE_TO_POINT, aNPC_ACT_OBJ_DEFAULT, 2240, 1300);
|
||||
}
|
||||
|
||||
static void aNRG_take_with_init(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) {
|
||||
if (Common_Get(clip).demo_clip != NULL && Common_Get(clip).demo_clip->type == mDemo_CLIP_TYPE_INTRO_DEMO) {
|
||||
ACTOR* demo_actor = (ACTOR*)Common_Get(clip).demo_clip->demo_class;
|
||||
|
||||
if (demo_actor != NULL) {
|
||||
INTRO_DEMO_ACTOR* intro_demo = (INTRO_DEMO_ACTOR*)demo_actor;
|
||||
|
||||
intro_demo->talk_flag = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
aNRG_set_request_act(rcn_guide, 4, aNPC_ACT_WALK2, aNPC_ACT_TYPE_TO_POINT, aNPC_ACT_OBJ_DEFAULT, 2240, 1300);
|
||||
}
|
||||
|
||||
static void aNRG_before_open_door_talk2_init(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) {
|
||||
INTRO_DEMO_ACTOR* intro_demo = (INTRO_DEMO_ACTOR*)Common_Get(clip).demo_clip->demo_class;
|
||||
|
||||
aNRG_set_house_master_name(intro_demo->house_idx);
|
||||
}
|
||||
|
||||
static void aNRG_exit_turn_init(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) {
|
||||
static s16 moveX[] = { 2240, 2240 };
|
||||
static s16 moveZ[] = { 1900, 1300 };
|
||||
int idx = 0;
|
||||
|
||||
if (rcn_guide->npc_class.actor_class.world.position.z < 1540.0f) {
|
||||
idx = 1;
|
||||
}
|
||||
|
||||
aNRG_set_request_act(rcn_guide, 4, aNPC_ACT_TURN, aNPC_ACT_TYPE_TO_POINT, aNPC_ACT_OBJ_DEFAULT, moveX[idx],
|
||||
moveZ[idx]);
|
||||
if (Common_Get(clip).demo_clip != NULL && Common_Get(clip).demo_clip->type == mDemo_CLIP_TYPE_INTRO_DEMO) {
|
||||
ACTOR* demo_actor = (ACTOR*)Common_Get(clip).demo_clip->demo_class;
|
||||
|
||||
if (demo_actor != NULL) {
|
||||
INTRO_DEMO_ACTOR* intro_demo = (INTRO_DEMO_ACTOR*)demo_actor;
|
||||
|
||||
intro_demo->talk_flag = TRUE;
|
||||
}
|
||||
}
|
||||
rcn_guide->next_think_idx = aNRC_THINK_EXIT;
|
||||
}
|
||||
|
||||
static void aNRG_setup_think_proc(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play, int think_idx) {
|
||||
// clang-format off
|
||||
static aNRG_setup_think_c dt_tbl[] = {
|
||||
{
|
||||
(aNRG_THINK_PROC)&none_proc1,
|
||||
&aNRG_call_init,
|
||||
&aNRG_force_talk_request,
|
||||
aNRG_FORCE_TALK_CALL,
|
||||
aNRC_THINK_APPROACH,
|
||||
},
|
||||
{
|
||||
&aNRG_approach,
|
||||
&aNRG_approach_init,
|
||||
(aNPC_TALK_REQUEST_PROC)&none_proc1,
|
||||
aNRG_FORCE_TALK_CALL,
|
||||
aNRC_THINK_APPROACH,
|
||||
},
|
||||
{
|
||||
(aNRG_THINK_PROC)&none_proc1,
|
||||
&aNRG_introduce_init,
|
||||
&aNRG_force_talk_request,
|
||||
aNRG_FORCE_TALK_INTRODUCE,
|
||||
aNRC_THINK_TURN,
|
||||
},
|
||||
{
|
||||
&aNRG_turn,
|
||||
&aNRG_turn_init,
|
||||
(aNPC_TALK_REQUEST_PROC)&none_proc1,
|
||||
aNRG_FORCE_TALK_CALL,
|
||||
aNRC_THINK_TAKE_WITH,
|
||||
},
|
||||
{
|
||||
&aNRG_take_with,
|
||||
&aNRG_take_with_init,
|
||||
(aNPC_TALK_REQUEST_PROC)&none_proc1,
|
||||
aNRG_FORCE_TALK_CALL,
|
||||
aNRC_THINK_TAKE_WITH,
|
||||
},
|
||||
{
|
||||
(aNRG_THINK_PROC)&none_proc1,
|
||||
(aNRG_THINK_INIT_PROC)&none_proc1,
|
||||
&aNRG_force_talk_request,
|
||||
aNRG_FORCE_TALK_EXPLAIN,
|
||||
aNRC_THINK_DECIDE_HOUSE_WAIT,
|
||||
},
|
||||
{
|
||||
&aNRG_decide_house_wait,
|
||||
&aNRG_introduce_init,
|
||||
&aNRG_norm_talk_request,
|
||||
aNRG_NORM_TALK_DECIDE_HOUSE,
|
||||
aNRC_THINK_DECIDE_HOUSE_WAIT,
|
||||
},
|
||||
{
|
||||
(aNRG_THINK_PROC)&none_proc1,
|
||||
(aNRG_THINK_INIT_PROC)&none_proc1,
|
||||
&aNRG_force_talk_request,
|
||||
aNRG_FORCE_TALK_STOP_WADE,
|
||||
aNRC_THINK_DECIDE_HOUSE_WAIT,
|
||||
},
|
||||
{
|
||||
(aNRG_THINK_PROC)&none_proc1,
|
||||
(aNRG_THINK_INIT_PROC)&none_proc1,
|
||||
&aNRG_force_talk_request,
|
||||
aNRG_FORCE_TALK_BEFORE_OPEN_DOOR_TALK,
|
||||
aNRC_THINK_ENTER_WAIT,
|
||||
},
|
||||
{
|
||||
(aNRG_THINK_PROC)&none_proc1,
|
||||
&aNRG_before_open_door_talk2_init,
|
||||
&aNRG_force_talk_request,
|
||||
aNRG_FORCE_TALK_BEFORE_OPEN_DOOR2_TALK,
|
||||
aNRC_THINK_ENTER_WAIT,
|
||||
},
|
||||
{
|
||||
&aNRG_enter_wait,
|
||||
(aNRG_THINK_INIT_PROC)&none_proc1,
|
||||
(aNPC_TALK_REQUEST_PROC)&none_proc1,
|
||||
aNRG_FORCE_TALK_CALL,
|
||||
aNRC_THINK_ENTER_WAIT,
|
||||
},
|
||||
{
|
||||
&aNRG_restart_wait,
|
||||
(aNRG_THINK_INIT_PROC)&none_proc1,
|
||||
(aNPC_TALK_REQUEST_PROC)&none_proc1,
|
||||
aNRG_FORCE_TALK_CALL,
|
||||
aNRC_THINK_RESTART_WAIT,
|
||||
},
|
||||
{
|
||||
(aNRG_THINK_PROC)&none_proc1,
|
||||
(aNRG_THINK_INIT_PROC)&none_proc1,
|
||||
&aNRG_force_talk_request,
|
||||
aNRG_FORCE_TALK_HOUSE_TAKEN,
|
||||
aNRC_THINK_DECIDE_HOUSE_WAIT,
|
||||
},
|
||||
{
|
||||
(aNRG_THINK_PROC)&none_proc1,
|
||||
(aNRG_THINK_INIT_PROC)&none_proc1,
|
||||
&aNRG_force_talk_request,
|
||||
aNRG_FORCE_TALK_HOUSE_VACANT,
|
||||
aNRC_THINK_DECIDE_HOUSE_WAIT,
|
||||
},
|
||||
{
|
||||
&aNRG_turn,
|
||||
&aNRG_exit_turn_init,
|
||||
(aNPC_TALK_REQUEST_PROC)&none_proc1,
|
||||
aNRG_FORCE_TALK_CALL,
|
||||
aNRC_THINK_EXIT_TURN,
|
||||
},
|
||||
{
|
||||
&aNRG_exit,
|
||||
(aNRG_THINK_INIT_PROC)&none_proc1,
|
||||
(aNPC_TALK_REQUEST_PROC)&none_proc1,
|
||||
aNRG_FORCE_TALK_CALL,
|
||||
aNRC_THINK_EXIT,
|
||||
},
|
||||
{
|
||||
(aNRG_THINK_PROC)&none_proc1,
|
||||
(aNRG_THINK_INIT_PROC)&none_proc1,
|
||||
(aNPC_TALK_REQUEST_PROC)&none_proc1,
|
||||
aNRG_FORCE_TALK_CALL,
|
||||
aNRC_THINK_WAIT,
|
||||
},
|
||||
};
|
||||
// clang-format on
|
||||
aNRG_setup_think_c* think_data = &dt_tbl[think_idx];
|
||||
|
||||
rcn_guide->think_idx = think_idx;
|
||||
rcn_guide->think_proc = think_data->think_proc;
|
||||
rcn_guide->npc_class.talk_info.talk_request_proc = think_data->talk_request_proc;
|
||||
rcn_guide->talk_idx = think_data->talk_idx;
|
||||
rcn_guide->next_think_idx = think_data->next_think_idx;
|
||||
(*think_data->think_init_proc)(rcn_guide, play);
|
||||
}
|
||||
|
||||
static void aNRG_think_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int type) {
|
||||
static aNPC_SUB_PROC think_proc[] = { &aNRG_think_init_proc, &aNRG_think_main_proc };
|
||||
|
||||
(*think_proc[type])(nactorx, play);
|
||||
}
|
||||
|
||||
static void aNRG_schedule_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
nactorx->think.think_proc = &aNRG_think_proc;
|
||||
Common_Get(clip).npc_clip->think_proc(nactorx, play, aNPC_THINK_SPECIAL, 0);
|
||||
}
|
||||
|
||||
static void aNRG_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 aNRG_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int type) {
|
||||
static aNPC_SUB_PROC sche_proc[] = { &aNRG_schedule_init_proc, &aNRG_schedule_main_proc };
|
||||
|
||||
(*sche_proc[type])(nactorx, play);
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
enum {
|
||||
aNRG_TALK_DEMAND_PAYMENT,
|
||||
aNRG_TALK_MENU_OPEN_WAIT,
|
||||
aNRG_TALK_MENU_CLOSE_WAIT,
|
||||
aNRG_TALK_DEMO_START_WAIT,
|
||||
aNRG_TALK_DEMO_END_WAIT,
|
||||
aNRG_TALK_FINISHED,
|
||||
|
||||
aNRG_TALK_NUM
|
||||
};
|
||||
|
||||
static void aNRG_demand_payment_change_talk_proc(NPC_RCN_GUIDE_ACTOR* rcn_guide, int talk_proc_idx);
|
||||
|
||||
static void aNRG_demand_payment_talk_proc(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) {
|
||||
u16 order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
|
||||
if (order != 0) {
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
mMsg_REQUEST_MAIN_DISAPPEAR_WAIT_TYPE1();
|
||||
aNRG_demand_payment_change_talk_proc(rcn_guide, aNRG_TALK_MENU_OPEN_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG_menu_open_wait_talk_proc(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) {
|
||||
if (mMsg_CHECK_MAIN_WAIT() == TRUE) {
|
||||
Submenu* submenu = &play->submenu;
|
||||
int idx = mPr_GetPossessionItemIdxWithCond(Now_Private, ITM_MONEY_1000, mPr_ITEM_COND_QUEST);
|
||||
|
||||
mSM_open_submenu(submenu, mSM_OVL_INVENTORY, mSM_IV_OPEN_QUEST, idx);
|
||||
mMsg_SET_LOCKCONTINUE();
|
||||
aNRG_demand_payment_change_talk_proc(rcn_guide, aNRG_TALK_MENU_CLOSE_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG_menu_close_wait_talk_proc(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) {
|
||||
Submenu* submenu = &play->submenu;
|
||||
|
||||
if (submenu->open_flag == FALSE) {
|
||||
if (submenu->item_p->item == EMPTY_NO) {
|
||||
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
|
||||
|
||||
mMsg_request_main_appear_wait_type1(msg_p);
|
||||
mMsg_ChangeMsgData(msg_p, 0x07EB); /* 'You better pay it all back, or I will have to...' */
|
||||
mMsg_Set_ForceNext(msg_p);
|
||||
mMsg_Unset_LockContinue(msg_p);
|
||||
aNRG_demand_payment_change_talk_proc(rcn_guide, aNRG_TALK_DEMAND_PAYMENT); /* Go back to first state */
|
||||
} else {
|
||||
aNRG_demand_payment_change_talk_proc(rcn_guide, aNRG_TALK_DEMO_START_WAIT); /* Handed over the Bells */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG_demo_start_wait_talk_proc(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) {
|
||||
if (Common_Get(clip).handOverItem_clip->request_mode == aHOI_REQUEST_TRANS_WAIT) {
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 1, 3);
|
||||
aNRG_demand_payment_change_talk_proc(rcn_guide, aNRG_TALK_DEMO_END_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG_demo_end_wait_talk_proc(NPC_RCN_GUIDE_ACTOR* rcn_guide, GAME_PLAY* play) {
|
||||
if (Common_Get(clip).handOverItem_clip->master_actor == NULL) {
|
||||
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
|
||||
|
||||
aNRG_set_shop_address(rcn_guide);
|
||||
rcn_guide->next_think_idx = aNRC_THINK_EXIT_TURN;
|
||||
mMsg_request_main_appear_wait_type1(msg_p);
|
||||
mMsg_Set_ForceNext(msg_p);
|
||||
aNRG_demand_payment_change_talk_proc(rcn_guide, aNRG_TALK_FINISHED);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG_demand_payment_change_talk_proc(NPC_RCN_GUIDE_ACTOR* rcn_guide, int talk_proc_idx) {
|
||||
// clang-format off
|
||||
static aNRG_TALK_PROC talk_proc[] = {
|
||||
&aNRG_demand_payment_talk_proc,
|
||||
&aNRG_menu_open_wait_talk_proc,
|
||||
&aNRG_menu_close_wait_talk_proc,
|
||||
&aNRG_demo_start_wait_talk_proc,
|
||||
&aNRG_demo_end_wait_talk_proc,
|
||||
(aNRG_TALK_PROC)&none_proc1,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
rcn_guide->talk_proc = talk_proc[talk_proc_idx];
|
||||
}
|
||||
|
||||
static void aNRG_set_force_talk_info(ACTOR* actorx) {
|
||||
// clang-format off
|
||||
static aNRG_talk_data_c dt_tbl[] = {
|
||||
{ 0x07DE, TRUE, CAMERA2_PROCESS_NORMAL, TRUE, (aNRG_TALK_PROC)&none_proc1 }, /* Step down from train station */
|
||||
{ 0x07DF, TRUE, CAMERA2_PROCESS_TALK, FALSE, (aNRG_TALK_PROC)&none_proc1 }, /* Ask about call from Rover */
|
||||
{ 0x07E1, TRUE, CAMERA2_PROCESS_TALK, FALSE, (aNRG_TALK_PROC)&none_proc1 }, /* Show houses */
|
||||
{ 0x07E2, TRUE, CAMERA2_PROCESS_NORMAL, FALSE, (aNRG_TALK_PROC)&none_proc1 }, /* Player tries leaving acre */
|
||||
{ 0x07E4, FALSE, CAMERA2_PROCESS_NORMAL, FALSE, (aNRG_TALK_PROC)&none_proc1 }, /* Player enters empty house */
|
||||
{ 0x07E3, FALSE, CAMERA2_PROCESS_NORMAL, FALSE, (aNRG_TALK_PROC)&none_proc1 }, /* Player enters taken house */
|
||||
{ 0x07E5, TRUE, CAMERA2_PROCESS_TALK, TRUE, (aNRG_TALK_PROC)&none_proc1 }, /* Player exits taken house */
|
||||
{ 0x07E6, TRUE, CAMERA2_PROCESS_TALK, TRUE, &aNRG_demand_payment_talk_proc }, /* Player exits empty house */
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
NPC_RCN_GUIDE_ACTOR* rcn_guide = (NPC_RCN_GUIDE_ACTOR*)actorx;
|
||||
int talk_idx = rcn_guide->talk_idx;
|
||||
aNRG_talk_data_c* data = &dt_tbl[talk_idx];
|
||||
|
||||
mDemo_Set_msg_num(data->msg_no);
|
||||
mDemo_Set_talk_turn(data->turn_flag);
|
||||
mDemo_Set_camera(data->camera_type);
|
||||
rcn_guide->talk_proc_idx = aNRG_TALK_DEMAND_PAYMENT;
|
||||
rcn_guide->talk_proc = data->talk_proc;
|
||||
if (data->melody_flag == TRUE) {
|
||||
rcn_guide->npc_class.talk_info.melody_inst = rcn_guide->melody_copy;
|
||||
} else {
|
||||
rcn_guide->npc_class.talk_info.melody_inst = 0;
|
||||
}
|
||||
|
||||
if (talk_idx == 0) {
|
||||
mBGMPsComp_make_ps_quiet(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG_force_talk_request(ACTOR* actorx, GAME* game) {
|
||||
mDemo_Request(mDemo_TYPE_SPEAK, actorx, &aNRG_set_force_talk_info);
|
||||
}
|
||||
|
||||
static void aNRG_set_norm_talk_info(ACTOR* actorx) {
|
||||
static aNRG_talk_data_c dt_tbl[] = {
|
||||
{ 0x0820, TRUE, CAMERA2_PROCESS_TALK, FALSE, (aNRG_TALK_PROC)&none_proc1 }, /* Normal talk about houses */
|
||||
};
|
||||
|
||||
NPC_RCN_GUIDE_ACTOR* rcn_guide = (NPC_RCN_GUIDE_ACTOR*)actorx;
|
||||
aNRG_talk_data_c* data = &dt_tbl[rcn_guide->talk_idx];
|
||||
|
||||
mDemo_Set_msg_num(data->msg_no);
|
||||
mDemo_Set_talk_turn(data->turn_flag);
|
||||
mDemo_Set_camera(data->camera_type);
|
||||
rcn_guide->talk_proc_idx = aNRG_TALK_DEMAND_PAYMENT;
|
||||
rcn_guide->talk_proc = data->talk_proc;
|
||||
if (data->melody_flag == TRUE) {
|
||||
rcn_guide->npc_class.talk_info.melody_inst = rcn_guide->melody_copy;
|
||||
} else {
|
||||
rcn_guide->npc_class.talk_info.melody_inst = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRG_norm_talk_request(ACTOR* actorx, GAME* game) {
|
||||
mDemo_Request(mDemo_TYPE_TALK, actorx, &aNRG_set_norm_talk_info);
|
||||
}
|
||||
|
||||
static int aNRG_talk_init(ACTOR* actorx, GAME* game) {
|
||||
NPC_RCN_GUIDE_ACTOR* rcn_guide = (NPC_RCN_GUIDE_ACTOR*)actorx;
|
||||
|
||||
rcn_guide->npc_class.talk_info.talk_request_proc = (aNPC_TALK_REQUEST_PROC)&none_proc1;
|
||||
mDemo_Set_ListenAble();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int aNRG_talk_end_chk(ACTOR* actorx, GAME* game) {
|
||||
NPC_RCN_GUIDE_ACTOR* rcn_guide = (NPC_RCN_GUIDE_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
int res = FALSE;
|
||||
|
||||
(*rcn_guide->talk_proc)(rcn_guide, play);
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, actorx) == FALSE && mDemo_Check(mDemo_TYPE_TALK, actorx) == FALSE) {
|
||||
/* We're done talking so move onto the next schedule step */
|
||||
aNRG_setup_think_proc(rcn_guide, play, rcn_guide->next_think_idx);
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
#include "ac_npc_rtc.h"
|
||||
|
||||
#include "m_name_table.h"
|
||||
#include "m_common_data.h"
|
||||
#include "m_player_lib.h"
|
||||
#include "jaudio_NES/staff.h"
|
||||
#include "m_msg.h"
|
||||
#include "m_bgm.h"
|
||||
#include "m_soncho.h"
|
||||
#include "m_card.h"
|
||||
#include "boot.h"
|
||||
#include "m_string.h"
|
||||
#include "libultra/libultra.h"
|
||||
#include "m_timeIn_ovl.h"
|
||||
|
||||
enum {
|
||||
aNRTC_THINK_START,
|
||||
aNRTC_THINK_TITLE,
|
||||
aNRTC_THINK_DOOR,
|
||||
aNRTC_THINK_CHECK,
|
||||
aNRTC_THINK_IPMENU,
|
||||
aNRTC_THINK_WAIT,
|
||||
|
||||
aNRTC_THINK_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aNRTC_TALK_BREAK_DATA,
|
||||
aNRTC_TALK_BREAK_DATA2,
|
||||
aNRTC_TALK_RTC_ERR,
|
||||
aNRTC_TALK_TIMER_OPEN_MSG_WAIT,
|
||||
aNRTC_TALK_TIMER_OPEN_WAIT,
|
||||
aNRTC_TALK_TIMER_CLOSE_WAIT,
|
||||
aNRTC_TALK_DELETE_BF,
|
||||
aNRTC_TALK_DELETE,
|
||||
aNRTC_TALK_FORMAT_CHK,
|
||||
aNRTC_TALK_FORMAT,
|
||||
aNRTC_TALK_END,
|
||||
|
||||
aNRTC_TALK_NUM
|
||||
};
|
||||
|
||||
static void aNRTC_actor_ct(ACTOR*, GAME*);
|
||||
static void aNRTC_actor_dt(ACTOR*, GAME*);
|
||||
static void aNRTC_actor_init(ACTOR*, GAME*);
|
||||
static void aNRTC_actor_save(ACTOR*, GAME*);
|
||||
|
||||
// clang-format off
|
||||
ACTOR_PROFILE Npc_Rtc_Profile = {
|
||||
mAc_PROFILE_NPC_RTC,
|
||||
ACTOR_PART_NPC,
|
||||
ACTOR_STATE_NONE,
|
||||
SP_NPC_RTC,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(NPC_RTC_ACTOR),
|
||||
&aNRTC_actor_ct,
|
||||
&aNRTC_actor_dt,
|
||||
&aNRTC_actor_init,
|
||||
mActor_NONE_PROC1,
|
||||
&aNRTC_actor_save,
|
||||
};
|
||||
|
||||
static void aNRTC_actor_move(ACTOR*, GAME*);
|
||||
static void aNRTC_actor_draw(ACTOR*, GAME*);
|
||||
|
||||
static int aNRTC_talk_init(ACTOR*, GAME*);
|
||||
static int aNRTC_talk_end_chk(ACTOR*, GAME*);
|
||||
|
||||
static void aNRTC_schedule_proc(NPC_ACTOR*, GAME_PLAY*, int);
|
||||
|
||||
static void aNRTC_talk_request(ACTOR* actor, GAME*);
|
||||
|
||||
static void aNRTC_change_talk_proc(NPC_RTC_ACTOR* rtc, int idx);
|
||||
|
||||
static u8 aNRTC_sound_mode[] = { Config_SOUND_MODE_STEREO, Config_SOUND_MODE_MONO, Config_SOUND_MODE_HEADPHONES };
|
||||
static u8 aNRTC_voice_mode[] = { Config_VOICE_MODE_ANIMALESE, Config_VOICE_MODE_CLICK, Config_VOICE_MODE_SILENT };
|
||||
|
||||
static void aNRTC_actor_ct(ACTOR* actor, GAME* game) {
|
||||
// clang-format off
|
||||
static aNPC_ct_data_c ct_data = {
|
||||
&aNRTC_actor_move,
|
||||
&aNRTC_actor_draw,
|
||||
5,
|
||||
mActor_NONE_PROC1,
|
||||
&aNRTC_talk_init,
|
||||
&aNRTC_talk_end_chk,
|
||||
0,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
NPC_RTC_ACTOR* rtc = (NPC_RTC_ACTOR*)actor;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
PLAYER_ACTOR* player;
|
||||
xyz_t center;
|
||||
xyz_t eye;
|
||||
if (Common_Get(clip.npc_clip)->birth_check_proc(actor, game) == TRUE) {
|
||||
rtc->npc_class.schedule.schedule_proc = &aNRTC_schedule_proc;
|
||||
Common_Get(clip.npc_clip)->ct_proc(actor, game, &ct_data);
|
||||
actor->status_data.weight = MASSTYPE_IMMOVABLE;
|
||||
mPlib_request_main_demo_wait_type1(game, 0, NULL);
|
||||
player = GET_PLAYER_ACTOR(play);
|
||||
if (player != NULL) {
|
||||
player->actor_class.state_bitfield |= ACTOR_STATE_INVISIBLE;
|
||||
}
|
||||
|
||||
center.x = 100.0f;
|
||||
center.y = 60.0f;
|
||||
center.z = 60.0f;
|
||||
|
||||
eye.x = 100.0f;
|
||||
eye.y = 130.0f;
|
||||
eye.z = 210.0f;
|
||||
|
||||
Camera2_change_priority(play, 0);
|
||||
Camera2_request_main_lock(play, ¢er, &eye, 40.0f, 0, 100.0f, 400.0f, 5);
|
||||
sAdo_SetOutMode(aNRTC_sound_mode[Save_Get(config.sound_mode)]);
|
||||
sAdo_SetVoiceMode(aNRTC_voice_mode[Save_Get(config.voice_mode)]);
|
||||
rtc->npc_class.condition_info.hide_request = 0;
|
||||
rtc->npc_class.talk_info.default_act = 9;
|
||||
rtc->npc_class.talk_info.melody_inst = 0;
|
||||
rtc->talk_flag = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRTC_actor_save(ACTOR* actor, GAME* game) {
|
||||
Common_Get(clip.npc_clip)->save_proc(actor, game);
|
||||
}
|
||||
|
||||
static void aNRTC_actor_dt(ACTOR* actor, GAME* game) {
|
||||
Common_Get(clip.npc_clip)->dt_proc(actor, game);
|
||||
}
|
||||
|
||||
static void aNRTC_actor_init(ACTOR* actor, GAME* game) {
|
||||
Common_Get(clip.npc_clip)->init_proc(actor, game);
|
||||
}
|
||||
|
||||
static void aNRTC_actor_move(ACTOR* actor, GAME* game) {
|
||||
StaffRollInfo_c info;
|
||||
f32 val = 0.5f;
|
||||
u8 arm_flag = TRUE;
|
||||
NPC_RTC_ACTOR* rtc = (NPC_RTC_ACTOR*)actor;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
|
||||
if (rtc->npc_class.draw.animation_id == aNPC_ANIM_4HAKU_E1) {
|
||||
sAdos_GetStaffRollInfo(&info);
|
||||
if (info.staffroll_part != STAFFROLL_PART_FINISH) {
|
||||
val = 0.0f;
|
||||
arm_flag = FALSE;
|
||||
rtc->npc_class.draw.main_animation.keyframe.frame_control.current_frame =
|
||||
1.0f + (64.0f * (f32)info.percent);
|
||||
}
|
||||
}
|
||||
|
||||
rtc->npc_class.draw.main_animation.keyframe.frame_control.speed = val;
|
||||
sAdos_TTKK_ARM(arm_flag);
|
||||
Common_Get(clip.npc_clip)->move_proc(actor, game);
|
||||
mSC_change_player_freeze(play);
|
||||
}
|
||||
|
||||
static void aNRTC_actor_draw(ACTOR* actor, GAME* game) {
|
||||
Common_Get(clip.npc_clip)->draw_proc(actor, game);
|
||||
}
|
||||
|
||||
#include "../src/actor/ac_npc_rtc_think.c.inc"
|
||||
#include "../src/actor/ac_npc_rtc_talk.c.inc"
|
||||
@@ -0,0 +1,321 @@
|
||||
static void aNRTC_set_slot_name(int slot_id, int str_no) {
|
||||
u8 name[mIN_ITEM_NAME_LEN];
|
||||
|
||||
mString_Load_StringFromRom(name, sizeof(name), 0x06CD + slot_id);
|
||||
mMsg_SET_FREE_STR(str_no, name, sizeof(name));
|
||||
}
|
||||
|
||||
static void aNRTC_rtc_err(NPC_RTC_ACTOR* rtc, GAME_PLAY* play) {
|
||||
if (mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) {
|
||||
switch (mChoice_GET_CHOSENUM()) {
|
||||
case mChoice_CHOICE0:
|
||||
aNRTC_change_talk_proc(rtc, aNRTC_TALK_TIMER_OPEN_MSG_WAIT);
|
||||
break;
|
||||
case mChoice_CHOICE1:
|
||||
rtc->think_idx = aNRTC_THINK_TITLE;
|
||||
aNRTC_change_talk_proc(rtc, aNRTC_TALK_END);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRTC_timer_open_msg_wait(NPC_RTC_ACTOR* rtc, GAME_PLAY* play) {
|
||||
int order = mDemo_Get_OrderValue(mDemo_TYPE_4, 9);
|
||||
|
||||
if (order == 1) {
|
||||
if (mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) {
|
||||
mDemo_Set_OrderValue(mDemo_TYPE_4, 9, 0);
|
||||
aNRTC_change_talk_proc(rtc, aNRTC_TALK_TIMER_OPEN_WAIT);
|
||||
mMsg_REQUEST_MAIN_DISAPPEAR_WAIT_TYPE1();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRTC_timer_open_wait(NPC_RTC_ACTOR* rtc, GAME_PLAY* play) {
|
||||
Submenu* submenu = &play->submenu;
|
||||
|
||||
if (mMsg_CHECK_MAIN_WAIT() == TRUE) {
|
||||
aNRTC_change_talk_proc(rtc, aNRTC_THINK_WAIT);
|
||||
mSM_open_submenu(submenu, mSM_OVL_TIMEIN, mTI_OVL_OPEN_INITIAL, 0);
|
||||
mMsg_REQUEST_MAIN_APPEAR_WAIT_TYPE1();
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRTC_timer_close_wait(NPC_RTC_ACTOR* rtc, GAME_PLAY* play) {
|
||||
if (play->submenu.open_flag == FALSE) {
|
||||
if (mMsg_CHECK_NOT_SERIES_MAIN_WAIT() == TRUE) {
|
||||
mMsg_SET_FORCENEXT();
|
||||
rtc->think_idx = aNRTC_THINK_DOOR;
|
||||
aNRTC_change_talk_proc(rtc, aNRTC_TALK_END);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRTC_delete_bf(NPC_RTC_ACTOR* rtc, GAME_PLAY* play) {
|
||||
int order = mDemo_Get_OrderValue(mDemo_TYPE_4, 9);
|
||||
|
||||
if ((mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) && (order != 0)) {
|
||||
|
||||
mMsg_SET_LOCKCONTINUE();
|
||||
aNRTC_change_talk_proc(rtc, aNRTC_TALK_DELETE);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRTC_delete(NPC_RTC_ACTOR* rtc, GAME_PLAY* play) {
|
||||
mMsg_Window_c* window;
|
||||
int card;
|
||||
int card_ret;
|
||||
|
||||
window = mMsg_Get_base_window_p();
|
||||
card_ret = mCD_EraseBrokenLand_bg(&card);
|
||||
|
||||
switch (card_ret) {
|
||||
case 0:
|
||||
rtc->think_idx = aNRTC_THINK_CHECK;
|
||||
mMsg_Set_continue_msg_num(window, 0x09DE);
|
||||
break;
|
||||
case 22:
|
||||
case 2:
|
||||
rtc->think_idx = aNRTC_THINK_TITLE;
|
||||
mMsg_Set_continue_msg_num(window, 0x09DF);
|
||||
break;
|
||||
case 25:
|
||||
return;
|
||||
case 15:
|
||||
rtc->think_idx = aNRTC_THINK_CHECK;
|
||||
mMsg_Set_continue_msg_num(window, 0x09E1);
|
||||
break;
|
||||
default:
|
||||
rtc->think_idx = aNRTC_THINK_TITLE;
|
||||
mMsg_Set_continue_msg_num(window, 0x09DF);
|
||||
break;
|
||||
}
|
||||
|
||||
if (card_ret != 25) {
|
||||
mMsg_Unset_LockContinue(window);
|
||||
aNRTC_change_talk_proc(rtc, aNRTC_TALK_END);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRTC_format_chk(NPC_RTC_ACTOR* rtc, GAME_PLAY* play) {
|
||||
if (mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) {
|
||||
aNRTC_change_talk_proc(rtc, aNRTC_TALK_END);
|
||||
switch (mChoice_GET_CHOSENUM()) {
|
||||
case mChoice_CHOICE0:
|
||||
rtc->think_idx = aNRTC_THINK_CHECK;
|
||||
break;
|
||||
case mChoice_CHOICE1:
|
||||
rtc->think_idx = aNRTC_THINK_DOOR;
|
||||
break;
|
||||
case mChoice_CHOICE2:
|
||||
rtc->think_idx = aNRTC_THINK_TITLE;
|
||||
break;
|
||||
case mChoice_CHOICE3:
|
||||
rtc->think_idx = aNRTC_THINK_CHECK;
|
||||
aNRTC_change_talk_proc(rtc, aNRTC_TALK_FORMAT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRTC_format(NPC_RTC_ACTOR* rtc, GAME_PLAY* play) {
|
||||
int order;
|
||||
mMsg_Window_c* window;
|
||||
|
||||
window = mMsg_Get_base_window_p();
|
||||
order = mDemo_Get_OrderValue(mDemo_TYPE_4, 9);
|
||||
switch (order) {
|
||||
case 1:
|
||||
mDemo_Set_OrderValue(mDemo_TYPE_4, 9, 2);
|
||||
mMsg_Set_LockContinue(window);
|
||||
break;
|
||||
case 2:
|
||||
switch (mCD_card_format_bg(Common_Get(memcard_slot))) {
|
||||
case mCD_RESULT_SUCCESS:
|
||||
mMsg_Set_continue_msg_num(window, 0x09E9);
|
||||
mMsg_Unset_LockContinue(window);
|
||||
aNRTC_change_talk_proc(rtc, aNRTC_TALK_END);
|
||||
rtc->think_idx = aNRTC_THINK_CHECK;
|
||||
mDemo_Set_OrderValue(mDemo_TYPE_4, 9, 0);
|
||||
break;
|
||||
case mCD_RESULT_ERROR:
|
||||
mMsg_Unset_LockContinue(window);
|
||||
aNRTC_change_talk_proc(rtc, aNRTC_TALK_END);
|
||||
rtc->think_idx = aNRTC_THINK_TITLE;
|
||||
mMsg_Set_continue_msg_num(window, 0x09E7);
|
||||
mDemo_Set_OrderValue(mDemo_TYPE_4, 9, 0);
|
||||
case mCD_RESULT_BUSY:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRTC_break_data(NPC_RTC_ACTOR* rtc, GAME_PLAY* play) {
|
||||
if (mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) {
|
||||
aNRTC_change_talk_proc(rtc, aNRTC_TALK_END);
|
||||
switch (mChoice_GET_CHOSENUM()) {
|
||||
case mChoice_CHOICE0:
|
||||
rtc->think_idx = aNRTC_THINK_CHECK;
|
||||
break;
|
||||
case mChoice_CHOICE1:
|
||||
aNRTC_change_talk_proc(rtc, aNRTC_TALK_DELETE_BF);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRTC_break_data_2(NPC_RTC_ACTOR* rtc, GAME_PLAY* play) {
|
||||
if (mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) {
|
||||
aNRTC_change_talk_proc(rtc, aNRTC_TALK_END);
|
||||
switch (mChoice_GET_CHOSENUM()) {
|
||||
case mChoice_CHOICE0:
|
||||
rtc->think_idx = aNRTC_THINK_CHECK;
|
||||
break;
|
||||
case mChoice_CHOICE1:
|
||||
rtc->think_idx = aNRTC_THINK_DOOR;
|
||||
break;
|
||||
case mChoice_CHOICE2:
|
||||
rtc->think_idx = aNRTC_THINK_TITLE;
|
||||
break;
|
||||
case mChoice_CHOICE3:
|
||||
rtc->think_idx = aNRTC_THINK_IPMENU;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRTC_change_talk_proc(NPC_RTC_ACTOR* rtc, int idx) {
|
||||
// clang-format off
|
||||
static aNRTC_PROC process[] = {
|
||||
&aNRTC_break_data,
|
||||
&aNRTC_break_data_2,
|
||||
&aNRTC_rtc_err,
|
||||
&aNRTC_timer_open_msg_wait,
|
||||
&aNRTC_timer_open_wait,
|
||||
&aNRTC_timer_close_wait,
|
||||
&aNRTC_delete_bf,
|
||||
&aNRTC_delete,
|
||||
&aNRTC_format_chk,
|
||||
&aNRTC_format,
|
||||
(aNRTC_PROC)&none_proc1,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
rtc->talk_idx = idx;
|
||||
rtc->talk_proc = process[idx];
|
||||
}
|
||||
|
||||
static void aNRTC_set_talk_info_talk_request() {
|
||||
int msg;
|
||||
|
||||
switch (Common_Get(save_error_type)) {
|
||||
case mFRm_ERROR_BAD_RTC:
|
||||
msg = 0x09CC;
|
||||
break;
|
||||
case mFRm_ERROR_DATA_CORRUPTED:
|
||||
msg = 0x09D1;
|
||||
break;
|
||||
case mFRm_ERROR_MEMCARD_INVALID:
|
||||
msg = 0x09DA;
|
||||
break;
|
||||
case mFRm_ERROR_MEMCARD_NO_SPACE:
|
||||
msg = 0x09D8;
|
||||
break;
|
||||
case mFRm_ERROR_NO_MEMCARD:
|
||||
msg = 0x09D4;
|
||||
break;
|
||||
case mFRm_ERROR_MEMCARD_TRAVELDATA_CONFLICT:
|
||||
msg = 0x09E2;
|
||||
break;
|
||||
case mFRm_ERROR_MEMCARD_DAMAGED:
|
||||
msg = 0x09E4;
|
||||
break;
|
||||
case mFRm_ERROR_MEMCARD_NO_FILES:
|
||||
msg = 0x09E3;
|
||||
break;
|
||||
case mFRm_ERROR_MEMCARD_FORMAT:
|
||||
msg = 0x09E5;
|
||||
break;
|
||||
case mFRm_ERROR_NOT_MEMCARD:
|
||||
msg = 0x09E6;
|
||||
break;
|
||||
default:
|
||||
msg = 0x09D4;
|
||||
break;
|
||||
}
|
||||
|
||||
mDemo_Set_msg_num(msg);
|
||||
mDemo_Set_camera(CAMERA2_PROCESS_NORMAL);
|
||||
}
|
||||
|
||||
static void aNRTC_talk_request(ACTOR* actor, GAME* game) {
|
||||
mDemo_Request(mDemo_TYPE_SPEAK, actor, &aNRTC_set_talk_info_talk_request);
|
||||
}
|
||||
|
||||
static int aNRTC_talk_init(ACTOR* actor, GAME* game) {
|
||||
NPC_RTC_ACTOR* rtc = (NPC_RTC_ACTOR*)actor;
|
||||
|
||||
mDemo_Set_ListenAble();
|
||||
aNRTC_set_slot_name(Common_Get(memcard_slot), mMsg_FREE_STR4);
|
||||
switch (Common_Get(save_error_type)) {
|
||||
case mFRm_ERROR_BAD_RTC:
|
||||
aNRTC_change_talk_proc(rtc, aNRTC_TALK_RTC_ERR);
|
||||
break;
|
||||
case mFRm_ERROR_DATA_CORRUPTED:
|
||||
aNRTC_change_talk_proc(rtc, aNRTC_TALK_BREAK_DATA);
|
||||
break;
|
||||
case mFRm_ERROR_MEMCARD_FORMAT:
|
||||
aNRTC_change_talk_proc(rtc, aNRTC_TALK_FORMAT_CHK);
|
||||
break;
|
||||
default:
|
||||
aNRTC_change_talk_proc(rtc, aNRTC_TALK_BREAK_DATA2);
|
||||
break;
|
||||
}
|
||||
rtc->npc_class.talk_info.talk_request_proc = mActor_NONE_PROC1;
|
||||
mMsg_SET_IDLING_REQ();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int aNRTC_talk_end_chk(ACTOR* actor, GAME* game) {
|
||||
NPC_RTC_ACTOR* rtc = (NPC_RTC_ACTOR*)actor;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
int res = FALSE;
|
||||
mMsg_Window_c* window;
|
||||
|
||||
window = mMsg_Get_base_window_p();
|
||||
(*rtc->talk_proc)(rtc, play);
|
||||
|
||||
if (mMsg_Check_idling_now(window) == TRUE) {
|
||||
mMsg_request_main_disappear_wait_type1(window);
|
||||
aNRTC_think_init_proc(&rtc->npc_class, play);
|
||||
rtc->talk_flag = FALSE;
|
||||
res = TRUE;
|
||||
rtc->bgm_timer = 50;
|
||||
rtc->fade_timer = 75;
|
||||
bzero(&play->fade_color_value, sizeof(rgba8888_t));
|
||||
} else {
|
||||
int counter = rtc->counter;
|
||||
|
||||
if ((mMsg_CHECK_MAINNORMAL() == TRUE) || (mChoice_CHECK_MAIN_NORMAL() == TRUE)) {
|
||||
counter++;
|
||||
if (counter > 600) {
|
||||
counter = 600;
|
||||
}
|
||||
} else {
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
if (mDemo_Get_OrderValue(mDemo_TYPE_4, 0) == 0) {
|
||||
if (counter >= 600) {
|
||||
if (rtc->npc_class.draw.animation_id != aNPC_ANIM_4HAKU_E1) {
|
||||
mDemo_Set_OrderValue(mDemo_TYPE_4, 0, 0xFF);
|
||||
}
|
||||
} else if (rtc->npc_class.draw.animation_id == aNPC_ANIM_4HAKU_E1) {
|
||||
mDemo_Set_OrderValue(mDemo_TYPE_4, 0, 0xFD);
|
||||
}
|
||||
}
|
||||
rtc->counter = counter;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
|
||||
static void aNRTC_talk_request(ACTOR* actor, GAME*);
|
||||
|
||||
static void aNRTC_think_start(NPC_ACTOR* actor, GAME_PLAY* play) {
|
||||
NPC_RTC_ACTOR* rtc = (NPC_RTC_ACTOR*)actor;
|
||||
if (rtc->first_talk_timer > 0) {
|
||||
rtc->first_talk_timer--;
|
||||
} else {
|
||||
rtc->talk_flag = TRUE;
|
||||
rtc->npc_class.talk_info.talk_request_proc = &aNRTC_talk_request;
|
||||
rtc->npc_class.condition_info.demo_flg = aNPC_COND_DEMO_SKIP_HEAD_LOOKAT;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRTC_think_title(NPC_ACTOR* actor, GAME_PLAY* play) {
|
||||
NPC_RTC_ACTOR* rtc = (NPC_RTC_ACTOR*)actor;
|
||||
|
||||
play->fb_wipe_type = 3;
|
||||
play->fb_fade_type = 4;
|
||||
mPlib_request_main_invade_type1((GAME*)play);
|
||||
Actor_info_save_actor(play);
|
||||
rtc->think_idx = aNRTC_THINK_WAIT;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
static Door_data_c door_data = {
|
||||
SCENE_PLAYERSELECT,
|
||||
mSc_DIRECT_NORTH,
|
||||
FALSE,
|
||||
0,
|
||||
{ 100, 0, 120 },
|
||||
EMPTY_NO,
|
||||
3,
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static void aNRTC_think_door(NPC_ACTOR* actor, GAME_PLAY* play) {
|
||||
if (sAdo_BgmFadeoutCheck() != 0) {
|
||||
goto_other_scene(play, &door_data, 1);
|
||||
Common_Set(transition.wipe_type, 3);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRTC_think_check(NPC_ACTOR* actor, GAME_PLAY* play) {
|
||||
NPC_RTC_ACTOR* rtc = (NPC_RTC_ACTOR*)actor;
|
||||
if (sAdo_BgmFadeoutCheck() != 0) {
|
||||
goto_other_scene(play, &door_data, 1);
|
||||
mCD_ReCheckLoadLand(play);
|
||||
Common_Set(transition.wipe_type, 3);
|
||||
rtc->think_idx = aNRTC_THINK_WAIT;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRTC_think_ipmenu(NPC_ACTOR* actor, GAME_PLAY* play) {
|
||||
NPC_RTC_ACTOR* rtc = (NPC_RTC_ACTOR*)actor;
|
||||
if (sAdo_BgmFadeoutCheck() != 0) {
|
||||
HotResetIplMenu();
|
||||
rtc->think_idx = aNRTC_THINK_WAIT;
|
||||
}
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
static aNPC_SUB_PROC aNRTC_proc_table[] = {
|
||||
&aNRTC_think_start,
|
||||
&aNRTC_think_title,
|
||||
&aNRTC_think_door,
|
||||
&aNRTC_think_check,
|
||||
&aNRTC_think_ipmenu,
|
||||
(aNPC_SUB_PROC)mActor_NONE_PROC1,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static void aNRTC_think_main_proc(NPC_ACTOR* actor, GAME_PLAY* play) {
|
||||
NPC_RTC_ACTOR* rtc = (NPC_RTC_ACTOR*)actor;
|
||||
if (rtc->fade_timer > 0) {
|
||||
rtc->fade_timer--;
|
||||
if (rtc->fade_timer == 0) {
|
||||
play->fade_color_value.c.a = -1;
|
||||
} else if (rtc->fade_timer < 25) {
|
||||
play->fade_color_value.c.a = 255.0f * (1.0f - (0.04f * rtc->fade_timer));
|
||||
}
|
||||
} else if (rtc->talk_flag == 0) {
|
||||
aNRTC_proc_table[rtc->think_idx](actor, play);
|
||||
}
|
||||
|
||||
if (rtc->bgm_timer == 0) {
|
||||
if (rtc->think_idx == 1) {
|
||||
mBGMPsComp_make_ps_wipe(0x21C2);
|
||||
} else {
|
||||
mBGMPsComp_make_ps_wipe(0x621C);
|
||||
}
|
||||
rtc->bgm_timer = -2;
|
||||
} else if (rtc->bgm_timer > 0) {
|
||||
rtc->bgm_timer--;
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRTC_think_init_proc(NPC_ACTOR* actor, GAME_PLAY* play) {
|
||||
NPC_RTC_ACTOR* rtc = (NPC_RTC_ACTOR*)actor;
|
||||
rtc->npc_class.request.act_priority = 4;
|
||||
rtc->npc_class.request.act_idx = 8;
|
||||
rtc->npc_class.request.act_type = 0;
|
||||
}
|
||||
|
||||
static void aNRTC_think_proc(NPC_ACTOR* actor, GAME_PLAY* play, int idx) {
|
||||
static aNPC_SUB_PROC think_proc[] = {
|
||||
&aNRTC_think_init_proc,
|
||||
&aNRTC_think_main_proc,
|
||||
};
|
||||
|
||||
think_proc[idx](actor, play);
|
||||
}
|
||||
|
||||
static void aNRTC_schedule_init_proc(NPC_ACTOR* actor, GAME_PLAY* play) {
|
||||
NPC_RTC_ACTOR* rtc = (NPC_RTC_ACTOR*)actor;
|
||||
rtc->npc_class.draw._5BE = 1;
|
||||
rtc->npc_class.talk_info.default_animation = aNPC_ANIM_4HAKU_E1;
|
||||
rtc->bgm_timer = -1;
|
||||
rtc->fade_timer = 0;
|
||||
rtc->first_talk_timer = 90;
|
||||
rtc->npc_class.think.think_proc = aNRTC_think_proc;
|
||||
rtc->think_idx = 0;
|
||||
Common_Get(clip.npc_clip)->think_proc(actor, play, aNPC_THINK_IN_BLOCK, 0);
|
||||
}
|
||||
|
||||
static void aNRTC_schedule_main_proc(NPC_ACTOR* actor, GAME_PLAY* play) {
|
||||
NPC_RTC_ACTOR* rtc = (NPC_RTC_ACTOR*)actor;
|
||||
if (Common_Get(clip.npc_clip)->think_proc(actor, play, -1, 1) == 0) {
|
||||
Common_Get(clip.npc_clip)->think_proc(actor, play, -1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void aNRTC_schedule_proc(NPC_ACTOR* actor, GAME_PLAY* play, int idx) {
|
||||
static aNPC_SUB_PROC sche_proc[] = {
|
||||
&aNRTC_schedule_init_proc,
|
||||
&aNRTC_schedule_main_proc,
|
||||
};
|
||||
|
||||
sche_proc[idx](actor, play);
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
#include "ac_npc_sendo.h"
|
||||
|
||||
#include "m_common_data.h"
|
||||
#include "ac_boat_demo.h"
|
||||
#include "sys_matrix.h"
|
||||
#include "m_msg.h"
|
||||
#include "libultra/libultra.h"
|
||||
#include "GBA2/gba2.h"
|
||||
#include "m_ledit_ovl.h"
|
||||
|
||||
static void aSEN_actor_ct(ACTOR* actorx, GAME* game);
|
||||
static void aSEN_actor_dt(ACTOR* actorx, GAME* game);
|
||||
static void aSEN_actor_init(ACTOR* actorx, GAME* game);
|
||||
static void aSEN_actor_move(ACTOR* actorx, GAME* game);
|
||||
static void aSEN_actor_draw(ACTOR* actorx, GAME* game);
|
||||
static void aSEN_actor_save(ACTOR* actorx, GAME* game);
|
||||
|
||||
ACTOR_PROFILE Npc_Sendo_Profile = {
|
||||
mAc_PROFILE_NPC_SENDO,
|
||||
ACTOR_PART_NPC,
|
||||
ACTOR_STATE_NONE,
|
||||
SP_NPC_SENDO,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(NPC_SENDO_ACTOR),
|
||||
&aSEN_actor_ct,
|
||||
&aSEN_actor_dt,
|
||||
&aSEN_actor_init,
|
||||
mActor_NONE_PROC1,
|
||||
&aSEN_actor_save
|
||||
};
|
||||
|
||||
static int aSEN_talk_init(ACTOR*, GAME*);
|
||||
static int aSEN_talk_end_chk(ACTOR*, GAME*);
|
||||
|
||||
static void aSEN_schedule_proc(NPC_ACTOR*, GAME_PLAY*, int);
|
||||
static void aSEN_setup_think_proc(NPC_SENDO_ACTOR*, GAME_PLAY*, u8);
|
||||
|
||||
static MtxF aSEN_matrix;
|
||||
|
||||
static void aSEN_actor_ct(ACTOR* actorx, GAME* game) {
|
||||
static aNPC_ct_data_c ct_data = {
|
||||
&aSEN_actor_move,
|
||||
&aSEN_actor_draw,
|
||||
5,
|
||||
(aNPC_TALK_REQUEST_PROC)&none_proc1,
|
||||
&aSEN_talk_init,
|
||||
&aSEN_talk_end_chk,
|
||||
0
|
||||
};
|
||||
|
||||
if ((*Common_Get(clip).npc_clip->birth_check_proc)(actorx, game) == TRUE) {
|
||||
NPC_ACTOR* npc_actor = (NPC_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
|
||||
npc_actor->schedule.schedule_proc = &aSEN_schedule_proc;
|
||||
(*Common_Get(clip).npc_clip->ct_proc)(actorx, game, &ct_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void aSEN_actor_save(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->save_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aSEN_actor_dt(ACTOR* actorx, GAME* game) {
|
||||
NPC_SENDO_ACTOR* sendo = (NPC_SENDO_ACTOR*)actorx;
|
||||
BOAT_DEMO_ACTOR* boat_demo;
|
||||
|
||||
(*Common_Get(clip).npc_clip->dt_proc)(actorx, game);
|
||||
|
||||
boat_demo = (BOAT_DEMO_ACTOR*)actorx->parent_actor;
|
||||
if (boat_demo != NULL && boat_demo->npc_sendo_actor == sendo) {
|
||||
boat_demo->npc_sendo_actor = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void aSEN_actor_init(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->init_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aSEN_actor_draw(ACTOR* actorx, GAME* game) {
|
||||
Matrix_put(&aSEN_matrix);
|
||||
(*Common_Get(clip).npc_clip->draw_proc)(actorx, game);
|
||||
}
|
||||
|
||||
#include "../src/actor/ac_npc_sendo_move.c_inc"
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,106 @@
|
||||
#include "ac_ev_broker.h"
|
||||
|
||||
#include "m_common_data.h"
|
||||
#include "m_player_lib.h"
|
||||
#include "m_msg.h"
|
||||
|
||||
enum {
|
||||
aEBRK_ACTION_TALK_WAIT,
|
||||
aEBRK_ACTION_TURN,
|
||||
aEBRK_ACTION_ENTER,
|
||||
aEBRK_ACTION_HIDE,
|
||||
|
||||
aEBRK_ACTION_NUM
|
||||
};
|
||||
|
||||
static void aEBRK_actor_ct(ACTOR* actorx, GAME* game);
|
||||
static void aEBRK_actor_dt(ACTOR* actorx, GAME* game);
|
||||
static void aEBRK_actor_init(ACTOR* actorx, GAME* game);
|
||||
static void aEBRK_actor_move(ACTOR* actorx, GAME* game);
|
||||
static void aEBRK_actor_draw(ACTOR* actorx, GAME* game);
|
||||
static void aEBRK_actor_save(ACTOR* actorx, GAME* game);
|
||||
|
||||
// clang-format off
|
||||
ACTOR_PROFILE Ev_Broker_Profile = {
|
||||
mAc_PROFILE_EV_BROKER,
|
||||
ACTOR_PART_NPC,
|
||||
ACTOR_STATE_NO_MOVE_WHILE_CULLED | ACTOR_STATE_NO_DRAW_WHILE_CULLED,
|
||||
SP_NPC_BROKER,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(EV_BROKER_ACTOR),
|
||||
&aEBRK_actor_ct,
|
||||
&aEBRK_actor_dt,
|
||||
&aEBRK_actor_init,
|
||||
mActor_NONE_PROC1,
|
||||
&aEBRK_actor_save,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static void aEBRK_talk_request(ACTOR* actorx, GAME* game);
|
||||
static int aEBRK_talk_init(ACTOR* actorx, GAME* game);
|
||||
static int aEBRK_talk_end_chk(ACTOR* actorx, GAME* game);
|
||||
|
||||
static void aEBRK_schedule_proc(NPC_ACTOR* npc_actorx, GAME_PLAY* play, int sched_type);
|
||||
|
||||
static int aEBRK_get_sell_item_sum(void);
|
||||
static int aEBRK_check_start_around(ACTOR* actorx, GAME* game);
|
||||
|
||||
static void aEBRK_actor_ct(ACTOR* actorx, GAME* game) {
|
||||
static aNPC_ct_data_c ct_data = {
|
||||
&aEBRK_actor_move, &aEBRK_actor_draw, 5, &aEBRK_talk_request, &aEBRK_talk_init, &aEBRK_talk_end_chk,
|
||||
};
|
||||
|
||||
EV_BROKER_ACTOR* broker = (EV_BROKER_ACTOR*)actorx;
|
||||
|
||||
if (Common_Get(clip).npc_clip->birth_check_proc(actorx, game) == TRUE) {
|
||||
broker->npc_class.schedule.schedule_proc = &aEBRK_schedule_proc;
|
||||
Common_Get(clip).npc_clip->ct_proc(actorx, game, &ct_data);
|
||||
broker->npc_class.actor_class.status_data.weight = 254;
|
||||
|
||||
if (aEBRK_get_sell_item_sum() == 0 || aEBRK_check_start_around(actorx, game) == FALSE) {
|
||||
broker->npc_class.talk_info.talk_request_proc = (aNPC_TALK_REQUEST_PROC)&none_proc1;
|
||||
broker->next_action = aEBRK_ACTION_HIDE;
|
||||
} else {
|
||||
int hide_npc = Common_Get(special_event_common).broker.hide_npc;
|
||||
|
||||
broker->npc_class.condition_info.hide_request = hide_npc;
|
||||
if (hide_npc == TRUE) {
|
||||
broker->npc_class.talk_info.talk_request_proc = (aNPC_TALK_REQUEST_PROC)&none_proc1;
|
||||
broker->next_action = aEBRK_ACTION_HIDE;
|
||||
} else {
|
||||
broker->next_action = aEBRK_ACTION_TALK_WAIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aEBRK_actor_save(ACTOR* actorx, GAME* game) {
|
||||
Common_Get(clip).npc_clip->save_proc(actorx, game);
|
||||
}
|
||||
|
||||
static void aEBRK_actor_dt(ACTOR* actorx, GAME* game) {
|
||||
Common_Get(clip).npc_clip->dt_proc(actorx, game);
|
||||
Common_Get(special_event_common).broker.hide_npc = FALSE;
|
||||
mEv_actor_dying_message(mEv_EVENT_BROKER_SALE, actorx);
|
||||
}
|
||||
|
||||
static void aEBRK_actor_init(ACTOR* actorx, GAME* game) {
|
||||
Common_Get(clip).npc_clip->init_proc(actorx, game);
|
||||
}
|
||||
|
||||
static void aEBRK_set_animation(EV_BROKER_ACTOR* broker, int action) {
|
||||
static int animeSeqNo[] = {
|
||||
aNPC_ANIM_WAIT1,
|
||||
aNPC_ANIM_WALK1,
|
||||
aNPC_ANIM_WALK1,
|
||||
aNPC_ANIM_WAIT1,
|
||||
};
|
||||
|
||||
Common_Get(clip).npc_clip->animation_init_proc(&broker->npc_class.actor_class, animeSeqNo[action], FALSE);
|
||||
}
|
||||
|
||||
static void aEBRK_actor_draw(ACTOR* actorx, GAME* game) {
|
||||
Common_Get(clip).npc_clip->draw_proc(actorx, game);
|
||||
}
|
||||
|
||||
#include "../src/actor/ac_ev_broker_move.c_inc"
|
||||
@@ -0,0 +1,303 @@
|
||||
static void aEBRK_set_request_act(EV_BROKER_ACTOR* broker) {
|
||||
broker->npc_class.request.act_priority = 4;
|
||||
broker->npc_class.request.act_idx = aNPC_ACT_SPECIAL;
|
||||
broker->npc_class.request.act_type = aNPC_ACT_TYPE_SEARCH;
|
||||
}
|
||||
|
||||
static void aEBRK_set_pl_talk_lock(EV_BROKER_ACTOR* broker, u8 flag) {
|
||||
if (broker->pl_talk_lock != flag) {
|
||||
if (flag == TRUE) {
|
||||
mPlib_Set_able_force_speak_label(&broker->npc_class.actor_class);
|
||||
} else {
|
||||
mPlib_Reset_able_force_speak_label();
|
||||
}
|
||||
|
||||
broker->pl_talk_lock = flag;
|
||||
}
|
||||
}
|
||||
|
||||
static int aEBRK_check_start_around_sub(ACTOR* check_actor, ACTOR* actorx, f32 pos_x, f32 pos_z) {
|
||||
int res = TRUE;
|
||||
|
||||
while (check_actor != NULL) {
|
||||
if (check_actor != actorx) {
|
||||
f32 dist_x = check_actor->world.position.x - pos_x;
|
||||
f32 dist_z = check_actor->world.position.z - pos_z;
|
||||
|
||||
if (SQ(dist_x) + SQ(dist_z) < SQ(mFI_UNIT_BASE_SIZE_F)) {
|
||||
res = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
check_actor = check_actor->next_actor;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int aEBRK_check_start_around(ACTOR* actorx, GAME* game) {
|
||||
static int part[] = { ACTOR_PART_NPC, ACTOR_PART_BG };
|
||||
f32 pos_x = actorx->world.position.x;
|
||||
f32 pos_z = actorx->world.position.z;
|
||||
int i;
|
||||
int res = TRUE;
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(part); i++) {
|
||||
if (!aEBRK_check_start_around_sub(((GAME_PLAY*)game)->actor_info.list[part[i]].actor, actorx, pos_x, pos_z)) {
|
||||
res = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void aEBRK_check_tent(ACTOR* actorx, GAME* game) {
|
||||
EV_BROKER_ACTOR* broker = (EV_BROKER_ACTOR*)actorx;
|
||||
ACTOR* tent_actor = broker->tent_actor;
|
||||
|
||||
if (broker->tent_actor == NULL) {
|
||||
broker->tent_actor =
|
||||
Actor_info_name_search(&((GAME_PLAY*)game)->actor_info, mAc_PROFILE_BRSHOP, ACTOR_PART_ITEM);
|
||||
} else if (tent_actor->id != mAc_PROFILE_BRSHOP || (tent_actor->mv_proc == NULL && tent_actor->dw_proc == NULL)) {
|
||||
Actor_delete(actorx);
|
||||
}
|
||||
}
|
||||
|
||||
static int aEBRK_get_sell_item_sum(void) {
|
||||
mActor_name_t* sell_item_p = Save_Get(event_save_data).special.event.broker.items;
|
||||
int sum = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(Save_Get(event_save_data).special.event.broker.items); i++) {
|
||||
if (*sell_item_p != EMPTY_NO) {
|
||||
sum++;
|
||||
}
|
||||
|
||||
sell_item_p++;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
static int aEBRK_check_pl_list(PersonalID_c* pid, int n) {
|
||||
int res = -1;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (mPr_CheckCmpPersonalID(pid, &Now_Private->player_ID) == TRUE) {
|
||||
res = i;
|
||||
}
|
||||
|
||||
pid++;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void aEBRK_talk_wait(EV_BROKER_ACTOR* broker) {
|
||||
int animeSeqNo = aNPC_ANIM_WAIT1;
|
||||
|
||||
if (chase_angle(&broker->npc_class.actor_class.shape_info.rotation.y, DEG2SHORT_ANGLE2(0.0f),
|
||||
DEG2SHORT_ANGLE2(5.625f)) == FALSE) {
|
||||
animeSeqNo = aNPC_ANIM_WALK1;
|
||||
}
|
||||
|
||||
broker->npc_class.actor_class.world.angle.y = broker->npc_class.actor_class.shape_info.rotation.y;
|
||||
|
||||
if (broker->npc_class.draw.animation_id != animeSeqNo) {
|
||||
Common_Get(clip).npc_clip->animation_init_proc(&broker->npc_class.actor_class, animeSeqNo, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void aEBRK_turn(EV_BROKER_ACTOR* broker) {
|
||||
if (broker->npc_class.actor_class.shape_info.rotation.y == broker->npc_class.movement.mv_angl) {
|
||||
broker->action_step = aNPC_ACTION_END_STEP;
|
||||
}
|
||||
}
|
||||
|
||||
static void aEBRK_enter(EV_BROKER_ACTOR* broker) {
|
||||
ACTOR* actorx = &broker->npc_class.actor_class;
|
||||
f32 walk_dist = actorx->home.position.z - actorx->world.position.z;
|
||||
|
||||
if (walk_dist > 60.0f) {
|
||||
broker->action_step = aNPC_ACTION_END_STEP;
|
||||
}
|
||||
}
|
||||
|
||||
static void aEBRK_set_spd_info(EV_BROKER_ACTOR* broker, int action) {
|
||||
if (action == aEBRK_ACTION_ENTER) {
|
||||
broker->npc_class.movement.max_speed = 1.0f;
|
||||
broker->npc_class.movement.acceleration = 0.1f;
|
||||
broker->npc_class.movement.deceleration = 0.1f;
|
||||
} else {
|
||||
broker->npc_class.actor_class.speed = 0.0f;
|
||||
broker->npc_class.movement.max_speed = 0.0f;
|
||||
broker->npc_class.movement.acceleration = 0.0f;
|
||||
broker->npc_class.movement.deceleration = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
static void aEBRK_setupAction(EV_BROKER_ACTOR* broker, int action) {
|
||||
static aEBRK_ACT_PROC process[] = {
|
||||
&aEBRK_talk_wait,
|
||||
&aEBRK_turn,
|
||||
&aEBRK_enter,
|
||||
(aEBRK_ACT_PROC)&none_proc1,
|
||||
};
|
||||
|
||||
broker->action_step = 0;
|
||||
broker->action = action;
|
||||
broker->action_proc = process[action];
|
||||
aEBRK_set_animation(broker, action);
|
||||
aEBRK_set_spd_info(broker, action);
|
||||
}
|
||||
|
||||
static void aEBRK_act_chg_data_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
nactorx->action.act_obj = aNPC_ACT_OBJ_PLAYER;
|
||||
}
|
||||
|
||||
static void aEBRK_act_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
EV_BROKER_ACTOR* broker = (EV_BROKER_ACTOR*)nactorx;
|
||||
|
||||
nactorx->action.step = 0;
|
||||
aEBRK_setupAction(broker, broker->next_action);
|
||||
}
|
||||
|
||||
static void aEBRK_act_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
EV_BROKER_ACTOR* broker = (EV_BROKER_ACTOR*)nactorx;
|
||||
|
||||
(*broker->action_proc)(broker);
|
||||
}
|
||||
|
||||
static void aEBRK_act_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc) {
|
||||
static aNPC_SUB_PROC act_proc[] = {
|
||||
&aEBRK_act_init_proc,
|
||||
&aEBRK_act_chg_data_proc,
|
||||
&aEBRK_act_main_proc,
|
||||
};
|
||||
|
||||
(*act_proc[proc])(nactorx, play);
|
||||
}
|
||||
|
||||
static void aEBRK_think_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
EV_BROKER_ACTOR* broker = (EV_BROKER_ACTOR*)nactorx;
|
||||
|
||||
if (nactorx->action.step == aNPC_ACTION_END_STEP) {
|
||||
aEBRK_set_request_act(broker);
|
||||
if (nactorx->action.idx == aNPC_ACT_TALK) {
|
||||
nactorx->movement.mv_angl = DEG2SHORT_ANGLE2(180.0f);
|
||||
nactorx->movement.mv_add_angl = DEG2SHORT_ANGLE2(11.25f);
|
||||
broker->next_action = aEBRK_ACTION_TURN;
|
||||
mPlib_request_main_demo_wait_type1(&play->game, 0, NULL);
|
||||
}
|
||||
} else if (broker->action_step == aNPC_ACTION_END_STEP) {
|
||||
switch (broker->action) {
|
||||
case aEBRK_ACTION_TURN:
|
||||
nactorx->condition_info.demo_flg =
|
||||
aNPC_COND_DEMO_SKIP_ENTRANCE_CHECK | aNPC_COND_DEMO_SKIP_HEAD_LOOKAT |
|
||||
aNPC_COND_DEMO_SKIP_TALK_CHECK | aNPC_COND_DEMO_SKIP_ITEM | aNPC_COND_DEMO_SKIP_FORWARD_CHECK |
|
||||
aNPC_COND_DEMO_SKIP_BGCHECK | aNPC_COND_DEMO_SKIP_OBJ_COL_CHECK | aNPC_COND_DEMO_SKIP_MOVE_Y |
|
||||
aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV | aNPC_COND_DEMO_SKIP_MOVE_RANGE_CHECK;
|
||||
aEBRK_setupAction(broker, aEBRK_ACTION_ENTER);
|
||||
break;
|
||||
case aEBRK_ACTION_ENTER:
|
||||
nactorx->condition_info.hide_request = TRUE;
|
||||
mPlib_request_main_wait_type3(&play->game);
|
||||
aEBRK_set_pl_talk_lock(broker, FALSE);
|
||||
aEBRK_setupAction(broker, aEBRK_ACTION_HIDE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aEBRK_think_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
EV_BROKER_ACTOR* broker = (EV_BROKER_ACTOR*)nactorx;
|
||||
|
||||
nactorx->think.interrupt_flags = 0;
|
||||
nactorx->action.act_proc = &aEBRK_act_proc;
|
||||
aEBRK_set_request_act(broker);
|
||||
}
|
||||
|
||||
static void aEBRK_think_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc) {
|
||||
static aNPC_SUB_PROC think_proc[] = {
|
||||
&aEBRK_think_init_proc,
|
||||
&aEBRK_think_main_proc,
|
||||
};
|
||||
|
||||
(*think_proc[proc])(nactorx, play);
|
||||
}
|
||||
|
||||
static void aEBRK_schedule_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
nactorx->think.think_proc = &aEBRK_think_proc;
|
||||
Common_Get(clip).npc_clip->think_proc(nactorx, play, aNPC_THINK_SPECIAL, 0);
|
||||
}
|
||||
|
||||
static void aEBRK_schedule_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
if (!Common_Get(clip).npc_clip->think_proc(nactorx, play, -1, 1)) {
|
||||
Common_Get(clip).npc_clip->think_proc(nactorx, play, -1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void aEBRK_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc) {
|
||||
static aNPC_SUB_PROC sche_proc[] = {
|
||||
&aEBRK_schedule_init_proc,
|
||||
&aEBRK_schedule_main_proc,
|
||||
};
|
||||
|
||||
(*sche_proc[proc])(nactorx, play);
|
||||
}
|
||||
|
||||
static void aEBRK_set_talk_info_talk_request(ACTOR* actorx) {
|
||||
int msg_no;
|
||||
u8 item_name[mIN_ITEM_NAME_LEN];
|
||||
mActor_name_t item;
|
||||
int idx;
|
||||
|
||||
idx = aEBRK_check_pl_list(Save_Get(event_save_data).special.event.broker.pid,
|
||||
ARRAY_COUNT(Save_Get(event_save_data).special.event.broker.pid));
|
||||
if (idx != -1) {
|
||||
item = Save_Get(event_save_data).special.event.broker.sold_items[idx];
|
||||
mIN_copy_name_str(item_name, item);
|
||||
mMsg_SET_ITEM_STR_ART(mMsg_ITEM_STR2, item_name, mIN_ITEM_NAME_LEN, item);
|
||||
msg_no = 0x078A;
|
||||
} else {
|
||||
idx = aEBRK_check_pl_list(&Common_Get(special_event_common).broker.entered_pid, 1);
|
||||
if (idx != -1) {
|
||||
msg_no = 0x0789;
|
||||
} else {
|
||||
msg_no = 0x788;
|
||||
}
|
||||
}
|
||||
|
||||
mDemo_Set_msg_num(msg_no);
|
||||
aEBRK_set_pl_talk_lock((EV_BROKER_ACTOR*)actorx, TRUE);
|
||||
}
|
||||
|
||||
static void aEBRK_talk_request(ACTOR* actorx, GAME* game) {
|
||||
mDemo_Request(mDemo_TYPE_TALK, actorx, &aEBRK_set_talk_info_talk_request);
|
||||
}
|
||||
|
||||
static int aEBRK_talk_init(ACTOR* actorx, GAME* game) {
|
||||
EV_BROKER_ACTOR* broker = (EV_BROKER_ACTOR*)actorx;
|
||||
|
||||
broker->npc_class.talk_info.talk_request_proc = (aNPC_TALK_REQUEST_PROC)&none_proc1;
|
||||
mDemo_Set_ListenAble();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int aEBRK_talk_end_chk(ACTOR* actorx, GAME* game) {
|
||||
int res = FALSE;
|
||||
|
||||
if (mDemo_Check(mDemo_TYPE_TALK, actorx) == FALSE) {
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void aEBRK_actor_move(ACTOR* actorx, GAME* game) {
|
||||
Common_Get(clip).npc_clip->move_proc(actorx, game);
|
||||
aEBRK_check_tent(actorx, game);
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
#include "ac_ev_castaway.h"
|
||||
|
||||
#include "m_common_data.h"
|
||||
|
||||
static void aECST_actor_ct(ACTOR* actorx, GAME* game);
|
||||
static void aECST_actor_dt(ACTOR* actorx, GAME* game);
|
||||
static void aECST_actor_init(ACTOR* actorx, GAME* game);
|
||||
static void aECST_actor_move(ACTOR* actorx, GAME* game);
|
||||
static void aECST_actor_draw(ACTOR* actorx, GAME* game);
|
||||
static void aECST_actor_save(ACTOR* actorx, GAME* game);
|
||||
|
||||
ACTOR_PROFILE Ev_Castaway_Profile = {
|
||||
mAc_PROFILE_EV_CASTAWAY,
|
||||
ACTOR_PART_NPC,
|
||||
ACTOR_STATE_CAN_MOVE_IN_DEMO_SCENES | ACTOR_STATE_NO_MOVE_WHILE_CULLED,
|
||||
EMPTY_NO,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(EV_CASTAWAY_ACTOR),
|
||||
&aECST_actor_ct,
|
||||
&aECST_actor_dt,
|
||||
&aECST_actor_init,
|
||||
mActor_NONE_PROC1,
|
||||
&aECST_actor_save,
|
||||
};
|
||||
|
||||
static void aECST_schedule_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int type);
|
||||
|
||||
static void aECST_actor_ct(ACTOR* actorx, GAME* game) {
|
||||
static aNPC_ct_data_c ct_data = { &aECST_actor_move, &aECST_actor_draw, 5, NULL, NULL, NULL, 0 };
|
||||
|
||||
static xyz_t def_pos = { 3580.0f, 0.0f, 4670.0f }; // 'G-5' @ 9-4
|
||||
|
||||
EV_CASTAWAY_ACTOR* castaway = (EV_CASTAWAY_ACTOR*)actorx;
|
||||
|
||||
if ((*Common_Get(clip).npc_clip->birth_check_proc)(actorx, game) == TRUE) {
|
||||
castaway->npc_class.schedule.schedule_proc = &aECST_schedule_proc;
|
||||
(*Common_Get(clip).npc_clip->ct_proc)(actorx, game, &ct_data);
|
||||
castaway->npc_class.condition_info.demo_flg = ~aNPC_COND_DEMO_SKIP_MOVE_Y; // is this a mistake?
|
||||
castaway->npc_class.condition_info.hide_request = FALSE;
|
||||
castaway->npc_class.palActorIgnoreTimer = -1;
|
||||
aNPC_SPNPC_BIT_SET(Common_Get(spnpc_first_talk_flags), aNPC_SPNPC_BIT_DOZAEMON);
|
||||
actorx->status_data.weight = 254;
|
||||
actorx->gravity = 0.0f;
|
||||
actorx->max_velocity_y = 0.0f;
|
||||
actorx->shape_info.rotation.y = DEG2SHORT_ANGLE(68.027344f); // 0x3060
|
||||
actorx->world.angle.y = DEG2SHORT_ANGLE(68.027344f); // 0x3060
|
||||
castaway->npc_class.movement.mv_angl = DEG2SHORT_ANGLE(68.027344f); // 0x3060
|
||||
actorx->world.position = def_pos;
|
||||
actorx->home.position = def_pos;
|
||||
}
|
||||
}
|
||||
|
||||
static void aECST_actor_save(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->save_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aECST_actor_dt(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->dt_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aECST_actor_init(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->init_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aECST_schedule_main_proc(NPC_ACTOR* actorx, GAME_PLAY* play) {
|
||||
if (actorx->draw.animation_id != 116) {
|
||||
(*Common_Get(clip).npc_clip->animation_init_proc)((ACTOR*)actorx, aNPC_ANIM_GETUP_WAIT_SEG1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void aECST_schedule_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int type) {
|
||||
static aNPC_SUB_PROC sche_proc[2] = { (aNPC_SUB_PROC)&none_proc1, aECST_schedule_main_proc };
|
||||
|
||||
(*sche_proc[type])(actorx, play);
|
||||
}
|
||||
|
||||
static void aECST_actor_move(ACTOR* actorx, GAME* game) {
|
||||
EV_CASTAWAY_ACTOR* castaway = (EV_CASTAWAY_ACTOR*)actorx;
|
||||
s16 cycle = castaway->bobbing_cycle;
|
||||
|
||||
cycle += 512;
|
||||
actorx->position_speed.y = (actorx->home.position.y + 4.0f + sin_s(cycle) * 4.0f) - actorx->world.position.y;
|
||||
castaway->bobbing_cycle = cycle;
|
||||
(*Common_Get(clip).npc_clip->move_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aECST_actor_draw(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->draw_proc)(actorx, game);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
#include "ac_ev_dokutu.h"
|
||||
|
||||
#include "m_common_data.h"
|
||||
|
||||
#include "../src/actor/ac_ev_dokutu_talk.c_inc"
|
||||
|
||||
static void aEVD_actor_ct(ACTOR* actorx, GAME* game);
|
||||
static void aEVD_actor_dt(ACTOR* actorx, GAME* game);
|
||||
static void aEVD_actor_init(ACTOR* actorx, GAME* game);
|
||||
static void aEVD_actor_save(ACTOR* actorx, GAME* game);
|
||||
static void aEVD_actor_move(ACTOR* actorx, GAME* game);
|
||||
static void aEVD_actor_draw(ACTOR* actorx, GAME* game);
|
||||
|
||||
ACTOR_PROFILE Ev_Dokutu_Profile = {
|
||||
mAc_PROFILE_EV_DOKUTU,
|
||||
ACTOR_PART_NPC,
|
||||
0,
|
||||
SP_NPC_EV_DOKUTU,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(EVENT_DOKUTU_ACTOR),
|
||||
&aEVD_actor_ct,
|
||||
&aEVD_actor_dt,
|
||||
&aEVD_actor_init,
|
||||
mActor_NONE_PROC1,
|
||||
&aEVD_actor_save
|
||||
};
|
||||
|
||||
static aNPC_ct_data_c ct_data = {
|
||||
&aEVD_actor_move,
|
||||
&aEVD_actor_draw,
|
||||
3,
|
||||
&aEVD_talk_request,
|
||||
&aEVD_talk_init,
|
||||
&aEVD_talk_end_chk,
|
||||
0
|
||||
};
|
||||
|
||||
static void aEVD_actor_ct(ACTOR* actorx, GAME* game) {
|
||||
if ((*Common_Get(clip).npc_clip->birth_check_proc)(actorx, game) == TRUE) {
|
||||
(*Common_Get(clip).npc_clip->ct_proc)(actorx, game, &ct_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void aEVD_actor_save(ACTOR* actorx, GAME* game) {
|
||||
mNpc_RenewalSetNpc(actorx);
|
||||
}
|
||||
|
||||
static void aEVD_actor_dt(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->dt_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aEVD_actor_init(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->init_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aEVD_actor_move(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->move_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aEVD_actor_draw(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->draw_proc)(actorx, game);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
static void aEVD_set_talk_info(ACTOR* actorx) {
|
||||
mDemo_Set_msg_num(0x3146);
|
||||
}
|
||||
|
||||
static void aEVD_talk_request(ACTOR* actorx, GAME* game) {
|
||||
mDemo_Request(mDemo_TYPE_TALK, actorx, &aEVD_set_talk_info);
|
||||
}
|
||||
|
||||
static int aEVD_talk_init(ACTOR* actorx, GAME* game) {
|
||||
mDemo_Set_ListenAble();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int aEVD_talk_end_chk(ACTOR* actorx, GAME* game) {
|
||||
int res = FALSE;
|
||||
|
||||
if (mDemo_Check(mDemo_TYPE_TALK, actorx) == FALSE) {
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
#include "ac_ev_ghost.h"
|
||||
|
||||
#include "m_event.h"
|
||||
#include "m_common_data.h"
|
||||
#include "m_msg.h"
|
||||
#include "m_string.h"
|
||||
#include "libultra/libultra.h"
|
||||
#include "m_player_lib.h"
|
||||
#include "m_item_name.h"
|
||||
#include "m_house.h"
|
||||
|
||||
enum {
|
||||
aEGH_TALK_END_WAIT,
|
||||
aEGH_TALK_GIVE_ME_WAIT,
|
||||
aEGH_TALK_SELECT_WAIT,
|
||||
aEGH_TALK_SELECT_ROOF,
|
||||
aEGH_TALK_GIVE_YOU_WAIT,
|
||||
aEGH_TALK_CLEAR_GRASS,
|
||||
|
||||
aEGH_TALK_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aEGH_THINK_NORMAL_WAIT,
|
||||
aEGH_THINK_IRAI,
|
||||
aEGH_THINK_IRAI_AF,
|
||||
aEGH_THINK_BYE,
|
||||
aEGH_THINK_WELCOM,
|
||||
aEGH_THINK_BYEBYE,
|
||||
aEGH_THINK_SPEAK, // ?
|
||||
|
||||
aEGH_THINK_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aEGH_THINK_INIT_NONE,
|
||||
aEGH_THINK_INIT_NORMAL_WAIT,
|
||||
aEGH_THINK_INIT_IRAI,
|
||||
aEGH_THINK_INIT_IRAI_AF,
|
||||
aEGH_THINK_INIT_BYE,
|
||||
aEGH_THINK_INIT_WELCOM,
|
||||
aEGH_THINK_INIT_BYEBYE,
|
||||
|
||||
aEGH_THINK_INIT_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aEGH_THINK_PROC_NONE,
|
||||
aEGH_THINK_PROC_IRAI,
|
||||
aEGH_THINK_PROC_BYE,
|
||||
aEGH_THINK_PROC_BYEBYE,
|
||||
aEGH_THINK_PROC_SPEAK_BYEBYE,
|
||||
|
||||
aEGH_THINK_PROC_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aEGH_TALK_REQUEST_NONE,
|
||||
aEGH_TALK_REQUEST_NORM,
|
||||
aEGH_TALK_REQUEST_FORCE,
|
||||
|
||||
aEGH_TALK_REQUEST_NUM
|
||||
};
|
||||
|
||||
typedef struct ghost_think_setup_s {
|
||||
u8 think_proc;
|
||||
u8 think_init_proc;
|
||||
u8 talk_request_proc;
|
||||
u8 talk_act;
|
||||
u8 talk_after_act;
|
||||
} aEGH_setup_c;
|
||||
|
||||
static void aEGH_actor_ct(ACTOR*, GAME*);
|
||||
static void aEGH_actor_dt(ACTOR*, GAME*);
|
||||
static void aEGH_actor_move(ACTOR*, GAME*);
|
||||
static void aEGH_actor_draw(ACTOR*, GAME*);
|
||||
static void aEGH_actor_init(ACTOR*, GAME*);
|
||||
static void aEGH_actor_save(ACTOR*, GAME*);
|
||||
|
||||
ACTOR_PROFILE Ev_Ghost_Profile = {
|
||||
mAc_PROFILE_EV_GHOST,
|
||||
ACTOR_PART_NPC,
|
||||
ACTOR_STATE_NONE,
|
||||
SP_NPC_EV_GHOST,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(EV_GHOST_ACTOR),
|
||||
&aEGH_actor_ct,
|
||||
&aEGH_actor_dt,
|
||||
&aEGH_actor_init,
|
||||
mActor_NONE_PROC1,
|
||||
&aEGH_actor_save
|
||||
};
|
||||
|
||||
static int aEGH_talk_init(ACTOR*, GAME*);
|
||||
static int aEGH_talk_end_chk(ACTOR*, GAME*);
|
||||
|
||||
static int aEGH_change_talk_proc(EV_GHOST_ACTOR* ghost, u8 talk_act);
|
||||
static void aEGH_setup_think_proc(EV_GHOST_ACTOR* ghost, GAME_PLAY* play, u8 think_act);
|
||||
static void aEGH_schedule_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int sched_type);
|
||||
|
||||
static int aEGH_bitset_func(u16 bit);
|
||||
static int aEGH_bitclr_func(u16 bit);
|
||||
static u16 aEGH_bitcheck_func(u16 bit);
|
||||
|
||||
static void aEGH_byebye_check(EV_GHOST_ACTOR* ghost, GAME_PLAY* play);
|
||||
|
||||
static void aEGH_actor_ct(ACTOR* actorx, GAME* game) {
|
||||
static aNPC_ct_data_c ct_data = {
|
||||
&aEGH_actor_move,
|
||||
&aEGH_actor_draw,
|
||||
5,
|
||||
(aNPC_TALK_REQUEST_PROC)&none_proc1,
|
||||
&aEGH_talk_init,
|
||||
&aEGH_talk_end_chk,
|
||||
0
|
||||
};
|
||||
|
||||
mEv_gst_c* ghost_save = (mEv_gst_c*)mEv_get_save_area(mEv_EVENT_GHOST, 54);
|
||||
EV_GHOST_ACTOR* ghost = (EV_GHOST_ACTOR*)actorx;
|
||||
lbRTC_time_c* rtc_time = Common_GetPointer(time.rtc_time);
|
||||
|
||||
if ((*Common_Get(clip).npc_clip->birth_check_proc)(actorx, game) == TRUE) {
|
||||
ghost->npc_class.schedule.schedule_proc = &aEGH_schedule_proc;
|
||||
(*Common_Get(clip).npc_clip->ct_proc)(actorx, game, &ct_data);
|
||||
ghost->npc_class.palActorIgnoreTimer = -1;
|
||||
ghost->_9A7 = 0;
|
||||
ghost->melody_inst = 0;
|
||||
ghost->npc_class.talk_info.melody_inst = 0;
|
||||
|
||||
if (ghost_save == NULL) {
|
||||
mEv_reserve_save_area(mEv_EVENT_GHOST, 54);
|
||||
ghost_save = (mEv_gst_c*)mEv_get_save_area(mEv_EVENT_GHOST, 54);
|
||||
|
||||
if (ghost_save != NULL) {
|
||||
ghost_save->flags = 0;
|
||||
ghost_save->okoruhito_str_no = RANDOM_F(32.0f);
|
||||
mTM_set_renew_time(&ghost_save->renew_time, rtc_time);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (
|
||||
rtc_time->year != ghost_save->renew_time.year ||
|
||||
rtc_time->month != ghost_save->renew_time.month ||
|
||||
rtc_time->day != ghost_save->renew_time.day
|
||||
) {
|
||||
ghost_save->flags = 0;
|
||||
ghost_save->okoruhito_str_no = RANDOM_F(32.0f);
|
||||
mTM_set_renew_time(&ghost_save->renew_time, rtc_time);
|
||||
}
|
||||
|
||||
if ((ghost_save->flags & mEv_GHOST_FLAG_RETURNED_SPIRITS) != 0) {
|
||||
Actor_delete(actorx);
|
||||
}
|
||||
}
|
||||
|
||||
if (Common_Get(player_no) == mPr_FOREIGNER) {
|
||||
Actor_delete(actorx);
|
||||
}
|
||||
|
||||
ghost->_9AA = 0;
|
||||
ghost->npc_class.talk_info.default_animation = 126;
|
||||
ghost->_9AC = 0;
|
||||
|
||||
if (aEGH_bitcheck_func(aEGH_BIT_FOUND_GHOST) != FALSE) {
|
||||
ghost->alpha = 140;
|
||||
}
|
||||
else {
|
||||
if (mFI_GetItemNumField_BCT(GRASS_A, GRASS_C) < aEGH_MINIMUM_GRASS_COUNT) {
|
||||
Actor_delete(actorx);
|
||||
}
|
||||
|
||||
ghost->alpha = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aEGH_actor_save(ACTOR* actorx, GAME* game) {
|
||||
mNpc_RenewalSetNpc(actorx);
|
||||
}
|
||||
|
||||
static void aEGH_actor_dt(ACTOR* actorx, GAME* game) {
|
||||
mEv_actor_dying_message(mEv_EVENT_GHOST, actorx);
|
||||
(*Common_Get(clip).npc_clip->dt_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aEGH_actor_init(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->init_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static int aEGH_set_request_act(EV_GHOST_ACTOR* ghost, u8 priority, u8 idx, u8 type, u16 arg0, u16 arg1, u16 arg2) {
|
||||
int res = FALSE;
|
||||
|
||||
if (priority >= ghost->npc_class.request.act_priority) {
|
||||
u16 args[6];
|
||||
|
||||
bzero(args, sizeof(args));
|
||||
args[0] = arg0;
|
||||
args[2] = arg1;
|
||||
args[3] = arg2;
|
||||
ghost->npc_class.request.act_priority = priority;
|
||||
ghost->npc_class.request.act_idx = idx;
|
||||
ghost->npc_class.request.act_type = type;
|
||||
mem_copy((u8*)ghost->npc_class.request.act_args, (u8*)args, sizeof(args));
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void aEGH_actor_move(ACTOR* actorx, GAME* game) {
|
||||
EV_GHOST_ACTOR* ghost = (EV_GHOST_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
int step;
|
||||
int alpha;
|
||||
int target_alpha;
|
||||
int delta_alpha;
|
||||
|
||||
if (aEGH_bitcheck_func(aEGH_BIT_FOUND_GHOST) != FALSE) {
|
||||
actorx->actor_specific = 1;
|
||||
}
|
||||
else {
|
||||
actorx->actor_specific = 0;
|
||||
}
|
||||
|
||||
(*Common_Get(clip).npc_clip->move_proc)(actorx, game);
|
||||
aEGH_byebye_check(ghost, play);
|
||||
|
||||
if (ghost->npc_class.schedule.type == aNPC_SCHEDULE_TYPE_WALK_WANDER && ghost->think_act != aEGH_THINK_SPEAK) {
|
||||
ghost->_9AC = 1;
|
||||
(*Common_Get(clip).npc_clip->chg_schedule_proc)((NPC_ACTOR*)ghost, play, aNPC_SCHEDULE_TYPE_SPECIAL);
|
||||
actorx->status_data.weight = 255;
|
||||
}
|
||||
|
||||
alpha = ghost->alpha;
|
||||
|
||||
if (aEGH_bitcheck_func(aEGH_BIT_FOUND_GHOST) != FALSE) {
|
||||
step = 1;
|
||||
|
||||
if (mDemo_Get_talk_actor() == actorx) {
|
||||
ghost->npc_class.draw._5BE = 0;
|
||||
ghost->npc_class.draw.animation_speed = 0.5f;
|
||||
target_alpha = 190;
|
||||
}
|
||||
else {
|
||||
if (actorx->speed > 0.1f) {
|
||||
target_alpha = 80;
|
||||
}
|
||||
else {
|
||||
target_alpha = 140;
|
||||
}
|
||||
|
||||
if (alpha <= 140) {
|
||||
step = 1;
|
||||
}
|
||||
|
||||
ghost->npc_class.draw._5BE = 1;
|
||||
ghost->npc_class.draw.animation_speed = 0.25f;
|
||||
}
|
||||
|
||||
delta_alpha = alpha - target_alpha;
|
||||
if (ABS(delta_alpha) < step) {
|
||||
alpha = target_alpha;
|
||||
}
|
||||
else {
|
||||
if (delta_alpha < 0) {
|
||||
alpha += step;
|
||||
}
|
||||
else {
|
||||
alpha -= step;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ghost->bye_bye_transparency_delay_timer != 0) {
|
||||
ghost->bye_bye_transparency_delay_timer--;
|
||||
}
|
||||
else {
|
||||
alpha -= 4;
|
||||
|
||||
if (alpha < 0) {
|
||||
alpha = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ghost->alpha = alpha;
|
||||
actorx->shape_info.draw_shadow = FALSE;
|
||||
}
|
||||
|
||||
static void aEGH_actor_draw(ACTOR* actorx, GAME* game) {
|
||||
EV_GHOST_ACTOR* ghost = (EV_GHOST_ACTOR*)actorx;
|
||||
GRAPH* graph = game->graph;
|
||||
Gfx* gfx;
|
||||
|
||||
OPEN_DISP(graph);
|
||||
gfx = NOW_POLY_XLU_DISP;
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
gDPSetEnvColor(gfx++, 255, 255, 255, ghost->alpha);
|
||||
|
||||
SET_POLY_XLU_DISP(gfx);
|
||||
CLOSE_DISP(graph);
|
||||
|
||||
(*Common_Get(clip).npc_clip->draw_proc)(actorx, game);
|
||||
}
|
||||
|
||||
#include "../src/actor/ac_ev_ghost_talk.c_inc"
|
||||
#include "../src/actor/ac_ev_ghost_schedule.c_inc"
|
||||
@@ -0,0 +1,305 @@
|
||||
static void aEGH_look_player(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
|
||||
if (ghost->npc_class.action.step == aNPC_ACTION_END_STEP) {
|
||||
u8 action = 4;
|
||||
s16 player_y = ghost->npc_class.actor_class.player_angle_y;
|
||||
s16 rot_y = ghost->npc_class.actor_class.shape_info.rotation.y;
|
||||
s16 diff = player_y - rot_y;
|
||||
|
||||
if (ABS(diff) < DEG2SHORT_ANGLE(67.5f)) {
|
||||
action = 0;
|
||||
}
|
||||
|
||||
aEGH_set_request_act(ghost, 4, action, 2, 1, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static int aEGH_bitset_func(u16 bit) {
|
||||
u32 player_no = Common_Get(player_no);
|
||||
mEv_gst_c* ghost_save = (mEv_gst_c*)mEv_get_save_area(mEv_EVENT_GHOST, 54);
|
||||
mEv_gst_common_c* ghost_common = (mEv_gst_common_c*)mEv_get_common_area(mEv_EVENT_GHOST, 55);
|
||||
|
||||
if (player_no == mPr_FOREIGNER) {
|
||||
if (ghost_common != NULL) {
|
||||
ghost_common->flags |= bit;
|
||||
return TRUE;
|
||||
}
|
||||
} else if (ghost_save != NULL) {
|
||||
ghost_save->flags |= (u16)(bit << player_no);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int aEGH_bitclr_func(u16 bit) {
|
||||
u32 player_no = Common_Get(player_no);
|
||||
mEv_gst_c* ghost_save = (mEv_gst_c*)mEv_get_save_area(mEv_EVENT_GHOST, 54);
|
||||
mEv_gst_common_c* ghost_common = (mEv_gst_common_c*)mEv_get_common_area(mEv_EVENT_GHOST, 55);
|
||||
|
||||
if (player_no == mPr_FOREIGNER) {
|
||||
if (ghost_common != NULL) {
|
||||
ghost_common->flags &= ~bit;
|
||||
return TRUE;
|
||||
}
|
||||
} else if (ghost_save != NULL) {
|
||||
ghost_save->flags &= ~(u16)(bit << player_no);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static u16 aEGH_bitcheck_func(u16 bit) {
|
||||
u32 player_no = Common_Get(player_no);
|
||||
mEv_gst_c* ghost_save = (mEv_gst_c*)mEv_get_save_area(mEv_EVENT_GHOST, 54);
|
||||
mEv_gst_common_c* ghost_common = (mEv_gst_common_c*)mEv_get_common_area(mEv_EVENT_GHOST, 55);
|
||||
|
||||
if (player_no == mPr_FOREIGNER) {
|
||||
if (ghost_common != NULL) {
|
||||
return ghost_common->flags & bit;
|
||||
}
|
||||
} else if (ghost_save != NULL) {
|
||||
return (u16)(bit << player_no) & ghost_save->flags;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int aEGH_equal_block(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
|
||||
int bx;
|
||||
int bz;
|
||||
|
||||
mFI_Wpos2BlockNum(&bx, &bz, GET_PLAYER_ACTOR(play)->actor_class.world.position);
|
||||
return bx == ghost->npc_class.actor_class.block_x && bz == ghost->npc_class.actor_class.block_z;
|
||||
}
|
||||
|
||||
static int aEGH_time_over() {
|
||||
return Common_Get(time.now_sec) > (4 * mTM_SECONDS_IN_HOUR);
|
||||
}
|
||||
|
||||
static void aEGH_byebye_check(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
|
||||
ACTOR* actorx = (ACTOR*)ghost;
|
||||
|
||||
if (mDemo_Check(mDemo_TYPE_TALK, actorx) == FALSE && mDemo_Check(mDemo_TYPE_SPEAK, actorx) == FALSE &&
|
||||
aEGH_time_over() != FALSE) {
|
||||
if (aEGH_equal_block(ghost, play)) {
|
||||
switch (ghost->think_act) {
|
||||
case aEGH_THINK_SPEAK: {
|
||||
aEGH_setup_think_proc(ghost, play, aEGH_THINK_BYEBYE);
|
||||
ghost->msg_no = 0x2EDD;
|
||||
ghost->npc_class.actor_class.talk_distance = 1000.0f;
|
||||
ghost->_9AA = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case aEGH_THINK_NORMAL_WAIT:
|
||||
case aEGH_THINK_IRAI_AF:
|
||||
case aEGH_THINK_BYE:
|
||||
case aEGH_THINK_WELCOM: {
|
||||
Actor_delete((ACTOR*)ghost);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
aEGH_setup_think_proc(ghost, play, aEGH_THINK_IRAI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aEGH_irai(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
|
||||
if (ghost->npc_class.actor_class.player_distance_xz > 220.0f) {
|
||||
aEGH_setup_think_proc(ghost, play, aEGH_THINK_BYE);
|
||||
}
|
||||
}
|
||||
|
||||
static void aEGH_bye(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
|
||||
if (ghost->npc_class.actor_class.player_distance_xz < 200.0f) {
|
||||
aEGH_setup_think_proc(ghost, play, aEGH_THINK_WELCOM);
|
||||
}
|
||||
}
|
||||
|
||||
static void aEGH_byebye(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
|
||||
if (ghost->alpha == 0) {
|
||||
Actor_delete((ACTOR*)ghost);
|
||||
} else {
|
||||
if (ghost->bye_bye_timer != 0) {
|
||||
ghost->bye_bye_timer--;
|
||||
|
||||
if (ghost->bye_bye_timer == 0) {
|
||||
sAdo_SysTrgStart(0x16C);
|
||||
}
|
||||
} else {
|
||||
if (ghost->bye_bye_angle < 30000) {
|
||||
ghost->bye_bye_angle += 60;
|
||||
}
|
||||
|
||||
ghost->npc_class.actor_class.shape_info.rotation.y += ghost->bye_bye_angle;
|
||||
ghost->npc_class.actor_class.world.angle.y = ghost->npc_class.actor_class.shape_info.rotation.y;
|
||||
ghost->npc_class.movement.mv_angl = ghost->npc_class.actor_class.world.angle.y;
|
||||
ghost->npc_class.movement.mv_add_angl = 0;
|
||||
}
|
||||
|
||||
if (ghost->bye_bye_scale_timer != 0) {
|
||||
ghost->bye_bye_scale_timer--;
|
||||
} else {
|
||||
ghost->npc_class.actor_class.scale.x += -0.00004f;
|
||||
ghost->npc_class.actor_class.scale.z = ghost->npc_class.actor_class.scale.x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aEGH_speak_byebye(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
|
||||
ACTOR* actorx = (ACTOR*)ghost;
|
||||
|
||||
if (mDemo_Check(mDemo_TYPE_TALK, actorx) == FALSE && mDemo_Check(mDemo_TYPE_SPEAK, actorx) == FALSE &&
|
||||
aEGH_equal_block(ghost, play) == FALSE) {
|
||||
aEGH_setup_think_proc(ghost, play, aEGH_THINK_IRAI);
|
||||
}
|
||||
}
|
||||
|
||||
static void aEGH_think_main_proc(NPC_ACTOR* actorx, GAME_PLAY* play) {
|
||||
EV_GHOST_ACTOR* ghost = (EV_GHOST_ACTOR*)actorx;
|
||||
|
||||
(*ghost->think_proc)(ghost, play);
|
||||
aEGH_look_player(ghost, play);
|
||||
}
|
||||
|
||||
static void aEGH_think_init_proc(NPC_ACTOR* actorx, GAME_PLAY* play) {
|
||||
EV_GHOST_ACTOR* ghost = (EV_GHOST_ACTOR*)actorx;
|
||||
u8 think_act;
|
||||
|
||||
if (ghost->_9AC) {
|
||||
ghost->_9AC = FALSE;
|
||||
} else {
|
||||
if (aEGH_bitcheck_func(aEGH_BIT_FOUND_GHOST)) {
|
||||
ghost->alpha = 140;
|
||||
think_act = aEGH_THINK_SPEAK;
|
||||
} else {
|
||||
ghost->alpha = 0;
|
||||
think_act = aEGH_THINK_IRAI_AF;
|
||||
}
|
||||
|
||||
actorx->actor_class.status_data.weight = 255;
|
||||
actorx->condition_info.hide_request = FALSE;
|
||||
aEGH_setup_think_proc(ghost, play, think_act);
|
||||
actorx->condition_info.demo_flg = aNPC_COND_DEMO_SKIP_FOOTSTEPS_VFX | aNPC_COND_DEMO_SKIP_FEEL_CHECK |
|
||||
aNPC_COND_DEMO_SKIP_FOOTSTEPS | aNPC_COND_DEMO_SKIP_ENTRANCE_CHECK |
|
||||
aNPC_COND_DEMO_SKIP_HEAD_LOOKAT;
|
||||
}
|
||||
}
|
||||
|
||||
static void aEGH_normal_wait_init(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
|
||||
(*Common_Get(clip).npc_clip->animation_init_proc)((ACTOR*)ghost, aNPC_ANIM_GSTWAIT1, FALSE);
|
||||
ghost->npc_class.draw.main_animation.keyframe.frame_control.mode = cKF_FRAMECONTROL_REPEAT;
|
||||
ghost->npc_class.action.idx = 0;
|
||||
aEGH_set_request_act(ghost, 4, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
static void aEGH_irai_init(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
|
||||
ghost->npc_class.actor_class.talk_distance = 80.0f;
|
||||
aEGH_normal_wait_init(ghost, play);
|
||||
ghost->msg_no = 0x2EE2;
|
||||
}
|
||||
|
||||
static void aEGH_irai_af_init(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
|
||||
ghost->npc_class.actor_class.talk_distance = 55.0f;
|
||||
ghost->msg_no = 0x2EE7;
|
||||
(*Common_Get(clip).npc_clip->chg_schedule_proc)((NPC_ACTOR*)ghost, play, 5);
|
||||
ghost->npc_class.actor_class.status_data.weight = 80;
|
||||
}
|
||||
|
||||
static void aEGH_bye_init(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
|
||||
ghost->npc_class.actor_class.talk_distance = 280.0f;
|
||||
aEGH_normal_wait_init(ghost, play);
|
||||
ghost->msg_no = 0x2ED8;
|
||||
}
|
||||
|
||||
static void aEGH_welcom_init(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
|
||||
ghost->npc_class.actor_class.talk_distance = 200.0f;
|
||||
aEGH_normal_wait_init(ghost, play);
|
||||
ghost->msg_no = 0x2ED3;
|
||||
}
|
||||
|
||||
static void aEGH_byebye_init(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
|
||||
aEGH_bitclr_func(aEGH_BIT_FOUND_GHOST);
|
||||
ghost->bye_bye_angle = -1000;
|
||||
ghost->bye_bye_timer = 25;
|
||||
ghost->bye_bye_scale_timer = 48;
|
||||
ghost->bye_bye_transparency_delay_timer = 43;
|
||||
aEGH_normal_wait_init(ghost, play);
|
||||
ghost->npc_class.head.lock_flag = TRUE;
|
||||
}
|
||||
|
||||
static aEGH_setup_c dt_tbl[aEGH_THINK_NUM] = {
|
||||
{ aEGH_THINK_PROC_BYE, aEGH_THINK_INIT_NORMAL_WAIT, aEGH_TALK_REQUEST_NONE, aEGH_TALK_END_WAIT,
|
||||
aEGH_THINK_NORMAL_WAIT },
|
||||
{ aEGH_THINK_PROC_BYEBYE, aEGH_THINK_INIT_BYEBYE, aEGH_TALK_REQUEST_NONE, aEGH_TALK_END_WAIT, aEGH_THINK_IRAI },
|
||||
|
||||
{ aEGH_THINK_PROC_NONE, aEGH_THINK_INIT_WELCOM, aEGH_TALK_REQUEST_FORCE, aEGH_TALK_END_WAIT, aEGH_THINK_WELCOM },
|
||||
|
||||
{ aEGH_THINK_PROC_BYE, aEGH_THINK_INIT_BYE, aEGH_TALK_REQUEST_FORCE, aEGH_TALK_GIVE_ME_WAIT,
|
||||
aEGH_THINK_NORMAL_WAIT },
|
||||
|
||||
{ aEGH_THINK_PROC_IRAI, aEGH_THINK_INIT_IRAI, aEGH_TALK_REQUEST_FORCE, aEGH_TALK_SELECT_WAIT, aEGH_THINK_SPEAK },
|
||||
|
||||
{ aEGH_THINK_PROC_SPEAK_BYEBYE, aEGH_THINK_INIT_NORMAL_WAIT, aEGH_TALK_REQUEST_FORCE, aEGH_TALK_SELECT_ROOF,
|
||||
aEGH_THINK_IRAI },
|
||||
|
||||
{ aEGH_THINK_PROC_NONE, aEGH_THINK_INIT_IRAI_AF, aEGH_TALK_REQUEST_NORM, aEGH_TALK_END_WAIT, aEGH_THINK_SPEAK }
|
||||
};
|
||||
|
||||
static aEGH_PROC proc_table[aEGH_THINK_PROC_NUM] = { (aEGH_PROC)&none_proc1, &aEGH_irai, &aEGH_bye, &aEGH_byebye,
|
||||
&aEGH_speak_byebye };
|
||||
|
||||
static aEGH_PROC init_table[aEGH_THINK_INIT_NUM] = { (aEGH_PROC)&none_proc1, &aEGH_normal_wait_init, &aEGH_irai_init,
|
||||
&aEGH_irai_af_init, &aEGH_bye_init, &aEGH_welcom_init,
|
||||
&aEGH_byebye_init };
|
||||
|
||||
static void aEGH_setup_think_proc(EV_GHOST_ACTOR* ghost, GAME_PLAY* play, u8 think_act) {
|
||||
static aNPC_TALK_REQUEST_PROC talk_request_table[aEGH_TALK_REQUEST_NUM] = { (aNPC_TALK_REQUEST_PROC)&none_proc1,
|
||||
&aEGH_norm_talk_request,
|
||||
&aEGH_force_talk_request };
|
||||
|
||||
aEGH_setup_c* data = &dt_tbl[think_act];
|
||||
|
||||
ghost->think_act = think_act;
|
||||
ghost->think_proc = proc_table[data->think_proc];
|
||||
ghost->npc_class.talk_info.talk_request_proc = talk_request_table[data->talk_request_proc];
|
||||
ghost->talk_act = data->talk_act;
|
||||
ghost->after_talk_think_act = data->talk_after_act;
|
||||
(*init_table[data->think_init_proc])(ghost, play);
|
||||
ghost->_9A7 = TRUE;
|
||||
}
|
||||
|
||||
static void aEGH_think_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int think_type) {
|
||||
switch (think_type) {
|
||||
case 0:
|
||||
aEGH_think_init_proc(actorx, play);
|
||||
break;
|
||||
case 1:
|
||||
aEGH_think_main_proc(actorx, play);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void aEGH_schedule_init_proc(NPC_ACTOR* actorx, GAME_PLAY* play) {
|
||||
actorx->think.think_proc = &aEGH_think_proc;
|
||||
(*Common_Get(clip).npc_clip->think_proc)(actorx, play, aNPC_THINK_SPECIAL, 0);
|
||||
}
|
||||
|
||||
static void aEGH_schedule_main_proc(NPC_ACTOR* actorx, GAME_PLAY* play) {
|
||||
if ((*Common_Get(clip).npc_clip->think_proc)(actorx, play, -1, 1) == FALSE) {
|
||||
(*Common_Get(clip).npc_clip->think_proc)(actorx, play, -1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void aEGH_schedule_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int sched_type) {
|
||||
switch (sched_type) {
|
||||
case 0:
|
||||
aEGH_schedule_init_proc(actorx, play);
|
||||
break;
|
||||
case 1:
|
||||
aEGH_schedule_main_proc(actorx, play);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,625 @@
|
||||
static int aEGH_hitodama_num() {
|
||||
int i;
|
||||
int num;
|
||||
Private_c* priv = Common_Get(now_private);
|
||||
|
||||
for (i = 0, num = 0; i < mEv_GHOST_HITODAMA_NUM; i++) {
|
||||
int n = mPr_GetPossessionItemSumWithCond(priv, ITM_SPIRIT0 + i, mPr_ITEM_COND_NORMAL);
|
||||
|
||||
num += n * (i + 1);
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
static void aEGH_okoruhito() {
|
||||
static u8 pf_string[mMsg_FREE_STRING_LEN];
|
||||
mEv_gst_c* ghost_ev = (mEv_gst_c*)mEv_get_save_area(mEv_EVENT_GHOST, 54);
|
||||
|
||||
mString_Load_StringFromRom(pf_string, sizeof(pf_string), 0x62E + ghost_ev->okoruhito_str_no);
|
||||
mMsg_Set_item_str(mMsg_Get_base_window_p(), mMsg_FREE_STR1, pf_string, sizeof(pf_string));
|
||||
}
|
||||
|
||||
static void aEGH_delete_hitodama() {
|
||||
int i;
|
||||
int num;
|
||||
Private_c* priv = Common_Get(now_private);
|
||||
|
||||
for (i = 0, num = 0; i < mEv_GHOST_HITODAMA_NUM; i++) {
|
||||
int idx = mPr_GetPossessionItemIdxWithCond(priv, ITM_SPIRIT0 + i, mPr_ITEM_COND_NORMAL);
|
||||
|
||||
while (idx != -1) {
|
||||
mPr_SetPossessionItem(Common_Get(now_private), idx, EMPTY_NO, mPr_ITEM_COND_NORMAL);
|
||||
idx = mPr_GetPossessionItemIdxWithCond(priv, ITM_SPIRIT0 + i, mPr_ITEM_COND_NORMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static mActor_name_t aEGH_get_collect(int selected_idx, mActor_name_t* list) {
|
||||
while (*list != EMPTY_NO) {
|
||||
if (mSP_CollectCheck(*list) == FALSE) {
|
||||
if (selected_idx > 0) {
|
||||
selected_idx--;
|
||||
}
|
||||
else {
|
||||
return *list;
|
||||
}
|
||||
}
|
||||
|
||||
list++;
|
||||
}
|
||||
|
||||
return EMPTY_NO;
|
||||
}
|
||||
|
||||
static void aEGH_check_collect_num(int* list_num, int* uncollect_num, mActor_name_t* list) {
|
||||
*list_num = 0;
|
||||
*uncollect_num = 0;
|
||||
|
||||
while (*list != EMPTY_NO) {
|
||||
(*list_num)++;
|
||||
|
||||
if (mSP_CollectCheck(*list) == FALSE) {
|
||||
(*uncollect_num)++;
|
||||
}
|
||||
|
||||
list++;
|
||||
}
|
||||
}
|
||||
|
||||
extern mActor_name_t ftr_listA[];
|
||||
extern mActor_name_t ftr_listB[];
|
||||
extern mActor_name_t ftr_listC[];
|
||||
extern mActor_name_t ftr_listEvent[];
|
||||
extern mActor_name_t ftr_listLottery[];
|
||||
extern mActor_name_t carpet_listA[];
|
||||
extern mActor_name_t carpet_listB[];
|
||||
extern mActor_name_t carpet_listC[];
|
||||
extern mActor_name_t carpet_listEvent[];
|
||||
extern mActor_name_t wall_listA[];
|
||||
extern mActor_name_t wall_listB[];
|
||||
extern mActor_name_t wall_listC[];
|
||||
extern mActor_name_t wall_listEvent[];
|
||||
extern mActor_name_t cloth_listA[];
|
||||
extern mActor_name_t cloth_listB[];
|
||||
extern mActor_name_t cloth_listC[];
|
||||
extern mActor_name_t cloth_listEvent[];
|
||||
extern mActor_name_t binsen_listA[];
|
||||
extern mActor_name_t binsen_listB[];
|
||||
extern mActor_name_t binsen_listC[];
|
||||
|
||||
static mActor_name_t list_haniwa[HANIWA_NUM + 1] = {
|
||||
FTR_HANIWA000_SOUTH,
|
||||
FTR_HANIWA001_SOUTH,
|
||||
FTR_HANIWA002_SOUTH,
|
||||
FTR_HANIWA003_SOUTH,
|
||||
FTR_HANIWA004_SOUTH,
|
||||
FTR_HANIWA005_SOUTH,
|
||||
FTR_HANIWA006_SOUTH,
|
||||
FTR_HANIWA007_SOUTH,
|
||||
FTR_HANIWA008_SOUTH,
|
||||
FTR_HANIWA009_SOUTH,
|
||||
FTR_HANIWA010_SOUTH,
|
||||
FTR_HANIWA011_SOUTH,
|
||||
FTR_HANIWA012_SOUTH,
|
||||
FTR_HANIWA013_SOUTH,
|
||||
FTR_HANIWA014_SOUTH,
|
||||
FTR_HANIWA015_SOUTH,
|
||||
FTR_HANIWA016_SOUTH,
|
||||
FTR_HANIWA017_SOUTH,
|
||||
FTR_HANIWA018_SOUTH,
|
||||
FTR_HANIWA019_SOUTH,
|
||||
FTR_HANIWA020_SOUTH,
|
||||
FTR_HANIWA021_SOUTH,
|
||||
FTR_HANIWA022_SOUTH,
|
||||
FTR_HANIWA023_SOUTH,
|
||||
FTR_HANIWA024_SOUTH,
|
||||
FTR_HANIWA025_SOUTH,
|
||||
FTR_HANIWA026_SOUTH,
|
||||
FTR_HANIWA027_SOUTH,
|
||||
FTR_HANIWA028_SOUTH,
|
||||
FTR_HANIWA029_SOUTH,
|
||||
FTR_HANIWA030_SOUTH,
|
||||
FTR_HANIWA031_SOUTH,
|
||||
FTR_HANIWA032_SOUTH,
|
||||
FTR_HANIWA033_SOUTH,
|
||||
FTR_HANIWA034_SOUTH,
|
||||
FTR_HANIWA035_SOUTH,
|
||||
FTR_HANIWA036_SOUTH,
|
||||
FTR_HANIWA037_SOUTH,
|
||||
FTR_HANIWA038_SOUTH,
|
||||
FTR_HANIWA039_SOUTH,
|
||||
FTR_HANIWA040_SOUTH,
|
||||
FTR_HANIWA041_SOUTH,
|
||||
FTR_HANIWA042_SOUTH,
|
||||
FTR_HANIWA043_SOUTH,
|
||||
FTR_HANIWA044_SOUTH,
|
||||
FTR_HANIWA045_SOUTH,
|
||||
FTR_HANIWA046_SOUTH,
|
||||
FTR_HANIWA047_SOUTH,
|
||||
FTR_HANIWA048_SOUTH,
|
||||
FTR_HANIWA049_SOUTH,
|
||||
FTR_HANIWA050_SOUTH,
|
||||
FTR_HANIWA051_SOUTH,
|
||||
FTR_HANIWA052_SOUTH,
|
||||
FTR_HANIWA053_SOUTH,
|
||||
FTR_HANIWA054_SOUTH,
|
||||
FTR_HANIWA055_SOUTH,
|
||||
FTR_HANIWA056_SOUTH,
|
||||
FTR_HANIWA057_SOUTH,
|
||||
FTR_HANIWA058_SOUTH,
|
||||
FTR_HANIWA059_SOUTH,
|
||||
FTR_HANIWA060_SOUTH,
|
||||
FTR_HANIWA061_SOUTH,
|
||||
FTR_HANIWA062_SOUTH,
|
||||
FTR_HANIWA063_SOUTH,
|
||||
FTR_HANIWA064_SOUTH,
|
||||
FTR_HANIWA065_SOUTH,
|
||||
FTR_HANIWA066_SOUTH,
|
||||
FTR_HANIWA067_SOUTH,
|
||||
FTR_HANIWA068_SOUTH,
|
||||
FTR_HANIWA069_SOUTH,
|
||||
FTR_HANIWA070_SOUTH,
|
||||
FTR_HANIWA071_SOUTH,
|
||||
FTR_HANIWA072_SOUTH,
|
||||
FTR_HANIWA073_SOUTH,
|
||||
FTR_HANIWA074_SOUTH,
|
||||
FTR_HANIWA075_SOUTH,
|
||||
FTR_HANIWA076_SOUTH,
|
||||
FTR_HANIWA077_SOUTH,
|
||||
FTR_HANIWA078_SOUTH,
|
||||
FTR_HANIWA079_SOUTH,
|
||||
FTR_HANIWA080_SOUTH,
|
||||
FTR_HANIWA081_SOUTH,
|
||||
FTR_HANIWA082_SOUTH,
|
||||
FTR_HANIWA083_SOUTH,
|
||||
FTR_HANIWA084_SOUTH,
|
||||
FTR_HANIWA085_SOUTH,
|
||||
FTR_HANIWA086_SOUTH,
|
||||
FTR_HANIWA087_SOUTH,
|
||||
FTR_HANIWA088_SOUTH,
|
||||
FTR_HANIWA089_SOUTH,
|
||||
FTR_HANIWA090_SOUTH,
|
||||
FTR_HANIWA091_SOUTH,
|
||||
FTR_HANIWA092_SOUTH,
|
||||
FTR_HANIWA093_SOUTH,
|
||||
FTR_HANIWA094_SOUTH,
|
||||
FTR_HANIWA095_SOUTH,
|
||||
FTR_HANIWA096_SOUTH,
|
||||
FTR_HANIWA097_SOUTH,
|
||||
FTR_HANIWA098_SOUTH,
|
||||
FTR_HANIWA099_SOUTH,
|
||||
FTR_HANIWA100_SOUTH,
|
||||
FTR_HANIWA101_SOUTH,
|
||||
FTR_HANIWA102_SOUTH,
|
||||
FTR_HANIWA103_SOUTH,
|
||||
FTR_HANIWA104_SOUTH,
|
||||
FTR_HANIWA105_SOUTH,
|
||||
FTR_HANIWA106_SOUTH,
|
||||
FTR_HANIWA107_SOUTH,
|
||||
FTR_HANIWA108_SOUTH,
|
||||
FTR_HANIWA109_SOUTH,
|
||||
FTR_HANIWA110_SOUTH,
|
||||
FTR_HANIWA111_SOUTH,
|
||||
FTR_HANIWA112_SOUTH,
|
||||
FTR_HANIWA113_SOUTH,
|
||||
FTR_HANIWA114_SOUTH,
|
||||
FTR_HANIWA115_SOUTH,
|
||||
FTR_HANIWA116_SOUTH,
|
||||
FTR_HANIWA117_SOUTH,
|
||||
FTR_HANIWA118_SOUTH,
|
||||
FTR_HANIWA119_SOUTH,
|
||||
FTR_HANIWA120_SOUTH,
|
||||
FTR_HANIWA121_SOUTH,
|
||||
FTR_HANIWA122_SOUTH,
|
||||
FTR_HANIWA123_SOUTH,
|
||||
FTR_HANIWA124_SOUTH,
|
||||
FTR_HANIWA125_SOUTH,
|
||||
FTR_HANIWA126_SOUTH,
|
||||
EMPTY_NO /* end of list */
|
||||
};
|
||||
|
||||
static mActor_name_t umbrella_list[UMBRELLA_NUM + 1] = {
|
||||
ITM_UMBRELLA00,
|
||||
ITM_UMBRELLA01,
|
||||
ITM_UMBRELLA02,
|
||||
ITM_UMBRELLA03,
|
||||
ITM_UMBRELLA04,
|
||||
ITM_UMBRELLA05,
|
||||
ITM_UMBRELLA06,
|
||||
ITM_UMBRELLA07,
|
||||
ITM_UMBRELLA08,
|
||||
ITM_UMBRELLA09,
|
||||
ITM_UMBRELLA10,
|
||||
ITM_UMBRELLA11,
|
||||
ITM_UMBRELLA12,
|
||||
ITM_UMBRELLA13,
|
||||
ITM_UMBRELLA14,
|
||||
ITM_UMBRELLA15,
|
||||
ITM_UMBRELLA16,
|
||||
ITM_UMBRELLA17,
|
||||
ITM_UMBRELLA18,
|
||||
ITM_UMBRELLA19,
|
||||
ITM_UMBRELLA20,
|
||||
ITM_UMBRELLA21,
|
||||
ITM_UMBRELLA22,
|
||||
ITM_UMBRELLA23,
|
||||
ITM_UMBRELLA24,
|
||||
ITM_UMBRELLA25,
|
||||
ITM_UMBRELLA26,
|
||||
ITM_UMBRELLA27,
|
||||
ITM_UMBRELLA28,
|
||||
ITM_UMBRELLA29,
|
||||
ITM_UMBRELLA30,
|
||||
ITM_UMBRELLA31,
|
||||
EMPTY_NO /* end of list */
|
||||
};
|
||||
|
||||
static mActor_name_t aEGH_not_collect_get() {
|
||||
static mActor_name_t* item_list[aEGH_ITEM_LIST_NUM] = {
|
||||
ftr_listA,
|
||||
ftr_listB,
|
||||
ftr_listC,
|
||||
ftr_listEvent,
|
||||
ftr_listLottery,
|
||||
carpet_listA,
|
||||
carpet_listB,
|
||||
carpet_listC,
|
||||
carpet_listEvent,
|
||||
wall_listA,
|
||||
wall_listB,
|
||||
wall_listC,
|
||||
wall_listEvent,
|
||||
cloth_listA,
|
||||
cloth_listB,
|
||||
cloth_listC,
|
||||
cloth_listEvent,
|
||||
binsen_listA,
|
||||
binsen_listB,
|
||||
binsen_listC,
|
||||
list_haniwa,
|
||||
umbrella_list
|
||||
};
|
||||
|
||||
int list_num_tbl[aEGH_ITEM_LIST_NUM];
|
||||
int uncollect_num_tbl[aEGH_ITEM_LIST_NUM];
|
||||
int no_uncollected_flag = FALSE;
|
||||
int selected_idx;
|
||||
mActor_name_t item;
|
||||
int i;
|
||||
int total_count;
|
||||
|
||||
/* Calculate total items in each list and uncollected items in each list */
|
||||
for (i = 0; i < aEGH_ITEM_LIST_NUM; i++) {
|
||||
aEGH_check_collect_num(&list_num_tbl[i], &uncollect_num_tbl[i], item_list[i]);
|
||||
}
|
||||
|
||||
for (i = 0, total_count = 0; i < aEGH_ITEM_LIST_NUM; i++) {
|
||||
total_count += uncollect_num_tbl[i];
|
||||
}
|
||||
|
||||
/* If no uncollected items remain, select one at random from all lists */
|
||||
if (total_count == 0) {
|
||||
no_uncollected_flag = TRUE; /* all items collected */
|
||||
for (i = 0, total_count = 0; i < aEGH_ITEM_LIST_NUM; i++) {
|
||||
total_count += list_num_tbl[i];
|
||||
}
|
||||
}
|
||||
|
||||
selected_idx = RANDOM(total_count);
|
||||
if (no_uncollected_flag) {
|
||||
/* Transform the absolute idx into the list idx by removing all entries up to the selected list */
|
||||
for (i = 0; i < aEGH_ITEM_LIST_NUM && selected_idx >= list_num_tbl[i]; i++) {
|
||||
selected_idx -= list_num_tbl[i];
|
||||
}
|
||||
|
||||
if (i != aEGH_ITEM_LIST_NUM) {
|
||||
item = item_list[i][selected_idx];
|
||||
}
|
||||
else {
|
||||
item = ITM_FOOD_PEACH; /* If we somehow failed to select an item, we'll give them a peach */
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Transform the absolute idx into the list idx by removing all entries up to the selected list */
|
||||
for (i = 0; i < aEGH_ITEM_LIST_NUM && selected_idx >= uncollect_num_tbl[i]; i++) {
|
||||
selected_idx -= uncollect_num_tbl[i];
|
||||
}
|
||||
|
||||
if (i != aEGH_ITEM_LIST_NUM) {
|
||||
item = aEGH_get_collect(selected_idx, item_list[i]); /* Get the uncollected item from the list */
|
||||
|
||||
if (item == EMPTY_NO) {
|
||||
item = ITM_FOOD_APPLE; /* If we somehow failed to get an uncollected item, we'll give them an apple */
|
||||
}
|
||||
}
|
||||
else {
|
||||
item = ITM_FOOD_PEACH; /* If we somehow failed to select an item, we'll give them a peach */
|
||||
}
|
||||
}
|
||||
|
||||
return mRmTp_FtrItemNo2Item1ItemNo(item, TRUE);
|
||||
}
|
||||
|
||||
static void aEGH_give_me_wait(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
|
||||
int order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
|
||||
switch (order) {
|
||||
case 1:
|
||||
{
|
||||
mPlib_request_main_give_type1((GAME*)play, ITM_SPIRIT0, 7, FALSE, FALSE);
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 2);
|
||||
mMsg_Set_LockContinue(mMsg_Get_base_window_p());
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 1, 3);
|
||||
aEGH_delete_hitodama();
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
if (Common_Get(clip).handOverItem_clip->master_actor == NULL) {
|
||||
mMsg_Unset_LockContinue(mMsg_Get_base_window_p());
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
aEGH_change_talk_proc(ghost, aEGH_TALK_SELECT_WAIT);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aEGH_select_wait(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
|
||||
int order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
|
||||
mEv_gst_c* ghost_data = (mEv_gst_c*)mEv_get_save_area(mEv_EVENT_GHOST, 54);
|
||||
|
||||
if (order == 1 && mMsg_Check_MainNormalContinue(mMsg_Get_base_window_p())) {
|
||||
ghost->after_talk_think_act = 1;
|
||||
ghost_data->flags |= mEv_GHOST_FLAG_RETURNED_SPIRITS;
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
|
||||
switch (mChoice_Get_ChoseNum(mChoice_Get_base_window_p())) {
|
||||
case mChoice_CHOICE0: /* Clear weeds */
|
||||
{
|
||||
u32 num_weeds = mFI_GetItemNumField(GRASS_A, GRASS_C);
|
||||
|
||||
if (num_weeds < 50) {
|
||||
mMsg_Set_continue_msg_num(msg_p, 0x2EF1);
|
||||
}
|
||||
else if (num_weeds < 150) {
|
||||
mMsg_Set_continue_msg_num(msg_p, 0x2EF2);
|
||||
}
|
||||
else if (num_weeds < 450) {
|
||||
mMsg_Set_continue_msg_num(msg_p, 0x2EF3);
|
||||
}
|
||||
else if (num_weeds < 900) {
|
||||
mMsg_Set_continue_msg_num(msg_p, 0x2EF4);
|
||||
}
|
||||
else {
|
||||
mMsg_Set_continue_msg_num(msg_p, 0x2EF5);
|
||||
}
|
||||
|
||||
aEGH_change_talk_proc(ghost, aEGH_TALK_CLEAR_GRASS);
|
||||
break;
|
||||
}
|
||||
|
||||
case mChoice_CHOICE1:
|
||||
{
|
||||
aEGH_change_talk_proc(ghost, aEGH_TALK_SELECT_ROOF);
|
||||
ghost->roof_pal = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case mChoice_CHOICE2:
|
||||
{
|
||||
u8 name[mIN_ITEM_NAME_LEN];
|
||||
|
||||
aEGH_change_talk_proc(ghost, aEGH_TALK_GIVE_YOU_WAIT);
|
||||
ghost->give_item = aEGH_not_collect_get();
|
||||
mIN_copy_name_str(name, ghost->give_item);
|
||||
mMsg_Set_item_str_art(msg_p, mMsg_ITEM_STR0, name, mIN_ITEM_NAME_LEN, mIN_get_item_article(ghost->give_item));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aEGH_select_roof(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
|
||||
int order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
int arrange_idx = mHS_get_arrange_idx(Common_Get(player_no));
|
||||
mHm_hs_c* home = Save_GetPointer(homes[arrange_idx]);
|
||||
|
||||
if (order == 1 && mMsg_Check_MainNormalContinue(mMsg_Get_base_window_p())) {
|
||||
int selected;
|
||||
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
selected = mChoice_Get_ChoseNum(mChoice_Get_base_window_p());
|
||||
|
||||
if (selected >= mChoice_CHOICE3) {
|
||||
ghost->roof_pal += 3;
|
||||
|
||||
if (ghost->roof_pal >= mSP_ROOF_COLOR_NUM) {
|
||||
ghost->roof_pal = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ghost->roof_pal += (u8)selected;
|
||||
home->outlook_pal = ghost->roof_pal;
|
||||
|
||||
/* Only update the 'next outlook' palette if the player doesn't have a coat of paint already scheduled */
|
||||
if ((Common_Get(now_private)->state_flags & mPr_FLAG_UPDATE_OUTLOOK_PENDING) == 0) {
|
||||
home->next_outlook_pal = ghost->roof_pal;
|
||||
}
|
||||
|
||||
aEGH_change_talk_proc(ghost, aEGH_TALK_END_WAIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aEGH_give_you_wait(EV_GHOST_ACTOR* ghost, GAME_PLAY* play) {
|
||||
int order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 1);
|
||||
|
||||
if (order == 2) {
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 0, ghost->give_item);
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 1, 7);
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 2, 0);
|
||||
mPr_SetFreePossessionItem(Common_Get(now_private), ghost->give_item, mPr_ITEM_COND_NORMAL);
|
||||
aEGH_change_talk_proc(ghost, aEGH_TALK_END_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static int aEGH_change_talk_proc(EV_GHOST_ACTOR* ghost, u8 talk_act) {
|
||||
ghost->talk_act = talk_act;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void aEGH_set_force_talk_info(ACTOR* actorx) {
|
||||
EV_GHOST_ACTOR* ghost = (EV_GHOST_ACTOR*)actorx;
|
||||
mEv_gst_common_c* ghost_common = (mEv_gst_common_c*)mEv_get_common_area(mEv_EVENT_GHOST, 55);
|
||||
|
||||
mDemo_Set_msg_num(ghost->msg_no + RANDOM(5));
|
||||
aEGH_okoruhito();
|
||||
|
||||
switch (ghost->msg_no) {
|
||||
case 0x2EE2:
|
||||
{
|
||||
mDemo_Set_talk_turn(TRUE);
|
||||
mDemo_Set_camera(CAMERA2_PROCESS_TALK);
|
||||
|
||||
if (aEGH_bitcheck_func(aEGH_BIT_FOUND_GHOST) == FALSE) {
|
||||
sAdo_SysTrgStart(0x6B);
|
||||
aEGH_bitset_func(aEGH_BIT_FOUND_GHOST);
|
||||
}
|
||||
|
||||
ghost_common->flags |= mEv_GHOST_FLAG_ACTIVE;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x2EDD:
|
||||
{
|
||||
mDemo_Set_talk_turn(TRUE);
|
||||
mDemo_Set_camera(CAMERA2_PROCESS_NORMAL);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x2ED3:
|
||||
case 0x2ED8:
|
||||
{
|
||||
mDemo_Set_talk_turn(FALSE);
|
||||
mDemo_Set_camera(CAMERA2_PROCESS_NORMAL);
|
||||
mMsg_sound_set_voice_click(mMsg_Get_base_window_p());
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
mDemo_Set_talk_turn(FALSE);
|
||||
mDemo_Set_camera(CAMERA2_PROCESS_NORMAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
aEGH_change_talk_proc(ghost, aEGH_TALK_END_WAIT);
|
||||
}
|
||||
|
||||
static void aEGH_force_talk_request(ACTOR* actorx, GAME* game) {
|
||||
EV_GHOST_ACTOR* ghost = (EV_GHOST_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
f32 dist = GET_PLAYER_ACTOR(play)->actor_class.world.position.y - actorx->world.position.y;
|
||||
|
||||
if (dist < 0.0f) {
|
||||
dist = -dist;
|
||||
}
|
||||
|
||||
if (!(
|
||||
!(ghost->_9A7 == FALSE && actorx->player_distance_xz < actorx->talk_distance) ||
|
||||
!(dist < 60.0f) && (ghost->_9AA == FALSE)
|
||||
)) {
|
||||
mDemo_Request(mDemo_TYPE_SPEAK, actorx, &aEGH_set_force_talk_info);
|
||||
}
|
||||
else {
|
||||
ghost->_9A7 = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void aEGH_set_norm_talk_info(ACTOR* actorx) {
|
||||
EV_GHOST_ACTOR* ghost = (EV_GHOST_ACTOR*)actorx;
|
||||
int hitodama_num;
|
||||
int msg_no;
|
||||
|
||||
aEGH_okoruhito();
|
||||
mDemo_Set_talk_turn(TRUE);
|
||||
mDemo_Set_camera(CAMERA2_PROCESS_TALK);
|
||||
aEGH_change_talk_proc(ghost, aEGH_TALK_END_WAIT);
|
||||
|
||||
hitodama_num = aEGH_hitodama_num();
|
||||
if (hitodama_num == 0) {
|
||||
msg_no = 0x2EE7 + RANDOM(5);
|
||||
}
|
||||
else if (hitodama_num >= mEv_GHOST_HITODAMA_NUM) {
|
||||
msg_no = 0x2EF0;
|
||||
aEGH_change_talk_proc(ghost, aEGH_TALK_GIVE_ME_WAIT);
|
||||
Save_Get(event_save_common).ghost_day = 0;
|
||||
}
|
||||
else {
|
||||
msg_no = 0x2EEB + hitodama_num;
|
||||
}
|
||||
|
||||
mDemo_Set_msg_num(msg_no);
|
||||
}
|
||||
|
||||
static void aEGH_norm_talk_request(ACTOR* actorx, GAME* game) {
|
||||
EV_GHOST_ACTOR* ghost = (EV_GHOST_ACTOR*)actorx;
|
||||
|
||||
if (ghost->_9A7 == FALSE) {
|
||||
mDemo_Request(mDemo_TYPE_TALK, actorx, &aEGH_set_norm_talk_info);
|
||||
}
|
||||
else {
|
||||
ghost->_9A7 = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static int aEGH_talk_init(ACTOR* actorx, GAME* game) {
|
||||
EV_GHOST_ACTOR* ghost = (EV_GHOST_ACTOR*)actorx;
|
||||
|
||||
ghost->npc_class.talk_info.talk_request_proc = (aNPC_TALK_REQUEST_PROC)&none_proc1;
|
||||
mDemo_Set_ListenAble();
|
||||
mDemo_Start(actorx);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef void (*aEGH_TALK_PROC)(EV_GHOST_ACTOR*, GAME_PLAY*);
|
||||
|
||||
static int aEGH_talk_end_chk(ACTOR* actorx, GAME* game) {
|
||||
static aEGH_TALK_PROC proc[aEGH_TALK_NUM] = {
|
||||
(aEGH_TALK_PROC)&none_proc1,
|
||||
&aEGH_give_me_wait,
|
||||
&aEGH_select_wait,
|
||||
&aEGH_select_roof,
|
||||
&aEGH_give_you_wait,
|
||||
(aEGH_TALK_PROC)&none_proc1
|
||||
};
|
||||
|
||||
EV_GHOST_ACTOR* ghost = (EV_GHOST_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
int res = FALSE;
|
||||
|
||||
(*proc[ghost->talk_act])(ghost, play);
|
||||
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, actorx) == FALSE && mDemo_Check(mDemo_TYPE_TALK, actorx) == FALSE) {
|
||||
if (ghost->talk_act == aEGH_TALK_CLEAR_GRASS) {
|
||||
Save_Set(clear_grass, TRUE);
|
||||
}
|
||||
|
||||
aEGH_setup_think_proc(ghost, play, ghost->after_talk_think_act);
|
||||
|
||||
if (ghost->melody_inst != 0) {
|
||||
ghost->npc_class.talk_info.melody_inst = ghost->melody_inst;
|
||||
ghost->melody_inst = 0;
|
||||
}
|
||||
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
#include "ac_ev_gypsy.h"
|
||||
|
||||
#include "m_choice.h"
|
||||
#include "m_common_data.h"
|
||||
#include "m_item_name.h"
|
||||
#include "m_msg.h"
|
||||
#include "m_play.h"
|
||||
#include "m_string.h"
|
||||
|
||||
enum {
|
||||
aEGPS_ACTION_TALK_END_WAIT,
|
||||
aEGPS_ACTION_CALL_IN,
|
||||
aEGPS_ACTION_DECIDE_RESULT,
|
||||
aEGPS_ACTION_DECIDE_RESULT2,
|
||||
|
||||
aEGPS_ACTION_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aEGPS_STR_TYPE_ADJECTIVE,
|
||||
aEGPS_STR_TYPE_NOUN,
|
||||
aEGPS_STR_TYPE_VERB,
|
||||
aEGPS_STR_TYPE_PLACE,
|
||||
|
||||
aEGPS_STR_TYPE_NUM
|
||||
};
|
||||
|
||||
static void aEGPS_actor_ct(ACTOR*, GAME*);
|
||||
static void aEGPS_actor_dt(ACTOR*, GAME*);
|
||||
static void aEGPS_actor_move(ACTOR*, GAME*);
|
||||
static void aEGPS_actor_draw(ACTOR*, GAME*);
|
||||
static void aEGPS_actor_save(ACTOR*, GAME*);
|
||||
static void aEGPS_actor_init(ACTOR*, GAME*);
|
||||
|
||||
ACTOR_PROFILE Ev_Gypsy_Profile = {
|
||||
mAc_PROFILE_EV_GYPSY,
|
||||
ACTOR_PART_NPC,
|
||||
ACTOR_STATE_NONE,
|
||||
SP_NPC_GYPSY,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(EV_GYPSY_ACTOR),
|
||||
&aEGPS_actor_ct,
|
||||
&aEGPS_actor_dt,
|
||||
&aEGPS_actor_init,
|
||||
mActor_NONE_PROC1,
|
||||
&aEGPS_actor_save
|
||||
};
|
||||
|
||||
static void aEGPS_talk_request(ACTOR* actorx, GAME* game);
|
||||
static int aEGPS_talk_init(ACTOR* actorx, GAME* game);
|
||||
static int aEGPS_talk_end_chk(ACTOR* actorx, GAME* game);
|
||||
static void aEGPS_setupAction(EV_GYPSY_ACTOR* gypsy, GAME_PLAY* play, int action);
|
||||
|
||||
static void aEGPS_actor_ct(ACTOR* actorx, GAME* game) {
|
||||
static aNPC_ct_data_c ct_data = {
|
||||
&aEGPS_actor_move,
|
||||
&aEGPS_actor_draw,
|
||||
2,
|
||||
&aEGPS_talk_request,
|
||||
&aEGPS_talk_init,
|
||||
&aEGPS_talk_end_chk,
|
||||
0
|
||||
};
|
||||
|
||||
EV_GYPSY_ACTOR* gypsy = (EV_GYPSY_ACTOR*)actorx;
|
||||
|
||||
if ((*Common_Get(clip).npc_clip->birth_check_proc)(actorx, game) == TRUE) {
|
||||
(*Common_Get(clip).npc_clip->ct_proc)(actorx, game, &ct_data);
|
||||
actorx->talk_distance = 80.0f;
|
||||
actorx->status_data.weight = 255;
|
||||
actorx->world.position.x += 20.0f;
|
||||
gypsy->setup_talk_proc = &aEGPS_setupAction;
|
||||
}
|
||||
}
|
||||
|
||||
static void aEGPS_actor_save(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->save_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aEGPS_actor_dt(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->dt_proc)(actorx, game);
|
||||
mEv_actor_dying_message(mEv_EVENT_GYPSY, actorx);
|
||||
}
|
||||
|
||||
static void aEGPS_actor_init(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->init_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aEGPS_actor_draw(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->draw_proc)(actorx, game);
|
||||
}
|
||||
|
||||
#include "../src/actor/ac_ev_gypsy_move.c_inc"
|
||||
@@ -0,0 +1,197 @@
|
||||
static void aEGPS_set_string(int type) {
|
||||
static int string_num[aEGPS_STR_TYPE_NUM] = { 0x1A4, 0x1C4, 0x184, 0x164 };
|
||||
u8 str[mIN_ITEM_NAME_LEN];
|
||||
int str_no = RANDOM(32) + string_num[type];
|
||||
|
||||
mString_Load_StringFromRom(str, sizeof(str), str_no);
|
||||
mMsg_Set_item_str(mMsg_Get_base_window_p(), type, str, sizeof(str));
|
||||
}
|
||||
|
||||
static void aEGPS_call_in(EV_GYPSY_ACTOR* gypsy, GAME_PLAY* play) {
|
||||
static int msg_no[] = {
|
||||
0x971, /* 'No' choice */
|
||||
0x973, /* 'Yes' choice */
|
||||
0x972 /* 'Yes' choice, but not enough Bells */
|
||||
};
|
||||
|
||||
static int next_act_idx[] = {
|
||||
aEGPS_ACTION_TALK_END_WAIT,
|
||||
aEGPS_ACTION_DECIDE_RESULT,
|
||||
aEGPS_ACTION_TALK_END_WAIT
|
||||
};
|
||||
|
||||
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
|
||||
|
||||
if (mMsg_Check_MainNormalContinue(msg_p) == TRUE) {
|
||||
int type = -1;
|
||||
|
||||
switch (mChoice_Get_ChoseNum(mChoice_Get_base_window_p())) {
|
||||
case mChoice_CHOICE0: /* Yes */
|
||||
if (Common_Get(now_private)->inventory.wallet >= aEGPS_FORTUNE_PRICE) {
|
||||
type = 1; // yes
|
||||
}
|
||||
else {
|
||||
type = 2; // not enough bells
|
||||
}
|
||||
break;
|
||||
case mChoice_CHOICE1: /* No */
|
||||
type = 0; // no
|
||||
break;
|
||||
}
|
||||
|
||||
if (type != -1) {
|
||||
mMsg_Set_continue_msg_num(msg_p, msg_no[type]);
|
||||
(*gypsy->setup_talk_proc)(gypsy, play, next_act_idx[type]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aEGPS_decide_result(EV_GYPSY_ACTOR* gypsy, GAME_PLAY* play) {
|
||||
static int msg_no[] = {
|
||||
0x974,
|
||||
0x975,
|
||||
0x976,
|
||||
0x977,
|
||||
0x978,
|
||||
0x979
|
||||
};
|
||||
|
||||
static int msg_no2[] = {
|
||||
0x97C,
|
||||
0x97D,
|
||||
0x97E,
|
||||
0x97F,
|
||||
0x980
|
||||
};
|
||||
|
||||
static u8 destiny[] = {
|
||||
mPr_DESTINY_NORMAL,
|
||||
mPr_DESTINY_POPULAR,
|
||||
mPr_DESTINY_UNPOPULAR,
|
||||
mPr_DESTINY_BAD_LUCK,
|
||||
mPr_DESTINY_MONEY_LUCK,
|
||||
mPr_DESTINY_GOODS_LUCK
|
||||
};
|
||||
|
||||
int demo_order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
int selected;
|
||||
|
||||
if (demo_order != 0) {
|
||||
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
|
||||
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
if (gypsy->talk_action == aEGPS_ACTION_DECIDE_RESULT) {
|
||||
selected = RANDOM(10);
|
||||
|
||||
if (selected < 4) {
|
||||
selected = 4; /* 50% chance of 'normal' luck, 10% chance for other types */
|
||||
}
|
||||
|
||||
selected -= 4;
|
||||
Common_Get(now_private)->destiny.type = destiny[selected];
|
||||
mMsg_Set_continue_msg_num(msg_p, msg_no[selected]);
|
||||
}
|
||||
else {
|
||||
/* aEGPS_ACTION_DECIDE_RESULT2 */
|
||||
selected = Common_Get(now_private)->destiny.type - 1;
|
||||
mMsg_Set_continue_msg_num(msg_p, msg_no2[selected]);
|
||||
}
|
||||
|
||||
(*gypsy->setup_talk_proc)(gypsy, play, aEGPS_ACTION_TALK_END_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aEGPS_decide_result_init(EV_GYPSY_ACTOR* gypsy, GAME_PLAY* play) {
|
||||
u32 wallet = Common_Get(now_private)->inventory.wallet;
|
||||
wallet -= aEGPS_FORTUNE_PRICE;
|
||||
Common_Get(now_private)->inventory.wallet = wallet;
|
||||
aEGPS_set_string(aEGPS_STR_TYPE_ADJECTIVE);
|
||||
aEGPS_set_string(aEGPS_STR_TYPE_NOUN);
|
||||
aEGPS_set_string(aEGPS_STR_TYPE_VERB);
|
||||
aEGPS_set_string(aEGPS_STR_TYPE_PLACE);
|
||||
gypsy->fortune_given = TRUE;
|
||||
}
|
||||
|
||||
static void aEGPS_init_proc(EV_GYPSY_ACTOR* gypsy, GAME_PLAY* play, int action) {
|
||||
static aEGPS_TALK_INIT_PROC init_proc[aEGPS_ACTION_NUM] = {
|
||||
(aEGPS_TALK_INIT_PROC)&none_proc1,
|
||||
(aEGPS_TALK_INIT_PROC)&none_proc1,
|
||||
&aEGPS_decide_result_init,
|
||||
(aEGPS_TALK_INIT_PROC)&none_proc1
|
||||
};
|
||||
|
||||
(*init_proc[action])(gypsy, play);
|
||||
}
|
||||
|
||||
static void aEGPS_setupAction(EV_GYPSY_ACTOR* gypsy, GAME_PLAY* play, int action) {
|
||||
static aEGPS_TALK_PROC process[aEGPS_ACTION_NUM] = {
|
||||
(aEGPS_TALK_PROC)&none_proc1,
|
||||
&aEGPS_call_in,
|
||||
&aEGPS_decide_result,
|
||||
&aEGPS_decide_result
|
||||
};
|
||||
|
||||
gypsy->talk_action = action;
|
||||
gypsy->talk_proc = process[action];
|
||||
aEGPS_init_proc(gypsy, play, action);
|
||||
}
|
||||
|
||||
static void aEGPS_set_talk_info(ACTOR* actorx) {
|
||||
EV_GYPSY_ACTOR* gypsy = (EV_GYPSY_ACTOR*)actorx;
|
||||
int msg_num;
|
||||
|
||||
if (gypsy->fortune_given == TRUE) {
|
||||
msg_num = 0x982; // Fortune given msg but scene not reloaded?
|
||||
}
|
||||
else if (Common_Get(now_private)->destiny.type == mPr_DESTINY_NORMAL) {
|
||||
msg_num = 0x970; // Should fortune be given?
|
||||
}
|
||||
else {
|
||||
msg_num = 0x97B; // Fortune given msg after scene was reloaded?
|
||||
}
|
||||
|
||||
mDemo_Set_msg_num(msg_num);
|
||||
}
|
||||
|
||||
static void aEGPS_talk_request(ACTOR* actorx, GAME* game) {
|
||||
mDemo_Request(mDemo_TYPE_TALK, actorx, &aEGPS_set_talk_info);
|
||||
}
|
||||
|
||||
static int aEGPS_talk_init(ACTOR* actorx, GAME* game) {
|
||||
EV_GYPSY_ACTOR* gypsy = (EV_GYPSY_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
int next_act_idx;
|
||||
|
||||
if (Common_Get(now_private)->destiny.type == mPr_DESTINY_NORMAL) {
|
||||
next_act_idx = aEGPS_ACTION_CALL_IN;
|
||||
}
|
||||
else {
|
||||
next_act_idx = aEGPS_ACTION_DECIDE_RESULT2;
|
||||
}
|
||||
|
||||
(*gypsy->setup_talk_proc)(gypsy, play, next_act_idx);
|
||||
mDemo_Set_ListenAble();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int aEGPS_talk_end_chk(ACTOR* actorx, GAME* game) {
|
||||
EV_GYPSY_ACTOR* gypsy = (EV_GYPSY_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
int res = FALSE;
|
||||
|
||||
(*gypsy->talk_proc)(gypsy, play);
|
||||
if (mDemo_Check(mDemo_TYPE_TALK, actorx) == FALSE) {
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void aEGPS_actor_move(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->move_proc)(actorx, game);
|
||||
|
||||
if (mDemo_Check(mDemo_TYPE_TALK, actorx) == FALSE) {
|
||||
chase_angle(&actorx->shape_info.rotation.y, 0, DEG2SHORT_ANGLE(5.625f));
|
||||
actorx->world.angle.y = actorx->shape_info.rotation.y;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
#include "ac_ev_kabuPeddler.h"
|
||||
|
||||
#include "m_common_data.h"
|
||||
#include "m_font.h"
|
||||
#include "m_msg.h"
|
||||
#include "m_player_lib.h"
|
||||
#include "m_play.h"
|
||||
|
||||
enum {
|
||||
aEKPD_ACTION_TALK_END_WAIT,
|
||||
aEKPD_ACTION_SELL_CHECK,
|
||||
aEKPD_ACTION_SELL_CHECK_AFTER,
|
||||
aEKPD_ACTION_SELL_CHECK2,
|
||||
aEKPD_ACTION_SELL_CEHCK_AFTER2,
|
||||
aEKPD_ACTION_MONEY_GET_DEMO_START_WAIT,
|
||||
aEKPD_ACTION_MONEY_GET_DEMO_END_WAIT,
|
||||
aEKPD_ACTION_KABU_TRANS_DEMO_START_WAIT,
|
||||
|
||||
aEKPD_ACTION_NUM
|
||||
};
|
||||
|
||||
static void aEKPD_actor_ct(ACTOR* actorx, GAME* game);
|
||||
static void aEKPD_actor_dt(ACTOR* actorx, GAME* game);
|
||||
static void aEKPD_actor_draw(ACTOR* actorx, GAME* game);
|
||||
static void aEKPD_actor_move(ACTOR* actorx, GAME* game);
|
||||
static void aEKPD_actor_save(ACTOR* actorx, GAME* game);
|
||||
static void aEKPD_actor_init(ACTOR* actorx, GAME* game);
|
||||
|
||||
ACTOR_PROFILE Ev_KabuPeddler_Profile = {
|
||||
mAc_PROFILE_EV_KABUPEDDLER,
|
||||
ACTOR_PART_NPC,
|
||||
ACTOR_STATE_NONE,
|
||||
SP_NPC_KABUPEDDLER,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(EV_KABUPEDDLER_ACTOR),
|
||||
&aEKPD_actor_ct,
|
||||
&aEKPD_actor_dt,
|
||||
&aEKPD_actor_init,
|
||||
mActor_NONE_PROC1,
|
||||
&aEKPD_actor_save
|
||||
};
|
||||
|
||||
static void aEKPD_setupAction(EV_KABUPEDDLER_ACTOR* kabuPeddler, GAME_PLAY* play, int talk_act);
|
||||
static void aEKPD_talk_request(ACTOR*, GAME*);
|
||||
static int aEKPD_talk_init(ACTOR*, GAME*);
|
||||
static int aEKPD_talk_end_chk(ACTOR*, GAME*);
|
||||
|
||||
static void aEKPD_actor_ct(ACTOR* actorx, GAME* game) {
|
||||
static aNPC_ct_data_c ct_data = {
|
||||
&aEKPD_actor_move,
|
||||
&aEKPD_actor_draw,
|
||||
3,
|
||||
&aEKPD_talk_request,
|
||||
&aEKPD_talk_init,
|
||||
&aEKPD_talk_end_chk,
|
||||
0
|
||||
};
|
||||
|
||||
EV_KABUPEDDLER_ACTOR* kabuPeddler = (EV_KABUPEDDLER_ACTOR*)actorx;
|
||||
|
||||
if ((*Common_Get(clip).npc_clip->birth_check_proc)(actorx, game) == TRUE) {
|
||||
(*Common_Get(clip).npc_clip->ct_proc)(actorx, game, &ct_data);
|
||||
kabuPeddler->setup_talk_proc = &aEKPD_setupAction;
|
||||
}
|
||||
}
|
||||
|
||||
static void aEKPD_actor_save(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->save_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aEKPD_actor_dt(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->dt_proc)(actorx, game);
|
||||
mEv_actor_dying_message(mEv_EVENT_KABU_PEDDLER, actorx);
|
||||
}
|
||||
|
||||
static void aEKPD_actor_init(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->init_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aEKPD_actor_draw(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->draw_proc)(actorx, game);
|
||||
}
|
||||
|
||||
#include "../src/actor/ac_ev_kabuPeddler_move.c_inc"
|
||||
@@ -0,0 +1,219 @@
|
||||
static int aEKPD_check_look() {
|
||||
mEv_kabu_peddler_c* peddler_data = &Save_Get(event_save_data).weekly.kabu_peddler;
|
||||
int res = FALSE;
|
||||
|
||||
if (mPr_CheckCmpPersonalID(&peddler_data->spoken_pids[Common_Get(player_no)],
|
||||
&Common_Get(now_private)->player_ID) == TRUE) {
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void aEKPD_set_price_str_sub(u32 price, int free_str_no) {
|
||||
u8 price_str[6];
|
||||
|
||||
mFont_UnintToString(price_str, sizeof(price_str), price, 5, TRUE, FALSE, TRUE);
|
||||
mMsg_Set_free_str(mMsg_Get_base_window_p(), free_str_no, price_str, sizeof(price_str));
|
||||
}
|
||||
|
||||
static void aEKPD_set_price_str() {
|
||||
static int sum[aEKPD_KABU_TYPE_NUM] = { 1, 10, 50, 100 };
|
||||
u32 price = Save_Get(kabu_price_schedule).daily_price[lbRTC_SUNDAY];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < aEKPD_KABU_TYPE_NUM; i++) {
|
||||
aEKPD_set_price_str_sub(price * sum[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
static int aEKPD_get_trans_space_idx() {
|
||||
return mPr_GetPossessionItemIdx(Common_Get(now_private), EMPTY_NO);
|
||||
}
|
||||
|
||||
static void aEKPD_hand_over_kabu(int idx, int kabu_type) {
|
||||
static mActor_name_t kabu_no[aEKPD_KABU_TYPE_NUM - 1] = { ITM_KABU_10, ITM_KABU_50, ITM_KABU_100 };
|
||||
|
||||
mPr_SetPossessionItem(Common_Get(now_private), idx, kabu_no[kabu_type], mPr_ITEM_COND_NORMAL);
|
||||
}
|
||||
|
||||
static void aEKPD_sell_check(EV_KABUPEDDLER_ACTOR* kabuPeddler, GAME_PLAY* play) {
|
||||
static int next_act[] = { aEKPD_ACTION_TALK_END_WAIT, aEKPD_ACTION_SELL_CHECK_AFTER, aEKPD_ACTION_SELL_CEHCK_AFTER2,
|
||||
0 };
|
||||
int talk_act_idx;
|
||||
int order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
|
||||
if (order != 0 && mMsg_Check_MainNormalContinue(mMsg_Get_base_window_p()) == TRUE) {
|
||||
int choseNum = mChoice_Get_ChoseNum(mChoice_Get_base_window_p());
|
||||
|
||||
switch (choseNum) {
|
||||
case mChoice_CHOICE0:
|
||||
case mChoice_CHOICE1:
|
||||
case mChoice_CHOICE2: {
|
||||
if (kabuPeddler->talk_act == aEKPD_ACTION_SELL_CHECK) {
|
||||
talk_act_idx = 1;
|
||||
} else {
|
||||
talk_act_idx = 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case mChoice_CHOICE3: {
|
||||
talk_act_idx = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
talk_act_idx = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (talk_act_idx != 0) {
|
||||
(*kabuPeddler->setup_talk_proc)(kabuPeddler, play, next_act[talk_act_idx]);
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
kabuPeddler->kabu_type = choseNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aEKPD_sell_check_after(EV_KABUPEDDLER_ACTOR* kabuPeddler, GAME_PLAY* play) {
|
||||
static int sell_sum[aEKPD_KABU_TYPE_NUM] = { 10, 50, 100, 0 };
|
||||
static int next_msg_no[] = { 0x0711, 0x0710, 0x070F };
|
||||
static int next_msg_no2[] = { 0x0711, 0x0717, 0x0716 };
|
||||
static int next_act[] = { aEKPD_ACTION_MONEY_GET_DEMO_START_WAIT, aEKPD_ACTION_TALK_END_WAIT,
|
||||
aEKPD_ACTION_TALK_END_WAIT };
|
||||
|
||||
if (mMsg_Check_MainNormalContinue(mMsg_Get_base_window_p()) == TRUE) {
|
||||
u32 price;
|
||||
int talk_act_idx;
|
||||
int trans_space_idx = aEKPD_get_trans_space_idx();
|
||||
|
||||
if (trans_space_idx != -1) {
|
||||
price = Save_Get(kabu_price_schedule).daily_price[lbRTC_SUNDAY] * sell_sum[kabuPeddler->kabu_type];
|
||||
|
||||
if (mSP_money_check(price) == TRUE) {
|
||||
mSP_get_sell_price(price); /* take money from player */
|
||||
aEKPD_hand_over_kabu(trans_space_idx, kabuPeddler->kabu_type);
|
||||
talk_act_idx = 0;
|
||||
} else {
|
||||
talk_act_idx = 1;
|
||||
}
|
||||
} else {
|
||||
talk_act_idx = 2;
|
||||
}
|
||||
|
||||
if (kabuPeddler->talk_act == 2) {
|
||||
mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), next_msg_no[talk_act_idx]);
|
||||
} else {
|
||||
mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), next_msg_no2[talk_act_idx]);
|
||||
}
|
||||
|
||||
(*kabuPeddler->setup_talk_proc)(kabuPeddler, play, next_act[talk_act_idx]);
|
||||
}
|
||||
}
|
||||
|
||||
static void aEKPD_money_get_demo_start_wait(EV_KABUPEDDLER_ACTOR* kabuPeddler, GAME_PLAY* play) {
|
||||
if (Common_Get(clip).handOverItem_clip->request_mode == aHOI_REQUEST_TRANS_WAIT) {
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 1, 3);
|
||||
(*kabuPeddler->setup_talk_proc)(kabuPeddler, play, aEKPD_ACTION_MONEY_GET_DEMO_END_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aEKPD_money_get_demo_end_wait(EV_KABUPEDDLER_ACTOR* kabuPeddler, GAME_PLAY* play) {
|
||||
if (Common_Get(clip).handOverItem_clip->master_actor == NULL) {
|
||||
mMsg_Unset_LockContinue(mMsg_Get_base_window_p());
|
||||
(*kabuPeddler->setup_talk_proc)(kabuPeddler, play, aEKPD_ACTION_KABU_TRANS_DEMO_START_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aEKPD_kabu_trans_demo_start_wait(EV_KABUPEDDLER_ACTOR* kabuPeddler, GAME_PLAY* play) {
|
||||
int order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 1);
|
||||
|
||||
if (order == 2) {
|
||||
(*kabuPeddler->setup_talk_proc)(kabuPeddler, play, aEKPD_ACTION_SELL_CHECK2);
|
||||
}
|
||||
}
|
||||
|
||||
static void aEKPD_sell_check_init(EV_KABUPEDDLER_ACTOR* kabuPeddler, GAME_PLAY* play) {
|
||||
aEKPD_set_price_str();
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
}
|
||||
|
||||
static void aEKPD_sell_check2_init(EV_KABUPEDDLER_ACTOR* kabuPeddler, GAME_PLAY* play) {
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 0, (mActor_name_t)(ITM_KABU_START + kabuPeddler->kabu_type));
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 1, 7);
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 2, 0);
|
||||
}
|
||||
|
||||
static void aEKPD_money_get_demo_start_wait_init(EV_KABUPEDDLER_ACTOR* kabuPeddler, GAME_PLAY* play) {
|
||||
mMsg_Set_LockContinue(mMsg_Get_base_window_p());
|
||||
mPlib_request_main_give_type1((GAME*)play, ITM_MONEY_10000, 7, FALSE, FALSE);
|
||||
}
|
||||
|
||||
typedef void (*aEKPD_INIT_PROC)(EV_KABUPEDDLER_ACTOR*, GAME_PLAY*);
|
||||
|
||||
static void aEKPD_init_proc(EV_KABUPEDDLER_ACTOR* kabuPeddler, GAME_PLAY* play, int act) {
|
||||
static aEKPD_INIT_PROC init_proc[aEKPD_ACTION_NUM] = {
|
||||
(aEKPD_INIT_PROC)&none_proc1, &aEKPD_sell_check_init, (aEKPD_INIT_PROC)&none_proc1,
|
||||
&aEKPD_sell_check2_init, (aEKPD_INIT_PROC)&none_proc1, &aEKPD_money_get_demo_start_wait_init,
|
||||
(aEKPD_INIT_PROC)&none_proc1, (aEKPD_INIT_PROC)&none_proc1
|
||||
};
|
||||
|
||||
(*init_proc[act])(kabuPeddler, play);
|
||||
}
|
||||
|
||||
static void aEKPD_setupAction(EV_KABUPEDDLER_ACTOR* kabuPeddler, GAME_PLAY* play, int act) {
|
||||
static aEKPD_PROC process[aEKPD_ACTION_NUM] = { (aEKPD_PROC)&none_proc1, &aEKPD_sell_check,
|
||||
&aEKPD_sell_check_after, &aEKPD_sell_check,
|
||||
&aEKPD_sell_check_after, &aEKPD_money_get_demo_start_wait,
|
||||
&aEKPD_money_get_demo_end_wait, &aEKPD_kabu_trans_demo_start_wait };
|
||||
|
||||
kabuPeddler->talk_act = act;
|
||||
kabuPeddler->talk_proc = process[act];
|
||||
aEKPD_init_proc(kabuPeddler, play, act);
|
||||
}
|
||||
|
||||
static void aEKPD_set_talk_info(ACTOR* actorx) {
|
||||
int msg_no = aEKPD_check_look() == TRUE ? 0x0718 : 0x06FD;
|
||||
|
||||
mDemo_Set_msg_num(msg_no);
|
||||
}
|
||||
|
||||
static void aEKPD_talk_request(ACTOR* actorx, GAME* game) {
|
||||
mDemo_Request(mDemo_TYPE_TALK, actorx, &aEKPD_set_talk_info);
|
||||
}
|
||||
|
||||
static int aEKPD_talk_init(ACTOR* actorx, GAME* game) {
|
||||
EV_KABUPEDDLER_ACTOR* kabuPeddler = (EV_KABUPEDDLER_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
|
||||
if (aEKPD_check_look() == FALSE) {
|
||||
mEv_kabu_peddler_c* kabu_data = &Save_Get(event_save_data).weekly.kabu_peddler;
|
||||
|
||||
mPr_CopyPersonalID(&kabu_data->spoken_pids[Common_Get(player_no)], &Common_Get(now_private)->player_ID);
|
||||
}
|
||||
|
||||
(*kabuPeddler->setup_talk_proc)(kabuPeddler, play, aEKPD_ACTION_SELL_CHECK);
|
||||
mDemo_Set_ListenAble();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int aEKPD_talk_end_chk(ACTOR* actorx, GAME* game) {
|
||||
EV_KABUPEDDLER_ACTOR* kabuPeddler = (EV_KABUPEDDLER_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
int res = FALSE;
|
||||
|
||||
(*kabuPeddler->talk_proc)(kabuPeddler, play);
|
||||
|
||||
if (mDemo_Check(mDemo_TYPE_TALK, actorx) == FALSE) {
|
||||
mEv_set_status(mEv_EVENT_KABU_PEDDLER, mEv_STATUS_TALK);
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void aEKPD_actor_move(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->move_proc)(actorx, game);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
#include "ac_ev_majin.h"
|
||||
#include "m_common_data.h"
|
||||
#include "m_name_table.h"
|
||||
#include "m_demo.h"
|
||||
|
||||
extern void aEMJ_actor_ct(ACTOR*, GAME*);
|
||||
extern void aEMJ_actor_dt(ACTOR*, GAME*);
|
||||
extern void aEMJ_actor_init(ACTOR*, GAME*);
|
||||
extern void aEMJ_actor_save(ACTOR*, GAME*);
|
||||
|
||||
ACTOR_PROFILE Ev_Majin_Profile = {
|
||||
mAc_PROFILE_EV_MAJIN, ACTOR_PART_NPC, ACTOR_STATE_NO_DRAW_WHILE_CULLED | ACTOR_STATE_NO_MOVE_WHILE_CULLED,
|
||||
SP_NPC_EV_MAJIN, ACTOR_OBJ_BANK_KEEP, sizeof(EV_NPCMAJIN_ACTOR),
|
||||
aEMJ_actor_ct, aEMJ_actor_dt, aEMJ_actor_init,
|
||||
NONE_ACTOR_PROC, aEMJ_actor_save,
|
||||
};
|
||||
|
||||
extern void aEMJ_actor_move(ACTOR*, GAME*);
|
||||
extern void aEMJ_actor_draw(ACTOR*, GAME*);
|
||||
|
||||
static int aEMJ_talk_init(ACTOR*, GAME*);
|
||||
static int aEMJ_talk_end_chk(ACTOR*, GAME*);
|
||||
static void aEMJ_schedule_proc(NPC_ACTOR*, GAME_PLAY*, int);
|
||||
|
||||
void aEMJ_actor_ct(ACTOR* actor, GAME* game) {
|
||||
static aNPC_ct_data_c ct_data = {
|
||||
&aEMJ_actor_move, &aEMJ_actor_draw, 5, mActor_NONE_PROC1, &aEMJ_talk_init, &aEMJ_talk_end_chk, 0,
|
||||
};
|
||||
EV_NPCMAJIN_ACTOR* majin = (EV_NPCMAJIN_ACTOR*)actor;
|
||||
|
||||
if (Common_Get(clip.npc_clip)->birth_check_proc(actor, game) == TRUE) {
|
||||
majin->npc_class.schedule.schedule_proc = aEMJ_schedule_proc;
|
||||
Common_Get(clip.npc_clip)->ct_proc(actor, game, &ct_data);
|
||||
majin->npc_class.head.lock_flag = 1;
|
||||
majin->npc_class.talk_info.default_turn_animation = aNPC_ANIM_WAIT_R1;
|
||||
majin->npc_class.talk_info.default_animation = aNPC_ANIM_WAIT_R1;
|
||||
majin->npc_class.talk_info.turn = 2;
|
||||
}
|
||||
}
|
||||
|
||||
void aEMJ_actor_save(ACTOR* actor, GAME* game) {
|
||||
Common_Get(clip.npc_clip)->save_proc(actor, game);
|
||||
}
|
||||
|
||||
void aEMJ_actor_dt(ACTOR* actor, GAME* game) {
|
||||
|
||||
if (Common_Get(clip.groundhog_control_clip) != NULL) {
|
||||
Common_Get(clip.groundhog_control_clip)->groundhog_npc_actor = NULL;
|
||||
}
|
||||
Common_Get(clip.npc_clip)->dt_proc(actor, game);
|
||||
Common_Get(clip.effect_clip)->effect_kill_proc(eEC_EFFECT_RESET_HOLE, RSV_NO);
|
||||
}
|
||||
|
||||
void aEMJ_actor_init(ACTOR* actor, GAME* game) {
|
||||
Common_Get(clip.npc_clip)->init_proc(actor, game);
|
||||
}
|
||||
|
||||
void aEMJ_set_animation(ACTOR* actor, int idx) {
|
||||
static s16 animeSeqNo[] = { aNPC_ANIM_APPEAR1, aNPC_ANIM_WAIT_R1, aNPC_ANIM_GO_UG1 };
|
||||
|
||||
Common_Get(clip.npc_clip)->animation_init_proc(actor, animeSeqNo[idx], 0);
|
||||
}
|
||||
|
||||
void aEMJ_actor_move(ACTOR* actor, GAME* game) {
|
||||
Common_Get(clip.npc_clip)->move_proc(actor, game);
|
||||
actor->shape_info.draw_shadow = 0;
|
||||
}
|
||||
|
||||
void aEMJ_actor_draw(ACTOR* actor, GAME* game) {
|
||||
Common_Get(clip.npc_clip)->draw_proc(actor, game);
|
||||
}
|
||||
|
||||
#include "../src/actor/ac_ev_majin_move.c_inc"
|
||||
@@ -0,0 +1,157 @@
|
||||
|
||||
void aEMJ_schedule_proc(NPC_ACTOR*, GAME_PLAY*, int);
|
||||
void aEMJ_setup_think_proc(NPC_ACTOR*, int);
|
||||
void aEMJ_force_talk_request(NPC_ACTOR*, GAME_PLAY*);
|
||||
|
||||
void aEMJ_set_request_act(NPC_ACTOR* actor, GAME_PLAY* play) {
|
||||
EV_NPCMAJIN_ACTOR* majin = (EV_NPCMAJIN_ACTOR*)actor;
|
||||
|
||||
majin->npc_class.request.act_priority = 4;
|
||||
majin->npc_class.request.act_idx = 22;
|
||||
majin->npc_class.request.act_type = 2;
|
||||
}
|
||||
|
||||
void aEMJ_act_init_proc(NPC_ACTOR* actor, GAME_PLAY* play) {
|
||||
EV_NPCMAJIN_ACTOR* majin = (EV_NPCMAJIN_ACTOR*)actor;
|
||||
|
||||
majin->npc_class.action.step = 0;
|
||||
}
|
||||
|
||||
void aEMJ_act_proc(NPC_ACTOR* actor, GAME_PLAY* play, int idx) {
|
||||
static aNPC_SUB_PROC act_proc[] = { aEMJ_act_init_proc, (aNPC_SUB_PROC)mActor_NONE_PROC1,
|
||||
(aNPC_SUB_PROC)mActor_NONE_PROC1 };
|
||||
|
||||
act_proc[idx](actor, play);
|
||||
}
|
||||
|
||||
void aEMJ_appear(NPC_ACTOR* actor, GAME_PLAY* play) {
|
||||
EV_NPCMAJIN_ACTOR* majin = (EV_NPCMAJIN_ACTOR*)actor;
|
||||
|
||||
if (majin->npc_class.draw.main_animation_state == cKF_STATE_STOPPED) {
|
||||
aEMJ_setup_think_proc(actor, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void aEMJ_retire(NPC_ACTOR* actor, GAME_PLAY* play) {
|
||||
if (actor->draw.main_animation_state == cKF_STATE_STOPPED) {
|
||||
((NPC_ACTOR*)(actor->actor_class.parent_actor))->npc_info.animal = (Animal_c*)1;
|
||||
Actor_delete(&actor->actor_class);
|
||||
}
|
||||
}
|
||||
|
||||
void aEMJ_think_main_proc(NPC_ACTOR* actor, GAME_PLAY* play) {
|
||||
EV_NPCMAJIN_ACTOR* majin = (EV_NPCMAJIN_ACTOR*)actor;
|
||||
|
||||
if (actor->action.idx == 0x16) {
|
||||
majin->think_proc(actor, play);
|
||||
} else {
|
||||
if (actor->action.step == aNPC_ACTION_END_STEP) {
|
||||
aEMJ_set_request_act(actor, play);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void aEMJ_think_init_proc(ACTOR* actor, GAME* game) {
|
||||
EV_NPCMAJIN_ACTOR* majin = (EV_NPCMAJIN_ACTOR*)actor;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
|
||||
majin->npc_class.action.act_proc = aEMJ_act_proc;
|
||||
aEMJ_set_request_act(&majin->npc_class, play);
|
||||
Common_Get(clip).effect_clip->effect_make_proc(0x5D, actor->world.position, 3, actor->shape_info.rotation.y,
|
||||
&play->game, 0xFFFF, 0, 0);
|
||||
aEMJ_setup_think_proc(&majin->npc_class, 0);
|
||||
}
|
||||
|
||||
void aEMJ_setup_think_proc(NPC_ACTOR* actor, int idx) {
|
||||
static NPC_DT_PROCS dt_tbl[] = {
|
||||
{ aEMJ_appear, (aNPC_SUB_PROC)none_proc1 },
|
||||
{ (aNPC_SUB_PROC)none_proc1, aEMJ_force_talk_request },
|
||||
{ aEMJ_retire, (aNPC_SUB_PROC)none_proc1 },
|
||||
};
|
||||
EV_NPCMAJIN_ACTOR* majin = (EV_NPCMAJIN_ACTOR*)actor;
|
||||
|
||||
NPC_DT_PROCS* current = &dt_tbl[idx];
|
||||
|
||||
majin->unk994 = idx;
|
||||
majin->think_proc = current->unk0;
|
||||
actor->talk_info.talk_request_proc = (mActor_proc)current->unk4;
|
||||
aEMJ_set_animation(&actor->actor_class, idx);
|
||||
}
|
||||
|
||||
void aEMJ_think_proc(NPC_ACTOR* actor, GAME_PLAY* play, int idx) {
|
||||
static aNPC_SUB_PROC think_proc[] = {
|
||||
(aNPC_SUB_PROC)(aEMJ_think_init_proc),
|
||||
aEMJ_think_main_proc,
|
||||
};
|
||||
|
||||
think_proc[idx](actor, play);
|
||||
}
|
||||
|
||||
void aEMJ_schedule_init_proc(NPC_ACTOR* actor, GAME_PLAY* play) {
|
||||
EV_NPCMAJIN_ACTOR* majin = (EV_NPCMAJIN_ACTOR*)actor;
|
||||
|
||||
majin->npc_class.think.think_proc = aEMJ_think_proc;
|
||||
majin->npc_class.condition_info.hide_request = 0;
|
||||
majin->npc_class.palActorIgnoreTimer = -1;
|
||||
majin->npc_class.actor_class.world.position.x += 20.0f;
|
||||
majin->npc_class.actor_class.world.position.z += 20.0f;
|
||||
Common_Get(clip.npc_clip)->think_proc(actor, play, 9, 0);
|
||||
}
|
||||
|
||||
void aEMJ_schedule_main_proc(NPC_ACTOR* actor, GAME_PLAY* play) {
|
||||
EV_NPCMAJIN_ACTOR* majin = (EV_NPCMAJIN_ACTOR*)actor;
|
||||
if (Common_Get(clip.npc_clip)->think_proc(actor, play, -1, 1) == 0) {
|
||||
Common_Get(clip.npc_clip)->think_proc(actor, play, -1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
void aEMJ_schedule_proc(NPC_ACTOR* actor, GAME_PLAY* play, int idx) {
|
||||
static aNPC_SUB_PROC sche_proc[] = { aEMJ_schedule_init_proc, aEMJ_schedule_main_proc };
|
||||
|
||||
sche_proc[idx](actor, play);
|
||||
}
|
||||
|
||||
void aEMJ_set_force_talk_info() {
|
||||
int msg_num;
|
||||
|
||||
switch (Common_Get(weather)) {
|
||||
case mEnv_WEATHER_CLEAR:
|
||||
msg_num = RANDOM(3.0f) + 0x3DAF;
|
||||
break;
|
||||
|
||||
case mEnv_WEATHER_SNOW:
|
||||
msg_num = RANDOM(3.0f) + 0x3DB2;
|
||||
break;
|
||||
|
||||
default:
|
||||
case mEnv_WEATHER_RAIN:
|
||||
msg_num = 0x3DAF;
|
||||
break;
|
||||
}
|
||||
|
||||
mDemo_Set_msg_num(msg_num);
|
||||
}
|
||||
|
||||
void aEMJ_force_talk_request(NPC_ACTOR* actor, GAME_PLAY* play) {
|
||||
mDemo_Request(10, &actor->actor_class, aEMJ_set_force_talk_info);
|
||||
}
|
||||
|
||||
int aEMJ_talk_init(ACTOR* actor, GAME* play) {
|
||||
EV_NPCMAJIN_ACTOR* majin = (EV_NPCMAJIN_ACTOR*)actor;
|
||||
|
||||
majin->npc_class.talk_info.talk_request_proc = (mActor_proc)none_proc1;
|
||||
mDemo_Set_ListenAble();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int aEMJ_talk_end_chk(ACTOR* actor, GAME* play) {
|
||||
EV_NPCMAJIN_ACTOR* majin = (EV_NPCMAJIN_ACTOR*)actor;
|
||||
int res = 0;
|
||||
|
||||
if (mDemo_Check(10, actor) == 0) {
|
||||
aEMJ_setup_think_proc(&majin->npc_class, 2);
|
||||
res = 1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
#include "ac_ev_santa.h"
|
||||
|
||||
#include "libultra/libultra.h"
|
||||
#include "m_common_data.h"
|
||||
#include "m_msg.h"
|
||||
#include "m_play.h"
|
||||
|
||||
enum {
|
||||
aESNT_ACTION_TALK_END_WAIT,
|
||||
aESNT_ACTION_CHK_WISH_1ST,
|
||||
aESNT_ACTION_CHK_WISH_2ND,
|
||||
aESNT_ACTION_CHK_WISH_FINAL,
|
||||
aESNT_ACTION_CHK_WISH_MORE,
|
||||
aESNT_ACTION_MOTION_START_WAIT,
|
||||
aESNT_ACTION_MOTION_END_WAIT,
|
||||
|
||||
aESNT_ACTION_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aESNT_WISH_FTR,
|
||||
aESNT_WISH_CLOTH,
|
||||
aESNT_WISH_WALL,
|
||||
aESNT_WISH_CARPET,
|
||||
|
||||
aESNT_WISH_NUM
|
||||
};
|
||||
|
||||
#define aESNT_TALK_TALK_SAME_PLAYER_NUM 3
|
||||
#define aESNT_TALK_TALK_OTHER_PLAYER_NUM 3
|
||||
#define aESNT_TALK_FINAL_PRESENT_NUM 1
|
||||
#define aESNT_TALK_FINAL_NO_PRESENT_NUM 1
|
||||
#define aESNT_TALK_SAME_BLOCK_NUM 3
|
||||
#define aESNT_TALK_HELLO_NUM 1
|
||||
#define aESNT_TALK_CHK_1ST_NUM 1
|
||||
#define aESNT_TALK_CHK_2ND_NUM 1
|
||||
#define aESNT_TALK_CHK_FINAL_NUM aESNT_WISH_NUM
|
||||
#define aESNT_TALK_ALMOST_RECOGNIZE_NUM 1
|
||||
#define aESNT_TALK_FINAL_PRESENT2_NUM 1
|
||||
#define aESNT_TALK_FINAL_NO_PRESENT2_NUM 1
|
||||
#define aESNT_TALK_NO_MORE_PRESENTS_NUM 3
|
||||
|
||||
enum {
|
||||
aESNT_TALK_TALK_SAME_PLAYER,
|
||||
aESNT_TALK_TALK_OTHER_PLAYER = aESNT_TALK_TALK_SAME_PLAYER + aESNT_TALK_TALK_SAME_PLAYER_NUM,
|
||||
aESNT_TALK_FINAL_PRESENT = aESNT_TALK_TALK_OTHER_PLAYER + aESNT_TALK_TALK_OTHER_PLAYER_NUM,
|
||||
aESNT_TALK_FINAL_NO_PRESENT = aESNT_TALK_FINAL_PRESENT + aESNT_TALK_FINAL_PRESENT_NUM,
|
||||
aESNT_TALK_SAME_BLOCK = aESNT_TALK_FINAL_NO_PRESENT + aESNT_TALK_FINAL_NO_PRESENT_NUM,
|
||||
aESNT_TALK_HELLO = aESNT_TALK_SAME_BLOCK + aESNT_TALK_SAME_BLOCK_NUM,
|
||||
aESNT_TALK_CHK_1ST = aESNT_TALK_HELLO + aESNT_TALK_HELLO_NUM,
|
||||
aESNT_TALK_CHK_2ND = aESNT_TALK_CHK_1ST + aESNT_TALK_CHK_1ST_NUM,
|
||||
aESNT_TALK_CHK_FINAL = aESNT_TALK_CHK_2ND + aESNT_TALK_CHK_2ND_NUM,
|
||||
aESNT_TALK_ALMOST_RECOGNIZE = aESNT_TALK_CHK_FINAL + aESNT_TALK_CHK_FINAL_NUM,
|
||||
aESNT_TALK_FINAL_PRESENT2 = aESNT_TALK_ALMOST_RECOGNIZE + aESNT_TALK_ALMOST_RECOGNIZE_NUM,
|
||||
aESNT_TALK_FINAL_NO_PRESENT2 = aESNT_TALK_FINAL_PRESENT2 + aESNT_TALK_FINAL_PRESENT2_NUM,
|
||||
aESNT_TALK_NO_MORE_PRESENTS = aESNT_TALK_FINAL_NO_PRESENT2 + aESNT_TALK_FINAL_NO_PRESENT2_NUM,
|
||||
|
||||
aESNT_TALK_NUM = aESNT_TALK_NO_MORE_PRESENTS + aESNT_TALK_NO_MORE_PRESENTS_NUM
|
||||
};
|
||||
|
||||
static void aESNT_actor_ct(ACTOR*, GAME*);
|
||||
static void aESNT_actor_dt(ACTOR*, GAME*);
|
||||
static void aESNT_actor_init(ACTOR*, GAME*);
|
||||
static void aESNT_actor_move(ACTOR*, GAME*);
|
||||
static void aESNT_actor_draw(ACTOR*, GAME*);
|
||||
static void aESNT_actor_save(ACTOR*, GAME*);
|
||||
static void aESNT_talk_request(ACTOR*, GAME*);
|
||||
static int aESNT_talk_init(ACTOR*, GAME*);
|
||||
static int aESNT_talk_end_chk(ACTOR*, GAME*);
|
||||
static void aESNT_setupAction(EVENT_SANTA_ACTOR*, GAME_PLAY*, int);
|
||||
|
||||
ACTOR_PROFILE Ev_Santa_Profile = {
|
||||
mAc_PROFILE_EV_SANTA,
|
||||
ACTOR_PART_NPC,
|
||||
ACTOR_STATE_NONE,
|
||||
SP_NPC_SANTA,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(EVENT_SANTA_ACTOR),
|
||||
&aESNT_actor_ct,
|
||||
&aESNT_actor_dt,
|
||||
&aESNT_actor_init,
|
||||
mActor_NONE_PROC1,
|
||||
&aESNT_actor_save
|
||||
};
|
||||
|
||||
static void aESNT_actor_ct(ACTOR* actorx, GAME* game) {
|
||||
static aNPC_ct_data_c ct_data = {
|
||||
&aESNT_actor_move,
|
||||
&aESNT_actor_draw,
|
||||
3,
|
||||
&aESNT_talk_request,
|
||||
&aESNT_talk_init,
|
||||
&aESNT_talk_end_chk,
|
||||
0
|
||||
};
|
||||
|
||||
EVENT_SANTA_ACTOR* santa = (EVENT_SANTA_ACTOR*)actorx;
|
||||
|
||||
if ((*Common_Get(clip).npc_clip->birth_check_proc)(actorx, game) == TRUE) {
|
||||
mEv_santa_event_c* event_p;
|
||||
mEv_santa_event_common_c* event_common_p;
|
||||
|
||||
(*Common_Get(clip).npc_clip->ct_proc)(actorx, game, &ct_data);
|
||||
santa->setup_talk_proc = &aESNT_setupAction;
|
||||
|
||||
event_p = (mEv_santa_event_c*)mEv_get_save_area(mEv_EVENT_TOY_DAY_JINGLE, 0);
|
||||
if (event_p == NULL) {
|
||||
/* Reserve event data */
|
||||
event_p = (mEv_santa_event_c*)mEv_reserve_save_area(mEv_EVENT_TOY_DAY_JINGLE, 0);
|
||||
bzero(event_p, sizeof(mEv_santa_event_c));
|
||||
mPr_ClearPersonalID(&event_p->pid);
|
||||
}
|
||||
santa->event_p = event_p;
|
||||
|
||||
event_common_p = (mEv_santa_event_common_c*)mEv_get_common_area(mEv_EVENT_TOY_DAY_JINGLE, 0);
|
||||
if (event_common_p == NULL) {
|
||||
event_common_p = (mEv_santa_event_common_c*)mEv_reserve_common_area(mEv_EVENT_TOY_DAY_JINGLE, 0);
|
||||
}
|
||||
santa->event_common_p = event_common_p;
|
||||
}
|
||||
}
|
||||
|
||||
static void aESNT_actor_save(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->save_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aESNT_actor_dt(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->dt_proc)(actorx, game);
|
||||
mEv_actor_dying_message(mEv_EVENT_TOY_DAY_JINGLE, actorx);
|
||||
}
|
||||
|
||||
static void aESNT_actor_init(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->init_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aESNT_actor_draw(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->draw_proc)(actorx, game);
|
||||
}
|
||||
|
||||
#include "../src/actor/ac_ev_santa_move.c_inc"
|
||||
@@ -0,0 +1,365 @@
|
||||
static void aESNT_chk_wish_1st(EVENT_SANTA_ACTOR* santa, GAME_PLAY* play) {
|
||||
if (mMsg_Check_MainNormalContinue(mMsg_Get_base_window_p()) == TRUE) {
|
||||
mEv_santa_event_common_c* event_common_p = santa->event_common_p;
|
||||
int present_flag;
|
||||
|
||||
switch (mChoice_Get_ChoseNum(mChoice_Get_base_window_p())) {
|
||||
case mChoice_CHOICE0:
|
||||
present_flag = 0;
|
||||
break;
|
||||
default:
|
||||
present_flag = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (santa->talk_act != aESNT_ACTION_CHK_WISH_1ST) {
|
||||
present_flag <<= 1;
|
||||
}
|
||||
|
||||
event_common_p->present |= present_flag;
|
||||
(*santa->setup_talk_proc)(santa, play, aESNT_ACTION_TALK_END_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aESNT_chk_wish_final(EVENT_SANTA_ACTOR* santa, GAME_PLAY* play) {
|
||||
if (mMsg_Check_MainNormalContinue(mMsg_Get_base_window_p()) == TRUE) {
|
||||
mEv_santa_event_common_c* event_common_p = santa->event_common_p;
|
||||
int present_flag = event_common_p->present;
|
||||
|
||||
switch (mChoice_Get_ChoseNum(mChoice_Get_base_window_p())) {
|
||||
case mChoice_CHOICE0:
|
||||
present_flag &= 1; /* Furniture & Cloth */
|
||||
break;
|
||||
default:
|
||||
present_flag &= 2; /* Wallpaper & Carpet */
|
||||
|
||||
if ((present_flag & aESNT_WISH_WALL) == 0) {
|
||||
present_flag = aESNT_WISH_CARPET;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
event_common_p->present = present_flag;
|
||||
(*santa->setup_talk_proc)(santa, play, aESNT_ACTION_TALK_END_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aESNT_chk_wish_more(EVENT_SANTA_ACTOR* santa, GAME_PLAY* play) {
|
||||
int order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
|
||||
if (order != 0) {
|
||||
mEv_santa_event_common_c* event_common_p = santa->event_common_p;
|
||||
u8 present = aESNT_WISH_FTR;
|
||||
|
||||
switch (mMsg_Get_msg_num(mMsg_Get_base_window_p())) {
|
||||
case MSG_SANTA_WISH_FTR:
|
||||
present = aESNT_WISH_FTR;
|
||||
break;
|
||||
case MSG_SANTA_WISH_WALL:
|
||||
present = aESNT_WISH_WALL;
|
||||
break;
|
||||
case MSG_SANTA_WISH_CARPET:
|
||||
present = aESNT_WISH_CARPET;
|
||||
break;
|
||||
case MSG_SANTA_WISH_CLOTH:
|
||||
present = aESNT_WISH_CLOTH;
|
||||
break;
|
||||
}
|
||||
|
||||
event_common_p->present = present;
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
(*santa->setup_talk_proc)(santa, play, aESNT_ACTION_TALK_END_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void aESNT_motion_start_wait(EVENT_SANTA_ACTOR* santa, GAME_PLAY* play) {
|
||||
int order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 1);
|
||||
|
||||
if (order == 2) {
|
||||
(*santa->setup_talk_proc)(santa, play, aESNT_ACTION_MOTION_END_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (*aESNT_INIT_PROC)(EVENT_SANTA_ACTOR*, GAME_PLAY*);
|
||||
|
||||
static void aESNT_chk_wish_more_init(EVENT_SANTA_ACTOR* santa, GAME_PLAY* play) {
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
}
|
||||
|
||||
static void aESNT_motion_end_wait_init(EVENT_SANTA_ACTOR* santa, GAME_PLAY* play) {
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 0, ITM_PRESENT);
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 1, 7);
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 2, 1);
|
||||
}
|
||||
|
||||
static void aESNT_init_proc(EVENT_SANTA_ACTOR* santa, GAME_PLAY* play, int act) {
|
||||
static aESNT_INIT_PROC init_proc[aESNT_ACTION_NUM] = {
|
||||
(aESNT_INIT_PROC)&none_proc1,
|
||||
(aESNT_INIT_PROC)&none_proc1,
|
||||
(aESNT_INIT_PROC)&none_proc1,
|
||||
(aESNT_INIT_PROC)&none_proc1,
|
||||
&aESNT_chk_wish_more_init,
|
||||
(aESNT_INIT_PROC)&none_proc1,
|
||||
&aESNT_motion_end_wait_init
|
||||
};
|
||||
|
||||
(*init_proc[act])(santa, play);
|
||||
}
|
||||
|
||||
static void aESNT_setupAction(EVENT_SANTA_ACTOR* santa, GAME_PLAY* play, int act) {
|
||||
static aESNT_TALK_PROC process[aESNT_ACTION_NUM] = {
|
||||
(aESNT_TALK_PROC)&none_proc1,
|
||||
&aESNT_chk_wish_1st,
|
||||
&aESNT_chk_wish_1st,
|
||||
&aESNT_chk_wish_final,
|
||||
&aESNT_chk_wish_more,
|
||||
&aESNT_motion_start_wait,
|
||||
(aESNT_TALK_PROC)&none_proc1
|
||||
};
|
||||
|
||||
santa->talk_act = act;
|
||||
santa->talk_proc = process[act];
|
||||
aESNT_init_proc(santa, play, act);
|
||||
}
|
||||
|
||||
static int aESNT_check_pl_cloth(mEv_santa_event_c* event_p) {
|
||||
mActor_name_t* cloth_p = event_p->cloth;
|
||||
mActor_name_t pl_cloth = Common_Get(now_private)->cloth.item;
|
||||
int i;
|
||||
int res = TRUE;
|
||||
|
||||
for (i = 0; i != event_p->present_count; i++) {
|
||||
if (*cloth_p == pl_cloth) {
|
||||
res = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
cloth_p++;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int aESNT_before_talk_present_decide_talk_data_idx(EVENT_SANTA_ACTOR* santa, mEv_santa_event_c* event_p, mEv_santa_event_common_c* event_common_p, int type) {
|
||||
static int talk_data_idx[2][2] = {
|
||||
{ aESNT_TALK_FINAL_PRESENT, aESNT_TALK_FINAL_NO_PRESENT },
|
||||
{ aESNT_TALK_FINAL_PRESENT2, aESNT_TALK_FINAL_NO_PRESENT2 }
|
||||
};
|
||||
static int category[aESNT_WISH_NUM] = { mSP_KIND_FURNITURE, mSP_KIND_CLOTH, mSP_KIND_WALLPAPER, mSP_KIND_CARPET };
|
||||
int item_idx = mPr_GetPossessionItemIdx(Common_Get(now_private), EMPTY_NO);
|
||||
int inv_full;
|
||||
mActor_name_t present;
|
||||
|
||||
if (item_idx != -1) {
|
||||
if (event_common_p->present >= aESNT_WISH_NUM) {
|
||||
event_common_p->present = aESNT_WISH_CARPET;
|
||||
}
|
||||
|
||||
mSP_SelectRandomItem_New(NULL, &present, 1, NULL, 0, category[event_common_p->present], mSP_LISTTYPE_CHRISTMAS, FALSE);
|
||||
mPr_SetPossessionItem(Common_Get(now_private), item_idx, present, mPr_ITEM_COND_PRESENT);
|
||||
mPr_CopyPersonalID(&event_p->pid, &Common_Get(now_private)->player_ID);
|
||||
santa->present = present;
|
||||
event_common_p->talk_counter = 0;
|
||||
event_p->cloth[event_p->present_count] = Common_Get(now_private)->cloth.item;
|
||||
event_p->present_count++;
|
||||
inv_full = FALSE;
|
||||
|
||||
}
|
||||
else {
|
||||
inv_full = TRUE;
|
||||
}
|
||||
|
||||
return talk_data_idx[type][inv_full];
|
||||
}
|
||||
|
||||
static int aESNT_before_talk_more_check_decide_talk_data_idx(mEv_santa_event_common_c* event_common_p) {
|
||||
int talk_data_idx = aESNT_TALK_HELLO;
|
||||
|
||||
switch (event_common_p->talk_counter) {
|
||||
case 0:
|
||||
talk_data_idx = aESNT_TALK_HELLO;
|
||||
break;
|
||||
case 1:
|
||||
talk_data_idx = aESNT_TALK_CHK_1ST;
|
||||
break;
|
||||
case 2:
|
||||
talk_data_idx = aESNT_TALK_CHK_2ND;
|
||||
break;
|
||||
case 3:
|
||||
talk_data_idx = aESNT_TALK_CHK_FINAL + event_common_p->present; /* select index based on desired present */
|
||||
break;
|
||||
}
|
||||
|
||||
event_common_p->talk_counter++;
|
||||
return talk_data_idx;
|
||||
}
|
||||
|
||||
static int aESNT_before_talk_decide_talk_data_idx(EVENT_SANTA_ACTOR* santa, GAME_PLAY* play, mEv_santa_event_c* event_p, mEv_santa_event_common_c* event_common_p) {
|
||||
int talk_data_idx;
|
||||
|
||||
/* @BUG - because we compare the acre the player is in (GAME_PLAY block table)
|
||||
* against the last acre we talked to Jingle, we can actually talk to him again
|
||||
* without having to find him again. If you trap him at the border of an acre
|
||||
* and then move into the adjacent acre and talk to him, GAME_PLAY's block state
|
||||
* updates which passes the 'same block' check. Rinse and repeat between two acres
|
||||
* to satisfy the talk requirements without having to do the search portion.
|
||||
*/
|
||||
#if !defined(BUGFIXES) || defined(ALLOW_EXPLOITS)
|
||||
if (play->block_table.block_x == event_common_p->bx && play->block_table.block_z == event_common_p->bz) {
|
||||
talk_data_idx = aESNT_TALK_SAME_BLOCK + RANDOM(aESNT_TALK_SAME_BLOCK_NUM);
|
||||
}
|
||||
#else
|
||||
/* Use Jingle's actor block instead of GAME_PLAY's current block (player block) */
|
||||
if (santa->npc_class.actor_class.block_x == event_common_p->bx && santa->npc_class.actor_class.block_x == event_common_p->bz) {
|
||||
talk_data_idx = aESNT_TALK_SAME_BLOCK + RANDOM(aESNT_TALK_SAME_BLOCK_NUM);
|
||||
}
|
||||
#endif
|
||||
else if (event_common_p->talk_counter >= 4) {
|
||||
talk_data_idx = aESNT_before_talk_present_decide_talk_data_idx(santa, event_p, event_common_p, 0);
|
||||
}
|
||||
else {
|
||||
talk_data_idx = aESNT_before_talk_more_check_decide_talk_data_idx(event_common_p);
|
||||
}
|
||||
|
||||
if (talk_data_idx != aESNT_TALK_FINAL_NO_PRESENT) {
|
||||
/* Update talked acre */
|
||||
#if !defined(BUGFIXES) || defined(ALLOW_EXPLOITS)
|
||||
event_common_p->bx = play->block_table.block_x;
|
||||
event_common_p->bz = play->block_table.block_z;
|
||||
#else
|
||||
event_common_p->bx = santa->npc_class.actor_class.block_x;
|
||||
event_common_p->bz = santa->npc_class.actor_class.block_z;
|
||||
#endif
|
||||
}
|
||||
|
||||
return talk_data_idx;
|
||||
}
|
||||
|
||||
static int aESNT_after_talk_restart_Q_decide_talk_data_idx(mEv_santa_event_common_c* event_common_p) {
|
||||
event_common_p->last_talk_cloth = Common_Get(now_private)->cloth.item;
|
||||
event_common_p->talk_counter++;
|
||||
return aESNT_TALK_ALMOST_RECOGNIZE;
|
||||
}
|
||||
|
||||
static int aESNT_after_talk_same_pl_decide_talk_data_idx(EVENT_SANTA_ACTOR* santa, mEv_santa_event_c* event_p, mEv_santa_event_common_c* event_common_p) {
|
||||
int talk_data_idx;
|
||||
|
||||
if (aESNT_check_pl_cloth(event_p) == TRUE) {
|
||||
if (event_p->present_count >= mEv_SANTA_CLOTH_NUM_MAX) {
|
||||
talk_data_idx = aESNT_TALK_NO_MORE_PRESENTS + RANDOM(aESNT_TALK_NO_MORE_PRESENTS_NUM);
|
||||
}
|
||||
else if (event_common_p->talk_counter == 0) {
|
||||
talk_data_idx = aESNT_after_talk_restart_Q_decide_talk_data_idx(event_common_p);
|
||||
}
|
||||
else if (event_common_p->last_talk_cloth == Common_Get(now_private)->cloth.item) {
|
||||
talk_data_idx = aESNT_before_talk_present_decide_talk_data_idx(santa, event_p, event_common_p, 1);
|
||||
}
|
||||
else {
|
||||
talk_data_idx = aESNT_after_talk_restart_Q_decide_talk_data_idx(event_common_p);
|
||||
event_common_p->talk_counter = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
event_common_p->talk_counter = 0;
|
||||
talk_data_idx = aESNT_TALK_TALK_SAME_PLAYER + RANDOM(aESNT_TALK_TALK_SAME_PLAYER_NUM);
|
||||
}
|
||||
|
||||
return talk_data_idx;
|
||||
}
|
||||
|
||||
static int aESNT_after_talk_other_pl_decide_talk_data_idx(mEv_santa_event_c* event_p) {
|
||||
mMsg_Set_free_str(mMsg_Get_base_window_p(), mMsg_FREE_STR0, event_p->pid.player_name, PLAYER_NAME_LEN);
|
||||
return aESNT_TALK_TALK_OTHER_PLAYER + RANDOM(aESNT_TALK_TALK_OTHER_PLAYER_NUM);
|
||||
}
|
||||
|
||||
static int aESNT_after_talk_decide_talk_data_idx(EVENT_SANTA_ACTOR* santa, mEv_santa_event_c* event_p, mEv_santa_event_common_c* event_common_p) {
|
||||
if (mPr_CheckCmpPersonalID(&event_p->pid, &Common_Get(now_private)->player_ID) == TRUE) {
|
||||
return aESNT_after_talk_same_pl_decide_talk_data_idx(santa, event_p, event_common_p);
|
||||
}
|
||||
else {
|
||||
return aESNT_after_talk_other_pl_decide_talk_data_idx(event_p);
|
||||
}
|
||||
}
|
||||
|
||||
static void aESNT_getP_talk_data(ACTOR* actorx) {
|
||||
static aESNT_talk_data_c talk_data[aESNT_TALK_NUM] = {
|
||||
{ 0x07BF, aESNT_ACTION_TALK_END_WAIT },
|
||||
{ 0x07C0, aESNT_ACTION_TALK_END_WAIT },
|
||||
{ 0x07C1, aESNT_ACTION_TALK_END_WAIT },
|
||||
{ 0x07C2, aESNT_ACTION_TALK_END_WAIT },
|
||||
{ 0x07C3, aESNT_ACTION_TALK_END_WAIT },
|
||||
{ 0x07C4, aESNT_ACTION_TALK_END_WAIT },
|
||||
{ 0x07BA, aESNT_ACTION_MOTION_START_WAIT },
|
||||
{ 0x07B9, aESNT_ACTION_TALK_END_WAIT },
|
||||
{ 0x07BC, aESNT_ACTION_TALK_END_WAIT },
|
||||
{ 0x07BD, aESNT_ACTION_TALK_END_WAIT },
|
||||
{ 0x07BE, aESNT_ACTION_TALK_END_WAIT },
|
||||
{ 0x07AA, aESNT_ACTION_TALK_END_WAIT },
|
||||
{ 0x07AB, aESNT_ACTION_CHK_WISH_1ST },
|
||||
{ 0x07AE, aESNT_ACTION_CHK_WISH_2ND },
|
||||
{ 0x07B2, aESNT_ACTION_CHK_WISH_FINAL },
|
||||
{ 0x07B4, aESNT_ACTION_CHK_WISH_FINAL },
|
||||
{ 0x07B1, aESNT_ACTION_CHK_WISH_FINAL },
|
||||
{ 0x07B3, aESNT_ACTION_CHK_WISH_FINAL },
|
||||
{ 0x2B4C, aESNT_ACTION_CHK_WISH_MORE },
|
||||
{ 0x2B59, aESNT_ACTION_MOTION_START_WAIT },
|
||||
{ 0x2B58, aESNT_ACTION_TALK_END_WAIT },
|
||||
{ 0x2B5B, aESNT_ACTION_TALK_END_WAIT },
|
||||
{ 0x2B5C, aESNT_ACTION_TALK_END_WAIT },
|
||||
{ 0x2B5D, aESNT_ACTION_TALK_END_WAIT }
|
||||
};
|
||||
|
||||
EVENT_SANTA_ACTOR* santa = (EVENT_SANTA_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)gamePT;
|
||||
mEv_santa_event_c* event_p = santa->event_p;
|
||||
mEv_santa_event_common_c* event_common_p = santa->event_common_p;
|
||||
int talk_data_idx;
|
||||
|
||||
if (mPr_NullCheckPersonalID(&event_p->pid) == FALSE) {
|
||||
talk_data_idx = aESNT_after_talk_decide_talk_data_idx(santa, event_p, event_common_p);
|
||||
}
|
||||
else {
|
||||
talk_data_idx = aESNT_before_talk_decide_talk_data_idx(santa, play, event_p, event_common_p);
|
||||
}
|
||||
|
||||
santa->talk_data_p = &talk_data[talk_data_idx];
|
||||
}
|
||||
|
||||
static void aESNT_set_talk_info(ACTOR* actorx) {
|
||||
EVENT_SANTA_ACTOR* santa = (EVENT_SANTA_ACTOR*)actorx;
|
||||
|
||||
aESNT_getP_talk_data(actorx);
|
||||
mEv_set_status(mEv_EVENT_TOY_DAY_JINGLE, mEv_STATUS_TALK);
|
||||
mDemo_Set_msg_num(santa->talk_data_p->msg_no);
|
||||
}
|
||||
|
||||
static void aESNT_talk_request(ACTOR* actorx, GAME* game) {
|
||||
mDemo_Request(mDemo_TYPE_TALK, actorx, &aESNT_set_talk_info);
|
||||
}
|
||||
|
||||
static int aESNT_talk_init(ACTOR* actorx, GAME* game) {
|
||||
EVENT_SANTA_ACTOR* santa = (EVENT_SANTA_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
|
||||
(*santa->setup_talk_proc)(santa, play, santa->talk_data_p->talk_act);
|
||||
mDemo_Set_ListenAble();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int aESNT_talk_end_chk(ACTOR* actorx, GAME* game) {
|
||||
EVENT_SANTA_ACTOR* santa = (EVENT_SANTA_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
int res = FALSE;
|
||||
|
||||
(*santa->talk_proc)(santa, play);
|
||||
if (mDemo_Check(mDemo_TYPE_TALK, actorx) == FALSE) {
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void aESNT_actor_move(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->move_proc)(actorx, game);
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
#include "ac_ev_soncho.h"
|
||||
|
||||
#include "m_common_data.h"
|
||||
|
||||
typedef struct soncho_event_save_s {
|
||||
u16 _00;
|
||||
u8 msg_no;
|
||||
} aESC_event_save_c;
|
||||
|
||||
static void aESC_actor_ct(ACTOR* actorx, GAME* game);
|
||||
static void aESC_actor_dt(ACTOR* actorx, GAME* game);
|
||||
static void aESC_actor_init(ACTOR* actorx, GAME* game);
|
||||
static void aESC_actor_draw(ACTOR* actorx, GAME* game);
|
||||
static void aESC_actor_save(ACTOR* actorx, GAME* game);
|
||||
static void aESC_actor_move(ACTOR* actorx, GAME* game);
|
||||
|
||||
static void aESC_talk_request(ACTOR* actorx, GAME* game);
|
||||
static int aESC_talk_init(ACTOR* actorx, GAME* game);
|
||||
static int aESC_talk_end_chk(ACTOR* actorx, GAME* game);
|
||||
|
||||
ACTOR_PROFILE Ev_Soncho_Profile = {
|
||||
mAc_PROFILE_EV_SONCHO,
|
||||
ACTOR_PART_NPC,
|
||||
0,
|
||||
SP_NPC_EV_SONCHO,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(EVENT_SONCHO_ACTOR),
|
||||
&aESC_actor_ct,
|
||||
&aESC_actor_dt,
|
||||
&aESC_actor_init,
|
||||
mActor_NONE_PROC1,
|
||||
&aESC_actor_save
|
||||
};
|
||||
|
||||
static aNPC_ct_data_c ct_data = {
|
||||
&aESC_actor_move,
|
||||
&aESC_actor_draw,
|
||||
4,
|
||||
&aESC_talk_request,
|
||||
&aESC_talk_init,
|
||||
&aESC_talk_end_chk,
|
||||
1
|
||||
};
|
||||
|
||||
static void aESC_actor_ct(ACTOR* actorx, GAME* game) {
|
||||
EVENT_SONCHO_ACTOR* soncho_actor = (EVENT_SONCHO_ACTOR*)actorx;
|
||||
aESC_event_save_c* soncho_event = (aESC_event_save_c*)mEv_get_save_area(mEv_EVENT_SONCHO_BRIDGE_MAKE, 34);
|
||||
|
||||
if ((*Common_Get(clip).npc_clip->birth_check_proc)(actorx, game) == TRUE) {
|
||||
(*Common_Get(clip).npc_clip->ct_proc)(actorx, game, &ct_data);
|
||||
soncho_actor->npc_class.palActorIgnoreTimer = -1;
|
||||
soncho_actor->npc_class.draw._5BD = 3;
|
||||
|
||||
if (soncho_event == NULL) {
|
||||
soncho_event = (aESC_event_save_c*)mEv_reserve_save_area(mEv_EVENT_SONCHO_BRIDGE_MAKE, 34);
|
||||
soncho_event->_00 = 0;
|
||||
soncho_event->msg_no = RANDOM(5);
|
||||
}
|
||||
|
||||
if (Save_Get(bridge).pending) {
|
||||
Actor_delete(actorx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aESC_actor_save(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->save_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aESC_actor_dt(ACTOR* actorx, GAME* game) {
|
||||
mEv_actor_dying_message(mEv_EVENT_SONCHO_BRIDGE_MAKE, actorx);
|
||||
(*Common_Get(clip).npc_clip->dt_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aESC_actor_init(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->init_proc)(actorx, game);
|
||||
}
|
||||
|
||||
static void aESC_actor_draw(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->draw_proc)(actorx, game);
|
||||
}
|
||||
|
||||
#include "../src/actor/ac_ev_soncho_talk.c_inc"
|
||||
@@ -0,0 +1,174 @@
|
||||
#include "m_msg.h"
|
||||
#include "m_font.h"
|
||||
|
||||
static int aESC_bitset_func() {
|
||||
u8 flags = Common_Get(spnpc_first_talk_flags);
|
||||
if (Common_Get(player_no) == mPr_FOREIGNER) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Common_Get(spnpc_first_talk_flags) = flags | (1 << aNPC_SPNPC_BIT_EV_SONCHO);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static u16 aESC_bitcheck_func() {
|
||||
u8 flags = Common_Get(spnpc_first_talk_flags);
|
||||
|
||||
if (Common_Get(player_no) == mPr_FOREIGNER) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return (Common_Get(spnpc_first_talk_flags) >> aNPC_SPNPC_BIT_EV_SONCHO) & 1;
|
||||
}
|
||||
|
||||
static void aESC_owari_message() {
|
||||
mMsg_Window_c* win_p = mMsg_Get_base_window_p();
|
||||
aESC_event_save_c* ev_save = (aESC_event_save_c*)mEv_get_save_area(mEv_EVENT_SONCHO_BRIDGE_MAKE, 34);
|
||||
|
||||
if ((*(u8*)&Save_Get(event_save_common).bridge_flags) & 0x80) {
|
||||
mMsg_Set_continue_msg_num(win_p, 0x2F47 + ev_save->msg_no);
|
||||
}
|
||||
else {
|
||||
mMsg_Set_continue_msg_num(win_p, 0x2F39 + ev_save->msg_no);
|
||||
}
|
||||
|
||||
ev_save->msg_no++;
|
||||
|
||||
if (ev_save->msg_no >= 5) {
|
||||
ev_save->msg_no = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void aESC_set_day() {
|
||||
u8 day_str[16];
|
||||
|
||||
int len = mFont_UnintToString(day_str, 16, Save_Get(bridge).build_date.day, 16, TRUE, FALSE, TRUE);
|
||||
mMsg_Set_free_str(mMsg_Get_base_window_p(), mMsg_FREE_STR0, day_str, len);
|
||||
}
|
||||
|
||||
/* They forgot to change the prefix on this copy-paste */
|
||||
static int aEGH_change_talk_proc(EVENT_SONCHO_ACTOR* soncho, u8 state) {
|
||||
soncho->talk_state = state;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void aESC_talk_select(EVENT_SONCHO_ACTOR* soncho, GAME* game) {
|
||||
lbRTC_time_c rtc_time = Common_Get(time.rtc_time);
|
||||
|
||||
if ((int)mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9) == 1 && mMsg_Check_MainNormalContinue(mMsg_Get_base_window_p())) {
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
aEGH_change_talk_proc(soncho, aESC_TALK_OWARI);
|
||||
|
||||
switch (mChoice_Get_ChoseNum(mChoice_Get_base_window_p())) {
|
||||
case 1:
|
||||
{
|
||||
Save_Get(bridge).pending = TRUE;
|
||||
lbRTC_Add_DD(&rtc_time, 1);
|
||||
Save_Get(bridge).build_date.year = rtc_time.year;
|
||||
Save_Get(bridge).build_date.month = rtc_time.month;
|
||||
Save_Get(bridge).build_date.day = rtc_time.day;
|
||||
Save_Get(bridge).block_x = soncho->npc_class.actor_class.block_x;
|
||||
Save_Get(bridge).block_z = soncho->npc_class.actor_class.block_z;
|
||||
aESC_set_day();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0:
|
||||
{
|
||||
if (soncho->first_talk != FALSE) {
|
||||
aESC_owari_message();
|
||||
}
|
||||
else {
|
||||
aEGH_change_talk_proc(soncho, aESC_TALK_SECAND);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void aESC_talk_secand(EVENT_SONCHO_ACTOR* soncho, GAME* game) {
|
||||
if ((int)mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9) == 1 && mMsg_Check_MainNormalContinue(mMsg_Get_base_window_p())) {
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
aEGH_change_talk_proc(soncho, aESC_TALK_OWARI);
|
||||
aESC_owari_message();
|
||||
}
|
||||
}
|
||||
|
||||
static int aESC_time_talk() {
|
||||
lbRTC_time_c rtc_time = Common_Get(time.rtc_time);
|
||||
|
||||
if (rtc_time.hour < 6 || rtc_time.hour >= 23) {
|
||||
return 0x2F36;
|
||||
}
|
||||
else if (rtc_time.hour < 10) {
|
||||
return 0x2F33;
|
||||
}
|
||||
else if (rtc_time.hour < 17) {
|
||||
return 0x2F34;
|
||||
}
|
||||
else {
|
||||
return 0x2F35;
|
||||
}
|
||||
}
|
||||
|
||||
static void aESC_set_talk_info_talk_request(ACTOR* actorx) {
|
||||
int msg_no;
|
||||
EVENT_SONCHO_ACTOR* soncho = (EVENT_SONCHO_ACTOR*)actorx;
|
||||
|
||||
aEGH_change_talk_proc(soncho, 0);
|
||||
if (Save_Get(bridge).pending) {
|
||||
msg_no = 0x2F44 + RANDOM(3);
|
||||
aESC_set_day();
|
||||
}
|
||||
else if (aESC_bitcheck_func()) {
|
||||
msg_no = 0x2F3E;
|
||||
aEGH_change_talk_proc(soncho, aESC_TALK_SELECT);
|
||||
soncho->first_talk = FALSE;
|
||||
}
|
||||
else {
|
||||
msg_no = aESC_time_talk();
|
||||
aEGH_change_talk_proc(soncho, aESC_TALK_SELECT);
|
||||
soncho->first_talk = TRUE;
|
||||
}
|
||||
|
||||
mDemo_Set_msg_num(msg_no);
|
||||
}
|
||||
|
||||
static void aESC_talk_request(ACTOR* actorx, GAME* game) {
|
||||
mDemo_Request(mDemo_TYPE_TALK, actorx, &aESC_set_talk_info_talk_request);
|
||||
}
|
||||
|
||||
static int aESC_talk_init(ACTOR* actorx, GAME* game) {
|
||||
aESC_bitset_func();
|
||||
mDemo_Set_ListenAble();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef void (*aESC_TALK_PROC)(EVENT_SONCHO_ACTOR*, GAME*);
|
||||
|
||||
static int aESC_talk_end_chk(ACTOR* actorx, GAME* game) {
|
||||
static aESC_TALK_PROC proc[aESC_TALK_NUM] = {
|
||||
(aESC_TALK_PROC)&none_proc1,
|
||||
&aESC_talk_select,
|
||||
&aESC_talk_secand
|
||||
};
|
||||
|
||||
EVENT_SONCHO_ACTOR* soncho = (EVENT_SONCHO_ACTOR*)actorx;
|
||||
int res = FALSE;
|
||||
|
||||
(*proc[soncho->talk_state])(soncho, game);
|
||||
|
||||
if (mDemo_Check(mDemo_TYPE_TALK, actorx) == FALSE) {
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void aESC_actor_move(ACTOR* actorx, GAME* game) {
|
||||
(*Common_Get(clip).npc_clip->move_proc)(actorx, game);
|
||||
}
|
||||
Reference in New Issue
Block a user