From 893b46479e7d2cb484166f6b2308d3b4c4e75766 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Sun, 3 Nov 2024 01:01:55 -0500 Subject: [PATCH] Implement & link ac_turi --- configure.py | 2 +- include/ac_ev_angler.h | 7 +- include/ac_turi.h | 8 +- include/ac_turi_clip.h | 32 ++++++ include/m_clip.h | 3 +- include/m_name_table.h | 1 + include/m_string.h | 1 + src/actor/ac_turi.c | 76 +++++++++++++++ src/actor/ac_turi_clip.c_inc | 184 +++++++++++++++++++++++++++++++++++ src/actor/ac_turi_draw.c_inc | 24 +++++ src/actor/ac_turi_move.c_inc | 103 ++++++++++++++++++++ 11 files changed, 437 insertions(+), 4 deletions(-) create mode 100644 include/ac_turi_clip.h create mode 100644 src/actor/ac_turi.c create mode 100644 src/actor/ac_turi_clip.c_inc create mode 100644 src/actor/ac_turi_draw.c_inc create mode 100644 src/actor/ac_turi_move.c_inc diff --git a/configure.py b/configure.py index 14a33d8d..bbf16323 100644 --- a/configure.py +++ b/configure.py @@ -1060,7 +1060,7 @@ config.libs = [ Object(Matching, "actor/ac_train_window.c"), Object(Matching, "actor/ac_tukimi.c"), Object(NonMatching, "actor/ac_tunahiki_control.c"), - Object(NonMatching, "actor/ac_turi.c"), + Object(Matching, "actor/ac_turi.c"), Object(Matching, "actor/ac_uki.c"), Object(Matching, "actor/ac_weather.c"), Object(Matching, "actor/ac_weather_fine.c"), diff --git a/include/ac_ev_angler.h b/include/ac_ev_angler.h index bbc14496..2d34a115 100644 --- a/include/ac_ev_angler.h +++ b/include/ac_ev_angler.h @@ -3,11 +3,17 @@ #include "types.h" #include "m_actor.h" +#include "m_personal_id.h" #ifdef __cplusplus extern "C" { #endif +typedef struct fish_event_data_s { + int size; + PersonalID_c pID; +} aEANG_event_data_c; + extern ACTOR_PROFILE Ev_Angler_Profile; #ifdef __cplusplus @@ -15,4 +21,3 @@ extern ACTOR_PROFILE Ev_Angler_Profile; #endif #endif - diff --git a/include/ac_turi.h b/include/ac_turi.h index 7d38ba59..5220072d 100644 --- a/include/ac_turi.h +++ b/include/ac_turi.h @@ -3,11 +3,18 @@ #include "types.h" #include "m_actor.h" +#include "ac_structure.h" #ifdef __cplusplus extern "C" { #endif +typedef struct turi_actor_s TURI_ACTOR; + +struct turi_actor_s { + STRUCTURE_ACTOR structure_class; +}; + extern ACTOR_PROFILE Turi_Profile; #ifdef __cplusplus @@ -15,4 +22,3 @@ extern ACTOR_PROFILE Turi_Profile; #endif #endif - diff --git a/include/ac_turi_clip.h b/include/ac_turi_clip.h new file mode 100644 index 00000000..21356250 --- /dev/null +++ b/include/ac_turi_clip.h @@ -0,0 +1,32 @@ +#ifndef AC_TURI_CLIP_H +#define AC_TURI_CLIP_H + +#include "types.h" +#include "ac_ev_angler.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int (*aTRC_GET_MSGNO_PROC)(mActor_name_t); +typedef void (*aTRC_RANDOM_TOPSIZE_PROC)(void); +typedef void (*aTRC_SET_TOPNAME_PROC)(void); +typedef int (*aTRC_FISH_RNDSIZE_PROC)(int); + +typedef struct turi_clip_s { + aTRC_GET_MSGNO_PROC get_msgno_proc; + aTRC_RANDOM_TOPSIZE_PROC random_topsize_proc; + aTRC_SET_TOPNAME_PROC set_topname_proc; + aTRC_FISH_RNDSIZE_PROC fish_rndsize_proc; +} aTRC_clip_c; + +extern int aTRC_clip_get_msgno(mActor_name_t item); +extern void aTRC_clip_random_topsize(void); +extern void aTRC_clip_set_topname(void); +extern int aTRC_clip_fish_rndsize(int size_rank); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_clip.h b/include/m_clip.h index ca54a5ba..d1bee711 100644 --- a/include/m_clip.h +++ b/include/m_clip.h @@ -31,6 +31,7 @@ #include "ac_boxTrick01.h" #include "ac_broker_design.h" #include "ac_garagara.h" +#include "ac_turi_clip.h" #ifdef __cplusplus extern "C" { @@ -90,7 +91,7 @@ typedef struct clip_s { /* 0x0D8 */ void* _0D8; /* 0x0DC */ aAL_Clip_c* animal_logo_clip; /* 0x0E0 */ void* _0E0; - /* 0x0E4 */ void* _0E4; + /* 0x0E4 */ aTRC_clip_c* turi_clip; /* 0x0E8 */ SIGN_ACTOR* sign_control_actor; /* 0x0EC */ aAPC_Clip_c* aprilfool_control_clip; /* 0x0F0 */ aEvMgr_Clip_c* event_manager_clip; diff --git a/include/m_name_table.h b/include/m_name_table.h index ade0fe08..0e598d22 100644 --- a/include/m_name_table.h +++ b/include/m_name_table.h @@ -3037,6 +3037,7 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define DUMMY_TUKIMI 0xF10A #define DUMMY_MIKUJI 0xF10D #define DUMMY_TAMA 0xF110 +#define DUMMY_TURI 0xF111 #define DUMMY_KOINOBORI 0xF114 #define DUMMY_WINDMILL 0xF116 #define DUMMY_LOTUS 0xF11B diff --git a/include/m_string.h b/include/m_string.h index 2ede566f..796c916b 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -10,6 +10,7 @@ extern "C" { #endif #define mString_MAX_STR 0x7FF +#define mString_DEFAULT_STR_SIZE 16 extern void mString_aram_init(); extern void mString_Load_StringFromRom(u8* dst, int dst_len, int str_no); diff --git a/src/actor/ac_turi.c b/src/actor/ac_turi.c new file mode 100644 index 00000000..5d0186e2 --- /dev/null +++ b/src/actor/ac_turi.c @@ -0,0 +1,76 @@ +#include "ac_turi.h" + +#include "ac_turi_clip.h" +#include "m_name_table.h" +#include "bg_item_h.h" +#include "m_fishrecord.h" +#include "m_font.h" +#include "m_msg.h" +#include "m_string.h" +#include "m_event_map_npc.h" +#include "m_common_data.h" +#include "m_player_lib.h" +#include "sys_matrix.h" +#include "m_rcp.h" + +enum { + aTUR_ACT_WAIT, + + aTUR_ACT_NUM +}; + +static void aTUR_actor_ct(ACTOR* actorx, GAME* game); +static void aTUR_actor_dt(ACTOR* actorx, GAME* game); +static void aTUR_actor_init(ACTOR* actorx, GAME* game); +static void aTUR_actor_move(ACTOR* actorx, GAME* game); +static void aTUR_actor_draw(ACTOR* actorx, GAME* game); + +// clang-format off +ACTOR_PROFILE Turi_Profile = { + mAc_PROFILE_TURI, + ACTOR_PART_ITEM, + ACTOR_STATE_TA_SET, + FISHCHECK_STAND0, + ACTOR_OBJ_BANK_KEEP, + sizeof(TURI_ACTOR), + &aTUR_actor_ct, + &aTUR_actor_dt, + &aTUR_actor_init, + &aTUR_actor_draw, + NULL, +}; +// clang-format on + +extern Vtx obj_e_turi_l_shadow_v[]; +extern Gfx obj_e_turi_l_shadow_model[]; + +extern Vtx obj_e_turi_r_shadow_v[]; +extern Gfx obj_e_turi_r_shadow_model[]; + +static u8 aTUR_shadow_vtx_fix_flg_table[] = { TRUE, FALSE, FALSE, TRUE, FALSE, TRUE }; +static bIT_ShadowData_c aTUR_shadow_data_l = { 6, aTUR_shadow_vtx_fix_flg_table, 60.0f, obj_e_turi_l_shadow_v, obj_e_turi_l_shadow_model, }; +static bIT_ShadowData_c aTUR_shadow_data_r = { 6, aTUR_shadow_vtx_fix_flg_table, 60.0f, obj_e_turi_r_shadow_v, obj_e_turi_r_shadow_model, }; + +static void aTRC_clip_ct(void); +static void aTRC_clip_dt(void); +static void aTUR_set_bgOffset(ACTOR* actorx, int type); +static void aTUR_setup_action(TURI_ACTOR* turi, int act_idx); + +#include "../src/actor/ac_turi_clip.c_inc" +#include "../src/actor/ac_turi_move.c_inc" +#include "../src/actor/ac_turi_draw.c_inc" + +static void aTUR_actor_ct(ACTOR* actorx, GAME* game) { + TURI_ACTOR* turi = (TURI_ACTOR*)actorx; + + turi->structure_class.arg0 = actorx->npc_id - FISHCHECK_STAND0; + turi->structure_class.structure_type = aSTR_TYPE_TURI + turi->structure_class.arg0; + turi->structure_class.structure_pal = aSTR_PAL_TURI + turi->structure_class.arg0; + aTUR_setup_action(turi, aTUR_ACT_WAIT); + aTUR_set_bgOffset(actorx, turi->structure_class.arg0 + 2); + aTRC_clip_ct(); +} + +static void aTUR_actor_dt(ACTOR* actorx, GAME* game) { + aTRC_clip_dt(); +} diff --git a/src/actor/ac_turi_clip.c_inc b/src/actor/ac_turi_clip.c_inc new file mode 100644 index 00000000..bd6ab20f --- /dev/null +++ b/src/actor/ac_turi_clip.c_inc @@ -0,0 +1,184 @@ +static aTRC_clip_c aTRC_clip; + +static void aTRC_clip_ct(void) { + aTRC_clip.get_msgno_proc = &aTRC_clip_get_msgno; + aTRC_clip.random_topsize_proc = &aTRC_clip_random_topsize; + aTRC_clip.set_topname_proc = &aTRC_clip_set_topname; + aTRC_clip.fish_rndsize_proc = &aTRC_clip_fish_rndsize; + CLIP(turi_clip) = &aTRC_clip; +} + +static void aTRC_clip_dt(void) { + CLIP(turi_clip) = NULL; +} + +static aEANG_event_data_c* get_fish_save_area(void) { + lbRTC_time_c now_time = Common_Get(time.rtc_time); + aEANG_event_data_c* fish_p; + + if (now_time.month == lbRTC_JUNE) { + fish_p = (aEANG_event_data_c*)mEv_get_save_area(0x1D, 0); + } else { + fish_p = (aEANG_event_data_c*)mEv_get_save_area(0x36, 0); + } + + return fish_p; +} + +static int get_top_of_angler_size(void) { + aEANG_event_data_c* fish_p = get_fish_save_area(); + + return fish_p->size; +} + +static void set_top_of_angler_pID(PersonalID_c pID) { + aEANG_event_data_c* fish_p = get_fish_save_area(); + + mPr_CopyPersonalID(&fish_p->pID, &pID); +} + +static PersonalID_c* getP_top_of_angler_pID(void) { + aEANG_event_data_c* fish_p = get_fish_save_area(); + + return &fish_p->pID; +} + +extern int aTRC_clip_fish_rndsize(int size_rank) { + return mFR_fish_rndsize(size_rank); +} + +extern int aTRC_clip_get_msgno(mActor_name_t item) { + switch (item) { + case ITM_FISH00: + return 0x10F6; + case ITM_FISH01: + return 0x10F7; + case ITM_FISH02: + return 0x10F8; + case ITM_FISH03: + return 0x10F9; + case ITM_FISH04: + return 0x10FA; + case ITM_FISH05: + return 0x1112; + case ITM_FISH06: + return 0x1116; + case ITM_FISH07: + return 0x111A; + case ITM_FISH08: + return 0x10FB; + case ITM_FISH09: + return 0x10FC; + case ITM_FISH10: + return 0x10FD; + case ITM_FISH11: + return 0x10FE; + case ITM_FISH12: + return 0x10FF; + case ITM_FISH13: + return 0x1100; + case ITM_FISH14: + return 0x1101; + case ITM_FISH15: + return 0x1102; + case ITM_FISH16: + return 0x110C; + case ITM_FISH17: + return 0x1103; + case ITM_FISH18: + return 0x1104; + case ITM_FISH19: + return 0x1105; + case ITM_FISH20: + return 0x1106; + case ITM_FISH21: + return 0x1107; + case ITM_FISH22: + return 0x1108; + case ITM_FISH23: + return 0x1109; + case ITM_FISH24: + return 0x110A; + case ITM_FISH25: + return 0x110B; + case ITM_FISH26: + return 0x110D; + case ITM_FISH27: + return 0x17E6; + case ITM_FISH28: + return 0x17E7; + case ITM_FISH29: + return 0x17E8; + case ITM_FISH30: + return 0x17E9; + case ITM_FISH31: + return 0x17EA; + case ITM_FISH32: + return 0x2FB0; + case ITM_FISH33: + return 0x2FAF; + case ITM_FISH34: + return 0x2FB2; + case ITM_FISH35: + return 0x2FB3; + case ITM_FISH36: + return 0x2FB4; + case ITM_FISH37: + return 0x2FB5; + case ITM_FISH38: + return 0x2FB6; + case ITM_FISH39: + return 0x2FB1; + default: + return 0x10F2; + } +} + +extern void aTRC_clip_random_topsize(void) { + u8 npc_name[ANIMAL_NAME_LEN]; + mActor_name_t npc_id; + static u8 l_name[] = { 0x98, 0xA6, 0x8F, 0xA1, CHAR_SPACE }; // untranslated, JP "ケニッチ" + aEANG_event_data_c* fish_p = get_fish_save_area(); + lbRTC_time_c now_time = Common_Get(time.rtc_time); + lbRTC_hour_t hour = now_time.hour; + int size; + + if (fish_p != NULL) { + size = mFR_make_NpcRecord(hour); + + if (size > fish_p->size) { + // update record info + fish_p->size = size; + set_top_of_angler_pID(Now_Private->player_ID); + + // clear relevant ids + fish_p->pID.land_id = RSV_NO; + fish_p->pID.player_id = RSV_NO; + + // get villager name for size record, preferring a villager participating in the event + if (mEvMN_GetJointEventRandomNpc(&npc_id) == TRUE) { + mNpc_GetNpcWorldNameTableNo(npc_name, npc_id); + } else { + mNpc_GetRandomAnimalName(npc_name); + } + + // overwrite player name & town name with villager name & dummy town name respectively + mem_copy(fish_p->pID.player_name, npc_name, sizeof(npc_name)); + mLd_ClearLandName(fish_p->pID.land_name); + mem_copy(fish_p->pID.land_name, l_name, sizeof(l_name)); + mEv_fishRecord_set(&fish_p->pID, size); + } + } +} + +extern void aTRC_clip_set_topname(void) { + mMsg_Window_c* msg_p = mMsg_Get_base_window_p(); + u8 num_str[mString_DEFAULT_STR_SIZE]; + PersonalID_c* pID_p; + int len; + + len = mString_Load_NumberStringAddUnitFromRom(num_str, get_top_of_angler_size(), 0x29E); + mMsg_Set_free_str(msg_p, mMsg_FREE_STR1, num_str, len); + pID_p = getP_top_of_angler_pID(); + mMsg_Set_free_str(msg_p, mMsg_FREE_STR0, pID_p->player_name, PLAYER_NAME_LEN); +} diff --git a/src/actor/ac_turi_draw.c_inc b/src/actor/ac_turi_draw.c_inc new file mode 100644 index 00000000..a56d88b8 --- /dev/null +++ b/src/actor/ac_turi_draw.c_inc @@ -0,0 +1,24 @@ +extern Gfx obj_e_turi_l_modelT[]; +extern Gfx obj_e_turi_r_modelT[]; + +static void aTUR_actor_draw(ACTOR* actorx, GAME* game) { + static Gfx* model[] = { obj_e_turi_l_modelT, obj_e_turi_r_modelT }; + static bIT_ShadowData_c* shadow[] = { &aTUR_shadow_data_l, &aTUR_shadow_data_r }; + GRAPH* graph = game->graph; + TURI_ACTOR* turi = (TURI_ACTOR*)actorx; + u16* pal_p = CLIP(structure_clip)->get_pal_segment_proc(turi->structure_class.structure_pal); + Mtx* mtx = _Matrix_to_Mtx_new(graph); + + if (mtx != NULL) { + _texture_z_light_fog_prim_npc(graph); + OPEN_POLY_OPA_DISP(graph); + + gSPSegment(POLY_OPA_DISP++, ANIME_1_TXT_SEG, pal_p); + gSPMatrix(POLY_OPA_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, model[turi->structure_class.arg0 & 1]); + + CLOSE_POLY_OPA_DISP(graph); + + CLIP(bg_item_clip)->draw_shadow_proc(game, shadow[turi->structure_class.arg0], FALSE); + } +} diff --git a/src/actor/ac_turi_move.c_inc b/src/actor/ac_turi_move.c_inc new file mode 100644 index 00000000..4ccbae79 --- /dev/null +++ b/src/actor/ac_turi_move.c_inc @@ -0,0 +1,103 @@ +static void aTUR_set_bgOffset(ACTOR* actorx, int idx) { + // clang-format off + static mCoBG_OffsetTable_c height_table_ct_l[] = { + { mCoBG_ATTRIBUTE_NONE, 0, 0, 0, 0, 0, 0 }, + { mCoBG_ATTRIBUTE_NONE, 10, 0, 10, 10, 10, 1 }, + { mCoBG_ATTRIBUTE_NONE, 10, 10, 10, 10, 0, 1 }, + { mCoBG_ATTRIBUTE_NONE, 10, 0, 10, 10, 10, 1 }, + { mCoBG_ATTRIBUTE_NONE, 10, 10, 10, 10, 10, 0 }, + { mCoBG_ATTRIBUTE_NONE, 10, 10, 10, 0, 10, 1 }, + { mCoBG_ATTRIBUTE_NONE, 10, 10, 0, 10, 10, 1 }, + { mCoBG_ATTRIBUTE_NONE, 10, 10, 10, 0 , 10, 1 }, + { mCoBG_ATTRIBUTE_NONE, 0, 0, 0, 0, 0, 0 }, + }; + // clang-format on + + // clang-format off + static mCoBG_OffsetTable_c height_table_ct_r[] = { + { mCoBG_ATTRIBUTE_NONE, 10, 0, 10, 10, 10, 1 }, + { mCoBG_ATTRIBUTE_NONE, 10, 10, 10, 10, 0, 1 }, + { mCoBG_ATTRIBUTE_NONE, 0, 0, 0, 0, 0, 0 }, + { mCoBG_ATTRIBUTE_NONE, 10, 10, 0, 10, 10, 1 }, + { mCoBG_ATTRIBUTE_NONE, 10, 10, 10, 10, 10, 0 }, + { mCoBG_ATTRIBUTE_NONE, 10, 10, 10, 10, 0, 1 }, + { mCoBG_ATTRIBUTE_NONE, 0, 0, 0, 0, 0, 0 }, + { mCoBG_ATTRIBUTE_NONE, 10, 10, 0, 10, 10, 1 }, + { mCoBG_ATTRIBUTE_NONE, 10, 10, 10, 0, 10, 1 }, + }; + // clang-format on + + static mCoBG_OffsetTable_c* height_table[] = { + height_table_ct_l, + height_table_ct_r, + height_table_ct_l, + height_table_ct_r, + }; + + static f32 addX[] = { -mFI_UNIT_BASE_SIZE_F, 0.0f, mFI_UNIT_BASE_SIZE_F }; + static f32 addZ[] = { -mFI_UNIT_BASE_SIZE_F, 0.0f, mFI_UNIT_BASE_SIZE_F }; + + mCoBG_OffsetTable_c* height_tbl_p = height_table[idx]; + xyz_t pos; + int type = idx & 1; + int z; + int x; + + for (z = 0; z < 3; z++) { + pos.z = actorx->home.position.z + addZ[z]; + + for (x = 0; x < 3; x++) { + if (type == 0) { + if (z * 3 + x != 0 && z * 3 + x != 8) { + pos.x = actorx->home.position.x + addX[x]; + + mCoBG_SetPluss5PointOffset_file(pos, *height_tbl_p, __FILE__, 121); + } + } else { + if (z * 3 + x != 2 && z * 3 + x != 6) { + pos.x = actorx->home.position.x + addX[x]; + + mCoBG_SetPluss5PointOffset_file(pos, *height_tbl_p, __FILE__, 127); + } + } + + height_tbl_p++; + } + } +} + +static void aTUR_wait(TURI_ACTOR* turi, GAME_PLAY* play) { + // empty +} + +static void aTUR_setup_action(TURI_ACTOR* turi, int act_idx) { + static void* process[] = { &aTUR_wait }; + + turi->structure_class.action_proc = (aSTR_MOVE_PROC)process[act_idx]; + turi->structure_class.action = act_idx; +} + +static void aTUR_actor_move(ACTOR* actorx, GAME* game) { + GAME_PLAY* play = (GAME_PLAY*)game; + TURI_ACTOR* turi = (TURI_ACTOR*)actorx; + ACTOR* player_actor = GET_PLAYER_ACTOR_ACTOR(play); + int turi_bx; + int turi_bz; + int player_bx; + int player_bz; + + mFI_Wpos2BlockNum(&turi_bx, &turi_bz, actorx->world.position); + mFI_Wpos2BlockNum(&player_bx, &player_bz, player_actor->world.position); + + if (!mDemo_Check(mDemo_TYPE_SCROLL, player_actor) && !mDemo_Check(mDemo_TYPE_SCROLL2, player_actor) && !mDemo_Check(mDemo_TYPE_SCROLL3, player_actor) && (turi_bx != player_bx || turi_bz != player_bz)) { + Actor_delete(actorx); + } else { + (*turi->structure_class.action_proc)((STRUCTURE_ACTOR*)turi, play); + } +} + +static void aTUR_actor_init(ACTOR* actorx, GAME* game) { + mFI_SetFG_common(DUMMY_TURI, actorx->home.position, FALSE); + aTUR_actor_move(actorx, game); + actorx->mv_proc = &aTUR_actor_move; +}