mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-06-04 10:26:19 -04:00
238 lines
7.8 KiB
C
238 lines
7.8 KiB
C
#include "ac_balloon.h"
|
|
|
|
#include "m_name_table.h"
|
|
#include "sys_matrix.h"
|
|
#include "m_player_lib.h"
|
|
#include "m_rcp.h"
|
|
|
|
enum {
|
|
Ac_Balloon_MODE_HIDE,
|
|
Ac_Balloon_MODE_FLY,
|
|
|
|
Ac_Balloon_MODE_NUM
|
|
};
|
|
|
|
static void Ac_Balloon_dt(ACTOR* actorx, GAME* game) {
|
|
// empty
|
|
}
|
|
|
|
extern void Ac_Balloon_request_hide(ACTOR* actorx, GAME* game) {
|
|
BALLOON_ACTOR* balloon = (BALLOON_ACTOR*)actorx;
|
|
|
|
balloon->setup_mode = Ac_Balloon_MODE_HIDE;
|
|
}
|
|
|
|
static void Ac_Balloon_setup_hide(ACTOR* actorx, GAME* game) {
|
|
BALLOON_ACTOR* balloon = (BALLOON_ACTOR*)actorx;
|
|
|
|
balloon->main_mode = Ac_Balloon_MODE_HIDE;
|
|
balloon->setup_mode = -1;
|
|
}
|
|
|
|
static void Ac_Balloon_Movement_hide(ACTOR* actorx, GAME* game) {
|
|
ACTOR* player_actor = GET_PLAYER_ACTOR_GAME_ACTOR(game);
|
|
|
|
if (player_actor != NULL) {
|
|
actorx->world.position = player_actor->world.position;
|
|
}
|
|
}
|
|
|
|
static void Ac_Balloon_main_hide(ACTOR* actorx, GAME* game) {
|
|
Ac_Balloon_Movement_hide(actorx, game);
|
|
}
|
|
|
|
extern void Ac_Balloon_request_fly(ACTOR* actorx, GAME* game, int balloon_type, s_xyz* angle_p, s16 lean, xyz_t* pos_p,
|
|
f32 start_frame, f32 speed) {
|
|
BALLOON_ACTOR* balloon = (BALLOON_ACTOR*)actorx;
|
|
|
|
balloon->setup_mode = Ac_Balloon_MODE_FLY;
|
|
balloon->balloon_type = balloon_type;
|
|
balloon->angle = *angle_p;
|
|
balloon->lean = lean;
|
|
balloon->start_frame = start_frame;
|
|
balloon->speed = speed;
|
|
balloon->pos = *pos_p;
|
|
}
|
|
|
|
static void Ac_Balloon_setup_fly(ACTOR* actorx, GAME* game) {
|
|
static int data[] = {
|
|
mPlayer_ITEM_DATA_BALLOON1, mPlayer_ITEM_DATA_BALLOON2, mPlayer_ITEM_DATA_BALLOON3, mPlayer_ITEM_DATA_BALLOON4,
|
|
mPlayer_ITEM_DATA_BALLOON5, mPlayer_ITEM_DATA_BALLOON6, mPlayer_ITEM_DATA_BALLOON7, mPlayer_ITEM_DATA_BALLOON8,
|
|
};
|
|
|
|
BALLOON_ACTOR* balloon = (BALLOON_ACTOR*)actorx;
|
|
f32 start_frame;
|
|
int data_type;
|
|
int anim_type;
|
|
cKF_SkeletonInfo_R_c* kf_p;
|
|
cKF_Skeleton_R_c* skeleton;
|
|
cKF_Animation_R_c* animation;
|
|
|
|
balloon->main_mode = Ac_Balloon_MODE_FLY;
|
|
balloon->saved_type = balloon->balloon_type;
|
|
data_type = Ac_Balloon_TYPE_VALID(balloon->balloon_type) != FALSE ? data[balloon->balloon_type]
|
|
: mPlayer_ITEM_DATA_BALLOON1;
|
|
start_frame = balloon->start_frame;
|
|
anim_type = start_frame < 1.0f ? mPlayer_ITEM_DATA_BALLOON_WAIT : mPlayer_ITEM_DATA_BALLOON_GYAZA;
|
|
kf_p = &balloon->keyframe;
|
|
skeleton = (cKF_Skeleton_R_c*)mPlib_Get_Item_DataPointer(data_type);
|
|
animation = (cKF_Animation_R_c*)mPlib_Get_Item_DataPointer(anim_type);
|
|
cKF_SkeletonInfo_R_ct(kf_p, skeleton, NULL, balloon->work, balloon->morph);
|
|
cKF_SkeletonInfo_R_init_standard_repeat_setframeandspeedandmorph(kf_p, animation, NULL, start_frame, 0.0f, 0.0f);
|
|
cKF_SkeletonInfo_R_play(kf_p);
|
|
cKF_SkeletonInfo_R_init_standard_repeat_setframeandspeedandmorph(
|
|
kf_p, mPlib_Get_Item_DataPointer(mPlayer_ITEM_DATA_BALLOON_WAIT), NULL, 1.0f, 0.5f, -5.0f);
|
|
|
|
actorx->shape_info.rotation = balloon->angle;
|
|
actorx->position_speed.y = 0.0f;
|
|
actorx->max_velocity_y = balloon->speed;
|
|
actorx->gravity = 0.2f;
|
|
actorx->world.position = balloon->pos;
|
|
balloon->setup_mode = -1;
|
|
}
|
|
|
|
static void Ac_Balloon_CulcAnimation_fly(ACTOR* actorx) {
|
|
BALLOON_ACTOR* balloon = (BALLOON_ACTOR*)actorx;
|
|
|
|
cKF_SkeletonInfo_R_play(&balloon->keyframe);
|
|
}
|
|
|
|
static void Ac_Balloon_Movement_fly(BALLOON_ACTOR* balloon) {
|
|
add_calc_short_angle2(&balloon->actor_class.shape_info.rotation.x, 0, 1.0f - sqrtf(0.5f), 50, 5);
|
|
add_calc_short_angle2(&balloon->actor_class.shape_info.rotation.z, 0, 1.0f - sqrtf(0.5f), 50, 5);
|
|
add_calc_short_angle2(&balloon->lean, 0, 1.0f - sqrtf(0.5f), 50, 5);
|
|
Actor_position_moveF(&balloon->actor_class);
|
|
}
|
|
|
|
static void Ac_Balloon_request_change_mode_fromFly(ACTOR* actorx, GAME* game) {
|
|
ACTOR* player_actor = GET_PLAYER_ACTOR_GAME_ACTOR(game);
|
|
|
|
if (player_actor != NULL && actorx->world.position.y - player_actor->world.position.y > 200.0f) {
|
|
Ac_Balloon_request_hide(actorx, game);
|
|
}
|
|
}
|
|
|
|
static void Ac_Balloon_main_fly(ACTOR* actorx, GAME* game) {
|
|
BALLOON_ACTOR* balloon = (BALLOON_ACTOR*)actorx;
|
|
|
|
Ac_Balloon_CulcAnimation_fly(actorx);
|
|
Ac_Balloon_Movement_fly(balloon);
|
|
Ac_Balloon_request_change_mode_fromFly(actorx, game);
|
|
}
|
|
|
|
typedef void (*Ac_Balloon_PROC)(ACTOR*, GAME*);
|
|
|
|
static void Ac_Balloon_main(ACTOR* actorx, GAME* game) {
|
|
BALLOON_ACTOR* balloon = (BALLOON_ACTOR*)actorx;
|
|
|
|
if (balloon->setup_mode >= 0 && balloon->setup_mode < Ac_Balloon_MODE_NUM) {
|
|
static Ac_Balloon_PROC data[] = { &Ac_Balloon_setup_hide, &Ac_Balloon_setup_fly };
|
|
|
|
if (data[balloon->setup_mode] != NULL) {
|
|
(*data[balloon->setup_mode])(actorx, game);
|
|
}
|
|
}
|
|
|
|
if (balloon->main_mode >= 0 && balloon->main_mode < Ac_Balloon_MODE_NUM) {
|
|
static Ac_Balloon_PROC data[] = { &Ac_Balloon_main_hide, &Ac_Balloon_main_fly };
|
|
|
|
if (data[balloon->main_mode] != NULL) {
|
|
(*data[balloon->main_mode])(actorx, game);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void Ac_Balloon_ct(ACTOR* actorx, GAME* game) {
|
|
Ac_Balloon_request_hide(actorx, game);
|
|
}
|
|
|
|
static int Ac_Balloon_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) {
|
|
switch (joint_idx) {
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
OPEN_POLY_OPA_DISP(game->graph);
|
|
|
|
gDPPipeSync(POLY_OPA_DISP++);
|
|
gDPSetTexEdgeAlpha(POLY_OPA_DISP++, 80);
|
|
|
|
CLOSE_POLY_OPA_DISP(game->graph);
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static int Ac_Balloon_draw_After(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) {
|
|
switch (joint_idx) {
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
OPEN_POLY_OPA_DISP(game->graph);
|
|
|
|
gDPPipeSync(POLY_OPA_DISP++);
|
|
gDPSetTexEdgeAlpha(POLY_OPA_DISP++, 144);
|
|
|
|
CLOSE_POLY_OPA_DISP(game->graph);
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void Ac_Balloon_draw_normal(ACTOR* actorx, GAME* game) {
|
|
GAME_PLAY* play = (GAME_PLAY*)game;
|
|
s16 angle_x;
|
|
s16 angle_y;
|
|
BALLOON_ACTOR* balloon = (BALLOON_ACTOR*)actorx;
|
|
int idx = game->frame_counter & 1;
|
|
Mtx* mtx = balloon->mtx[idx];
|
|
GRAPH* graph = game->graph;
|
|
xyz_t* pos = &actorx->world.position;
|
|
|
|
Matrix_push();
|
|
angle_x = actorx->shape_info.rotation.x - DEG2SHORT_ANGLE2(90.0f);
|
|
angle_y = actorx->shape_info.rotation.y;
|
|
Matrix_translate(pos->x, pos->y, pos->z, 0);
|
|
Matrix_RotateY(angle_y, 1);
|
|
Matrix_RotateX(angle_x, 1);
|
|
Matrix_RotateZ(DEG2SHORT_ANGLE2(90.0f), 1);
|
|
Matrix_RotateX(balloon->lean, 1);
|
|
Matrix_scale(actorx->scale.x, actorx->scale.y, actorx->scale.z, 1);
|
|
|
|
OPEN_POLY_OPA_DISP(graph);
|
|
|
|
gSPMatrix(POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
|
|
CLOSE_POLY_OPA_DISP(graph);
|
|
|
|
_texture_z_light_fog_prim(graph);
|
|
Setpos_HiliteReflect_init(pos, play);
|
|
cKF_Si3_draw_R_SV((GAME*)play, &balloon->keyframe, mtx, &Ac_Balloon_draw_Before, &Ac_Balloon_draw_After, balloon);
|
|
Matrix_pull();
|
|
}
|
|
|
|
static void Ac_Balloon_draw(ACTOR* actorx, GAME* game) {
|
|
BALLOON_ACTOR* balloon = (BALLOON_ACTOR*)actorx;
|
|
|
|
if (balloon->main_mode != Ac_Balloon_MODE_HIDE) {
|
|
Ac_Balloon_draw_normal(actorx, game);
|
|
}
|
|
}
|
|
|
|
ACTOR_PROFILE Balloon_Profile = {
|
|
mAc_PROFILE_BALLOON,
|
|
ACTOR_PART_BG,
|
|
ACTOR_STATE_NO_DRAW_WHILE_CULLED | ACTOR_STATE_NO_MOVE_WHILE_CULLED,
|
|
ITM_BALLOON_START,
|
|
ACTOR_OBJ_BANK_KEEP,
|
|
sizeof(BALLOON_ACTOR),
|
|
&Ac_Balloon_ct,
|
|
&Ac_Balloon_dt,
|
|
&Ac_Balloon_main,
|
|
&Ac_Balloon_draw,
|
|
NULL,
|
|
};
|