Files
ac-decomp/rel/ac_train1.c
T
2023-07-17 07:30:57 -04:00

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