Merge pull request #211 from Cuyler36/ac_boat

Implement & link ac_boat
This commit is contained in:
Cuyler36
2024-01-06 23:42:49 -05:00
committed by GitHub
12 changed files with 861 additions and 28 deletions
+4
View File
@@ -588,6 +588,10 @@ ac_ev_majin.c:
.text: [0x80592A40, 0x80593158]
.rodata: [0x80649D98,0x80649DA0]
.data: [0x806C2B50, 0x806C2BD0]
ac_boat.c:
.text: [0x805A6CF4, 0x805A856C]
.rodata: [0x8064A5B0, 0x8064A630]
.data: [0x806C4440, 0x806C4560]
ac_douzou.c:
.text: [0x805AD6D8, 0x805AE704]
.rodata: [0x8064A7C0, 0x8064A7E8]
+23 -1
View File
@@ -3,6 +3,7 @@
#include "types.h"
#include "m_actor.h"
#include "c_keyframe.h"
#ifdef __cplusplus
extern "C" {
@@ -10,9 +11,30 @@ extern "C" {
typedef struct boat_s BOAT_ACTOR;
typedef void (*aBT_PROC)(BOAT_ACTOR*, GAME_PLAY*);
struct boat_s {
ACTOR actor_class;
// TODO
int _174;
cKF_SkeletonInfo_R_c keyframe;
int _1E8;
s_xyz work[15];
s_xyz morph[15];
aBT_PROC action_proc;
int _2A4;
int _2A8;
int _2AC;
int _2B0;
int action;
int roll_cycle;
int roll_timer;
int point;
int direction;
f32 _2C8;
f32 _2CC;
f32 _2D0;
f32 rudder;
int _2D8;
};
extern ACTOR_PROFILE Boat_Profile;
+14 -14
View File
@@ -8,6 +8,7 @@
#include "m_npc_schedule.h"
#include "m_actor_dlftbls.h"
#include "m_npc.h"
#include "c_keyframe.h"
#ifdef __cplusplus
extern "C" {
@@ -137,21 +138,21 @@ typedef struct npc_info_s {
mActor_name_t npc_name;
} NpcActorInfo_c;
typedef struct npc_animation_s {
cKF_SkeletonInfo_R_c keyframe;
s_xyz work[27];
s_xyz morph[27];
int _1B4;
s8 animation_id;
} aNPC_ANIMATION_c;
/* TODO: draw data */
typedef struct npc_draw_info_s {
/* 0x000 */ int _00;
/* 0x004 */ int _04;
/* 0x008 */ u8 _000[0x20 - 8];
/* 0x020 */ f32 _20;
/* 0x024 */ f32 _24;
/* 0x028 */ u8 _028[0x534 - 0x028];
/* 0x538 */ u8 _534;
/* 0x538 */ u8 _535;
/* 0x538 */ u8 _536;
/* 0x538 */ u8 _537;
/* 0x538 */ u8 _538;
/* 0x538 */ u8 _539;
/* 0x540 */ u8 _53A[0x580 - 0x53A];
/* 0x000 */ u8 _000[0x14 - 0];
/* 0x014 */ aNPC_ANIMATION_c main_animation;
/* 0x1D0 */ aNPC_ANIMATION_c sub_animation0;
/* 0x38C */ aNPC_ANIMATION_c sub_animation1;
/* 0x548 */ u8 _548[0x580 - 0x548];
/* 0x580 */ int animation_id;
/* 0x584 */ int texture_bank_idx;
/* 0x588 */ u8 _588[0x5BD - 0x588];
@@ -160,7 +161,6 @@ typedef struct npc_draw_info_s {
/* 0x5BE */ u8 _5BF[0x630 - 0x5BF];
} aNPC_draw_info_c;
typedef void (*aNPC_THINK_PROC)(NPC_ACTOR*, GAME_PLAY*, int);
#define aNPC_THINK_INTERRUPT_FRIENDSHIP (1 << 0)
+2
View File
@@ -260,6 +260,8 @@ extern int mCoBG_ExistHeightGap_KeepAndNow(xyz_t wpos);
extern void mCoBG_GetNorm_By3Point(xyz_t* norm, xyz_t* p0, xyz_t* p1, xyz_t* p2);
extern int mCoBG_SearchWaterLimitDistN(xyz_t* water_pos, xyz_t wpos, s16 angle, float max_dist, int divisor);
extern f32 mCoBG_GetBalloonGroundY(const xyz_t* pos);
extern void mCoBG_MakeBoatCollision(ACTOR* actor, xyz_t* pos, s16* angle_y);
extern void mCoBG_DeleteBoatCollision(ACTOR* actor);
extern void mCoBG_InitMoveBgData();
extern void mCoBG_InitBlockBgCheckMode();
+1 -1
View File
@@ -300,7 +300,7 @@ typedef struct common_data_s {
/* 0x02DBA2 */ s16 island_weather;
/* 0x02DBA4 */ s16 island_weather_intensity;
/* 0x02DBA6 */ s16 _2DBA6;
/* 0x02DBA8 */ u8 _2DBA8;
/* 0x02DBA8 */ u8 memcard_slot;
/* 0X02DBAC */ int famicom_2DBAC;
/* 0x02DBB0 */ s16 can_look_goki_count;
/* 0x02DBB4 */ f32 rainbow_opacity; /* current opacity of rainbow (0.0f - 1.0f) */
+1
View File
@@ -2164,6 +2164,7 @@ extern int mNT_check_unknown(mActor_name_t item_no);
#define DUMMY_TAMA 0xF110
#define DUMMY_DOUZOU 0xF11D
#define DUMMY_NAMEPLATE 0xF11F
#define DUMMY_BOAT 0xF128
#define RSV_DOOR 0xFE1B
#define RSV_FE1C 0xFE1C
+5 -1
View File
@@ -18,7 +18,7 @@ extern void mPlib_request_main_invade_type1(GAME_PLAY* play);
extern mActor_name_t mPlib_Get_itemNo_forWindow();
extern int mPlib_check_able_change_camera_normal_index();
extern void mPlib_request_main_refuse_type1(GAME_PLAY* play);
extern void mPlib_request_main_wait_type3(GAME_PLAY* play);
extern void mPlib_request_main_wait_type3(GAME* game);
extern void mPlib_Set_able_force_speak_label(ACTOR* actor);
extern int mPlib_request_main_demo_walk_type1(GAME* game, f32 goal_x, f32 goal_z, f32 speed, int flag);
extern void mPlib_Set_goal_player_demo_walk(f32 goal_x, f32 goal_z, f32 speed);
@@ -51,6 +51,10 @@ extern int mPlib_Check_tree_shaken_little(const xyz_t* pos);
extern int mPlib_request_main_recieve_wait_type1(GAME* game, mActor_name_t item, int counter_flag);
extern int mPlib_able_player_warp_forEvent();
extern int mPlib_Get_unable_wade();
extern void mPlib_Set_boat_angleZ(s16 angleZ);
extern int mPlib_Get_end_player_demo_walk();
extern int mPlib_request_main_demo_geton_boat_type1(f32 goal_x, f32 goal_z, s16 angleY);
extern int mPlib_request_main_demo_getoff_boat_standup_type1(const xyz_t* pos, s16 angleY);
extern mPlayer_change_data_from_submenu_c* mPlib_Get_change_data_from_submenu_p();
+2 -2
View File
@@ -206,7 +206,7 @@ static void aAp_StartFlyMove(ACTOR* actor, GAME* game) {
airplane->rotZ = 0.0f;
airplane->y_speed = 0.0f;
mPlib_request_main_wait_type3(play);
mPlib_request_main_wait_type3((GAME*)play);
}
}
@@ -349,7 +349,7 @@ static void aAp_ZbuttonChangeStatus(AIRPLANE_ACTOR* actor, GAME* game) {
}
}
else if (actor->status == aAp_STATUS_START_FLY_MOVE) {
mPlib_request_main_wait_type3(play);
mPlib_request_main_wait_type3((GAME*)play);
actor->status = aAp_STATUS_PLAYER_CATCH;
}
}
+222
View File
@@ -0,0 +1,222 @@
#include "ac_boat.h"
#include "ac_boat_demo.h"
#include "m_play.h"
#include "m_common_data.h"
#include "m_rcp.h"
#include "m_player_lib.h"
#include "libultra/libultra.h"
#include "sys_matrix.h"
enum {
aBT_DIRECTION_TO_ISLAND,
aBT_DIRECTION_FROM_ISLAND,
aBT_DIRECTION_NUM
};
enum {
aBT_ACTION_DEMO_CTRL_BIRTH_WAIT,
aBT_ACTION_WAIT,
aBT_ACTION_PL_RIDE_MOVE_START_WAIT,
aBT_ACTION_PL_RIDE_MOVE_END_WAIT,
aBT_ACTION_PL_RIDE_ON_START_WAIT,
aBT_ACTION_PL_RIDE_ON_END_WAIT,
aBT_ACTION_SITDOWN_END_WAIT,
aBT_ACTION_MOVE_WAIT,
aBT_ACTION_MOVE,
aBT_ACTION_MOMENT,
aBT_ACTION_DRAW_UP,
aBT_ACTION_ARRIVE_CALL_END_WAIT,
aBT_ACTION_PL_RIDE_OFF_START_WAIT,
aBT_ACTION_PL_RIDE_OFF_END_WAIT,
aBT_ACTION_ANCHOR,
aBT_ACTION_NUM
};
static void aBT_actor_ct(ACTOR*, GAME*);
static void aBT_actor_dt(ACTOR*, GAME*);
static void aBT_actor_init(ACTOR*, GAME*);
static void aBT_actor_draw(ACTOR*, GAME*);
ACTOR_PROFILE Boat_Profile = {
mAc_PROFILE_BOAT,
ACTOR_PART_ITEM,
ACTOR_STATE_CAN_MOVE_IN_DEMO_SCENES | ACTOR_STATE_TA_SET | ACTOR_STATE_NO_MOVE_WHILE_CULLED,
BOAT,
ACTOR_OBJ_BANK_KEEP,
sizeof(BOAT_ACTOR),
&aBT_actor_ct,
&aBT_actor_dt,
&aBT_actor_init,
&aBT_actor_draw,
NULL
};
static xyz_t aBT_chk_point[] = {
// Position Z-X X Z
{ 3420.0f, 0.0f, 4260.0f }, // F-5 unit 5.5 - 10.5
{ 3380.0f, 0.0f, 4300.0f }, // F-5 unit 4.5 - 11.5
{ 3340.0f, 0.0f, 4380.0f }, // F-5 unit 3.5 - 13.5
{ 3340.0f, 0.0f, 4620.0f }, // G-5 unit 3.5 - 3.5
{ 3740.0f, 0.0f, 4980.0f }, // G-5 unit 13.5 - 12.5
{ 3740.0f, 0.0f, 5220.0f }, // H-5 unit 13.5 - 2.5
{ 3700.0f, 0.0f, 5300.0f }, // H-5 unit 12.5 - 4.5
{ 3660.0f, 0.0f, 5340.0f } // H-5 unit 11.5 - 5.5
};
static int aBT_last_point_idx[aBT_DIRECTION_NUM] = { 7, 0 };
s16 aBT_init_angleY[aBT_DIRECTION_NUM] = {
DEG2SHORT_ANGLE(-45.0f), // 0xE000
DEG2SHORT_ANGLE(135.0f) // 0x6000
};
static void aBT_setupAction(BOAT_ACTOR* boat_actor, GAME_PLAY* play, int action);
static int aBT_check_other_boat(ACTOR* actorx, GAME* game);
extern cKF_Skeleton_R_c cKF_bs_r_obj_e_boat;
extern cKF_Animation_R_c cKF_ba_r_obj_e_boat;
static void aBT_actor_ct(ACTOR* actorx, GAME* game) {
BOAT_ACTOR* boat_actor = (BOAT_ACTOR*)actorx;
if (aBT_check_other_boat(actorx, game) == TRUE) {
GAME_PLAY* play = (GAME_PLAY*)game;
cKF_SkeletonInfo_R_c* keyframe = &boat_actor->keyframe;
int direction = aBT_DIRECTION_TO_ISLAND;
if (actorx->block_z != 6) {
direction = aBT_DIRECTION_FROM_ISLAND;
}
#line 326
actorx->world.position.y = 1.0f + mCoBG_GetWaterHeight(actorx->world.position);
actorx->shape_info.rotation.y = aBT_init_angleY[direction];
actorx->world.angle.y = aBT_init_angleY[direction];
xyz_t_move(&actorx->home.position, &actorx->world.position);
/* Load & play boat rocking animation */
cKF_SkeletonInfo_R_ct(keyframe, &cKF_bs_r_obj_e_boat, NULL, boat_actor->work, boat_actor->morph);
cKF_SkeletonInfo_R_init(keyframe, keyframe->skeleton, &cKF_ba_r_obj_e_boat, 1.0f, 81.0f, 1.0f, 0.0f, 0.0f, cKF_FRAMECONTROL_REPEAT, NULL);
cKF_SkeletonInfo_R_play(keyframe);
actorx->gravity = 0.003f;
actorx->max_velocity_y = 0.1f;
actorx->position_speed.y = 0.1f;
boat_actor->roll_timer = 200;
boat_actor->direction = direction;
aBT_setupAction(boat_actor, play, aBT_ACTION_DEMO_CTRL_BIRTH_WAIT);
mCoBG_MakeBoatCollision(actorx, &actorx->world.position, &actorx->shape_info.rotation.y);
}
else {
Actor_delete(actorx); // another boat already exists
}
}
static void aBT_actor_dt(ACTOR* actorx, GAME* game) {
BOAT_ACTOR* boat_actor = (BOAT_ACTOR*)actorx;
GAME_PLAY* play = (GAME_PLAY*)game;
cKF_SkeletonInfo_R_c* keyframe = &boat_actor->keyframe;
BOAT_DEMO_ACTOR* boat_demo;
cKF_SkeletonInfo_R_dt(keyframe);
mFI_SetFG_common(BOAT, actorx->home.position, FALSE);
boat_demo = (BOAT_DEMO_ACTOR*)actorx->parent_actor;
if (boat_demo != NULL && boat_demo->boat_actor == boat_actor) {
boat_demo->boat_actor = NULL;
}
mCoBG_DeleteBoatCollision(actorx);
}
#include "../src/ac_boat_move.c_inc"
static u32 aBT_calc_furrow_alpha(BOAT_ACTOR* boat_actor) {
f32 speed = boat_actor->actor_class.speed;
if (speed > 0.625f) {
speed = 0.625f;
}
return (u32)((speed / 0.625f) * 150.0f);
}
static int aBT_actor_draw_before(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) {
BOAT_ACTOR* boat_actor = (BOAT_ACTOR*)arg;
switch (joint_idx) {
case 3:
{
Matrix_translate(boat_actor->actor_class.world.position.x, boat_actor->actor_class.world.position.y, boat_actor->actor_class.world.position.z, 0);
Matrix_RotateY(boat_actor->actor_class.shape_info.rotation.y, 1);
Matrix_scale(boat_actor->actor_class.scale.x, boat_actor->actor_class.scale.y, boat_actor->actor_class.scale.z, 1);
break;
}
case 5:
{
joint_rot->x = 0;
joint_rot->y = 0;
joint_rot->z = boat_actor->_2CC; // boat furrow joint?
break;
}
case 6:
{
joint_rot->x = 0;
joint_rot->y = 0;
joint_rot->z = boat_actor->_2D0; // boat furrow joint?
break;
}
}
return TRUE;
}
static void aBT_actor_draw(ACTOR* actorx, GAME* game) {
BOAT_ACTOR* boat_actor = (BOAT_ACTOR*)actorx;
cKF_SkeletonInfo_R_c* keyframe = &boat_actor->keyframe;
GRAPH* graph = game->graph;
Gfx* scroll_gfx;
f32 _2C8 = boat_actor->_2C8 - actorx->speed * 0.5f;
while (_2C8 < -32.0f) {
_2C8 += 32.0f;
}
boat_actor->_2C8 = _2C8;
scroll_gfx = two_tex_scroll_dolphin(graph, 0, 0, 0, 32, 32, 1, 0, _2C8 * 8.0f, 32, 32);
if (scroll_gfx != NULL) {
Mtx* mtx = GRAPH_ALLOC_TYPE(graph, Mtx, keyframe->skeleton->num_shown_joints);
if (mtx != NULL) {
Gfx* gfx;
u16* pal = Common_Get(clip).structure_clip->get_pal_segment_proc(aSTR_PAL_BOAT);
_texture_z_light_fog_prim(graph);
_texture_z_light_fog_prim_xlu(graph);
OPEN_DISP(graph);
gfx = NOW_POLY_OPA_DISP;
gDPPipeSync(gfx++);
gDPLoadTLUT_Dolphin(gfx++, 15, 16, 1, pal);
SET_POLY_OPA_DISP(gfx);
gfx = NOW_POLY_XLU_DISP;
gDPPipeSync(gfx++);
gSPSegment(gfx++, G_MWO_SEGMENT_9, scroll_gfx);
gDPLoadTLUT_Dolphin(gfx++, 15, 16, 1, pal);
gDPSetEnvColor(gfx++, 155, 155, 255, aBT_calc_furrow_alpha(boat_actor));
SET_POLY_XLU_DISP(gfx);
CLOSE_DISP(graph);
cKF_Si3_draw_R_SV(game, keyframe, mtx, &aBT_actor_draw_before, NULL, actorx);
}
}
}
+580
View File
@@ -0,0 +1,580 @@
static void aBT_passenger_ctrl(BOAT_ACTOR* boat_actor) {
if (boat_actor->actor_class.child_actor != NULL) {
xyz_t passenger_pos;
s_xyz passenger_angle;
BOAT_DEMO_ACTOR* boat_demo = (BOAT_DEMO_ACTOR*)boat_actor->actor_class.parent_actor;
xyz_t_add(&boat_actor->actor_class.world.position, &boat_demo->passenger_ofs, &passenger_pos);
passenger_angle.y = boat_actor->actor_class.shape_info.rotation.y - DEG2SHORT_ANGLE(-180.0f);
(*GET_PLAYER_ACTOR_NOW()->Set_force_position_angle_proc)(
gamePT,
&passenger_pos, &passenger_angle,
mPlayer_FORCE_POSITION_ANGLE_POSX | mPlayer_FORCE_POSITION_ANGLE_POSY | mPlayer_FORCE_POSITION_ANGLE_POSZ |
mPlayer_FORCE_POSITION_ANGLE_ROTY
);
mPlib_Set_boat_angleZ(boat_actor->actor_class.shape_info.rotation.z);
}
}
static int aBT_check_other_boat(ACTOR* actorx, GAME* game) {
GAME_PLAY* play = (GAME_PLAY*)game;
ACTOR* actor = play->actor_info.list[ACTOR_PART_ITEM].actor;
int res = TRUE;
while (TRUE) {
ACTOR* other_actor = Actor_info_fgName_search_sub(actor, BOAT);
if (other_actor == NULL) {
break;
}
else if (other_actor != actorx) {
res = FALSE;
break;
}
actor = other_actor->next_actor;
}
return res;
}
static void aBT_anime_proc(BOAT_ACTOR* boat_actor) {
if (boat_actor->action == aBT_ACTION_MOVE) {
NPC_SENDO_ACTOR* sendo_actor = ((BOAT_DEMO_ACTOR*)boat_actor->actor_class.parent_actor)->npc_sendo_actor;
/* Attempt to sync boat animation with Kapp'n's animation */
if (sendo_actor != NULL && sendo_actor->npc_class.draw.animation_id == 123) {
cKF_SkeletonInfo_R_c* keyframe = &sendo_actor->npc_class.draw.main_animation.keyframe;
boat_actor->keyframe.frame_control.current_frame = keyframe->frame_control.current_frame;
if (
cKF_FrameControl_passCheck_now(&keyframe->frame_control, 35.0f) == TRUE ||
cKF_FrameControl_passCheck_now(&keyframe->frame_control, 52.0f) == TRUE
) {
boat_actor->roll_timer = 400;
}
}
cKF_SkeletonInfo_R_play(&boat_actor->keyframe);
}
}
static void aBT_roll_ctrl(BOAT_ACTOR* boat_actor) {
int timer = boat_actor->roll_timer;
int timer_sub = timer - 200;
int roll_cycle;
if (ABS(timer_sub) < 2) {
timer = 200;
}
else if (timer_sub < 0) {
timer += 2;
}
else {
timer -= 2;
}
boat_actor->roll_timer = timer;
roll_cycle = boat_actor->roll_cycle;
roll_cycle += timer;
boat_actor->roll_cycle = roll_cycle;
boat_actor->actor_class.shape_info.rotation.z = sin_s(roll_cycle) * 1024.0f; // [-5.625f, 5.625f] degree rocking arc
}
static int aBT_check_alive(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
int bx;
int bz;
int alive = FALSE;
if (
mFI_Wpos2BlockNum(&bx, &bz, boat_actor->actor_class.world.position) == TRUE &&
play->block_table.block_x == bx && play->block_table.block_z == bz
) {
alive = TRUE;
}
return alive;
}
static void aBT_up_down_proc(BOAT_ACTOR* boat_actor) {
if (boat_actor->actor_class.world.position.y < boat_actor->actor_class.home.position.y) {
if (boat_actor->actor_class.max_velocity_y < 0.0f) {
boat_actor->actor_class.gravity = 0.003f + RANDOM_F(0.002f);
}
boat_actor->actor_class.max_velocity_y = 0.1f;
}
else {
if (boat_actor->actor_class.max_velocity_y > 0.0f) {
boat_actor->actor_class.gravity = 0.003f + RANDOM_F(0.002f);
}
boat_actor->actor_class.max_velocity_y = -0.1f;
}
}
static void aBT_position_move(BOAT_ACTOR* boat_actor) {
aBT_up_down_proc(boat_actor);
Actor_position_moveF((ACTOR*)boat_actor);
if ((boat_actor->actor_class.world.position.y - boat_actor->actor_class.home.position.y) - -1.6f < 0.0f) {
boat_actor->actor_class.world.position.y = boat_actor->actor_class.home.position.y + -1.6f;
}
}
static void aBT_calc_wave_angl(BOAT_ACTOR* boat_actor, s16 angle) {
f32 var_f1_2;
f32 var_f2_2;
s16 var_r30;
s16 var_r4;
s16 var_r5;
s16 _2CC_diff = boat_actor->_2CC;
s16 _2D0_diff = boat_actor->_2D0;
s16 half_rudder = ABS(boat_actor->rudder) * 0.5f;
_2CC_diff -= angle;
_2D0_diff -= angle;
if (ABS((int)_2CC_diff) >= 0x300) {
var_f2_2 = (f32)ABS(_2CC_diff);
if (var_f2_2 > 1536.0f) {
var_f2_2 = 1536.0f;
}
if (half_rudder > 40) {
var_r4 = half_rudder;
}
else {
var_r4 = 40;
}
var_r5 = ((int)((f32)(var_r4 - 30) * ((var_f2_2 - 768.0f) / 768.0f)) + 30);
}
else {
var_r5 = 30;
}
if (ABS(_2D0_diff) >= 0x600) {
var_f1_2 = (f32)ABS(_2D0_diff);
if (var_f1_2 > 2304.0f) {
var_f1_2 = 2304.0f;
}
if (half_rudder > 30) {
var_r4 = half_rudder;
}
else {
var_r4 = 30;
}
var_r30 = ((int)((f32)(var_r4 - 20) * ((var_f1_2 - 1536.0f) / 768.0f)) + 20);
}
else {
var_r30 = 20;
}
chase_angle(&_2CC_diff, 0, var_r5);
chase_angle(&_2D0_diff, 0, var_r30);
boat_actor->_2CC = _2CC_diff;
boat_actor->_2D0 = _2D0_diff;
}
static void aBT_ctrl_rudder(BOAT_ACTOR* boat_actor, s16 p0, s16 p1, s16 p2) {
s16 rudder = boat_actor->rudder;
s16 step;
if (rudder * p2 >= 0) {
if (p1 > 256) {
step = ((p1 - 256) * 14) / 768 + 2;
if (step > 16) {
step = 16;
}
}
else {
step = 2;
}
}
else {
step = 16;
}
step /= 2.0f;
if (p0 == 0) {
rudder = 0;
}
else if (p0 < 0) {
rudder -= step;
if (rudder < -38) {
rudder = -38;
}
}
else {
rudder += step;
if (rudder > 38) {
rudder = 38;
}
}
boat_actor->rudder = rudder;
}
static void aBT_ctrl_direction(BOAT_ACTOR* boat_actor) {
int point = boat_actor->point;
s16 anglY = boat_actor->actor_class.shape_info.rotation.y;
xyz_t* chk_point = &aBT_chk_point[point];
f32 dZ = chk_point->z - boat_actor->actor_class.world.position.z;
f32 dX = chk_point->x - boat_actor->actor_class.world.position.x;
s16 p2 = atans_table(dZ, dX);
s16 p0 = p2 - boat_actor->actor_class.world.angle.y; // diff to target rotation
s16 p1 = ABS(p0);
f32 rudder;
aBT_ctrl_rudder(boat_actor, p0, p1, p2);
rudder = boat_actor->rudder * 0.5f;
if ((f32)p0 * rudder <= 0.0f && (f32)p1 < ABS(rudder)) {
boat_actor->actor_class.world.angle.y = p2;
}
else {
boat_actor->actor_class.world.angle.y += rudder;
}
boat_actor->actor_class.shape_info.rotation.y = boat_actor->actor_class.world.angle.y;
aBT_calc_wave_angl(boat_actor, boat_actor->actor_class.shape_info.rotation.y - anglY);
if (boat_actor->direction == aBT_DIRECTION_TO_ISLAND) {
if (dZ < 0.0f) {
boat_actor->point = point + 1;
}
}
else {
if (dZ > 0.0f) {
boat_actor->point = point - 1;
}
}
}
static void aBT_calc_speed(BOAT_ACTOR* boat_actor) {
f32 target;
f32 step;
if (boat_actor->point == aBT_last_point_idx[boat_actor->direction]) {
target = 0.0f;
step = 0.0017f;
}
else {
target = 0.625f;
step = 0.01f;
}
chase_f(&boat_actor->actor_class.speed, target, step);
}
static void aBT_demo_ctrl_birth_wait(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
ACTOR* boat_demo = Actor_info_make_actor(&play->actor_info, (GAME*)play, mAc_PROFILE_BOAT_DEMO, 0.0f, 0.0f, 0.0f, 0, 0, 0, -1, -1, -1, EMPTY_NO, -1, -1, -1);
if (boat_demo != NULL) {
aBT_setupAction(boat_actor, play, aBT_ACTION_WAIT);
}
}
static void aBT_wait(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
if (aBT_check_alive(boat_actor, play) == FALSE) {
boat_actor->action = -1;
}
else {
BOAT_DEMO_ACTOR* boat_demo = (BOAT_DEMO_ACTOR*)boat_actor->actor_class.parent_actor;
if (boat_demo != NULL && boat_demo->action == aBTD_ACTION_PL_RIDE_ON_END_WAIT) {
aBT_setupAction(boat_actor, play, aBT_ACTION_PL_RIDE_MOVE_START_WAIT);
}
}
}
static void aBT_pl_ride_move_start_wait(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
GAME* game = (GAME*)play;
if (mPlib_get_player_actor_main_index(game) == mPlayer_INDEX_DEMO_WALK) {
aBT_setupAction(boat_actor, play, aBT_ACTION_PL_RIDE_MOVE_END_WAIT);
}
else {
s16 dir = boat_actor->actor_class.shape_info.rotation.y + DEG2SHORT_ANGLE(90.0f);
f32 x = cos_s(dir);
f32 z = sin_s(dir);
mPlib_request_main_demo_walk_type1(
game,
boat_actor->actor_class.world.position.x + x * 56.0f, boat_actor->actor_class.world.position.z + z * 56.0f,
1.0f,
0
);
}
}
static void aBT_pl_ride_move_end_wait(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
if (mPlib_Get_end_player_demo_walk()) {
aBT_setupAction(boat_actor, play, aBT_ACTION_PL_RIDE_ON_START_WAIT);
}
}
static void aBT_pl_ride_on_start_wait(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
if (mPlib_get_player_actor_main_index((GAME*)play) == mPlayer_INDEX_DEMO_GETON_BOAT) {
aBT_setupAction(boat_actor, play, aBT_ACTION_PL_RIDE_ON_END_WAIT);
}
else {
s16 dir = boat_actor->actor_class.shape_info.rotation.y + DEG2SHORT_ANGLE(90.0f);
f32 x = cos_s(dir);
f32 z = sin_s(dir);
mPlib_request_main_demo_geton_boat_type1(
boat_actor->actor_class.world.position.x + x * 56.0f, boat_actor->actor_class.world.position.z + z * 56.0f,
boat_actor->actor_class.shape_info.rotation.y + DEG2SHORT_ANGLE(-90.0f)
);
}
}
static void aBT_pl_ride_on_end_wait(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
if (mPlib_get_player_actor_main_index((GAME*)play) == mPlayer_INDEX_DEMO_GETON_BOAT_SITDOWN) {
aBT_setupAction(boat_actor, play, aBT_ACTION_SITDOWN_END_WAIT);
}
}
static void aBT_sitdown_end_wait(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
if (mPlib_get_player_actor_main_index((GAME*)play) == mPlayer_INDEX_DEMO_GETON_BOAT_WAIT) {
aBT_setupAction(boat_actor, play, aBT_ACTION_MOVE_WAIT);
}
}
static void aBT_move_wait(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
BOAT_DEMO_ACTOR* boat_demo = (BOAT_DEMO_ACTOR*)boat_actor->actor_class.parent_actor;
if (boat_demo != NULL && boat_demo->action == aBTD_ACTION_SONG_BGM_START_WAIT) {
aBT_setupAction(boat_actor, play, aBT_ACTION_MOVE);
}
}
static void aBT_move(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
aBT_ctrl_direction(boat_actor);
if (boat_actor->direction == aBT_DIRECTION_TO_ISLAND) {
if (boat_actor->point >= 8) {
aBT_setupAction(boat_actor, play, aBT_ACTION_DRAW_UP);
}
else {
if (boat_actor->action == aBT_ACTION_MOVE && boat_actor->point == 7) {
aBT_setupAction(boat_actor, play, aBT_ACTION_MOMENT);
}
aBT_calc_speed(boat_actor);
}
}
else if (boat_actor->point <= -1) {
aBT_setupAction(boat_actor, play, aBT_ACTION_DRAW_UP);
}
else {
if (boat_actor->action == aBT_ACTION_MOVE && boat_actor->point == 0) {
aBT_setupAction(boat_actor, play, aBT_ACTION_MOMENT);
}
aBT_calc_speed(boat_actor);
}
}
static void aBT_draw_up(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
int last_point_idx = aBT_last_point_idx[boat_actor->direction];
xyz_t* last_chk_point = &aBT_chk_point[last_point_idx];
s16 anglY = boat_actor->actor_class.shape_info.rotation.y;
int drawn_up_point = 0;
chase_f(&boat_actor->rudder, 16.0f, 0.5f);
/* Wait for proper rotation */
if (chase_angle(&boat_actor->actor_class.shape_info.rotation.y, aBT_init_angleY[boat_actor->direction], boat_actor->rudder) == TRUE) {
drawn_up_point++;
}
boat_actor->actor_class.world.angle.y = boat_actor->actor_class.shape_info.rotation.y;
aBT_calc_wave_angl(boat_actor, boat_actor->actor_class.shape_info.rotation.y - anglY);
/* Wait for proper X coordinate */
if (chase_f(&boat_actor->actor_class.world.position.x, last_chk_point->x, 0.05f) == TRUE) {
drawn_up_point++;
}
/* Wait for proper Z coordinate */
if (chase_f(&boat_actor->actor_class.world.position.z, last_chk_point->z, 0.05f) == TRUE) {
drawn_up_point++;
}
/* Ensure all three criteria are met */
if (drawn_up_point == 3) {
aBT_setupAction(boat_actor, play, aBT_ACTION_ARRIVE_CALL_END_WAIT);
}
}
static void aBT_arrive_call_end_wait(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
BOAT_DEMO_ACTOR* boat_demo = (BOAT_DEMO_ACTOR*)boat_actor->actor_class.parent_actor;
if (boat_demo->action == aBTD_ACTION_PL_RIDE_OFF_END_WAIT) {
aBT_setupAction(boat_actor, play, aBT_ACTION_PL_RIDE_OFF_START_WAIT);
}
}
static void aBT_pl_ride_off_start_wait(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
if (mPlib_get_player_actor_main_index((GAME*)play) == mPlayer_INDEX_DEMO_GETOFF_BOAT_STANDUP) {
aBT_setupAction(boat_actor, play, aBT_ACTION_PL_RIDE_OFF_END_WAIT);
}
else {
xyz_t pos;
PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play);
s16 dir = boat_actor->actor_class.shape_info.rotation.y + DEG2SHORT_ANGLE(-90.0f);
f32 z = cos_s(dir);
f32 x = sin_s(dir);
pos.x = player->actor_class.world.position.x + x * 47.0f;
pos.y = 40.0f;
pos.z = player->actor_class.world.position.z + z * 47.0f;
mPlib_request_main_demo_getoff_boat_standup_type1(&pos, boat_actor->actor_class.shape_info.rotation.y + DEG2SHORT_ANGLE(-90.0f));
}
}
static void aBT_pl_ride_off_end_wait(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
if (mPlib_get_player_actor_main_index((GAME*)play) == mPlayer_INDEX_DEMO_WAIT) {
aBT_setupAction(boat_actor, play, aBT_ACTION_ANCHOR);
}
}
static void aBT_anchor(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
if (aBT_check_alive(boat_actor, play) == FALSE) {
boat_actor->action = -1;
}
}
typedef void (*aBT_INIT_PROC)(BOAT_ACTOR*, GAME_PLAY*);
static void aBT_wait_init(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
boat_actor->actor_class.speed = 0.0f;
}
static void aBT_sitdown_end_wait_init(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play);
BOAT_DEMO_ACTOR* boat_demo = (BOAT_DEMO_ACTOR*)boat_actor->actor_class.parent_actor;
boat_actor->actor_class.child_actor = (ACTOR*)player;
xyz_t_sub(&player->actor_class.world.position, &boat_actor->actor_class.world.position, &boat_demo->passenger_ofs);
boat_actor->roll_timer += 800;
boat_actor->actor_class.position_speed.y = -0.2f;
}
static void aBT_move_wait_init(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
BOAT_DEMO_ACTOR* boat_demo = (BOAT_DEMO_ACTOR*)boat_actor->actor_class.parent_actor;
boat_demo->demo_act = aBTD_DEMO_START_CALL_END;
}
static void aBT_move_init(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
static int chk_point_idx[aBT_DIRECTION_NUM] = { 1, 6 };
boat_actor->point = chk_point_idx[boat_actor->direction];
}
static void aBT_moment_init(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
BOAT_DEMO_ACTOR* boat_demo = (BOAT_DEMO_ACTOR*)boat_actor->actor_class.parent_actor;
boat_demo->demo_act = aBTD_DEMO_TOUCH_WHARF_END;
}
static void aBT_draw_up_init(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
boat_actor->actor_class.speed = 0.0f;
}
static void aBT_arrive_call_end_wait_init(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
BOAT_DEMO_ACTOR* boat_demo = (BOAT_DEMO_ACTOR*)boat_actor->actor_class.parent_actor;
boat_demo->demo_act = aBTD_DEMO_PL_RIDE_OFF_START;
}
static void aBT_pl_ride_off_start_wait_init(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
boat_actor->actor_class.child_actor = NULL;
}
static void aBT_pl_ride_off_end_wait_init(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
boat_actor->roll_timer += 800;
}
static void aBT_anchor_init(BOAT_ACTOR* boat_actor, GAME_PLAY* play) {
BOAT_DEMO_ACTOR* boat_demo = (BOAT_DEMO_ACTOR*)boat_actor->actor_class.parent_actor;
boat_demo->demo_act = aBTD_DEMO_ANCHOR;
mPlib_request_main_wait_type3((GAME*)play);
}
static void aBT_setupAction(BOAT_ACTOR* boat_actor, GAME_PLAY* play, int action) {
static aBT_INIT_PROC init_proc[aBT_ACTION_NUM] = {
(aBT_INIT_PROC)&none_proc1,
&aBT_wait_init,
(aBT_INIT_PROC)&none_proc1,
(aBT_INIT_PROC)&none_proc1,
(aBT_INIT_PROC)&none_proc1,
(aBT_INIT_PROC)&none_proc1,
&aBT_sitdown_end_wait_init,
&aBT_move_wait_init,
&aBT_move_init,
&aBT_moment_init,
&aBT_draw_up_init,
&aBT_arrive_call_end_wait_init,
&aBT_pl_ride_off_start_wait_init,
&aBT_pl_ride_off_end_wait_init,
&aBT_anchor_init
};
static aBT_PROC process[aBT_ACTION_NUM] = {
&aBT_demo_ctrl_birth_wait,
&aBT_wait,
&aBT_pl_ride_move_start_wait,
&aBT_pl_ride_move_end_wait,
&aBT_pl_ride_on_start_wait,
&aBT_pl_ride_on_end_wait,
&aBT_sitdown_end_wait,
&aBT_move_wait,
&aBT_move,
&aBT_move,
&aBT_draw_up,
&aBT_arrive_call_end_wait,
&aBT_pl_ride_off_start_wait,
&aBT_pl_ride_off_end_wait,
&aBT_anchor
};
boat_actor->action = action;
boat_actor->action_proc = process[action];
(*init_proc[action])(boat_actor, play);
}
static void aBT_actor_move(ACTOR* actorx, GAME* game) {
BOAT_ACTOR* boat_actor = (BOAT_ACTOR*)actorx;
GAME_PLAY* play = (GAME_PLAY*)game;
aBT_anime_proc(boat_actor);
aBT_position_move(boat_actor);
aBT_roll_ctrl(boat_actor);
(*boat_actor->action_proc)(boat_actor, play);
aBT_passenger_ctrl(boat_actor);
if (boat_actor->action == -1) {
Actor_delete(actorx);
}
}
static void aBT_actor_init(ACTOR* actorx, GAME* game) {
mFI_SetFG_common(DUMMY_BOAT, actorx->home.position, FALSE);
aBT_actor_move(actorx, game);
actorx->mv_proc = &aBT_actor_move;
}
+2 -2
View File
@@ -113,11 +113,11 @@ void aNRTC_actor_move(ACTOR* actor, GAME* game){
if(info.unk0 != 4){
val = 0.0f;
arm_flag = FALSE;
rtc->npc_class.draw._24 = 1.0f + (64.0f * (f32)info.unk8);
rtc->npc_class.draw.main_animation.keyframe.frame_control.current_frame = 1.0f + (64.0f * (f32)info.unk8);
}
}
rtc->npc_class.draw._20 = val;
rtc->npc_class.draw.main_animation.keyframe.frame_control.speed = val;
sAdos_TTKK_ARM(arm_flag);
Common_Get(clip.npc_clip)->move_proc(actor,game);
mSC_change_player_freeze(play);
+5 -7
View File
@@ -1,10 +1,8 @@
void aNRTC_set_slot_name(NPC_ACTOR* actor, int str_no) {
NPCRTC_ACTOR* rtc = (NPCRTC_ACTOR*)actor;
u8 name[16];
mString_Load_StringFromRom(name, sizeof(name), &rtc->npc_class.draw._539);
void aNRTC_set_slot_name(int slot_id, int str_no) {
u8 name[mIN_ITEM_NAME_LEN];
mString_Load_StringFromRom(name, sizeof(name), 0x6CD + slot_id);
mMsg_Set_free_str(mMsg_Get_base_window_p(),str_no, name, sizeof(name));
}
@@ -145,7 +143,7 @@ void aNRTC_format(NPCRTC_ACTOR* rtc, GAME_PLAY* play) {
mMsg_Set_LockContinue(window);
break;
case 2:
card_ret = mCD_card_format_bg(Common_Get(_2DBA8));
card_ret = mCD_card_format_bg(Common_Get(memcard_slot));
switch (card_ret) {
case 1:
mMsg_Set_continue_msg_num(window, 0x9E9);
@@ -273,7 +271,7 @@ int aNRTC_talk_init(ACTOR* actor, GAME* game) {
NPCRTC_ACTOR* rtc = (NPCRTC_ACTOR*)actor;
mDemo_Set_ListenAble();
aNRTC_set_slot_name((NPC_ACTOR*)Common_Get(_2DBA8), 4);
aNRTC_set_slot_name(Common_Get(memcard_slot), mMsg_FREE_STR4);
switch (Common_Get(save_error_type)) {
case 0:
aNRTC_change_talk_proc(rtc, 2);