mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-06-01 09:17:16 -04:00
241 lines
7.2 KiB
C
241 lines
7.2 KiB
C
#include "ac_train1.h"
|
|
#include "ac_train0.h"
|
|
|
|
#include "graph.h"
|
|
#include "m_name_table.h"
|
|
#include "m_rcp.h"
|
|
#include "m_player.h"
|
|
#include "m_player_lib.h"
|
|
#include "sys_math3d.h"
|
|
#include "m_common_data.h"
|
|
#include "m_field_info.h"
|
|
#include "m_event.h"
|
|
|
|
|
|
static void aTR1_actor_ct(ACTOR* actor, GAME* game);
|
|
static void aTR1_actor_dt(ACTOR* actor, GAME* game);
|
|
static void aTR1_actor_move(ACTOR* actor, GAME* game);
|
|
static void aTR1_actor_draw(ACTOR* actor, GAME* game);
|
|
|
|
ACTOR_PROFILE Train1_Profile = {
|
|
mAc_PROFILE_TRAIN1,
|
|
ACTOR_PART_ITEM,
|
|
ACTOR_STATE_CAN_MOVE_IN_DEMO_SCENES | 1 << 11 | ACTOR_STATE_NO_MOVE_WHILE_CULLED, //figure out flag 0x800
|
|
TRAIN1,
|
|
ACTOR_OBJ_BANK_3,
|
|
sizeof(TRAIN1_ACTOR),
|
|
&aTR1_actor_ct,
|
|
&aTR1_actor_dt,
|
|
&aTR1_actor_move,
|
|
&aTR1_actor_draw,
|
|
NULL
|
|
};
|
|
|
|
extern cKF_Skeleton_R_c cKF_bs_r_obj_train1_3;
|
|
extern cKF_Animation_R_c cKF_ba_r_obj_train1_3_open;
|
|
extern cKF_Animation_R_c cKF_ba_r_obj_train1_3_close;
|
|
|
|
|
|
static void aTR1_setupAction(ACTOR*, int);
|
|
|
|
static void aTR1_actor_ct(ACTOR* actor, GAME* game){
|
|
TRAIN1_ACTOR* train1 = (TRAIN1_ACTOR*)actor;
|
|
|
|
cKF_SkeletonInfo_R_ct(&train1->keyframe, &cKF_bs_r_obj_train1_3, NULL, train1->work, train1->morph);
|
|
aTR1_setupAction((ACTOR*)train1, 5);
|
|
train1->anim_state = cKF_SkeletonInfo_R_play(&train1->keyframe);
|
|
actor->world.angle.y = 0x4000;
|
|
train1->tr_speed = 1.0f;
|
|
}
|
|
|
|
|
|
static void aTR1_actor_dt(ACTOR* actor, GAME* game){
|
|
TRAIN1_ACTOR* train1 = (TRAIN1_ACTOR*)actor;
|
|
|
|
xyz_t tr_home_pos;
|
|
|
|
tr_home_pos = train1->actor_class.home.position;
|
|
|
|
mFI_SetFG_common(EMPTY_NO, tr_home_pos, FALSE);
|
|
cKF_SkeletonInfo_R_dt(&train1->keyframe);
|
|
}
|
|
|
|
static void aTR1_OngenTrgStart(ACTOR* actor, u16 id){
|
|
TRAIN1_ACTOR* train1 = (TRAIN1_ACTOR*)actor;
|
|
|
|
sAdo_OngenTrgStart(id, &train1->actor_class.world.position);
|
|
}
|
|
|
|
static f32 calc_speed1(ACTOR* actor0, ACTOR* actor1) {
|
|
TRAIN0_ACTOR* train0 = (TRAIN0_ACTOR*)actor0;
|
|
TRAIN1_ACTOR* train1 = (TRAIN1_ACTOR*)actor1;
|
|
|
|
if (fabsf(actor1->speed) < 0.008f) {
|
|
return 0.8f + train0->tr_speed;
|
|
}
|
|
|
|
if (actor1->speed < train0->tr_speed){
|
|
return train0->tr_speed + (0.5f * - (actor1->speed - train0->tr_speed));
|
|
}
|
|
|
|
return train0->tr_speed;
|
|
}
|
|
|
|
static f32 calc_speed2(ACTOR* actor){
|
|
TRAIN1_ACTOR* train1 = (TRAIN1_ACTOR*)actor;
|
|
int should_stop = fabsf(train1->tr0_pos) < 0.008f;
|
|
|
|
return should_stop == FALSE ? train1->tr0_pos : -0.23f;
|
|
}
|
|
|
|
static void aTR1_position_move(ACTOR* actor){
|
|
TRAIN1_ACTOR* train1 = (TRAIN1_ACTOR*)actor;
|
|
TRAIN0_ACTOR* train0 = (TRAIN0_ACTOR*)actor->parent_actor;
|
|
|
|
f32 diff;
|
|
f32 tr_back_calc;
|
|
f32 base_x_pos;
|
|
|
|
tr_back_calc = train1->actor_class.world.position.x;
|
|
base_x_pos = -125.0f + train0->tr1_pos;
|
|
tr_back_calc += 0.5f * train1->actor_class.speed;
|
|
|
|
diff = tr_back_calc - base_x_pos;
|
|
if((diff) <= 0.0f){
|
|
train1->actor_class.speed = calc_speed1(actor->parent_actor, actor);
|
|
train1->actor_class.world.position.x = base_x_pos;
|
|
}
|
|
else if((diff) > 2.0f){
|
|
train1->actor_class.speed = calc_speed2(actor->parent_actor);
|
|
train1->actor_class.world.position.x = 2.0f + base_x_pos;
|
|
}
|
|
else{
|
|
chase_f(&train1->actor_class.speed, 0.0f, 0.0025f);
|
|
train1->actor_class.world.position.x = tr_back_calc;
|
|
}
|
|
}
|
|
|
|
static void aTR1_chg_station_attr(int station){
|
|
static xyz_t doorway_pos = { 2180.0f, 0.0f, 820.0f };
|
|
xyz_t soil_pos;
|
|
xyz_t unk20_pos;
|
|
|
|
if(mEv_CheckFirstIntro() == 0){
|
|
if(station == 5){
|
|
soil_pos = doorway_pos;
|
|
mCoBG_SetAttribute(&soil_pos, 7);
|
|
}
|
|
else if(station == 6){
|
|
unk20_pos = doorway_pos;
|
|
mCoBG_SetAttribute(&unk20_pos, 0x20);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void aTR1_passenger_ctrl(ACTOR* actor){
|
|
TRAIN1_ACTOR* train1 = (TRAIN1_ACTOR*)actor;
|
|
|
|
GAME_PLAY* play = (GAME_PLAY*)gamePT;
|
|
xyz_t pos;
|
|
s_xyz rot;
|
|
|
|
if(train1->player_pass_exists == 1){
|
|
pos.x = train1->actor_class.world.position.x + 60.0f;
|
|
pos.y = train1->actor_class.world.position.y + 20.0f;
|
|
pos.z = train1->actor_class.world.position.z + 20.0f;
|
|
rot.x = ZeroSVec.x;
|
|
rot.y = ZeroSVec.y;
|
|
rot.z = ZeroSVec.z;
|
|
get_player_actor_withoutCheck((GAME_PLAY*)gamePT)->Set_force_position_angle_proc(gamePT, &pos, &rot, mPlayer_FORCE_POSITION_ANGLE_POSX | mPlayer_FORCE_POSITION_ANGLE_POSY | mPlayer_FORCE_POSITION_ANGLE_POSZ | mPlayer_FORCE_POSITION_ANGLE_ROTY);
|
|
}
|
|
else if(train1->player_pass_leaving == 1){
|
|
pos.x = train1->actor_class.world.position.x + 2.0f;
|
|
pos.y = train1->actor_class.world.position.y + 16.0f;
|
|
pos.z = train1->actor_class.world.position.z + 20.0f;
|
|
get_player_actor_withoutCheck((GAME_PLAY*)gamePT)->Set_force_position_angle_proc(gamePT, &pos, NULL, mPlayer_FORCE_POSITION_ANGLE_POSX | mPlayer_FORCE_POSITION_ANGLE_POSY | mPlayer_FORCE_POSITION_ANGLE_POSZ);
|
|
|
|
}
|
|
}
|
|
|
|
#pragma pool_data on
|
|
static void aTR1_setupAction(ACTOR* actor, int action){
|
|
TRAIN1_ACTOR* train1 = (TRAIN1_ACTOR*)actor;
|
|
|
|
static cKF_Animation_R_c* anime_table[] = {&cKF_ba_r_obj_train1_3_open, &cKF_ba_r_obj_train1_3_close};
|
|
static f32 anime_end[] = {24.0f, 32.0f};
|
|
static int animeSeqNoTable[] = {0,0,0,0,0,1,1,0,0};
|
|
static f32 anime_spd[] = {0.0f,0.0f,0.0f,0.0f, 0.5f, 0.0f,0.5f,0.0f,0.0f};
|
|
|
|
cKF_Animation_R_c* anime_pt;
|
|
f32 speed;
|
|
f32 end;
|
|
f32 tr_speed;
|
|
int seq_no = animeSeqNoTable[action];
|
|
|
|
anime_pt = anime_table[seq_no];
|
|
speed = anime_spd[action];
|
|
end = anime_end[seq_no];
|
|
|
|
tr_speed = 1.0f;
|
|
train1->tr_action = action;
|
|
|
|
if((train1->tr_action == 6) || (train1->tr_action == 4)){
|
|
if((mEv_CheckTitleDemo() == 0) && (tr_speed != train1->tr_speed)){
|
|
aTR1_OngenTrgStart(actor, 43);
|
|
}
|
|
else{
|
|
tr_speed = end;
|
|
}
|
|
}
|
|
cKF_SkeletonInfo_R_init(&train1->keyframe, train1->keyframe.skeleton, anime_pt,
|
|
1.0f, end, tr_speed, speed, 0.0f, 0, NULL );
|
|
aTR1_chg_station_attr(action);
|
|
}
|
|
#pragma pool_data reset
|
|
|
|
static void aTR1_actor_move(ACTOR* actor, GAME* game){
|
|
TRAIN1_ACTOR* train1 = (TRAIN1_ACTOR*)actor;
|
|
TRAIN0_ACTOR* train0 = (TRAIN0_ACTOR*)actor->parent_actor;
|
|
cKF_SkeletonInfo_R_c* keyframe = &train1->keyframe;
|
|
|
|
|
|
train1->anim_state = cKF_SkeletonInfo_R_play(keyframe);
|
|
if(mEv_CheckTitleDemo() <= 0){
|
|
aTR1_position_move((ACTOR*)train1);
|
|
}
|
|
aTR1_passenger_ctrl((ACTOR*)train1);
|
|
|
|
if(train0->tr_action != train1->tr_action){
|
|
aTR1_setupAction((ACTOR*)train1, train0->tr_action);
|
|
}
|
|
|
|
train1->tr_speed = 0.0f;
|
|
}
|
|
|
|
static void aTR1_actor_draw(ACTOR* actor, GAME* game){
|
|
u16* pal = (*Common_Get(clip).structure_clip->get_pal_segment_proc)(0x3A);
|
|
|
|
TRAIN1_ACTOR* train1 = (TRAIN1_ACTOR*)actor;
|
|
|
|
GRAPH* graph = game->graph;
|
|
cKF_SkeletonInfo_R_c* keyf;
|
|
Mtx* mtx;
|
|
Gfx* gfx;
|
|
|
|
keyf = &train1->keyframe;
|
|
mtx = GRAPH_ALLOC_TYPE(graph, Mtx, keyf->skeleton->num_shown_joints);
|
|
|
|
if(mtx != NULL){
|
|
_texture_z_light_fog_prim_npc(graph);
|
|
|
|
OPEN_DISP(graph);
|
|
|
|
gfx = NOW_POLY_OPA_DISP;
|
|
gSPSegment(gfx++, 0x8, pal);
|
|
SET_POLY_OPA_DISP(gfx);
|
|
CLOSE_DISP(graph);
|
|
|
|
cKF_Si3_draw_R_SV(game, keyf, mtx, NULL,NULL,train1);
|
|
}
|
|
}
|