#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); }