From cdf61f91bea69c78d257e00fd7cea14808395788 Mon Sep 17 00:00:00 2001 From: Cuyler36 <24523422+Cuyler36@users.noreply.github.com> Date: Wed, 14 Aug 2024 22:17:40 -0400 Subject: [PATCH] Implement & link ac_bridge_a --- config/rel_slices.yml | 4 + include/ac_bridge_a.h | 2 +- include/m_name_table.h | 1 + src/ac_bridge_a.c | 197 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 src/ac_bridge_a.c diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 0bd59c42..7fde6ccd 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -842,6 +842,10 @@ ac_br_shop.c: .text: [0x805A856C, 0x805A9474] .rodata: [0x8064A630, 0x8064A660] .data: [0x806C4560, 0x806C4688] +ac_bridge_a.c: + .text: [0x805A9474, 0x805A9CA0] + .rodata: [0x8064A660, 0x8064A6D0] + .data: [0x806C4688, 0x806C4730] ac_buggy.c: .text: [0x805A9CA0, 0x805AAB3C] .rodata: [0x8064A6D0, 0x8064A708] diff --git a/include/ac_bridge_a.h b/include/ac_bridge_a.h index 77d727ec..cba3f65a 100644 --- a/include/ac_bridge_a.h +++ b/include/ac_bridge_a.h @@ -3,6 +3,7 @@ #include "types.h" #include "m_actor.h" +#include "ac_structure.h" #ifdef __cplusplus extern "C" { @@ -15,4 +16,3 @@ extern ACTOR_PROFILE Bridge_A_Profile; #endif #endif - diff --git a/include/m_name_table.h b/include/m_name_table.h index da58bca7..4d34127c 100644 --- a/include/m_name_table.h +++ b/include/m_name_table.h @@ -2757,6 +2757,7 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define DUMMY_DOUZOU 0xF11D #define DUMMY_NAMEPLATE 0xF11F #define DUMMY_MUSEUM 0xF120 +#define DUMMY_BRIDGE 0xF121 #define DUMMY_FLAG 0xF122 #define DUMMY_COTTAGE_MY 0xF123 #define DUMMY_COTTAGE_NPC 0xF124 diff --git a/src/ac_bridge_a.c b/src/ac_bridge_a.c new file mode 100644 index 00000000..9f2bbc56 --- /dev/null +++ b/src/ac_bridge_a.c @@ -0,0 +1,197 @@ +#include "ac_bridge_a.h" + +#include "m_common_data.h" +#include "m_name_table.h" +#include "m_field_info.h" +#include "m_player_lib.h" +#include "m_rcp.h" +#include "m_debug.h" + +static void aBridgeA_actor_ct(ACTOR* actorx, GAME* game); +static void aBridgeA_actor_dt(ACTOR* actorx, GAME* game); +static void aBridgeA_actor_init(ACTOR* actorx, GAME* game); +static void aBridgeA_actor_move(ACTOR* actorx, GAME* game); +static void aBridgeA_actor_draw(ACTOR* actorx, GAME* game); + +// clang-format off +ACTOR_PROFILE Bridge_A_Profile = { + mAc_PROFILE_BRIDGE_A, + ACTOR_PART_ITEM, + ACTOR_STATE_TA_SET, + BRIDGE_A0, + ACTOR_OBJ_BANK_KEEP, + sizeof(STRUCTURE_ACTOR), + &aBridgeA_actor_ct, + &aBridgeA_actor_dt, + &aBridgeA_actor_init, + &aBridgeA_actor_draw, + NULL, +}; +// clang-format on + +static void aBridgeA_set_BgOffset(ACTOR* actorx) { + // clang-format off + static const mCoBG_OffsetTable_c rewrite_data[] = { + { mCoBG_ATTRIBUTE_31, 4, 4, 4, 4, 4, 0 }, + { mCoBG_ATTRIBUTE_27, 4, 0, 4, 4, 4, 1 }, + { mCoBG_ATTRIBUTE_28, 4, 4, 0, 4, 4, 1 }, + { mCoBG_ATTRIBUTE_29, 4, 4, 4, 0, 4, 1 }, + { mCoBG_ATTRIBUTE_30, 4, 4, 4, 4, 0, 1 }, + { mCoBG_ATTRIBUTE_31, 0, 0, 0, 0, 0, 0 }, + }; + // clang-format on + + static s_xyz unit_offset_a0[] = { + { 0, 0, 0 }, { 0, 1, -1 }, { -1, 1, 0 }, { 1, 3, 0 }, { 0, 3, 1 }, { 1, 5, -1 }, { -1, 5, 1 }, + }; + + static s_xyz unit_offset_a1[] = { + { 0, 0, 0 }, { 0, 4, -1 }, { 1, 4, 0 }, { -1, 2, 0 }, { 0, 2, 1 }, { -1, 5, -1 }, { 1, 5, 1 }, + }; + + f32 dist_to_ground = mCoBG_GetBgY_OnlyCenter_FromWpos2(actorx->world.position, 0.0f); + s_xyz* unit_offset = actorx->npc_id == BRIDGE_A0 ? unit_offset_a0 : unit_offset_a1; + int i; + + for (i = 0; i < 7; i++) { + xyz_t pos = actorx->world.position; + f32 ut_dist_to_ground; + + pos.x += unit_offset[i].x * mFI_UNIT_BASE_SIZE_F; + pos.z += unit_offset[i].z * mFI_UNIT_BASE_SIZE_F; + ut_dist_to_ground = mCoBG_GetBgY_OnlyCenter_FromWpos2(pos, 0.0f); + + /* s_xyz->y is repurposed to be the index into 'rewrite_data' array (could be new struct too) */ + if (unit_offset[i].y == 5 && ut_dist_to_ground == dist_to_ground) { + mCoBG_SetPluss5PointOffset_file(pos, rewrite_data[0], __FILE__, 217); + } else { + mCoBG_SetPluss5PointOffset_file(pos, rewrite_data[unit_offset[i].y], __FILE__, 220); + } + + /* Update all bridge units other than the main item unit */ + if (i != 0) { + mFI_SetFG_common(RSV_NO, pos, FALSE); + } + } +} + +extern cKF_Skeleton_R_c cKF_bs_r_obj_s_bridgeA; +extern cKF_Skeleton_R_c cKF_bs_r_obj_w_bridgeA; + +extern cKF_Animation_R_c cKF_ba_r_obj_s_bridgeA; +extern cKF_Animation_R_c cKF_ba_r_obj_w_bridgeA; + +static void aBridgeA_actor_ct(ACTOR* actorx, GAME* game) { + static cKF_Skeleton_R_c* skl[] = { &cKF_bs_r_obj_s_bridgeA, &cKF_bs_r_obj_w_bridgeA }; + static cKF_Animation_R_c* anm[] = { &cKF_ba_r_obj_s_bridgeA, &cKF_ba_r_obj_w_bridgeA }; + + STRUCTURE_ACTOR* bridge = (STRUCTURE_ACTOR*)actorx; + int idx; + + if (Common_Get(time).season == mTM_SEASON_WINTER) { + idx = 1; + } else { + idx = 0; + } + + bridge->actor_class.world.position.y += 1.5f; + cKF_SkeletonInfo_R_ct(&bridge->keyframe, skl[idx], anm[idx], bridge->work_area, bridge->morph_area); + cKF_SkeletonInfo_R_init_standard_repeat(&bridge->keyframe, anm[idx], NULL); + cKF_SkeletonInfo_R_play(&bridge->keyframe); + + if (actorx->npc_id == BRIDGE_A0) { + actorx->shape_info.rotation.y = DEG2SHORT_ANGLE2(0.0f); + } else { + actorx->shape_info.rotation.y = DEG2SHORT_ANGLE2(-90.0f); + } + + aBridgeA_set_BgOffset(actorx); + bridge->arg1_f = 0.0f; + bridge->arg0_f = 0.0f; + sAdo_RegistPlussBridge(&actorx->world.position); +} + +static void aBridgeA_actor_dt(ACTOR* actorx, GAME* game) { + sAdo_DeletePlussBridge(); +} + +static f32 aBridge_player_check(STRUCTURE_ACTOR* bridge, GAME_PLAY* play) { + PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play); + xyz_t player_pos = player->actor_class.world.position; + xyz_t bridge_pos = bridge->actor_class.world.position; + xyz_t player_dist_from_bridge; + f32 bridge_run_speed = player->actor_class.speed * (0.75f + (f32)GETREG(TAKREG, 23) * 0.01f); + f32 dist0; + f32 dist1; + + xyz_t_sub(&player_pos, &bridge_pos, &player_dist_from_bridge); + if (bridge->actor_class.npc_id == BRIDGE_A1) { + dist0 = player_dist_from_bridge.x - player_dist_from_bridge.z; + dist1 = player_dist_from_bridge.x + player_dist_from_bridge.z; + } else { + dist0 = player_dist_from_bridge.x + player_dist_from_bridge.z; + dist1 = player_dist_from_bridge.x - player_dist_from_bridge.z; + } + + if ((dist0 > -mFI_UNIT_BASE_SIZE_F && dist0 < mFI_UNIT_BASE_SIZE_F) && + (dist1 > -mFI_UNIT_BASE_SIZE_F * 2 && dist1 < mFI_UNIT_BASE_SIZE_F * 2)) { + if (bridge_run_speed > bridge->arg0_f) { + bridge->arg1_f = 1.0f + (f32)GETREG(TAKREG, 20) * 0.01f; + bridge->arg0_f = bridge_run_speed; + } else if (bridge_run_speed > 0.1f) { + add_calc(&bridge->arg0_f, bridge_run_speed, 0.1f + (f32)GETREG(TAKREG, 22) * 0.01f, 0.1f, 0.01f); + add_calc(&bridge->arg1_f, 1.0f, 0.1f + (f32)GETREG(TAKREG, 24) * 0.01f, 0.1f, 0.01f); + return; + } + } + + add_calc(&bridge->arg1_f, 0.0f, (0.08f + (f32)GETREG(TAKREG, 21) * 0.01f) * (0.4f + bridge->arg0_f * 0.1f), 0.1f, + 0.01f); +} + +static void aBridgeA_actor_move(ACTOR* actorx, GAME* game) { + STRUCTURE_ACTOR* bridge = (STRUCTURE_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + + aBridge_player_check(bridge, play); + bridge->keyframe.frame_control.speed = bridge->arg0_f * 0.5f; + cKF_SkeletonInfo_R_play(&bridge->keyframe); + if (bridge->arg1_f == 0.0f) { + bridge->arg1_f = 0.0f; + bridge->arg0_f = 0.0f; + bridge->keyframe.frame_control.current_frame = 0.0f; + } +} + +static void aBridgeA_actor_init(ACTOR* actorx, GAME* game) { + mFI_SetFG_common(DUMMY_BRIDGE, actorx->home.position, FALSE); + aBridgeA_actor_move(actorx, game); + actorx->mv_proc = &aBridgeA_actor_move; +} + +static int aBridgeA_before_disp(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) { + static s16 base_r_table[] = { + DEG2SHORT_ANGLE2(0.0f), DEG2SHORT_ANGLE2(0.0f), DEG2SHORT_ANGLE2(314.703369f), + DEG2SHORT_ANGLE2(90.296631f), DEG2SHORT_ANGLE2(270.302124f), DEG2SHORT_ANGLE2(44.697876f), + }; + + STRUCTURE_ACTOR* bridge = (STRUCTURE_ACTOR*)arg; + f32 rot = bridge->arg1_f; + + if (joint_idx > 1) { + f32 inv = 1.0f - rot; + + joint_rot->z = rot * (f32)joint_rot->z + inv * (f32)base_r_table[joint_idx]; + } + + return TRUE; +} + +static void aBridgeA_actor_draw(ACTOR* actorx, GAME* game) { + STRUCTURE_ACTOR* bridge = (STRUCTURE_ACTOR*)actorx; + Mtx* mtx_p = (Mtx*)GRAPH_ALLOC_TYPE(game->graph, Mtx, bridge->keyframe.skeleton->num_shown_joints); + + _texture_z_light_fog_prim(game->graph); + cKF_Si3_draw_R_SV(game, &bridge->keyframe, mtx_p, &aBridgeA_before_disp, NULL, actorx); +}