From dd727850f724a6491b0c318f5004b0b1bfc87a33 Mon Sep 17 00:00:00 2001 From: Ian Ling Date: Wed, 11 Jun 2025 12:41:45 -0700 Subject: [PATCH] Implement and link ac_npc_shasho.c --- configure.py | 2 +- include/ac_npc_shasho.h | 17 +- src/actor/npc/ac_npc_shasho.c | 122 +++++++++++++++ src/actor/npc/ac_npc_shasho_move.c_inc | 205 +++++++++++++++++++++++++ 4 files changed, 344 insertions(+), 2 deletions(-) create mode 100644 src/actor/npc/ac_npc_shasho.c create mode 100644 src/actor/npc/ac_npc_shasho_move.c_inc diff --git a/configure.py b/configure.py index d7f30ba5..e925e541 100644 --- a/configure.py +++ b/configure.py @@ -1137,7 +1137,7 @@ config.libs = [ Object(NonMatching, "actor/npc/ac_npc_restart.c"), Object(Matching, "actor/npc/ac_npc_rtc.c"), Object(Matching, "actor/npc/ac_npc_sendo.c"), - Object(NonMatching, "actor/npc/ac_npc_shasho.c"), + Object(Matching, "actor/npc/ac_npc_shasho.c"), Object(Matching, "actor/npc/ac_npc_shop_master.c"), Object(Matching, "actor/npc/ac_npc_shop_mastersp.c"), Object(Matching, "actor/npc/ac_npc_sleep_obaba.c"), diff --git a/include/ac_npc_shasho.h b/include/ac_npc_shasho.h index cd9ee0b8..def64052 100644 --- a/include/ac_npc_shasho.h +++ b/include/ac_npc_shasho.h @@ -3,11 +3,27 @@ #include "types.h" #include "m_actor.h" +#include "ac_npc.h" #ifdef __cplusplus extern "C" { #endif +typedef struct npc_shasho_s NPC_SHASHO_ACTOR; + +typedef void (*aNSS_PROC)(ACTOR*, GAME*); +typedef void (*aNSS_INIT_PROC)(NPC_SHASHO_ACTOR*, GAME_PLAY*); +typedef void (*aNSS_MOVE_PROC)(NPC_SHASHO_ACTOR*, GAME*); + +/* sizeof(npc_shasho_s) == 0x9a4 */ +struct npc_shasho_s { + /* 0x000 */ NPC_ACTOR npc_class; + /* 0x994 */ int action; + /* 0x998 */ int unk_move_action; + /* 0x99C */ aNSS_PROC talk_action; + /* 0x9A0 */ ACTOR* train_door_actor; +}; + extern ACTOR_PROFILE Npc_Shasho_Profile; #ifdef __cplusplus @@ -15,4 +31,3 @@ extern ACTOR_PROFILE Npc_Shasho_Profile; #endif #endif - diff --git a/src/actor/npc/ac_npc_shasho.c b/src/actor/npc/ac_npc_shasho.c new file mode 100644 index 00000000..cfac7ee0 --- /dev/null +++ b/src/actor/npc/ac_npc_shasho.c @@ -0,0 +1,122 @@ +#include "ac_npc_shasho.h" + +#include "ac_npc.h" +#include "ac_npc_mask_cat2.h" +#include "ac_train_door.h" +#include "audio.h" +#include "c_keyframe.h" +#include "m_actor.h" +#include "m_actor_type.h" +#include "m_common_data.h" +#include "m_lib.h" +#include "m_play_h.h" + +enum { + aNSS_ACT_ENTER_WALK_BACK_DECK, + aNSS_ACT_ENTER_TURN_BACK_DECK, + aNSS_ACT_ENTER_BACK_DOOR, + aNSS_ACT_WALK_TO_FRONT_DOOR, + aNSS_ACT_EXIT_FRONT_DOOR, + aNSS_ACT_EXIT_FRONT_DOOR2, + aNSS_ACT_WALK_TO_BACK_DOOR, + aNSS_ACT_ENTER_BACK_DOOR2, + aNSS_ACT_EXIT_TURN_BACK_DECK, + aNSS_ACT_EXIT_WALK_BACK_DECK, + + aNSS_ACT_NUM +}; + +static void aNSS_actor_ct(ACTOR* actorx, GAME* game); +static void aNSS_actor_dt(ACTOR* actorx, GAME* game); +static void aNSS_actor_init(ACTOR* actorx, GAME* game); +static void aNSS_actor_move(ACTOR* actorx, GAME* game); +static void aNSS_actor_draw(ACTOR* actorx, GAME* game); +static void aNSS_actor_save(ACTOR* actorx, GAME* game); + +static void aNSS_set_animation(ACTOR*, int); +static void aNSS_set_walk_spd(NPC_SHASHO_ACTOR*); +static void aNSS_set_stop_spd(NPC_SHASHO_ACTOR*); +static void aNSS_set_door_SE(NPC_SHASHO_ACTOR* shasho_actor); +static void aNSS_enter_walk_back_deck(ACTOR* actorx, GAME* game); +static void aNSS_enter_turn_back_deck(ACTOR* actorx, GAME* game); +static void aNSS_enter_back_door(ACTOR* actorx, GAME* game); +static void aNSS_walk_to_front_door(ACTOR* actorx, GAME* game); +static void aNSS_exit_front_door(ACTOR* actorx, GAME* game); +static void aNSS_walk_to_back_door(ACTOR* actorx, GAME* game); +static void aNSS_exit_turn_back_deck(ACTOR* actorx, GAME* game); +static void aNSS_exit_walk_back_deck(ACTOR* actorx, GAME* game); +static void aNSS_enter_walk_back_deck_init(NPC_SHASHO_ACTOR* shasho_actor, GAME_PLAY* game_play); +static void aNSS_enter_turn_back_deck_init(NPC_SHASHO_ACTOR* shasho_actor, GAME_PLAY* game_play); +static void aNSS_enter_back_door_init(NPC_SHASHO_ACTOR* shasho_actor, GAME_PLAY* game_play); +static void aNSS_walk_to_front_door_init(NPC_SHASHO_ACTOR* shasho_actor, GAME_PLAY* game_play); +static void aNSS_exit_front_door_init(NPC_SHASHO_ACTOR* shasho_actor, GAME_PLAY* game_play); +static void aNSS_enter_front_door_init(NPC_SHASHO_ACTOR* shasho_actor, GAME_PLAY* game_play); +static void aNSS_exit_back_door_init(NPC_SHASHO_ACTOR* shasho_actor, GAME_PLAY* game_play); +static void aNSS_exit_walk_back_deck_init(NPC_SHASHO_ACTOR* shasho_actor, GAME_PLAY* game_play); +static void aNSS_init_proc(ACTOR* actorx, GAME* game, int action); +static void aNSS_setupAction(ACTOR* actorx, GAME* game, int action); + +ACTOR_PROFILE Npc_Shasho_Profile = { + mAc_PROFILE_NPC_SHASHO, ACTOR_PART_NPC, ACTOR_STATE_NO_MOVE_WHILE_CULLED | ACTOR_STATE_NO_DRAW_WHILE_CULLED, + SP_NPC_SASHO, ACTOR_OBJ_BANK_KEEP, sizeof(NPC_SHASHO_ACTOR), + &aNSS_actor_ct, &aNSS_actor_dt, &aNSS_actor_init, + mActor_NONE_PROC1, &aNSS_actor_save +}; + +static void aNSS_actor_ct(ACTOR* actorx, GAME* game) { + static aNPC_ct_data_c ct_data = { + &aNSS_actor_move, &aNSS_actor_draw, aNPC_CT_SCHED_TYPE_NONE, NULL, NULL, NULL, 0 + }; + static xyz_t start_pos[2] = { { 140.0f, 0.0f, 350.0f }, { 100.0f, 0.0f, 48.0f } }; + static short start_angl[2] = { DEG2SHORT_ANGLE(-180.0f), DEG2SHORT_ANGLE(90.0f) }; + static int action[2] = { aNSS_ACT_EXIT_FRONT_DOOR2, aNSS_ACT_ENTER_WALK_BACK_DECK }; + + NPC_SHASHO_ACTOR* shasho_actor = (NPC_SHASHO_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + + int type = actorx->actor_specific; + + NPC_CLIP->ct_proc(actorx, game, &ct_data); + + shasho_actor->npc_class.condition_info.demo_flg = + aNPC_COND_DEMO_SKIP_MOVE_RANGE_CHECK | aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV | aNPC_COND_DEMO_SKIP_MOVE_Y | + aNPC_COND_DEMO_SKIP_OBJ_COL_CHECK | aNPC_COND_DEMO_SKIP_BGCHECK | aNPC_COND_DEMO_SKIP_FORWARD_CHECK | + aNPC_COND_DEMO_SKIP_ITEM | aNPC_COND_DEMO_SKIP_TALK_CHECK | aNPC_COND_DEMO_SKIP_HEAD_LOOKAT | + aNPC_COND_DEMO_SKIP_ENTRANCE_CHECK; + shasho_actor->npc_class.palActorIgnoreTimer = -1; + shasho_actor->npc_class.condition_info.hide_flg = FALSE; + shasho_actor->train_door_actor = Actor_info_fgName_search(&play->actor_info, TRAIN_DOOR, ACTOR_PART_BG); + actorx->shape_info.draw_shadow = TRUE; + actorx->shape_info.rotation.y = start_angl[type]; + actorx->world.angle.y = start_angl[type]; + actorx->world.position.x = start_pos[type].x; + actorx->world.position.z = start_pos[type].z; + + aNSS_setupAction(&shasho_actor->npc_class.actor_class, &play->game, action[type]); +} + +static void aNSS_actor_save(ACTOR* actorx, GAME* game) { + (*Common_Get(clip).npc_clip->save_proc)(actorx, game); +} + +static void aNSS_actor_dt(ACTOR* actorx, GAME* game) { + ACTOR* sasho_actor = actorx; + NPC_MASK_CAT2_ACTOR* mask_cat2_actor = (NPC_MASK_CAT2_ACTOR*)sasho_actor->parent_actor; + + if (sasho_actor->parent_actor) { + sasho_actor->parent_actor = NULL; + mask_cat2_actor->sasho_actor = NULL; + } + + (*Common_Get(clip).npc_clip->dt_proc)(actorx, game); +} + +static void aNSS_actor_init(ACTOR* actorx, GAME* game) { + (*Common_Get(clip).npc_clip->init_proc)(actorx, game); +} + +static void aNSS_actor_draw(ACTOR* actorx, GAME* game) { + NPC_CLIP->draw_proc(actorx, game); +} + +#include "../src/actor/npc/ac_npc_shasho_move.c_inc" diff --git a/src/actor/npc/ac_npc_shasho_move.c_inc b/src/actor/npc/ac_npc_shasho_move.c_inc new file mode 100644 index 00000000..c7fd3579 --- /dev/null +++ b/src/actor/npc/ac_npc_shasho_move.c_inc @@ -0,0 +1,205 @@ +static void aNSS_set_animation(ACTOR* actorx, int action) { + static int seq_no[] = { 1, 1, 0x36, 1, 0x3B, 0x36, 1, 0x3B, 1, 1 }; + NPC_CLIP->animation_init_proc(actorx, seq_no[action], 0); +} + +static void aNSS_set_walk_spd(NPC_SHASHO_ACTOR* shasho_actor) { + shasho_actor->npc_class.movement.speed.max_speed = 1.0; + shasho_actor->npc_class.movement.speed.acceleration = 0.1; + shasho_actor->npc_class.movement.speed.deceleration = 0.2; +} + +static void aNSS_set_stop_spd(NPC_SHASHO_ACTOR* shasho_actor) { + shasho_actor->npc_class.actor_class.speed = 0.0; + shasho_actor->npc_class.movement.speed.max_speed = 0.0; + shasho_actor->npc_class.movement.speed.acceleration = 0.0; + shasho_actor->npc_class.movement.speed.deceleration = 0.0; +} + +static void aNSS_set_door_SE(NPC_SHASHO_ACTOR* shasho_actor) { + static f32 chk_pat[] = { 2.0f, 27.0f }; + static u16 se_no[] = { NA_SE_TRAINDOOR0, NA_SE_TRAINDOOR1 }; + static xyz_t front_door_pos = { 140.0f, 0.0f, 350.0f }; + int i; + + for (i = 0; i < 2; i++) { + if (cKF_FrameControl_passCheck_now(&shasho_actor->npc_class.draw.main_animation.keyframe.frame_control, + chk_pat[i])) { + sAdo_OngenTrgStart(se_no[i], &front_door_pos); + break; + } + } +} + +static void aNSS_enter_walk_back_deck(ACTOR* actorx, GAME* game) { + NPC_SHASHO_ACTOR* shasho_actor = (NPC_SHASHO_ACTOR*)actorx; + + if (actorx->world.position.x > 140.0f) + aNSS_setupAction(actorx, game, aNSS_ACT_ENTER_TURN_BACK_DECK); +} + +static void aNSS_enter_turn_back_deck(ACTOR* actorx, GAME* game) { + NPC_SHASHO_ACTOR* shasho_actor = (NPC_SHASHO_ACTOR*)actorx; + if (chase_angle(&actorx->shape_info.rotation.y, 0, 0x600) == TRUE) { + aNSS_setupAction(actorx, game, aNSS_ACT_ENTER_BACK_DOOR); + + shasho_actor->npc_class.draw.main_animation.keyframe.morph_counter = 0.0f; + } + + actorx->world.angle.y = actorx->shape_info.rotation.y; +} + +static void aNSS_enter_back_door(ACTOR* actorx, GAME* game) { + TRAINDOOR_ACTOR* train_door_actor; + NPC_SHASHO_ACTOR* shasho_actor = (NPC_SHASHO_ACTOR*)actorx; + + if (actorx->world.position.z < 130.0f) { + actorx->shape_info.rotation.y = 0; + actorx->world.angle.y = 0; + actorx->world.position.x = 140.0f; + actorx->world.position.z = 130.0f; + } + + if (shasho_actor->npc_class.draw.main_animation_state == cKF_STATE_STOPPED) { + aNSS_setupAction(actorx, game, shasho_actor->unk_move_action); + if (shasho_actor->action == 8) + shasho_actor->npc_class.draw.main_animation.keyframe.morph_counter = 0.0; + } else { + if (cKF_FrameControl_passCheck_now(&shasho_actor->npc_class.draw.main_animation.keyframe.frame_control, + 20.0f) == TRUE) { + train_door_actor = (TRAINDOOR_ACTOR*)shasho_actor->train_door_actor; + train_door_actor->open_flag = TRUE; + } + } +} + +static void aNSS_walk_to_front_door(ACTOR* actorx, GAME* game) { + if (actorx->world.position.z > 350.0f) { + actorx->world.position.z = 350.0f; + aNSS_setupAction(actorx, game, aNSS_ACT_EXIT_FRONT_DOOR); + } +} + +static void aNSS_exit_front_door(ACTOR* actorx, GAME* game) { + NPC_SHASHO_ACTOR* shasho_actor = (NPC_SHASHO_ACTOR*)actorx; + + if (shasho_actor->npc_class.draw.main_animation_state == cKF_STATE_STOPPED) { + if (shasho_actor->unk_move_action == -1) { + shasho_actor->action = -1; + } else { + aNSS_setupAction(actorx, game, shasho_actor->unk_move_action); + } + } else { + aNSS_set_door_SE(shasho_actor); + } +} + +static void aNSS_walk_to_back_door(ACTOR* actorx, GAME* game) { + NPC_SHASHO_ACTOR* shasho_actor = (NPC_SHASHO_ACTOR*)actorx; + + if (actorx->world.position.z < 130.0f) { + actorx->world.position.z = 130.0f; + aNSS_setupAction(actorx, game, aNSS_ACT_ENTER_BACK_DOOR2); + } +} + +static void aNSS_exit_turn_back_deck(ACTOR* actorx, GAME* game) { + NPC_SHASHO_ACTOR* shasho_actor = (NPC_SHASHO_ACTOR*)actorx; + + if (actorx->world.position.z > 70.0f) { + actorx->shape_info.rotation.y = 0x6000; + actorx->world.angle.y = 0x6000; + actorx->world.position.x = 150.0f; + actorx->world.position.z = 70.0f; + } + + if (chase_angle(&actorx->shape_info.rotation.y, DEG2SHORT_ANGLE(-90.0f), 0x600) == TRUE) { + aNSS_setupAction(actorx, game, aNSS_ACT_EXIT_WALK_BACK_DECK); + } + + actorx->world.angle.y = actorx->shape_info.rotation.y; +} + +static void aNSS_exit_walk_back_deck(ACTOR* actorx, GAME* game) { + NPC_SHASHO_ACTOR* shasho_actor = (NPC_SHASHO_ACTOR*)actorx; + + if (!(actorx->world.position.x < 100.0f)) + return; + + shasho_actor->action = -1; +} + +static void aNSS_enter_walk_back_deck_init(NPC_SHASHO_ACTOR* shasho_actor, GAME_PLAY* game_play) { + aNSS_set_walk_spd(shasho_actor); +} + +static void aNSS_enter_turn_back_deck_init(NPC_SHASHO_ACTOR* shasho_actor, GAME_PLAY* game_play) { + aNSS_set_walk_spd(shasho_actor); +} + +static void aNSS_enter_back_door_init(NPC_SHASHO_ACTOR* shasho_actor, GAME_PLAY* game_play) { + aNSS_set_stop_spd(shasho_actor); + shasho_actor->unk_move_action = 0x3; +} + +static void aNSS_walk_to_front_door_init(NPC_SHASHO_ACTOR* shasho_actor, GAME_PLAY* game_play) { + aNSS_set_walk_spd(shasho_actor); +} + +static void aNSS_exit_front_door_init(NPC_SHASHO_ACTOR* shasho_actor, GAME_PLAY* game_play) { + aNSS_set_walk_spd(shasho_actor); + shasho_actor->unk_move_action = -1; +} + +static void aNSS_enter_front_door_init(NPC_SHASHO_ACTOR* shasho_actor, GAME_PLAY* game_play) { + aNSS_set_stop_spd(shasho_actor); + shasho_actor->unk_move_action = 0x6; +} + +static void aNSS_exit_back_door_init(NPC_SHASHO_ACTOR* shasho_actor, GAME_PLAY* game_play) { + aNSS_set_stop_spd(shasho_actor); + shasho_actor->unk_move_action = 0x8; +} + +static void aNSS_exit_walk_back_deck_init(NPC_SHASHO_ACTOR* shasho_actor, GAME_PLAY* game_play) { + aNSS_set_walk_spd(shasho_actor); +} + +static void aNSS_init_proc(ACTOR* actorx, GAME* game, int action) { + static aNSS_INIT_PROC init_proc[] = { &aNSS_enter_walk_back_deck_init, &aNSS_enter_turn_back_deck_init, + &aNSS_enter_back_door_init, &aNSS_walk_to_front_door_init, + &aNSS_exit_front_door_init, &aNSS_enter_front_door_init, + &aNSS_walk_to_front_door_init, &aNSS_exit_back_door_init, + (aNSS_INIT_PROC)&none_proc1, &aNSS_exit_walk_back_deck_init }; + + NPC_SHASHO_ACTOR* sasho_actor = (NPC_SHASHO_ACTOR*)actorx; + GAME_PLAY* game_play = (GAME_PLAY*)game; + init_proc[action](sasho_actor, game_play); +} + +static void aNSS_setupAction(ACTOR* actorx, GAME* game, int action) { + static aNSS_PROC process[] = { &aNSS_enter_walk_back_deck, &aNSS_enter_turn_back_deck, &aNSS_enter_back_door, + &aNSS_walk_to_front_door, &aNSS_exit_front_door, &aNSS_exit_front_door, + &aNSS_walk_to_back_door, &aNSS_enter_back_door, &aNSS_exit_turn_back_deck, + &aNSS_exit_walk_back_deck }; + + NPC_SHASHO_ACTOR* sasho_actor = (NPC_SHASHO_ACTOR*)actorx; + GAME_PLAY* game_play = (GAME_PLAY*)game; + + sasho_actor->action = action; + sasho_actor->talk_action = process[action]; + + aNSS_set_animation(actorx, action); + aNSS_init_proc(actorx, game, action); +} + +static void aNSS_actor_move(ACTOR* actorx, GAME* game) { + NPC_SHASHO_ACTOR* shasho_actor = (NPC_SHASHO_ACTOR*)actorx; + + NPC_CLIP->move_before_proc(actorx, game); + shasho_actor->talk_action(&shasho_actor->npc_class.actor_class, game); + NPC_CLIP->move_after_proc(actorx, game); + + if (shasho_actor->action == -1) + Actor_delete(actorx); +}