diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 93ba40ca..800acbd4 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -775,6 +775,10 @@ ac_fallSESW.c: .text: [0x805AEF84, 0x805AF278] .rodata: [0x8064A830, 0x8064A858] .data: [0x806C5148, 0x806C51B0] +ac_goza.c: + .text: [0x805AF4C4, 0x805AF924] + .rodata: [0x8064A868, 0x8064A878] + .data: [0x806C5200, 0x806C5340] ac_kago.c: .text: [0x805B1A08, 0x805B1D50] .data: [0x806C5750, 0x806C57A8] diff --git a/include/ac_goza.h b/include/ac_goza.h index 155d528c..21b3558b 100644 --- a/include/ac_goza.h +++ b/include/ac_goza.h @@ -2,7 +2,7 @@ #define AC_GOZA_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 28bd44e4..1d832a8e 100644 --- a/include/m_name_table.h +++ b/include/m_name_table.h @@ -2721,6 +2721,7 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define DUMMY_BUGGY 0xF105 #define DUMMY_CAR 0xF106 #define DUMMY_KAMAKURA 0xF107 +#define DUMMY_GOZA 0xF108 #define DUMMY_RADIO 0xF109 #define DUMMY_YATAI 0xF10A #define DUMMY_TUKIMI 0xF10A diff --git a/src/ac_goza.c b/src/ac_goza.c new file mode 100644 index 00000000..3cf4f2ab --- /dev/null +++ b/src/ac_goza.c @@ -0,0 +1,110 @@ +#include "ac_goza.h" + +#include "m_name_table.h" +#include "bg_item_h.h" +#include "m_common_data.h" +#include "m_house.h" +#include "m_player_lib.h" +#include "m_demo.h" +#include "ac_intro_demo.h" +#include "m_bgm.h" +#include "sys_matrix.h" +#include "m_rcp.h" +#include "libforest/gbi_extensions.h" + +enum { + aGOZ_UNKNOWN, + + aGOZ_ACTION_NUM +}; + +static void aGOZ_actor_ct(ACTOR* actor, GAME* game); +static void aGOZ_actor_init(ACTOR* actor, GAME* game); +static void aGOZ_actor_draw(ACTOR* actor, GAME* game); + +// clang-format off +ACTOR_PROFILE Goza_Profile = { + mAc_PROFILE_GOZA, + ACTOR_PART_ITEM, + ACTOR_STATE_TA_SET, + SAKURA_TABLE0, + ACTOR_OBJ_BANK_KEEP, + sizeof(STRUCTURE_ACTOR), + &aGOZ_actor_ct, + mActor_NONE_PROC1, + &aGOZ_actor_init, + &aGOZ_actor_draw, + NULL +}; +// clang-format on + +// clang-format off +static u8 aGOZ_shadow_vtx_fix_flg_tableA[] = { + TRUE, TRUE, FALSE, FALSE, + FALSE, TRUE, TRUE, TRUE, + FALSE, FALSE, FALSE, TRUE, + TRUE, TRUE, FALSE, FALSE, + FALSE, TRUE, TRUE, TRUE, + FALSE, FALSE, FALSE, TRUE, + TRUE, TRUE, TRUE, TRUE +}; +// clang-format on + +// clang-format off +static u8 aGOZ_shadow_vtx_fix_flg_tableB[] = { + FALSE, TRUE, TRUE, FALSE, + FALSE, TRUE, FALSE, TRUE, + TRUE, FALSE, FALSE, TRUE, + FALSE, TRUE, TRUE, FALSE, + FALSE, TRUE, FALSE, TRUE, + TRUE, FALSE, FALSE, TRUE, + TRUE, TRUE, TRUE, TRUE +}; +// clang-format on + +extern Vtx obj_e_hfes_shadow_a_v[]; +extern Gfx obj_e_hfes_shadow_a_modelT[]; + +// clang-format off +static bIT_ShadowData_c aGOZ_shadow_dataA = { + 28, + aGOZ_shadow_vtx_fix_flg_tableA, + 20.0f, + obj_e_hfes_shadow_a_v, + obj_e_hfes_shadow_a_modelT +}; +// clang-format on + +extern Vtx obj_e_hfes_shadow_b_v[]; +extern Gfx obj_e_hfes_shadow_b_modelT[]; + +// clang-format off +static bIT_ShadowData_c aGOZ_shadow_dataB = { + 28, + aGOZ_shadow_vtx_fix_flg_tableB, + 20.0f, + obj_e_hfes_shadow_b_v, + obj_e_hfes_shadow_b_modelT +}; +// clang-format on + +static bIT_ShadowData_c* aGOZ_shadow_data_table[] = { &aGOZ_shadow_dataB, &aGOZ_shadow_dataA }; + +static void aGOZ_setup_action(STRUCTURE_ACTOR* goza, int action); +static void aGOZ_set_bgOffset(STRUCTURE_ACTOR* kamakura, int offs); + +static void aGOZ_actor_ct(ACTOR* actor, GAME* game) { + STRUCTURE_ACTOR* goza; + + goza = (STRUCTURE_ACTOR*)actor; + + goza->arg1 = (actor->npc_id - SAKURA_TABLE0) & 1; + + aGOZ_setup_action(goza, aGOZ_UNKNOWN); + + aGOZ_set_bgOffset(goza, 1); +} + +#include "../src/ac_goza_move.c_inc" + +#include "../src/ac_goza_draw.c_inc" diff --git a/src/ac_goza_draw.c_inc b/src/ac_goza_draw.c_inc new file mode 100644 index 00000000..5e718397 --- /dev/null +++ b/src/ac_goza_draw.c_inc @@ -0,0 +1,54 @@ +extern Gfx obj_e_hanami_a_model[]; +extern Gfx obj_e_hanami_b_model[]; + +extern Gfx obj_e_hanami_a_modelT[]; +extern Gfx obj_e_hanami_b_modelT[]; + +static void aGOZ_actor_draw(ACTOR* actor, GAME* game) { + static Gfx* gfx_opa_table[] = { obj_e_hanami_a_model, obj_e_hanami_b_model }; + static Gfx* gfx_xlu_table[] = { obj_e_hanami_a_modelT, obj_e_hanami_b_modelT }; + + STRUCTURE_ACTOR* goza; + GRAPH* graph; + Mtx* mtx; + int type; + Gfx* poly_opa; + Gfx* poly_xlu; + + goza = (STRUCTURE_ACTOR*)actor; + graph = game->graph; + type = goza->arg1 & 1; + + _Matrix_to_Mtx_new(graph); + _texture_z_light_fog_prim_shadow(graph); + _texture_z_light_fog_prim_xlu(graph); + _texture_z_light_fog_prim_npc(graph); + + OPEN_DISP(graph); + { + poly_opa = NOW_POLY_OPA_DISP; + mtx = _Matrix_to_Mtx_new(graph); + if (mtx != NULL) { + gSPMatrix(poly_opa++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(poly_opa++, gfx_opa_table[type]); + } + + SET_POLY_OPA_DISP(poly_opa); + + poly_xlu = NOW_POLY_XLU_DISP; + mtx = _Matrix_to_Mtx_new(graph); + if (mtx != NULL) { + gSPMatrix(poly_xlu++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(poly_xlu++, gfx_xlu_table[type]); + } + + SET_POLY_XLU_DISP(poly_xlu); + } + CLOSE_DISP(graph); + + if (mtx == NULL) { + return; + } + + (*Common_Get(clip).bg_item_clip->draw_shadow_proc)(game, aGOZ_shadow_data_table[type & 1], FALSE); +} diff --git a/src/ac_goza_move.c_inc b/src/ac_goza_move.c_inc new file mode 100644 index 00000000..d79a8a7f --- /dev/null +++ b/src/ac_goza_move.c_inc @@ -0,0 +1,89 @@ +static void aGOZ_set_bgOffset(STRUCTURE_ACTOR* goza, int offs) { + // clang-format off + static mCoBG_OffsetTable_c rewrite_dataA[] = { + { mCoBG_ATTRIBUTE_NONE, 0, 0, 0, 0, 0, 0 }, + { mCoBG_ATTRIBUTE_NONE, 2, 0, 2, 2, 2, 1 }, + { mCoBG_ATTRIBUTE_NONE, 2, 2, 2, 2, 0, 1 }, + { mCoBG_ATTRIBUTE_NONE, 2, 0, 2, 2, 2, 1 }, + { mCoBG_ATTRIBUTE_NONE, 2, 2, 2, 2, 2, 0 }, + { mCoBG_ATTRIBUTE_NONE, 2, 2, 2, 0, 2, 1 }, + { mCoBG_ATTRIBUTE_NONE, 2, 2, 0, 2, 2, 1 }, + { mCoBG_ATTRIBUTE_NONE, 2, 2, 2, 0, 2, 1 }, + { mCoBG_ATTRIBUTE_NONE, 0, 0, 0, 0, 0, 0 } + }; + // clang-format on + + // clang-format off + static mCoBG_OffsetTable_c rewrite_dataB[] = { + { mCoBG_ATTRIBUTE_NONE, 2, 0, 2, 2, 2, 1 }, + { mCoBG_ATTRIBUTE_NONE, 2, 2, 2, 2, 0, 1 }, + { mCoBG_ATTRIBUTE_NONE, 0, 0, 0, 0, 0, 0 }, + { mCoBG_ATTRIBUTE_NONE, 2, 2, 0, 2, 2, 1 }, + { mCoBG_ATTRIBUTE_NONE, 2, 2, 2, 2, 2, 0 }, + { mCoBG_ATTRIBUTE_NONE, 2, 2, 2, 2, 0, 1 }, + { mCoBG_ATTRIBUTE_NONE, 0, 0, 0, 0, 0, 0 }, + { mCoBG_ATTRIBUTE_NONE, 2, 2, 0, 2, 2, 1 }, + { mCoBG_ATTRIBUTE_NONE, 2, 2, 2, 0, 2, 1 } + }; + // clang-format on + + static mCoBG_OffsetTable_c* rewrite_data[] = { rewrite_dataA, rewrite_dataB }; + + int j; + int i; + mCoBG_OffsetTable_c* offset; + xyz_t pos; + + offset = rewrite_data[goza->arg1 & 1]; + for (i = -1; i <= 1; i++) { + for (j = -1; j <= 1; j++) { + pos = goza->actor_class.world.position; + pos.x += mFI_UT_WORLDSIZE_X_F * j; + pos.z += mFI_UT_WORLDSIZE_Z_F * i; + + mCoBG_SetPluss5PointOffset_file(pos, *offset, __FILE__, 167); + + offset++; + } + } +} + +static void aGOZ_setup_action(STRUCTURE_ACTOR* goza, int action) { + static aSTR_MOVE_PROC process[] = { (aSTR_MOVE_PROC)&none_proc1 }; + + goza->action_proc = process[action]; +} + +static void aGOZ_actor_move(ACTOR* actor, GAME* game) { + GAME_PLAY* play; + STRUCTURE_ACTOR* goza; + PLAYER_ACTOR* player; + int bx1; + int bz1; + int bx2; + int bz2; + + play = (GAME_PLAY*)game; + goza = (STRUCTURE_ACTOR*)actor; + player = GET_PLAYER_ACTOR(play); + + mFI_Wpos2BlockNum(&bx1, &bz1, actor->world.position); + mFI_Wpos2BlockNum(&bx2, &bz2, player->actor_class.world.position); + + if ((mDemo_Check(mDemo_TYPE_SCROLL, &player->actor_class) == FALSE) && + (mDemo_Check(mDemo_TYPE_SCROLL2, &player->actor_class) == FALSE) && + (mDemo_Check(mDemo_TYPE_SCROLL3, &player->actor_class) == FALSE) && ((bx1 != bx2) || (bz1 != bz2))) { + Actor_delete(actor); + } else { + goza->action_proc(goza, play); + } +} + +static void aGOZ_actor_init(ACTOR* actor, GAME* game) { + xyz_t pos; + + pos = actor->home.position; + mFI_SetFG_common(DUMMY_GOZA, pos, FALSE); + aGOZ_actor_move(actor, game); + actor->mv_proc = aGOZ_actor_move; +}