diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 6e781dab..71d01b16 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -629,6 +629,9 @@ ac_dummy.c: ac_kago.c: .text: [0x805B1A08, 0x805B1D50] .data: [0x806C5750, 0x806C57A8] +ac_mikuji.c: + .text: [0x805B414C, 0x805B44C4] + .data: [0x806C5C10, 0x806C5CA0] ac_nameplate.c: .text: [0x805B63FC,0x805B65C4] .data: [0x806C6110,0x806C6138] diff --git a/include/ac_mikuji.h b/include/ac_mikuji.h index cfbde288..37c8e18f 100644 --- a/include/ac_mikuji.h +++ b/include/ac_mikuji.h @@ -8,6 +8,20 @@ extern "C" { #endif +typedef struct actor_mikuji_s MIKUJI_ACTOR; + +typedef void (*MIKUJI_PROC)(MIKUJI_ACTOR*, GAME_PLAY*); + +struct actor_mikuji_s{ + ACTOR actor_class; + u8 pad[0x2A0 - 0x174]; + MIKUJI_PROC proc; + u8 pad2[0x2B4 - 0x2A4]; + int current_action; + int next_action; + u8 pad3[0x2DC - 0x2BC]; +}; + extern ACTOR_PROFILE Mikuji_Profile; #ifdef __cplusplus diff --git a/include/m_name_table.h b/include/m_name_table.h index b5133bf6..aae01313 100644 --- a/include/m_name_table.h +++ b/include/m_name_table.h @@ -2162,6 +2162,7 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define DUMMY_RESERVE 0xF102 #define DUMMY_SHRINE 0xF103 #define DUMMY_RADIO 0xF109 +#define DUMMY_MIKUJI 0xF10D #define DUMMY_TAMA 0xF110 #define DUMMY_DOUZOU 0xF11D #define DUMMY_NAMEPLATE 0xF11F diff --git a/src/ac_mikuji.c b/src/ac_mikuji.c new file mode 100644 index 00000000..2029c3c0 --- /dev/null +++ b/src/ac_mikuji.c @@ -0,0 +1,52 @@ +#include "ac_mikuji.h" + +#include "m_rcp.h" +#include "sys_matrix.h" +#include "m_name_table.h" +#include "bg_item.h" +#include "m_player_lib.h" +#include "m_field_info.h" +#include "m_demo.h" +#include "m_common_data.h" + +static void aMIK_actor_ct(ACTOR* actor, GAME* game); +static void aMIK_actor_init(ACTOR* actor, GAME* game); +static void aMIK_actor_draw(ACTOR* actor, GAME* game); + +ACTOR_PROFILE Mikuji_Profile = { + mAc_PROFILE_MIKUJI, + ACTOR_PART_ITEM, + ACTOR_STATE_TA_SET, + NEWYEAR_TABLE, + ACTOR_OBJ_BANK_KEEP, + sizeof(MIKUJI_ACTOR), + &aMIK_actor_ct, + NONE_ACTOR_PROC, + &aMIK_actor_init, + &aMIK_actor_draw, + NULL +}; + +extern Vtx obj_e_mikuji_shadow_v[]; +extern Gfx obj_e_mikuji_shadow_model[]; + +u8 aMIK_shadow_vtx_fix_flg_table[] = {1,0,0,1,0,1,1,0}; +bIT_ShadowData_c aMIK_shadow_data = { + 8, + aMIK_shadow_vtx_fix_flg_table, + 60.0f, + obj_e_mikuji_shadow_v, + obj_e_mikuji_shadow_model, +}; + +extern Gfx obj_e_mikuji_model[]; + +static void aMIK_set_bgOffset(MIKUJI_ACTOR* mikuji, int offs); + +static void aMIK_actor_ct(ACTOR* actor, GAME* game) +{ + aMIK_set_bgOffset((MIKUJI_ACTOR*)actor, 1); +} + +#include "../src/ac_mikuji_move.c_inc" +#include "../src/ac_mikuji_draw.c_inc" diff --git a/src/ac_mikuji_draw.c_inc b/src/ac_mikuji_draw.c_inc new file mode 100644 index 00000000..b6c0c58c --- /dev/null +++ b/src/ac_mikuji_draw.c_inc @@ -0,0 +1,24 @@ +static void aMIK_actor_draw(ACTOR* actor, GAME* game){ + MIKUJI_ACTOR* mikuji = (MIKUJI_ACTOR*)actor; + + Mtx* cur; + GRAPH* graph = game->graph; + u16* pal; + Gfx* gfx; + + OPEN_DISP(graph); + pal = Common_Get(clip.structure_clip)->get_pal_segment_proc(aSTR_PAL_MIKUJI); + + cur = _Matrix_to_Mtx_new(graph); + + if(cur != NULL){ + _texture_z_light_fog_prim_npc(graph); + gfx = NOW_POLY_OPA_DISP; + gSPMatrix(gfx++, cur, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(gfx++, obj_e_mikuji_model); + SET_POLY_OPA_DISP(gfx); + Common_Get(clip.bg_item_clip)->draw_shadow_proc(game, &aMIK_shadow_data, 0); + } + + CLOSE_DISP(graph); +} diff --git a/src/ac_mikuji_move.c_inc b/src/ac_mikuji_move.c_inc new file mode 100644 index 00000000..96d67ff4 --- /dev/null +++ b/src/ac_mikuji_move.c_inc @@ -0,0 +1,50 @@ +static void aMIK_set_bgOffset(MIKUJI_ACTOR* mikuji, int offs) +{ + static mCoBG_OffsetTable_c height_table_ct[] = { { 0x64, 2, 0, 2, 2, 2, 1 }, + { 0x64, 6, 6, 6, 6, 0, 1 }, + { 0x64, 2, 2, 0, 2, 2, 1 }, + { 0x64, 2, 2, 2, 0, 2, 1 } }; + static mCoBG_OffsetTable_c* height_table[] = { height_table_ct, height_table_ct }; + static f32 addX[] = { 0.0f, 40.0f }; + static f32 addZ[] = { 40.0f, 80.0f }; + + mCoBG_OffsetTable_c* offset; + int i; + xyz_t pos; + + offset = height_table[offs]; + + for(i = 0; i < 2; i++){ + pos.z = mikuji->actor_class.home.position.z + addZ[i]; + pos.x = mikuji->actor_class.home.position.x + addX[0]; + mCoBG_SetPluss5PointOffset_file(pos, *offset, __FILE__, 97); + offset++; + pos.x = mikuji->actor_class.home.position.x + addX[1]; + mCoBG_SetPluss5PointOffset_file(pos, *offset, __FILE__, 101); + offset++; + } +} + +static void aMIK_actor_move(ACTOR* actor, GAME* game){ + int world_bx, world_bz; + int player_bx, player_bz; + PLAYER_ACTOR* player_actor = get_player_actor_withoutCheck((GAME_PLAY*)game); + + mFI_Wpos2BlockNum(&world_bx, &world_bz, actor->world.position); + mFI_Wpos2BlockNum(&player_bx, &player_bz, player_actor->actor_class.world.position); + + if ( + mDemo_Check(mDemo_TYPE_SCROLL, (ACTOR*)player_actor) == FALSE && + mDemo_Check(mDemo_TYPE_SCROLL2, (ACTOR*)player_actor) == FALSE && + mDemo_Check(mDemo_TYPE_SCROLL3, (ACTOR*)player_actor) == FALSE && + (world_bx != player_bx || world_bz != player_bz) + ) { + Actor_delete(actor); + } +} + +static void aMIK_actor_init(ACTOR* actor, GAME* game){ + mFI_SetFG_common(DUMMY_MIKUJI, actor->home.position, 0); + aMIK_actor_move(actor, game); + actor->mv_proc = &aMIK_actor_move; +}