diff --git a/config/rel_slices.yml b/config/rel_slices.yml index f9a71fe0..cb9088d3 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -733,6 +733,10 @@ ac_train1.c: .text: [0x805C0614, 0x805C0CC8] .rodata: [0x8064AD80, 0x8064ADB0] .data: [0x806C7300, 0x806C7388] +ac_tukimi.c: + .text: [0x805C0CC8, 0x805C11A8] + .rodata: [0x8064ADB0, 0x8064ADC0] + .data: [0x806C7388, 0x806C7400] ac_yatai.c: .text: [0x805C1D34, 0x805C217C] .rodata: [0x8064ADC0, 0x8064ADC8] diff --git a/include/ac_tukimi.h b/include/ac_tukimi.h index b83a4abd..40929a31 100644 --- a/include/ac_tukimi.h +++ b/include/ac_tukimi.h @@ -2,7 +2,7 @@ #define AC_TUKIMI_H #include "types.h" -#include "m_actor.h" +#include "ac_structure.h" #ifdef __cplusplus extern "C" { diff --git a/include/m_name_table.h b/include/m_name_table.h index d601e435..6a14655b 100644 --- a/include/m_name_table.h +++ b/include/m_name_table.h @@ -2698,6 +2698,7 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define DUMMY_SHRINE 0xF103 #define DUMMY_RADIO 0xF109 #define DUMMY_YATAI 0xF10A +#define DUMMY_TUKIMI 0xF10A #define DUMMY_MIKUJI 0xF10D #define DUMMY_TAMA 0xF110 #define DUMMY_KOINOBORI 0xF114 diff --git a/src/ac_tukimi.c b/src/ac_tukimi.c new file mode 100644 index 00000000..151f2ff9 --- /dev/null +++ b/src/ac_tukimi.c @@ -0,0 +1,80 @@ +#include "ac_tukimi.h" + +#include "m_name_table.h" +#include "sys_matrix.h" +#include "m_lib.h" +#include "m_rcp.h" +#include "m_common_data.h" +#include "m_player_lib.h" + +static void aTUK_actor_ct(ACTOR* actor, GAME* game); +static void aTUK_actor_dt(ACTOR* actor, GAME* game); +static void aTUK_actor_init(ACTOR* actor, GAME* game); +static void aTUK_actor_draw(ACTOR* actor, GAME* game); + +ACTOR_PROFILE Tukimi_Profile = { + mAc_PROFILE_TUKIMI, + ACTOR_PART_ITEM, + ACTOR_STATE_TA_SET, + NEWYEAR_SHRINE0, + ACTOR_OBJ_BANK_KEEP, + sizeof(STRUCTURE_ACTOR), + &aTUK_actor_ct, + &aTUK_actor_dt, + &aTUK_actor_init, + &aTUK_actor_draw, + NULL +}; + +u8 aTUK_shadow_vtx_fix_flg_table[8] = { + TRUE, TRUE, FALSE, FALSE, + TRUE, FALSE, TRUE, FALSE +}; + +extern Vtx obj_e_tukimi_l_shadow_v[]; +extern Gfx obj_e_tukimi_l_shadow_model[]; +static bIT_ShadowData_c aTUK_shadow_data_l = { + 8, aTUK_shadow_vtx_fix_flg_table, + 60.0f, + obj_e_tukimi_l_shadow_v, + obj_e_tukimi_l_shadow_model +}; + +extern Vtx obj_e_tukimi_r_shadow_v[]; +extern Gfx obj_e_tukimi_r_shadow_model[]; +static bIT_ShadowData_c aTUK_shadow_data_r = { + 8, aTUK_shadow_vtx_fix_flg_table, + 60.0f, + obj_e_tukimi_r_shadow_v, + obj_e_tukimi_r_shadow_model +}; + +extern cKF_Skeleton_R_c cKF_bs_r_obj_e_tukimi_l; +extern cKF_Skeleton_R_c cKF_bs_r_obj_e_tukimi_r; + +static void aTUK_set_bgOffset(STRUCTURE_ACTOR* tukimi, int idx); +static void aTUK_setup_action(ACTOR* actor); + +static void aTUK_actor_ct(ACTOR* actor, GAME* game) { + static cKF_Skeleton_R_c* skl[2] = { &cKF_bs_r_obj_e_tukimi_l, &cKF_bs_r_obj_e_tukimi_r }; + + STRUCTURE_ACTOR* tukimi = (STRUCTURE_ACTOR*)actor; + + tukimi->arg0 = actor->npc_id - NEWYEAR_SHRINE0; + tukimi->structure_pal = tukimi->arg0 + aSTR_PAL_TUKIMI; + tukimi->structure_type = tukimi->arg0 + aSTR_TYPE_TUKIMI; + + cKF_SkeletonInfo_R_ct(&tukimi->keyframe, skl[tukimi->arg0], NULL, tukimi->work_area, tukimi->morph_area); + aTUK_set_bgOffset(tukimi, tukimi->arg0 + 1); + aTUK_setup_action(actor); + cKF_SkeletonInfo_R_play(&tukimi->keyframe); +} + +static void aTUK_actor_dt(ACTOR* actor, GAME* game) { + STRUCTURE_ACTOR* tukimi = (STRUCTURE_ACTOR*)actor; + cKF_SkeletonInfo_R_dt(&tukimi->keyframe); +} + +#include "../src/ac_tukimi_move.c_inc" + +#include "../src/ac_tukimi_draw.c_inc" diff --git a/src/ac_tukimi_draw.c_inc b/src/ac_tukimi_draw.c_inc new file mode 100644 index 00000000..ea6c1c8d --- /dev/null +++ b/src/ac_tukimi_draw.c_inc @@ -0,0 +1,75 @@ +extern Gfx obj_e_tukimi_l_endai_model[]; +extern Gfx obj_e_tukimi_r_endai_model[]; + +static int aTUK_actor_draw_before(GAME* game, cKF_SkeletonInfo_R_c* keyframe, int joint_idx, Gfx** joint_shape, u8* joint_flags, void* arg, s_xyz* joint_rot, xyz_t* joint_pos) { + if (joint_idx == 7) { + *joint_shape = NULL; + } + + return TRUE; +} + +static int aTUK_actor_draw_after(GAME* game,cKF_SkeletonInfo_R_c* info, int idx, Gfx** gfxp, u8* dispbuf, void* actor, s_xyz* rotation, xyz_t* translation) { + static Gfx* mdl[] = { obj_e_tukimi_l_endai_model, obj_e_tukimi_r_endai_model }; + + STRUCTURE_ACTOR* tukimi; + GRAPH* graph; + Mtx* mtx; + u16* pal; + Gfx* gfx; + + tukimi = (STRUCTURE_ACTOR*)actor; + graph = game->graph; + + if (idx == 7) { + mtx = _Matrix_to_Mtx_new(graph); + if (mtx != NULL) { + pal = (*Common_Get(clip).structure_clip->get_pal_segment_proc)(tukimi->structure_pal); + + _texture_z_light_fog_prim_shadow(graph); + + OPEN_DISP(graph); + + gfx = NOW_SHADOW_DISP; + gSPSegment(gfx++, G_MWO_SEGMENT_8, pal); + gSPMatrix(gfx++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(gfx++, mdl[tukimi->arg0]); + + SET_SHADOW_DISP(gfx); + CLOSE_DISP(graph); + } + } + + return TRUE; +} + +static void aTUK_actor_draw(ACTOR* actor, GAME* game) { + static bIT_ShadowData_c* shadow_data[2] = { &aTUK_shadow_data_l, &aTUK_shadow_data_r }; + + GRAPH* graph; + cKF_SkeletonInfo_R_c* keyframe; + STRUCTURE_ACTOR* tukimi; + Gfx* gfx; + u16* pal; + Mtx* mtx; + + graph = game->graph; + tukimi = (STRUCTURE_ACTOR*)actor; + keyframe = &tukimi->keyframe; + mtx = GRAPH_ALLOC_TYPE(graph, Mtx, keyframe->skeleton->num_shown_joints); + if (mtx != NULL) { + pal = Common_Get(clip.structure_clip)->get_pal_segment_proc(tukimi->structure_pal); + + OPEN_DISP(graph); + + _texture_z_light_fog_prim_npc(graph); + + gfx = NOW_POLY_OPA_DISP; + gSPSegment(gfx++, G_MWO_SEGMENT_8, pal); + SET_POLY_OPA_DISP(gfx); + + cKF_Si3_draw_R_SV(game, keyframe, mtx, aTUK_actor_draw_before, aTUK_actor_draw_after, actor); + (*Common_Get(clip).bg_item_clip->draw_shadow_proc)(game, shadow_data[tukimi->arg0], FALSE); + CLOSE_DISP(graph); + } +} diff --git a/src/ac_tukimi_move.c_inc b/src/ac_tukimi_move.c_inc new file mode 100644 index 00000000..22eb42d2 --- /dev/null +++ b/src/ac_tukimi_move.c_inc @@ -0,0 +1,48 @@ +extern cKF_Animation_R_c cKF_ba_r_obj_e_tukimi_l; +extern cKF_Animation_R_c cKF_ba_r_obj_e_tukimi_r; + +static void aTUK_set_bgOffset(STRUCTURE_ACTOR* tukimi, int id) { + id = id == 0 ? 6 : 6; + mCoBG_SetPlussOffset(tukimi->actor_class.home.position, id, 100); +} + +static void aTUK_setup_action(ACTOR* actor) { + static cKF_Animation_R_c* ani[] = { &cKF_ba_r_obj_e_tukimi_l, &cKF_ba_r_obj_e_tukimi_r }; + + STRUCTURE_ACTOR* tukimi = (STRUCTURE_ACTOR*)actor; + cKF_SkeletonInfo_R_init(&tukimi->keyframe, tukimi->keyframe.skeleton, ani[tukimi->arg0], 1.0f, 271.0f, 1.0f, 0.5f, 0.0f, 1, NULL); +} + +static void aTUK_actor_move(ACTOR* actor, GAME* game) { + STRUCTURE_ACTOR* tukimi; + GAME_PLAY* game_play; + PLAYER_ACTOR* player_actor; + int tukimi_bx; + int tukimi_bz; + int player_bx; + int player_bz; + + tukimi = (STRUCTURE_ACTOR*)actor; + game_play = (GAME_PLAY*)game; + + player_actor = get_player_actor_withoutCheck(game_play); + mFI_Wpos2BlockNum(&tukimi_bx, &tukimi_bz, tukimi->actor_class.world.position); + mFI_Wpos2BlockNum(&player_bx, &player_bz, player_actor->actor_class.world.position); + + if (mDemo_Check(mDemo_TYPE_SCROLL, &player_actor->actor_class) == FALSE + && mDemo_Check(mDemo_TYPE_SCROLL2, &player_actor->actor_class) == FALSE + && mDemo_Check(mDemo_TYPE_SCROLL3, &player_actor->actor_class) == FALSE + && (tukimi_bx != player_bx || tukimi_bz != player_bz)) + { + Actor_delete(actor); + } + else { + cKF_SkeletonInfo_R_play(&tukimi->keyframe); + } +} + +static void aTUK_actor_init(ACTOR* actor, GAME* game) { + mFI_SetFG_common(DUMMY_TUKIMI, actor->home.position, FALSE); + aTUK_actor_move(actor, game); + actor->mv_proc = aTUK_actor_move; +}