Merge pull request #400 from Cuyler36:ac_bridge_a

Implement & link ac_bridge_a
This commit is contained in:
Cuyler36
2024-08-14 22:18:00 -04:00
committed by GitHub
4 changed files with 203 additions and 1 deletions
+4
View File
@@ -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]
+1 -1
View File
@@ -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
+1
View File
@@ -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
+197
View File
@@ -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);
}