|
|
|
@@ -61,6 +61,9 @@ static void aSMAN_process_combine_body_init(ACTOR* actorx);
|
|
|
|
|
static void aSMAN_process_player_push_init(ACTOR* actorx, GAME* game);
|
|
|
|
|
static void aSMAN_process_air_init(ACTOR* actorx);
|
|
|
|
|
static void aSMAN_process_hole_init(ACTOR* actorx);
|
|
|
|
|
static void aSMAN_process_player_push_scroll_init(ACTOR* actorx);
|
|
|
|
|
static void aSMAN_process_swim_init(ACTOR* actorx);
|
|
|
|
|
static void aSMAN_process_combine_head_init(ACTOR* actorx);
|
|
|
|
|
|
|
|
|
|
static int aSMAN_process_normal(ACTOR* actorx, GAME* game);
|
|
|
|
|
static int aSMAN_process_player_push(ACTOR* actorx, GAME* game);
|
|
|
|
@@ -69,6 +72,8 @@ static int aSMAN_process_combine_body(ACTOR* actorx, GAME* game);
|
|
|
|
|
static int aSMAN_process_combine_head_jump(ACTOR* actorx, GAME* game);
|
|
|
|
|
static int aSMAN_process_swim(ACTOR* actorx, GAME* game);
|
|
|
|
|
static int aSMAN_process_air(ACTOR* actorx, GAME* game);
|
|
|
|
|
static int aSMAN_process_hole(ACTOR* actorx, GAME* game);
|
|
|
|
|
static int aSMAN_process_combine_head(ACTOR* actorx, GAME* game);
|
|
|
|
|
|
|
|
|
|
static void aSMAN_actor_ct(ACTOR* actorx, GAME* game) {
|
|
|
|
|
static int part_tbl[] = { aSMAN_PART0, aSMAN_PART1 };
|
|
|
|
@@ -122,7 +127,7 @@ static void aSNOWMAN_Set_PSnowman_info(SNOWMAN_ACTOR* actor) {
|
|
|
|
|
sman_info.data.body_size = actor->body_scale * 255;
|
|
|
|
|
sman_info.data.score = actor->result;
|
|
|
|
|
mCoBG_SetPlussOffset(actor->actor_class.world.position, 0, mCoBG_ATTRIBUTE_NONE);
|
|
|
|
|
if ((actor->flags & 0x80) == 0) {
|
|
|
|
|
if ((actor->flags & aSMAN_FLAG_DELETE) == 0) {
|
|
|
|
|
mSN_regist_snowman_society(&sman_info);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -132,8 +137,8 @@ static void aSMAN_actor_dt(ACTOR* actorx, GAME* game) {
|
|
|
|
|
|
|
|
|
|
ClObjPipe_dt(game, &actor->col_pipe);
|
|
|
|
|
if (actor->snowman_part == aSMAN_PART0) {
|
|
|
|
|
if (actor->flags & 0x20) {
|
|
|
|
|
if (actor->flags & 1) {
|
|
|
|
|
if (actor->flags & aSMAN_FLAG_COMBINED) {
|
|
|
|
|
if (actor->flags & aSMAN_FLAG_HEAD_JUMP) {
|
|
|
|
|
if (actor->fg_pos.x != 0.0f || actor->fg_pos.z != 0.0f) {
|
|
|
|
|
aSNOWMAN_Set_PSnowman_info(actor);
|
|
|
|
|
} else {
|
|
|
|
@@ -144,7 +149,7 @@ static void aSMAN_actor_dt(ACTOR* actorx, GAME* game) {
|
|
|
|
|
mEv_clear_common_place(mEv_EVENT_SNOWMAN_SEASON, 100 + aSMAN_PART0);
|
|
|
|
|
mEv_clear_common_area(mEv_EVENT_SNOWMAN_SEASON, aSMAN_PART0);
|
|
|
|
|
} else {
|
|
|
|
|
if ((actor->flags & 8) || (actor->flags & 4) || !mRlib_Set_Position_Check(actorx)) {
|
|
|
|
|
if ((actor->flags & aSMAN_FLAG_IN_HOLE) || (actor->flags & aSMAN_FLAG_MOVED) || !mRlib_Set_Position_Check(actorx)) {
|
|
|
|
|
mEv_clear_common_place(mEv_EVENT_SNOWMAN_SEASON, 100 + aSMAN_PART0);
|
|
|
|
|
mEv_clear_common_area(mEv_EVENT_SNOWMAN_SEASON, aSMAN_PART0);
|
|
|
|
|
} else {
|
|
|
|
@@ -156,8 +161,8 @@ static void aSMAN_actor_dt(ACTOR* actorx, GAME* game) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (actor->flags & 0x20) {
|
|
|
|
|
if (actor->flags & 1) {
|
|
|
|
|
if (actor->flags & aSMAN_FLAG_COMBINED) {
|
|
|
|
|
if (actor->flags & aSMAN_FLAG_HEAD_JUMP) {
|
|
|
|
|
if (actor->fg_pos.x != 0.0f || actor->fg_pos.z != 0.0f) {
|
|
|
|
|
aSNOWMAN_Set_PSnowman_info(actor);
|
|
|
|
|
} else {
|
|
|
|
@@ -168,7 +173,7 @@ static void aSMAN_actor_dt(ACTOR* actorx, GAME* game) {
|
|
|
|
|
mEv_clear_common_place(mEv_EVENT_SNOWMAN_SEASON, 100 + aSMAN_PART1);
|
|
|
|
|
mEv_clear_common_area(mEv_EVENT_SNOWMAN_SEASON, aSMAN_PART1);
|
|
|
|
|
} else {
|
|
|
|
|
if ((actor->flags & 8) || (actor->flags & 4) || !mRlib_Set_Position_Check(actorx)) {
|
|
|
|
|
if ((actor->flags & aSMAN_FLAG_IN_HOLE) || (actor->flags & aSMAN_FLAG_MOVED) || !mRlib_Set_Position_Check(actorx)) {
|
|
|
|
|
mEv_clear_common_place(mEv_EVENT_SNOWMAN_SEASON, 100 + aSMAN_PART1);
|
|
|
|
|
mEv_clear_common_area(mEv_EVENT_SNOWMAN_SEASON, aSMAN_PART1);
|
|
|
|
|
} else {
|
|
|
|
@@ -301,7 +306,7 @@ static void aSMAN_House_Tree_Rev_Check(ACTOR* actorx) {
|
|
|
|
|
SNOWMAN_ACTOR* actor = (SNOWMAN_ACTOR*)actorx;
|
|
|
|
|
|
|
|
|
|
if (mRlib_HeightGapCheck_And_ReversePos(actorx) != TRUE) {
|
|
|
|
|
actor->flags |= 4;
|
|
|
|
|
actor->flags |= aSMAN_FLAG_MOVED;
|
|
|
|
|
Actor_delete(actorx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -365,7 +370,7 @@ static int aSMAN_get_ground_norm(ACTOR* actorx, xyz_t* norm, xyz_t* pos) {
|
|
|
|
|
|
|
|
|
|
if (mRlib_Get_ground_norm_inHole(actorx, norm, &hole_dist, &angle, &norm_rate, 1.0f - actor->normalized_scale * 0.5f)) {
|
|
|
|
|
aSMAN_get_hole_offset(actorx, hole_dist);
|
|
|
|
|
if ((actor->flags & 8) == 0) {
|
|
|
|
|
if ((actor->flags & aSMAN_FLAG_IN_HOLE) == 0) {
|
|
|
|
|
s16 angle_mod;
|
|
|
|
|
f32 cos = cos_s(angle);
|
|
|
|
|
f32 sin = sin_s(angle);
|
|
|
|
@@ -388,7 +393,7 @@ static int aSMAN_get_ground_norm(ACTOR* actorx, xyz_t* norm, xyz_t* pos) {
|
|
|
|
|
norm->y = sin_s(norm_rate);
|
|
|
|
|
if (hole_dist < 1.0f) {
|
|
|
|
|
if (ABS(actorx->position_speed.x) < 1.0f && ABS(actorx->position_speed.z) < 1.0f) {
|
|
|
|
|
actor->flags |= 8;
|
|
|
|
|
actor->flags |= aSMAN_FLAG_IN_HOLE;
|
|
|
|
|
actorx->state_bitfield &= ~ACTOR_STATE_NO_MOVE_WHILE_CULLED;
|
|
|
|
|
actorx->status_data.weight = MASSTYPE_HEAVY;
|
|
|
|
|
actorx->speed = 0.0f;
|
|
|
|
@@ -503,18 +508,18 @@ static void aSMAN_MakeBreakEffect(SNOWMAN_ACTOR* actor, GAME* game) {
|
|
|
|
|
static int aSMAN_status_check_in_move(SNOWMAN_ACTOR* actor, GAME* game) {
|
|
|
|
|
int ret = FALSE;
|
|
|
|
|
|
|
|
|
|
if ((actor->flags & 2) != 0 && (actor->flags & 0x20) == 0) {
|
|
|
|
|
actor->flags |= 4;
|
|
|
|
|
if ((actor->flags & aSMAN_FLAG_ON_GROUND) != 0 && (actor->flags & aSMAN_FLAG_COMBINED) == 0) {
|
|
|
|
|
actor->flags |= aSMAN_FLAG_MOVED;
|
|
|
|
|
aSMAN_MakeBreakEffect(actor, game);
|
|
|
|
|
Actor_delete((ACTOR*)actor);
|
|
|
|
|
ret = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (actor->flags & 0x20) {
|
|
|
|
|
if (actor->flags & aSMAN_FLAG_COMBINED) {
|
|
|
|
|
ret = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (actor->flags & 8) {
|
|
|
|
|
if (actor->flags & aSMAN_FLAG_IN_HOLE) {
|
|
|
|
|
ret = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -531,7 +536,7 @@ static void aSMAN_position_move(ACTOR* actorx) {
|
|
|
|
|
mCoBG_GetBgY_AngleS_FromWpos(&actor->ground_angle, actorx->world.position, 0.0f);
|
|
|
|
|
chase_f(&actorx->speed, actor->base_speed, actor->accel);
|
|
|
|
|
|
|
|
|
|
if ((actor->flags & 0x20) != 0 || (actor->flags & 8) != 0 ||
|
|
|
|
|
if ((actor->flags & aSMAN_FLAG_COMBINED) != 0 || (actor->flags & aSMAN_FLAG_IN_HOLE) != 0 ||
|
|
|
|
|
actor->process == aSMAN_process_combine_body || actor->process == aSMAN_process_player_push_scroll) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@@ -544,7 +549,7 @@ static int aSMAN_BGcheck(ACTOR* actorx, GAME* game) {
|
|
|
|
|
SNOWMAN_ACTOR* actor = (SNOWMAN_ACTOR*)actorx;
|
|
|
|
|
f32 r = actor->normalized_scale * 20.0f + 10.0f;
|
|
|
|
|
|
|
|
|
|
if ((actor->flags & 0x20) != 0 || actor->process == aSMAN_process_combine_head_jump || actor->process == aSMAN_process_combine_body) {
|
|
|
|
|
if ((actor->flags & aSMAN_FLAG_COMBINED) != 0 || actor->process == aSMAN_process_combine_head_jump || actor->process == aSMAN_process_combine_body) {
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -558,8 +563,8 @@ static int aSMAN_BGcheck(ACTOR* actorx, GAME* game) {
|
|
|
|
|
|
|
|
|
|
if (actorx->world.position.y - actorx->last_world_position.y > 60.0f) {
|
|
|
|
|
actorx->world.position = actorx->last_world_position;
|
|
|
|
|
actor->flags |= 0x4;
|
|
|
|
|
actor->flags |= 0x2;
|
|
|
|
|
actor->flags |= aSMAN_FLAG_MOVED;
|
|
|
|
|
actor->flags |= aSMAN_FLAG_ON_GROUND;
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -571,8 +576,8 @@ static int aSMAN_BGcheck(ACTOR* actorx, GAME* game) {
|
|
|
|
|
f32 speed = actorx->speed * sin_s(colAngle);
|
|
|
|
|
|
|
|
|
|
if (ABS(speed) > 5.0f) {
|
|
|
|
|
actor->flags |= 0x4;
|
|
|
|
|
actor->flags |= 0x2;
|
|
|
|
|
actor->flags |= aSMAN_FLAG_MOVED;
|
|
|
|
|
actor->flags |= aSMAN_FLAG_ON_GROUND;
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -625,7 +630,7 @@ static int aSMAN_snowman_hit_check(SNOWMAN_ACTOR* actor, GAME* game, ACTOR* oc_a
|
|
|
|
|
|
|
|
|
|
attr = mCoBG_Wpos2Attribute(center_pos, NULL);
|
|
|
|
|
mFI_Wpos2UtNum_inBlock(&b_ux, &b_uz, center_pos);
|
|
|
|
|
if (attr == mCoBG_ATTRIBUTE_STONE || attr == mCoBG_ATTRIBUTE_WOOD || mCoBG_Wpos2CheckSlateCol(¢er_pos, FALSE) || b_ux == 0 || b_ux == (UT_X_NUM - 1) || b_uz == 0 || b_uz == (UT_Z_NUM - 1) || (oc_actor->flags & 0x8) != 0 || oc_actor->ground_angle.x != 0 || oc_actor->ground_angle.z != 0 || !aSNOWMAN_player_block_check((ACTOR*)actor, game)) {
|
|
|
|
|
if (attr == mCoBG_ATTRIBUTE_STONE || attr == mCoBG_ATTRIBUTE_WOOD || mCoBG_Wpos2CheckSlateCol(¢er_pos, FALSE) || b_ux == 0 || b_ux == (UT_X_NUM - 1) || b_uz == 0 || b_uz == (UT_Z_NUM - 1) || (oc_actor->flags & aSMAN_FLAG_IN_HOLE) != 0 || oc_actor->ground_angle.x != 0 || oc_actor->ground_angle.z != 0 || !aSNOWMAN_player_block_check((ACTOR*)actor, game)) {
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -657,7 +662,7 @@ static int aSMAN_snowman_hit_check(SNOWMAN_ACTOR* actor, GAME* game, ACTOR* oc_a
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void aSMAN_OBJcheck(SNOWMAN_ACTOR* actor, GAME* game) {
|
|
|
|
|
if ((actor->flags & 0x20) != 0) {
|
|
|
|
|
if ((actor->flags & aSMAN_FLAG_COMBINED) != 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -797,10 +802,10 @@ static void aSMAN_calc_objChkRange(ACTOR* actorx) {
|
|
|
|
|
actor->col_pipe.attribute.pipe.height = (actor->normalized_scale * 15.0f + 5.0f) * 2.5f;
|
|
|
|
|
actor->col_pipe.attribute.pipe.offset = -(actor->normalized_scale * 15.0f + 5.0f);
|
|
|
|
|
|
|
|
|
|
if ((actor->flags & 0x8) != 0) {
|
|
|
|
|
if ((actor->flags & aSMAN_FLAG_IN_HOLE) != 0) {
|
|
|
|
|
actor->col_pipe.attribute.pipe.radius = 20;
|
|
|
|
|
actorx->status_data.weight = MASSTYPE_HEAVY;
|
|
|
|
|
} else if (actor->process == aSMAN_process_combine_body && (actor->flags & 0x20) == 0) {
|
|
|
|
|
} else if (actor->process == aSMAN_process_combine_body && (actor->flags & aSMAN_FLAG_COMBINED) == 0) {
|
|
|
|
|
actor->col_pipe.attribute.pipe.radius = 20;
|
|
|
|
|
} else {
|
|
|
|
|
actor->col_pipe.attribute.pipe.radius = actor->normalized_scale * 15.0f + 5.0f;
|
|
|
|
@@ -823,7 +828,7 @@ static int aSMAN_Player_push_Request(ACTOR* actorx, GAME* game) {
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((actor->flags & 0x8) != 0) {
|
|
|
|
|
if ((actor->flags & aSMAN_FLAG_IN_HOLE) != 0) {
|
|
|
|
|
aSMAN_process_hole_init(actorx);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
@@ -893,5 +898,510 @@ static void aSMAN_process_player_push_init(ACTOR* actorx, GAME* game) {
|
|
|
|
|
actor->process = aSMAN_process_player_push;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void aSMAN_actor_move(ACTOR* actorx, GAME* game);
|
|
|
|
|
static void aSMAN_actor_draw(ACTOR* actorx, GAME* game);
|
|
|
|
|
static int aSMAN_process_player_push(ACTOR* actorx, GAME* game) {
|
|
|
|
|
SNOWMAN_ACTOR* actor = (SNOWMAN_ACTOR*)actorx;
|
|
|
|
|
ACTOR* playerx = GET_PLAYER_ACTOR_GAME_ACTOR(game);
|
|
|
|
|
ACTOR* oc_actorx = aSMAN_get_oc_actor(actor);
|
|
|
|
|
s16 player_angle = search_position_angleY(&playerx->world.position, &actorx->world.position);
|
|
|
|
|
s16 move_angle = gamePT->mcon.move_angle + DEG2SHORT_ANGLE2(90.0f);
|
|
|
|
|
s16 diff_angle = DIFF_SHORT_ANGLE(move_angle, player_angle);
|
|
|
|
|
f32 move_pR = gamePT->mcon.move_pR;
|
|
|
|
|
|
|
|
|
|
add_calc0(&actor->y_ofs, 1.0f - sqrtf(0.5f), 50.0f);
|
|
|
|
|
add_calc(&actor->accel, 0.1f, 1.0f - sqrtf(0.8f), 0.005f, 0.0005f);
|
|
|
|
|
|
|
|
|
|
if (oc_actorx != NULL && aSMAN_snowman_hit_check(actor, game, oc_actorx) == TRUE) {
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mPlib_Check_Label_main_wade_snowball(actorx)) {
|
|
|
|
|
aSMAN_process_player_push_scroll_init(actorx);
|
|
|
|
|
} else if (!mPlib_Check_Label_main_push_snowball(actorx)) {
|
|
|
|
|
aSMAN_process_normal_init(actorx);
|
|
|
|
|
return FALSE;
|
|
|
|
|
} else {
|
|
|
|
|
xyz_t norm;
|
|
|
|
|
s16 norm_angle_diff = aSMAN_get_norm_push_angle_distance(actorx, &norm, player_angle);
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
if ((ABS(diff_angle) > DEG2SHORT_ANGLE2(55.0f) || actor->normalized_scale <= 0.2f || aSMAN_player_push_HitWallCheck(actorx, game)) || (((!F32_IS_ZERO(norm.x) || !F32_IS_ZERO(norm.z)) && ABS(norm_angle_diff) < DEG2SHORT_ANGLE2(120.0f)) || move_pR == 0.0f)) {
|
|
|
|
|
aSMAN_player_push_free(game);
|
|
|
|
|
aSMAN_process_normal_init(actorx);
|
|
|
|
|
return FALSE;
|
|
|
|
|
} else {
|
|
|
|
|
xyz_t aim_pos = playerx->world.position;
|
|
|
|
|
f32 dist;
|
|
|
|
|
f32 speed;
|
|
|
|
|
s16 player_angle_y;
|
|
|
|
|
|
|
|
|
|
speed = (actor->normalized_scale * 20.0f + 10.0f) + 10.0f;
|
|
|
|
|
player_angle_y = playerx->shape_info.rotation.y;
|
|
|
|
|
actor->base_speed = move_pR * (3.0f - actor->normalized_scale * 1.5f) * cos_s(diff_angle);
|
|
|
|
|
if (mPlib_CheckButtonOnly_forDush()) {
|
|
|
|
|
actor->base_speed *= 1.5f;
|
|
|
|
|
}
|
|
|
|
|
actorx->world.angle.y = move_angle;
|
|
|
|
|
mRlib_spdF_Angle_to_spdXZ(&actorx->position_speed, &actorx->speed, &actorx->world.angle.y);
|
|
|
|
|
aSMAN_set_speed_relations_norm_player_push(actorx, game);
|
|
|
|
|
mRlib_spdF_Angle_to_spdXZ(&aim_pos, &speed, &player_angle);
|
|
|
|
|
xyz_t_sub(&actorx->world.position, &aim_pos, &aim_pos);
|
|
|
|
|
aim_pos.y = mCoBG_GetBgY_AngleS_FromWpos(NULL, aim_pos, 0.0f);
|
|
|
|
|
|
|
|
|
|
add_calc_short_angle2(&player_angle_y, player_angle, CALC_EASE2(0.5f), 455, 45);
|
|
|
|
|
dist = search_position_distanceXZ(&actorx->world.position, &actorx->last_world_position);
|
|
|
|
|
dist *= 0.4f;
|
|
|
|
|
mPlib_SetParam_for_push_snowball(&aim_pos, player_angle_y, dist < 1.0f ? dist : 1.0f);
|
|
|
|
|
|
|
|
|
|
mCoBG_BgCheckControll(NULL, playerx, 18.0f, 0.0f, mCoBG_WALL_TYPE1, mCoBG_REVERSE_TYPE_REVERSE, mCoBG_CHECK_TYPE_PLAYER);
|
|
|
|
|
if ((actorx->bg_collision_check.result.hit_wall & mCoBG_HIT_WALL) != 0) {
|
|
|
|
|
s16 wall_angle = mRlib_Get_HitWallAngleY(actorx);
|
|
|
|
|
s16 wall_angle_diff = DIFF_SHORT_ANGLE(wall_angle - actorx->world.angle.y, DEG2SHORT_ANGLE(-180.0f));
|
|
|
|
|
|
|
|
|
|
if (wall_angle_diff < DEG2SHORT_ANGLE2(20.0f) && move_pR * cos_s(wall_angle_diff) > 0.7f) {
|
|
|
|
|
actor->timer++;
|
|
|
|
|
if (actor->timer > 120) {
|
|
|
|
|
actor->flags |= aSMAN_FLAG_MOVED;
|
|
|
|
|
actor->flags |= aSMAN_FLAG_ON_GROUND;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
actor->timer = 0;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
actor->timer = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
aSMAN_Make_Effect_Ground(actorx, game);
|
|
|
|
|
if (actorx->speed > 1.0f) {
|
|
|
|
|
sAdo_OngenPos((u32)actorx, 52, &actorx->world.position);
|
|
|
|
|
}
|
|
|
|
|
aSMAN_player_push_scroll_request(actorx, game);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!actorx->bg_collision_check.result.on_ground) {
|
|
|
|
|
aSMAN_process_air_init(actorx);
|
|
|
|
|
aSMAN_player_push_free(game);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
actor->roll_speed = actorx->speed;
|
|
|
|
|
aSMAN_calc_scale(actorx);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void aSMAN_process_player_push_scroll_init(ACTOR* actorx) {
|
|
|
|
|
SNOWMAN_ACTOR* actor = (SNOWMAN_ACTOR*)actorx;
|
|
|
|
|
|
|
|
|
|
actor->process = aSMAN_process_player_push_scroll;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int aSMAN_process_player_push_scroll(ACTOR* actorx, GAME* game) {
|
|
|
|
|
SNOWMAN_ACTOR* actor = (SNOWMAN_ACTOR*)actorx;
|
|
|
|
|
|
|
|
|
|
if (!mPlib_Check_Label_main_wade_snowball(actorx)) {
|
|
|
|
|
aSMAN_process_player_push_init(actorx, game);
|
|
|
|
|
} else {
|
|
|
|
|
xyz_t pos;
|
|
|
|
|
f32 rev_x = actor->rev_pos.x;
|
|
|
|
|
f32 rev_z = actor->rev_pos.z;
|
|
|
|
|
f32 rev_xz = sqrtf(SQ(rev_x) + SQ(rev_z));
|
|
|
|
|
|
|
|
|
|
mPlib_GetSnowballPos_forWadeSnowball(&pos);
|
|
|
|
|
actorx->world.position = pos;
|
|
|
|
|
if ((actor->flags & aSMAN_FLAG_ON_GROUND) != 0 || rev_xz > (actor->normalized_scale * 20.0f + 10.0f) * 0.5f) {
|
|
|
|
|
actor->flags |= aSMAN_FLAG_MOVED;
|
|
|
|
|
actor->flags |= aSMAN_FLAG_ON_GROUND;
|
|
|
|
|
mPlib_Set_crash_snowball_for_wade(TRUE);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void aSMAN_process_swim_init(ACTOR* actorx) {
|
|
|
|
|
SNOWMAN_ACTOR* actor = (SNOWMAN_ACTOR*)actorx;
|
|
|
|
|
|
|
|
|
|
actorx->shape_info.draw_shadow = FALSE;
|
|
|
|
|
actor->timer = 0;
|
|
|
|
|
actor->flags |= aSMAN_FLAG_MOVED;
|
|
|
|
|
actor->process = aSMAN_process_swim;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int aSMAN_process_swim(ACTOR* actorx, GAME* game) {
|
|
|
|
|
SNOWMAN_ACTOR* actor = (SNOWMAN_ACTOR*)actorx;
|
|
|
|
|
|
|
|
|
|
aSMAN_set_speed_relations_swim(actorx);
|
|
|
|
|
if (actorx->scale.x < 0.001f) {
|
|
|
|
|
Actor_delete(actorx);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xyz_t_mult_v(&actorx->scale, 0.999f);
|
|
|
|
|
actor->normalized_scale = (actorx->scale.x - 0.01f) / 0.02f;
|
|
|
|
|
if (actorx->scale.x >= 0.01f) {
|
|
|
|
|
if (CLIP(gyo_clip) != NULL) {
|
|
|
|
|
CLIP(gyo_clip)->ballcheck_gyoei_proc(&actorx->world.position, (actorx->scale.x * 30.0f) / 0.03f, aGYO_BALLCHECK_TYPE_SNOWMAN);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!actorx->bg_collision_check.result.is_in_water && actorx->bg_collision_check.result.unit_attribute == mCoBG_ATTRIBUTE_WATERFALL) {
|
|
|
|
|
aSMAN_process_air_init(actorx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (actor->timer < 32) {
|
|
|
|
|
if (((game->frame_counter & 3) == 0 && actor->timer < 16) || (game->frame_counter & 7) == 0) {
|
|
|
|
|
xyz_t pos = actorx->world.position;
|
|
|
|
|
pos.y = mCoBG_GetWaterHeight_File(pos, __FILE__, 1855);
|
|
|
|
|
eEC_CLIP->effect_make_proc(eEC_EFFECT_TURI_HAMON, pos, 1, actorx->world.angle.y, game, actorx->npc_id, 5, (s16)(actor->normalized_scale * 100.0f));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
actor->timer++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void aSMAN_process_air_init(ACTOR* actorx) {
|
|
|
|
|
SNOWMAN_ACTOR* actor = (SNOWMAN_ACTOR*)actorx;
|
|
|
|
|
f32 bg_y = mCoBG_GetBgY_AngleS_FromWpos(NULL, actorx->world.position, 0.0f);
|
|
|
|
|
f32 min_speed = (actor->normalized_scale * 20.0f + 10.0f) * 0.1f;
|
|
|
|
|
|
|
|
|
|
if (actorx->world.position.y - bg_y > 20.0f) {
|
|
|
|
|
sAdo_OngenTrgStart(0x43D, &actorx->world.position);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
actor->fall_height = actorx->world.position.y;
|
|
|
|
|
actorx->gravity = 0.8f;
|
|
|
|
|
actorx->max_velocity_y = -30.0f;
|
|
|
|
|
if (actorx->speed < min_speed) {
|
|
|
|
|
actorx->speed = min_speed;
|
|
|
|
|
}
|
|
|
|
|
actorx->position_speed.y = 3.2f;
|
|
|
|
|
actor->process = aSMAN_process_air;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int aSMAN_process_air(ACTOR* actorx, GAME* game) {
|
|
|
|
|
SNOWMAN_ACTOR* actor = (SNOWMAN_ACTOR*)actorx;
|
|
|
|
|
|
|
|
|
|
add_calc0(&actor->y_ofs, CALC_EASE(0.5f), 50.0f);
|
|
|
|
|
if (actorx->bg_collision_check.result.hit_wall & mCoBG_HIT_WALL) {
|
|
|
|
|
s16 wall_angle = mRlib_Get_HitWallAngleY(actorx);
|
|
|
|
|
|
|
|
|
|
add_calc_short_angle2(&actorx->world.angle.y, wall_angle, CALC_EASE2(0.2f), DEG2SHORT_ANGLE2(22.5f), 45);
|
|
|
|
|
add_calc(&actorx->speed, 3.0f, CALC_EASE(0.5f), 0.25f, 0.05f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (actorx->bg_collision_check.result.is_in_water) {
|
|
|
|
|
xyz_t pos = actorx->world.position;
|
|
|
|
|
|
|
|
|
|
pos.y = mCoBG_GetWaterHeight_File(pos, __FILE__, 1934);
|
|
|
|
|
eEC_CLIP->effect_make_proc(eEC_EFFECT_AMI_MIZU, pos, 1, 0, game, actorx->npc_id, 2, (s16)(actor->normalized_scale * 100.0f));
|
|
|
|
|
if (CLIP(gyo_clip) != NULL) {
|
|
|
|
|
CLIP(gyo_clip)->ballcheck_gyoei_proc(&actorx->world.position, (actorx->scale.x * 30.0f) / 0.03f, aGYO_BALLCHECK_TYPE_NORMAL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sAdo_OngenTrgStart(NA_SE_27, &actorx->world.position);
|
|
|
|
|
aSMAN_process_swim_init(actorx);
|
|
|
|
|
} else if (actorx->bg_collision_check.result.on_ground) {
|
|
|
|
|
if (actor->fall_height - actorx->world.position.y >= 55.0f || mCoBG_ExistHeightGap_KeepAndNow_Detail(actorx->world.position)) {
|
|
|
|
|
actor->flags |= aSMAN_FLAG_MOVED;
|
|
|
|
|
actor->flags |= aSMAN_FLAG_ON_GROUND;
|
|
|
|
|
} else {
|
|
|
|
|
aSMAN_process_normal_init(actorx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void aSMAN_process_hole_init(ACTOR* actorx) {
|
|
|
|
|
SNOWMAN_ACTOR* actor = (SNOWMAN_ACTOR*)actorx;
|
|
|
|
|
|
|
|
|
|
actorx->gravity = 0.0f;
|
|
|
|
|
actorx->speed = 0.0f;
|
|
|
|
|
actor->roll_speed = 0.0f;
|
|
|
|
|
actor->accel = 0.1f;
|
|
|
|
|
actor->base_speed = 0.0f;
|
|
|
|
|
actor->process = aSMAN_process_hole;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int aSMAN_process_hole(ACTOR* actorx, GAME* game) {
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int aSMAN_decide_scale_result(f32 head_scale, f32 body_scale) {
|
|
|
|
|
f32 ratio = head_scale / body_scale;
|
|
|
|
|
f32 adjusted_ratio = ABS(ratio - 0.85f);
|
|
|
|
|
int result;
|
|
|
|
|
|
|
|
|
|
if (adjusted_ratio <= 0.05f) { // [0%, 5%] margin = perfect
|
|
|
|
|
result = mSN_RESULT_PERFECT;
|
|
|
|
|
} else if (adjusted_ratio <= 0.15f) { // (5%, 15%] margin = good
|
|
|
|
|
result = mSN_RESULT_GOOD;
|
|
|
|
|
} else if (adjusted_ratio <= 0.25f) { // (15%, 25%] margin = okay
|
|
|
|
|
result = mSN_RESULT_OK;
|
|
|
|
|
} else { // anything larger = bad
|
|
|
|
|
result = mSN_RESULT_BAD;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int aSMAN_get_snowman_indx(void) {
|
|
|
|
|
mSN_snowman_data_c* snowman_p = Save_Get(snowmen).snowmen_data;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < mSN_SAVE_COUNT; i++) {
|
|
|
|
|
if (!snowman_p->exists) {
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
snowman_p++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void aSMAN_process_combine_head_jump_init(ACTOR* actorx, GAME* game) {
|
|
|
|
|
SNOWMAN_ACTOR* actor = (SNOWMAN_ACTOR*)actorx;
|
|
|
|
|
ACTOR* oc_actorx = actor->col_actor;
|
|
|
|
|
SNOWMAN_ACTOR* oc_actor = (SNOWMAN_ACTOR*)oc_actorx;
|
|
|
|
|
xyz_t oc_pos = oc_actorx->world.position;
|
|
|
|
|
xyz_t pos;
|
|
|
|
|
f32 height = (actor->normalized_scale * 20.0f + 10.0f) + (oc_actor->normalized_scale * 20.0f + 10.0f);
|
|
|
|
|
|
|
|
|
|
mPlib_request_main_demo_wait_type1(game, FALSE, actorx);
|
|
|
|
|
actor->flags |= aSMAN_FLAG_COMBINED;
|
|
|
|
|
actor->flags |= aSMAN_FLAG_HEAD_JUMP;
|
|
|
|
|
actor->timer = 0;
|
|
|
|
|
actorx->parent_actor = oc_actorx;
|
|
|
|
|
actor->roll_speed = 0.0f;
|
|
|
|
|
mFI_Wpos2UtCenterWpos(&pos, oc_pos);
|
|
|
|
|
oc_pos.y += height * 0.6f;
|
|
|
|
|
oc_pos.x = pos.x;
|
|
|
|
|
oc_pos.z = pos.z;
|
|
|
|
|
xyz_t_sub(&actorx->world.position, &oc_pos, &actor->combine_dist);
|
|
|
|
|
xyz_t_mult_v(&actor->combine_dist, 1.0f/60.0f);
|
|
|
|
|
actorx->shape_info.draw_shadow = FALSE;
|
|
|
|
|
actor->result = aSMAN_decide_scale_result(actorx->scale.x, oc_actorx->scale.x);
|
|
|
|
|
actor->msg_no = 0x08A1 + ((Common_Get(snowman_msg_id) + aSMAN_get_snowman_indx()) % mSN_SAVE_COUNT) + actor->result * 3;
|
|
|
|
|
actor->body_scale = oc_actor->normalized_scale;
|
|
|
|
|
|
|
|
|
|
if (actor->result == mSN_RESULT_PERFECT) {
|
|
|
|
|
aSMAN_SendPresentMail();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Save_Set(snowman_year, Common_Get(time.rtc_time.year) % 100);
|
|
|
|
|
Save_Set(snowman_month, Common_Get(time.rtc_time.month));
|
|
|
|
|
Save_Set(snowman_day, Common_Get(time.rtc_time.day));
|
|
|
|
|
Save_Set(snowman_hour, Common_Get(time.rtc_time.hour));
|
|
|
|
|
|
|
|
|
|
mQst_NextSnowman(actorx->world.position);
|
|
|
|
|
sAdo_OngenTrgStart(NA_SE_104, &actorx->world.position);
|
|
|
|
|
actor->process = aSMAN_process_combine_head_jump;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int aSMAN_process_combine_head_jump(ACTOR* actorx, GAME* game) {
|
|
|
|
|
SNOWMAN_ACTOR* actor = (SNOWMAN_ACTOR*)actorx;
|
|
|
|
|
|
|
|
|
|
if (actor->timer == 0 && mPlib_check_label_player_demo_wait(game, actorx)) {
|
|
|
|
|
mPlib_Set_able_force_speak_label(actorx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (actor->timer == 60) {
|
|
|
|
|
int i;
|
|
|
|
|
s16 angle = DEG2SHORT_ANGLE2(-90.0f);
|
|
|
|
|
xyz_t pos = actorx->world.position;
|
|
|
|
|
|
|
|
|
|
pos.y -= (actor->normalized_scale * 20.0f + 10.0f) * 0.7f;
|
|
|
|
|
for (i = 0; i < 5; i++) {
|
|
|
|
|
eEC_CLIP->effect_make_proc(eEC_EFFECT_DUST, pos, 1, angle, game, actorx->npc_id, 0, 9);
|
|
|
|
|
angle += DEG2SHORT_ANGLE2(45.0f);
|
|
|
|
|
}
|
|
|
|
|
actorx->shape_info.ofs_y = 0.0f;
|
|
|
|
|
aSMAN_FG_Position_Get(actorx);
|
|
|
|
|
aSMAN_process_combine_head_init(actorx);
|
|
|
|
|
return FALSE;
|
|
|
|
|
} else {
|
|
|
|
|
xyz_t_sub(&actorx->world.position, &actor->combine_dist, &actorx->world.position);
|
|
|
|
|
actorx->shape_info.ofs_y = (actor->timer * 8.0f + actor->timer * -(1.0f/7.5f) * actor->timer) * 25.0f;
|
|
|
|
|
add_calc_short_angle2(&actor->head_vec.x, 0, CALC_EASE(0.5f), DEG2SHORT_ANGLE2(22.5f), 91);
|
|
|
|
|
add_calc_short_angle2(&actor->head_vec.y, 0, CALC_EASE(0.5f), DEG2SHORT_ANGLE2(22.5f), 91);
|
|
|
|
|
add_calc_short_angle2(&actor->head_vec.z, 0, CALC_EASE(0.5f), DEG2SHORT_ANGLE2(22.5f), 91);
|
|
|
|
|
actor->timer++;
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void aSMAN_set_talk_info_combine_head_init(ACTOR* actorx) {
|
|
|
|
|
static int base_msg_no[] = { 0x0895, 0x0898, 0x089B, 0x089E };
|
|
|
|
|
SNOWMAN_ACTOR* actor = (SNOWMAN_ACTOR*)actorx;
|
|
|
|
|
|
|
|
|
|
actor->head_vec = ZeroSVec;
|
|
|
|
|
mDemo_Set_msg_num(base_msg_no[actor->result] + RANDOM(3));
|
|
|
|
|
mDemo_Set_talk_turn(TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void aSMAN_set_talk_info_normal_init(ACTOR* actorx) {
|
|
|
|
|
SNOWMAN_ACTOR* actor = (SNOWMAN_ACTOR*)actorx;
|
|
|
|
|
|
|
|
|
|
mDemo_Set_msg_num(actor->msg_no);
|
|
|
|
|
mDemo_Set_ListenAble();
|
|
|
|
|
mDemo_Set_camera(CAMERA2_PROCESS_NORMAL);
|
|
|
|
|
mPlib_Set_able_hand_all_item_in_demo(FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void aSMAN_process_combine_head_init(ACTOR* actorx) {
|
|
|
|
|
SNOWMAN_ACTOR* actor = (SNOWMAN_ACTOR*)actorx;
|
|
|
|
|
ACTOR* parentx = actorx->parent_actor;
|
|
|
|
|
SNOWMAN_ACTOR* parent = (SNOWMAN_ACTOR*)parentx;
|
|
|
|
|
f32 ofs_y;
|
|
|
|
|
f32 ofs;
|
|
|
|
|
|
|
|
|
|
ofs_y = ((actor->normalized_scale * 20.0f + 10.0f) + (parent->normalized_scale * 20.0f + 10.0f));
|
|
|
|
|
ofs_y *= 0.6f;
|
|
|
|
|
actor->timer = 0;
|
|
|
|
|
ofs = ((actorx->scale.y + actorx->parent_actor->scale.y) * 10.0f);
|
|
|
|
|
Actor_world_to_eye(actorx, (ofs * 0.8f) * 100.0f);
|
|
|
|
|
actorx->world.position.x = parentx->world.position.x;
|
|
|
|
|
actorx->world.position.z = parentx->world.position.z;
|
|
|
|
|
actorx->world.position.y = parentx->world.position.y + ofs_y;
|
|
|
|
|
actorx->shape_info.rotation.x = DEG2SHORT_ANGLE2(-17.578125f);
|
|
|
|
|
mCoBG_SetPlussOffset(actorx->world.position, 3, mCoBG_ATTRIBUTE_NONE);
|
|
|
|
|
if ((actorx->state_bitfield & ACTOR_STATE_NO_CULL) == 0) {
|
|
|
|
|
actor->flags |= aSMAN_FLAG_NO_SPEAK;
|
|
|
|
|
} else {
|
|
|
|
|
mDemo_Request(mDemo_TYPE_SPEAK, actorx, aSMAN_set_talk_info_combine_head_init);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
actor->process = aSMAN_process_combine_head;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int aSMAN_process_combine_head(ACTOR* actorx, GAME* game) {
|
|
|
|
|
SNOWMAN_ACTOR* actor = (SNOWMAN_ACTOR*)actorx;
|
|
|
|
|
|
|
|
|
|
if ((actor->flags & aSMAN_FLAG_NO_SPEAK) == 0) {
|
|
|
|
|
if (mDemo_Check(mDemo_TYPE_SPEAK, actorx) == TRUE) {
|
|
|
|
|
if (!mDemo_Check_ListenAble()) {
|
|
|
|
|
mDemo_Set_ListenAble();
|
|
|
|
|
mDemo_Set_camera(CAMERA2_PROCESS_NORMAL);
|
|
|
|
|
mPlib_Set_able_hand_all_item_in_demo(FALSE);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
actor->flags |= aSMAN_FLAG_NO_SPEAK;
|
|
|
|
|
}
|
|
|
|
|
} else if (!mRlib_PSnowman_NormalTalk(actorx, (GAME_PLAY*)game, &actor->impact_speed, aSMAN_set_talk_info_normal_init)) {
|
|
|
|
|
SNOWMAN_ACTOR* parent = (SNOWMAN_ACTOR*)actorx->parent_actor;
|
|
|
|
|
|
|
|
|
|
actor->flags |= aSMAN_FLAG_MOVED;
|
|
|
|
|
actor->flags |= aSMAN_FLAG_DELETE;
|
|
|
|
|
parent->flags |= aSMAN_FLAG_DELETE;
|
|
|
|
|
aSMAN_MakeBreakEffect(actor, game);
|
|
|
|
|
mQst_BackSnowman(actorx->world.position);
|
|
|
|
|
Actor_delete(actorx);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void aSMAN_process_combine_body_init(ACTOR* actorx) {
|
|
|
|
|
SNOWMAN_ACTOR* actor = (SNOWMAN_ACTOR*)actorx;
|
|
|
|
|
xyz_t pos;
|
|
|
|
|
f32 speed_x;
|
|
|
|
|
f32 speed_z;
|
|
|
|
|
|
|
|
|
|
mFI_Wpos2UtCenterWpos(&pos, actorx->world.position);
|
|
|
|
|
xyz_t_sub(&actorx->world.position, &pos, &actor->combine_dist);
|
|
|
|
|
xyz_t_mult_v(&actor->combine_dist, 1.0f/60.0f);
|
|
|
|
|
speed_x = actor->combine_dist.x;
|
|
|
|
|
speed_z = actor->combine_dist.z;
|
|
|
|
|
actor->roll_speed = sqrtf(SQ(speed_x) + SQ(speed_z));
|
|
|
|
|
actorx->world.angle.y = atans_table(-speed_z, -speed_x);
|
|
|
|
|
actor->timer = 0;
|
|
|
|
|
actorx->speed = 0.0f;
|
|
|
|
|
actor->accel = 0.0f;
|
|
|
|
|
actor->base_speed = 0.0f;
|
|
|
|
|
actor->process = aSMAN_process_combine_body;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int aSMAN_process_combine_body(ACTOR* actorx, GAME* game) {
|
|
|
|
|
SNOWMAN_ACTOR* actor = (SNOWMAN_ACTOR*)actorx;
|
|
|
|
|
|
|
|
|
|
if ((actor->flags & aSMAN_FLAG_COMBINED) == 0) {
|
|
|
|
|
if (actor->timer >= 60) {
|
|
|
|
|
actor->roll_speed = 0.0f;
|
|
|
|
|
actor->flags |= aSMAN_FLAG_COMBINED;
|
|
|
|
|
} else {
|
|
|
|
|
xyz_t_sub(&actorx->world.position, &actor->combine_dist, &actorx->world.position);
|
|
|
|
|
actor->timer++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((actor->flags & aSMAN_FLAG_DELETE) != 0) {
|
|
|
|
|
actor->flags |= aSMAN_FLAG_MOVED;
|
|
|
|
|
aSMAN_MakeBreakEffect(actor, game);
|
|
|
|
|
Actor_delete(actorx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void aSMAN_actor_move(ACTOR* actorx, GAME* game) {
|
|
|
|
|
SNOWMAN_ACTOR* actor = (SNOWMAN_ACTOR*)actorx;
|
|
|
|
|
GAME_PLAY* play = (GAME_PLAY*)game;
|
|
|
|
|
|
|
|
|
|
if ((actorx->state_bitfield & ACTOR_STATE_NO_CULL) == 0) {
|
|
|
|
|
if ((actor->flags & aSMAN_FLAG_COMBINED) != 0 && (actor->flags & aSMAN_FLAG_HEAD_JUMP) != 0 && !aSNOWMAN_player_block_check(actorx, game) && (actor->flags & aSMAN_FLAG_NO_SPEAK) != 0) {
|
|
|
|
|
Actor_delete(actorx);
|
|
|
|
|
Actor_delete(actorx->parent_actor);
|
|
|
|
|
return;
|
|
|
|
|
} else if (actorx->speed == 0.0f && actor->process != aSMAN_process_combine_head) {
|
|
|
|
|
actor->col_pipe.collision_obj.collision_flags0 &= ~ClObj_FLAG_COLLIDED;
|
|
|
|
|
actor->col_pipe.collision_obj.collided_actor = NULL;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
aSMAN_status_check_in_move(actor, game);
|
|
|
|
|
aSMAN_position_move(actorx);
|
|
|
|
|
aSMAN_BGcheck(actorx, game);
|
|
|
|
|
actor->process(actorx, game);
|
|
|
|
|
aSMAN_calc_objChkRange(actorx);
|
|
|
|
|
aSMAN_calc_axis(actorx);
|
|
|
|
|
|
|
|
|
|
if ((actor->flags & aSMAN_FLAG_COMBINED) == 0) {
|
|
|
|
|
CollisionCheck_Uty_ActorWorldPosSetPipeC(actorx, &actor->col_pipe);
|
|
|
|
|
CollisionCheck_setOC(game, &play->collision_check, &actor->col_pipe.collision_obj);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern Gfx act_darumaA_model[];
|
|
|
|
|
extern Gfx act_darumaB_model[];
|
|
|
|
|
|
|
|
|
|
static void aSMAN_actor_draw(ACTOR* actorx, GAME* game) {
|
|
|
|
|
static Gfx* displayList[] = { act_darumaA_model, act_darumaB_model };
|
|
|
|
|
SNOWMAN_ACTOR* actor = (SNOWMAN_ACTOR*)actorx;
|
|
|
|
|
GRAPH* graph = game->graph;
|
|
|
|
|
int idx;
|
|
|
|
|
|
|
|
|
|
if ((actor->flags & aSMAN_FLAG_HEAD_JUMP) == 0 || actor->process != aSMAN_process_combine_head) {
|
|
|
|
|
Matrix_translate(0.0f, actor->y_ofs, 0.0, 1);
|
|
|
|
|
Matrix_rotateXYZ(actor->head_vec.x, actor->head_vec.y, actor->head_vec.z, 1);
|
|
|
|
|
idx = 1;
|
|
|
|
|
} else {
|
|
|
|
|
idx = 0;
|
|
|
|
|
mRlib_PSnowmanBreakNeckSwing(&actor->head_vec.y, actor->impact_speed, actor->normalized_scale);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_texture_z_light_fog_prim(graph);
|
|
|
|
|
|
|
|
|
|
OPEN_POLY_OPA_DISP(graph);
|
|
|
|
|
|
|
|
|
|
gDPPipeSync(POLY_OPA_DISP++);
|
|
|
|
|
gSPMatrix(POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
|
|
|
gSPDisplayList(POLY_OPA_DISP++, displayList[idx]);
|
|
|
|
|
|
|
|
|
|
CLOSE_POLY_OPA_DISP(graph);
|
|
|
|
|
}
|
|
|
|
|