diff --git a/configure.py b/configure.py index feca854a..ad7aa2a9 100644 --- a/configure.py +++ b/configure.py @@ -1116,7 +1116,7 @@ config.libs = [ Object(Matching, "actor/npc/ac_npc_engineer.c"), Object(Matching, "actor/npc/ac_npc_guide.c"), Object(Matching, "actor/npc/ac_npc_guide2.c"), - Object(NonMatching, "actor/npc/ac_npc_hem.c"), + Object(Matching, "actor/npc/ac_npc_hem.c"), Object(Matching, "actor/npc/ac_npc_majin.c"), Object(Matching, "actor/npc/ac_npc_majin2.c"), Object(Matching, "actor/npc/ac_npc_majin3.c"), diff --git a/src/actor/npc/ac_npc_hem.c b/src/actor/npc/ac_npc_hem.c new file mode 100644 index 00000000..0da6b396 --- /dev/null +++ b/src/actor/npc/ac_npc_hem.c @@ -0,0 +1,87 @@ +#include "ac_npc_hem.h" +#include "m_name_table.h" +#include "ac_npc.h" +#include "ac_npc_h.h" +#include "m_common_data.h" +#include "m_msg.h" +#include "m_soncho.h" +#include "ac_shrine.h" + +struct _NPC_HEM_ACTOR; + +typedef (*NPC_HEM_PROC)(struct _NPC_HEM_ACTOR*); + +typedef struct _NPC_HEM_ACTOR { + NPC_ACTOR actor; + int processIndex; + aNPC_SUB_PROC processFunction; + aNPC_SUB_PROC talkProcess; + u8 _9A0; + u8 _9A1; + s16 _9A2; +} NPC_HEM_ACTOR; + +void aNHM_actor_ct(ACTOR* actorx, GAME* game); +void aNHM_actor_dt(ACTOR* actorx, GAME* game); +void aNHM_actor_init(ACTOR* actorx, GAME* game); +void aNHM_actor_save(ACTOR* actorx, GAME* game); +void aNHM_actor_move(ACTOR* actorx, GAME* game); +void aNHM_actor_draw(ACTOR* actorx, GAME* game); +BOOL aNHM_talk_init(ACTOR* actorx, GAME* game); +BOOL aNHM_talk_end_chk(ACTOR* actorx, GAME* game); +void aNHM_schedule_proc(NPC_ACTOR*, GAME_PLAY*, int); +void aNHM_talk_request(ACTOR* actorx, GAME* game); +void aNHM_change_talk_proc(NPC_ACTOR* actorx, int); + +// clang-format off +ACTOR_PROFILE Npc_Hem_Profile = { + mAc_PROFILE_NPC_HEM, + ACTOR_PART_NPC, + ACTOR_STATE_NONE, + SP_NPC_HEM, + ACTOR_OBJ_BANK_KEEP, + sizeof(NPC_HEM_ACTOR), + aNHM_actor_ct, + aNHM_actor_dt, + aNHM_actor_init, + (mActor_proc)none_proc1, + aNHM_actor_save +}; +// clang-format on + +void aNHM_actor_ct(ACTOR* actorx, GAME* game) { + // clang-format off + static aNPC_ct_data_c ct_data = { + aNHM_actor_move, + aNHM_actor_draw, + aNPC_CT_SCHED_TYPE_SPECIAL, + (aNPC_TALK_REQUEST_PROC)none_proc1, + aNHM_talk_init, + aNHM_talk_end_chk, + 0 + }; + // clang-format on + + if (NPC_CLIP->birth_check_proc(actorx, game) == TRUE) { + ((NPC_HEM_ACTOR*)actorx)->actor.schedule.schedule_proc = aNHM_schedule_proc; + NPC_CLIP->ct_proc(actorx, game, &ct_data); + } +} + +void aNHM_actor_save(ACTOR* actorx, GAME* game) { + NPC_CLIP->save_proc(actorx, game); +} + +void aNHM_actor_dt(ACTOR* actorx, GAME* game) { + NPC_CLIP->dt_proc(actorx, game); +} + +void aNHM_actor_init(ACTOR* actorx, GAME* game) { + NPC_CLIP->init_proc(actorx, game); +} + +void aNHM_actor_draw(ACTOR* actorx, GAME* game) { + NPC_CLIP->draw_proc(actorx, game); +} + +#include "../../actor/npc/ac_npc_hem.c_inc" diff --git a/src/actor/npc/ac_npc_hem.c_inc b/src/actor/npc/ac_npc_hem.c_inc new file mode 100644 index 00000000..13b3f2ba --- /dev/null +++ b/src/actor/npc/ac_npc_hem.c_inc @@ -0,0 +1,175 @@ + +void aNHM_set_request_act(NPC_ACTOR* actorx) { + NPC_HEM_ACTOR* hem = (NPC_HEM_ACTOR*)actorx; + hem->actor.request.act_priority = 4; + hem->actor.request.act_idx = aNPC_ACT_SPECIAL; + hem->actor.request.act_type = aNPC_ACT_TYPE_DEFAULT; +} + +void aNHM_appear_wait(NPC_ACTOR* actorx, GAME_PLAY* play) { + NPC_HEM_ACTOR* hem = (NPC_HEM_ACTOR*)actorx; + if (Common_Get(hem_visible) == TRUE) { + hem->actor.condition_info.hide_request = FALSE; + hem->actor.talk_info.talk_request_proc = aNHM_talk_request; + } +} + +void aNHM_disappear_wait(NPC_ACTOR* actorx, GAME_PLAY* play) { + NPC_HEM_ACTOR* hem = (NPC_HEM_ACTOR*)actorx; + if (Common_Get(hem_visible) == FALSE) { + hem->_9A0 = TRUE; + } +} + +void aNHM_setupAction(NPC_HEM_ACTOR* hem, int processInd) { + static aNPC_SUB_PROC process[] = { aNHM_appear_wait, aNHM_disappear_wait }; + hem->actor.action.step = 0; + hem->processIndex = processInd; + hem->processFunction = process[processInd]; + NPC_CLIP->animation_init_proc(&hem->actor.actor_class, aNPC_ANIM_WAIT1, FALSE); +} + +void aNHM_act_chg_data_proc(NPC_ACTOR* actorx, GAME_PLAY* play) { + NPC_HEM_ACTOR* hem = (NPC_HEM_ACTOR*)actorx; + hem->actor.action.act_obj = aNPC_ACT_OBJ_PLAYER; +} + +void aNHM_act_init_proc(NPC_ACTOR* actorx, GAME_PLAY* play) { + NPC_HEM_ACTOR* hem = (NPC_HEM_ACTOR*)actorx; + int x = 0; + if (hem->_9A1 == TRUE) { + eEC_CLIP->effect_make_proc(eEC_EFFECT_MAKE_HEM, hem->actor.actor_class.world.position, 2, 0, &play->game, -1, 0, + 0); + x = 1; + } + aNHM_setupAction(hem, x); +} + +void aNHM_act_main_proc(NPC_ACTOR* actorx, GAME_PLAY* play) { + NPC_HEM_ACTOR* hem = (NPC_HEM_ACTOR*)actorx; + hem->processFunction(actorx, play); +} + +void aNHM_act_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int action) { + static aNPC_SUB_PROC act_proc[] = { aNHM_act_init_proc, aNHM_act_chg_data_proc, aNHM_act_main_proc }; + act_proc[action](actorx, play); +} + +void aNHM_think_main_proc(NPC_ACTOR* actorx, GAME_PLAY* play) { + NPC_HEM_ACTOR* hem = (NPC_HEM_ACTOR*)actorx; + if (hem->actor.action.step == (u8)-1) { + hem->actor.condition_info.demo_flg = aNPC_COND_DEMO_SKIP_HEAD_LOOKAT | aNPC_COND_DEMO_SKIP_FORWARD_CHECK | + aNPC_COND_DEMO_SKIP_BGCHECK | aNPC_COND_DEMO_SKIP_MOVE_RANGE_CHECK | + aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV | aNPC_COND_DEMO_SKIP_MOVE_Y; + hem->actor.collision.check_kind = aNPC_BG_CHECK_TYPE_ONLY_GROUND; + aNHM_set_request_act(actorx); + } +} + +void aNHM_think_init_proc(NPC_ACTOR* actorx, GAME_PLAY* play) { + NPC_HEM_ACTOR* hem = (NPC_HEM_ACTOR*)actorx; + hem->actor.action.act_proc = aNHM_act_proc; + aNHM_set_request_act(actorx); +} + +void aNHM_think_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int action) { + static aNPC_SUB_PROC think_proc[] = { aNHM_think_init_proc, aNHM_think_main_proc }; + think_proc[action](actorx, play); +} + +void aNHM_schedule_init_proc(NPC_ACTOR* actorx, GAME_PLAY* play) { + NPC_HEM_ACTOR* hem = (NPC_HEM_ACTOR*)actorx; + hem->actor.think.think_proc = aNHM_think_proc; + hem->actor.palActorIgnoreTimer = -1; + hem->actor.condition_info.demo_flg = aNPC_COND_DEMO_SKIP_HEAD_LOOKAT | aNPC_COND_DEMO_SKIP_FORWARD_CHECK | + aNPC_COND_DEMO_SKIP_BGCHECK | aNPC_COND_DEMO_SKIP_MOVE_RANGE_CHECK | + aNPC_COND_DEMO_SKIP_MOVE_CIRCLE_REV | aNPC_COND_DEMO_SKIP_MOVE_Y; + hem->actor.collision.check_kind = aNPC_BG_CHECK_TYPE_ONLY_GROUND; + hem->_9A2 = 90; + hem->actor.actor_class.status_data.weight = MASSTYPE_HEAVY; + hem->actor.actor_class.world.position.x += 20.f; + hem->actor.actor_class.world.position.z -= 20.f; + NPC_CLIP->think_proc(&hem->actor, play, 9, 0); +} + +void aNHM_schedule_main_proc(NPC_ACTOR* actorx, GAME_PLAY* play) { + if (NPC_CLIP->think_proc(actorx, play, -1, 1) == FALSE) { + NPC_CLIP->think_proc(actorx, play, -1, 2); + } +} + +void aNHM_schedule_proc(NPC_ACTOR* actorx, GAME_PLAY* play, int proc) { + static aNPC_SUB_PROC sche_proc[] = { aNHM_schedule_init_proc, aNHM_schedule_main_proc }; + sche_proc[proc](actorx, play); +} + +void aNHM_trans_demo_start_wait_talk_proc(NPC_ACTOR* actorx, GAME_PLAY* play) { + NPC_HEM_ACTOR* hem = (NPC_HEM_ACTOR*)actorx; + if ((int)mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 1) == 2) { + mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 0, ITM_GOLDEN_AXE); + mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 1, 7); + mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 2, 2); + hem->_9A1 = 1; + mMsg_SET_LOCKCONTINUE(); + aNHM_change_talk_proc(actorx, 1); + } +} + +void aNHM_trans_demo_end_wait_talk_proc(NPC_ACTOR* actorx, GAME_PLAY* play) { + if (Common_Get(clip).handOverItem_clip->master_actor == NULL) { + mMsg_UNSET_LOCKCONTINUE(); + aNHM_change_talk_proc(actorx, 2); + } +} + +void aNHM_change_talk_proc(NPC_ACTOR* actorx, int ind) { + static aNPC_SUB_PROC process[] = { aNHM_trans_demo_start_wait_talk_proc, aNHM_trans_demo_end_wait_talk_proc, + (aNPC_SUB_PROC)none_proc1 }; + + NPC_HEM_ACTOR* hem = (NPC_HEM_ACTOR*)actorx; + hem->talkProcess = process[ind]; +} + +void aNHM_set_force_talk_info_talk_request() { + mDemo_Set_msg_num(0x2c51); + mPr_SetFreePossessionItem(Now_Private, ITM_GOLDEN_AXE, 0); + mSC_trophy_set(0x1d); + mFAs_ClearGoodField(); + mDemo_Set_talk_return_get_golden_axe_demo(1); +} + +void aNHM_talk_request(ACTOR* actorx, GAME* game) { + mDemo_Request(8, actorx, aNHM_set_force_talk_info_talk_request); +} + +BOOL aNHM_talk_init(ACTOR* actorx, GAME* game) { + NPC_HEM_ACTOR* hem = (NPC_HEM_ACTOR*)actorx; + BOOL x = FALSE; + hem->_9A2--; + if (hem->_9A2 <= 0) { + hem->actor.talk_info.talk_request_proc = (aNPC_TALK_REQUEST_PROC)none_proc1; + aNHM_change_talk_proc(&hem->actor, 0); + mDemo_Set_ListenAble(); + x = TRUE; + } + return x; +} + +BOOL aNHM_talk_end_chk(ACTOR* actorx, GAME* game) { + NPC_HEM_ACTOR* hem = (NPC_HEM_ACTOR*)actorx; + BOOL x = FALSE; + hem->talkProcess(&hem->actor, (GAME_PLAY*)game); + if (mDemo_Check(8, actorx) == FALSE) { + x = TRUE; + } + return x; +} + +void aNHM_actor_move(ACTOR* actorx, GAME* game) { + NPC_HEM_ACTOR* hem = (NPC_HEM_ACTOR*)actorx; + NPC_CLIP->move_proc(actorx, game); + if (hem->_9A0 == TRUE) { + aSHR_GET_CLIP()->hem_flag = FALSE; + Actor_delete(actorx); + } +}