From ca63c36bb4a82d48efffab9fb2a66dc767f2118e Mon Sep 17 00:00:00 2001 From: Prakxo Date: Fri, 5 Jan 2024 15:20:07 +0100 Subject: [PATCH] link enginner and majin --- config/rel_slices.yml | 7 ++ include/ac_ev_majin.h | 7 ++ include/ac_npc.h | 9 ++- include/ac_npc_engineer.h | 5 ++ include/ef_effect_control.h | 4 +- src/ac_ev_majin.c | 87 ++++++++++++++++++++ src/ac_ev_majin_move.c_inc | 157 ++++++++++++++++++++++++++++++++++++ src/ac_npc_engineer.c | 72 +++++++++++++++++ 8 files changed, 346 insertions(+), 2 deletions(-) create mode 100644 src/ac_ev_majin.c create mode 100644 src/ac_ev_majin_move.c_inc create mode 100644 src/ac_npc_engineer.c diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 1023603e..9d408db2 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -559,10 +559,17 @@ ac_npc_curator.c: .text: [0x8054B06C, 0x8054CF28] .rodata: [0x806495B0, 0x806495B8] .data: [0x806A4FB0, 0x806A5530] +ac_npc_engineer.c: + .text: [0x80552984, 0x80552B5C] + .data: [0x806A61C8, 0x806A6208] ac_npc_rtc.c: .text: [0x80573044, 0x80574134] .rodata: [0x80649A08, 0x80649A40] .data: [0x806BF648,0x806BF788] +ac_ev_majin.c: + .text: [0x80592A40, 0x80593158] + .rodata: [0x80649D98,0x80649DA0] + .data: [0x806C2B50, 0x806C2BD0] ac_douzou.c: .text: [0x805AD6D8, 0x805AE704] .rodata: [0x8064A7C0, 0x8064A7E8] diff --git a/include/ac_ev_majin.h b/include/ac_ev_majin.h index 3818c93b..dfffeffe 100644 --- a/include/ac_ev_majin.h +++ b/include/ac_ev_majin.h @@ -3,11 +3,18 @@ #include "types.h" #include "m_actor.h" +#include "ac_npc.h" #ifdef __cplusplus extern "C" { #endif +typedef struct actor_ev_majin_actor_s{ + NPC_ACTOR npc_class; + int unk994; + aNPC_SUB_PROC think_proc; +}EV_NPCMAJIN_ACTOR; + extern ACTOR_PROFILE Ev_Majin_Profile; #ifdef __cplusplus diff --git a/include/ac_npc.h b/include/ac_npc.h index 4b057324..8cfce413 100644 --- a/include/ac_npc.h +++ b/include/ac_npc.h @@ -136,7 +136,9 @@ typedef struct npc_info_s { /* TODO: draw data */ typedef struct npc_draw_info_s { - /* 0x000 */ u8 _000[0x20 - 0]; + /* 0x000 */ int _00; + /* 0x004 */ int _04; + /* 0x008 */ u8 _000[0x20 - 8]; /* 0x020 */ f32 _20; /* 0x024 */ f32 _24; /* 0x024 */ u8 _028[0x534 - 0x028]; @@ -421,6 +423,11 @@ typedef struct npc_control_actor_s { u8 _8F4[0x9D8 - 0x8F4]; // TODO } NPC_CONTROL_ACTOR; +typedef struct npc_destruct_table_proc{ + aNPC_SUB_PROC unk0; + aNPC_SUB_PROC unk4; +}NPC_DT_PROCS; + extern ACTOR_PROFILE Npc_Profile; #ifdef __cplusplus diff --git a/include/ac_npc_engineer.h b/include/ac_npc_engineer.h index d50e9040..1a30fbae 100644 --- a/include/ac_npc_engineer.h +++ b/include/ac_npc_engineer.h @@ -3,11 +3,16 @@ #include "types.h" #include "m_actor.h" +#include "ac_npc.h" #ifdef __cplusplus extern "C" { #endif +typedef struct actor_npc_engineer_s{ + NPC_ACTOR npc_class; +}NPCENGINEER_ACTOR; + extern ACTOR_PROFILE Npc_Engineer_Profile; #ifdef __cplusplus diff --git a/include/ef_effect_control.h b/include/ef_effect_control.h index d55f4864..29518dce 100644 --- a/include/ef_effect_control.h +++ b/include/ef_effect_control.h @@ -31,6 +31,7 @@ enum { }; typedef void (*eEC_NAME2EFFECTMAKE_PROC)(int, xyz_t, int, short, GAME*, u16, s16, s16); +typedef void (*eEC_NAME2EFFECTKILL_PROC)(int,u16); typedef void (*eEC_REGISTEFFECTLIGHT_PROC)(f32*, s16,s16,s16); @@ -38,7 +39,8 @@ typedef int (*eEC_EFFECTLIGHTSTATUS_PROC)(rgba_t*, int*); // returns eEC_LIGHT_C typedef struct effect_control_clip_s { /* 0x00 */ eEC_NAME2EFFECTMAKE_PROC effect_make_proc; - /* 0x04 */ u8 _04[0x30 - 0x04]; + /* 0x04 */ eEC_NAME2EFFECTKILL_PROC effect_kill_proc; + /* 0x08 */ u8 _08[0x30 - 0x08]; /* 0x30 */ eEC_REGISTEFFECTLIGHT_PROC regist_effect_light; /* 0x34 */ void* _34; /* 0x38 */ void* _38; diff --git a/src/ac_ev_majin.c b/src/ac_ev_majin.c new file mode 100644 index 00000000..1a0c83a3 --- /dev/null +++ b/src/ac_ev_majin.c @@ -0,0 +1,87 @@ +#include "ac_ev_majin.h" +#include "m_common_data.h" +#include "m_name_table.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 = 0x4E; + majin->npc_class.talk_info.default_animation = 0x4E; + 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(0x5D, 0xFFFF); + +} + +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[] = {79,78,80}; + + 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/ac_ev_majin_move.c_inc" \ No newline at end of file diff --git a/src/ac_ev_majin_move.c_inc b/src/ac_ev_majin_move.c_inc new file mode 100644 index 00000000..5d690c21 --- /dev/null +++ b/src/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._04 == 1) { + aEMJ_setup_think_proc(actor, 1); + } +} + +void aEMJ_retire(NPC_ACTOR* actor, GAME_PLAY* play) { + if (actor->draw._04 == 1) { + ((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; +} diff --git a/src/ac_npc_engineer.c b/src/ac_npc_engineer.c new file mode 100644 index 00000000..a8c3d4bf --- /dev/null +++ b/src/ac_npc_engineer.c @@ -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); +}