mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-23 06:34:18 -04:00
Merge pull request #400 from Cuyler36:ac_bridge_a
Implement & link ac_bridge_a
This commit is contained in:
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user