205 lines
6.6 KiB
C
205 lines
6.6 KiB
C
struct RacingPenguinData {
|
|
s16 text;
|
|
f32 radius;
|
|
f32 height;
|
|
};
|
|
|
|
static struct RacingPenguinData sRacingPenguinData[] = {
|
|
{ DIALOG_055, 200.0f, 200.0f },
|
|
{ DIALOG_164, 350.0f, 250.0f },
|
|
};
|
|
|
|
void bhv_racing_penguin_init(void) {
|
|
if (gMarioState->numStars == 120) {
|
|
cur_obj_scale(8.0f);
|
|
o->header.gfx.scale[1] = 5.0f;
|
|
o->oBehParams2ndByte = 1;
|
|
}
|
|
}
|
|
|
|
static void racing_penguin_act_wait_for_mario(void) {
|
|
if (o->oTimer > o->oRacingPenguinInitTextCooldown && o->oPosY - gMarioObject->oPosY <= 0.0f
|
|
&& cur_obj_can_mario_activate_textbox_2(400.0f, 400.0f)) {
|
|
o->oAction = RACING_PENGUIN_ACT_SHOW_INIT_TEXT;
|
|
}
|
|
}
|
|
|
|
static void racing_penguin_act_show_init_text(void) {
|
|
s32 response;
|
|
struct Object *child;
|
|
|
|
response = obj_update_race_proposition_dialog(sRacingPenguinData[o->oBehParams2ndByte].text);
|
|
if (response == 1) {
|
|
child = cur_obj_nearest_object_with_behavior(bhvPenguinRaceFinishLine);
|
|
child->parentObj = o;
|
|
|
|
child = cur_obj_nearest_object_with_behavior(bhvPenguinRaceShortcutCheck);
|
|
child->parentObj = o;
|
|
|
|
o->oPathedStartWaypoint = o->oPathedPrevWaypoint =
|
|
segmented_to_virtual(ccm_seg7_trajectory_penguin_race);
|
|
o->oPathedPrevWaypointFlags = 0;
|
|
|
|
o->oAction = RACING_PENGUIN_ACT_PREPARE_FOR_RACE;
|
|
o->oVelY = 60.0f;
|
|
;
|
|
} else if (response == 2) {
|
|
o->oAction = RACING_PENGUIN_ACT_WAIT_FOR_MARIO;
|
|
o->oRacingPenguinInitTextCooldown = 60;
|
|
}
|
|
}
|
|
|
|
static void racing_penguin_act_prepare_for_race(void) {
|
|
if (obj_begin_race(TRUE)) {
|
|
o->oAction = RACING_PENGUIN_ACT_RACE;
|
|
o->oForwardVel = 20.0f;
|
|
}
|
|
|
|
cur_obj_rotate_yaw_toward(0x4000, 2500);
|
|
}
|
|
|
|
static void racing_penguin_act_race(void) {
|
|
f32 targetSpeed;
|
|
f32 minSpeed;
|
|
|
|
if (cur_obj_follow_path(0) == PATH_REACHED_END) {
|
|
o->oRacingPenguinReachedBottom = TRUE;
|
|
o->oAction = RACING_PENGUIN_ACT_FINISH_RACE;
|
|
} else {
|
|
targetSpeed = o->oPosY - gMarioObject->oPosY;
|
|
minSpeed = 70.0f;
|
|
|
|
cur_obj_play_sound_1(SOUND_AIR_ROUGH_SLIDE);
|
|
|
|
if (targetSpeed < 100.0f || (o->oPathedPrevWaypointFlags & WAYPOINT_MASK_00FF) >= 35) {
|
|
if ((o->oPathedPrevWaypointFlags & WAYPOINT_MASK_00FF) >= 35) {
|
|
minSpeed = 60.0f;
|
|
}
|
|
|
|
approach_f32_ptr(&o->oRacingPenguinWeightedNewTargetSpeed, -500.0f, 100.0f);
|
|
} else {
|
|
approach_f32_ptr(&o->oRacingPenguinWeightedNewTargetSpeed, 1000.0f, 30.0f);
|
|
}
|
|
|
|
targetSpeed = 0.1f * (o->oRacingPenguinWeightedNewTargetSpeed + targetSpeed);
|
|
clamp_f32(&targetSpeed, minSpeed, 150.0f);
|
|
obj_forward_vel_approach(targetSpeed, 0.4f);
|
|
|
|
cur_obj_init_animation_with_sound(1);
|
|
cur_obj_rotate_yaw_toward(o->oPathedTargetYaw, (s32)(15.0f * o->oForwardVel));
|
|
|
|
if (cur_obj_check_if_at_animation_end() && (o->oMoveFlags & 0x00000003)) {
|
|
spawn_object_relative_with_scale(0, 0, -100, 0, 4.0f, o, MODEL_SMOKE, bhvWhitePuffSmoke2);
|
|
}
|
|
}
|
|
|
|
if (mario_is_in_air_action()) {
|
|
if (o->oTimer > 60) {
|
|
o->oRacingPenguinMarioCheated = TRUE;
|
|
}
|
|
} else {
|
|
o->oTimer = 0;
|
|
}
|
|
}
|
|
|
|
static void racing_penguin_act_finish_race(void) {
|
|
if (o->oForwardVel != 0.0f) {
|
|
if (o->oTimer > 5 && (o->oMoveFlags & 0x00000200)) {
|
|
cur_obj_play_sound_2(SOUND_OBJ_POUNDING_LOUD);
|
|
set_camera_shake_from_point(SHAKE_POS_SMALL, o->oPosX, o->oPosY, o->oPosZ);
|
|
o->oForwardVel = 0.0f;
|
|
}
|
|
} else if (cur_obj_init_anim_and_check_if_end(2) != 0) {
|
|
o->oAction = RACING_PENGUIN_ACT_SHOW_FINAL_TEXT;
|
|
}
|
|
}
|
|
|
|
static void racing_penguin_act_show_final_text(void) {
|
|
s32 textResult;
|
|
|
|
if (o->oRacingPenguinFinalTextbox == 0) {
|
|
if (cur_obj_rotate_yaw_toward(0, 200)) {
|
|
cur_obj_init_animation_with_sound(3);
|
|
o->oForwardVel = 0.0f;
|
|
|
|
if (cur_obj_can_mario_activate_textbox_2(400.0f, 400.0f)) {
|
|
if (o->oRacingPenguinMarioWon) {
|
|
if (o->oRacingPenguinMarioCheated) {
|
|
o->oRacingPenguinFinalTextbox = DIALOG_132;
|
|
o->oRacingPenguinMarioWon = FALSE;
|
|
} else {
|
|
o->oRacingPenguinFinalTextbox = DIALOG_056;
|
|
}
|
|
} else {
|
|
o->oRacingPenguinFinalTextbox = DIALOG_037;
|
|
}
|
|
}
|
|
} else {
|
|
cur_obj_init_animation_with_sound(0);
|
|
|
|
#ifndef VERSION_JP
|
|
play_penguin_walking_sound(1);
|
|
#endif
|
|
|
|
o->oForwardVel = 4.0f;
|
|
}
|
|
} else if (o->oRacingPenguinFinalTextbox > 0) {
|
|
if ((textResult = cur_obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG, o->oRacingPenguinFinalTextbox)) != 0) {
|
|
o->oRacingPenguinFinalTextbox = -1;
|
|
o->oTimer = 0;
|
|
}
|
|
} else if (o->oRacingPenguinMarioWon) {
|
|
#ifdef VERSION_JP
|
|
spawn_default_star(-7339.0f, -5700.0f, -6774.0f);
|
|
#else
|
|
cur_obj_spawn_star_at_y_offset(-7339.0f, -5700.0f, -6774.0f, 200.0f);
|
|
#endif
|
|
o->oRacingPenguinMarioWon = FALSE;
|
|
}
|
|
}
|
|
|
|
void bhv_racing_penguin_update(void) {
|
|
cur_obj_update_floor_and_walls();
|
|
|
|
switch (o->oAction) {
|
|
case RACING_PENGUIN_ACT_WAIT_FOR_MARIO:
|
|
racing_penguin_act_wait_for_mario();
|
|
break;
|
|
case RACING_PENGUIN_ACT_SHOW_INIT_TEXT:
|
|
racing_penguin_act_show_init_text();
|
|
break;
|
|
case RACING_PENGUIN_ACT_PREPARE_FOR_RACE:
|
|
racing_penguin_act_prepare_for_race();
|
|
break;
|
|
case RACING_PENGUIN_ACT_RACE:
|
|
racing_penguin_act_race();
|
|
break;
|
|
case RACING_PENGUIN_ACT_FINISH_RACE:
|
|
racing_penguin_act_finish_race();
|
|
break;
|
|
case RACING_PENGUIN_ACT_SHOW_FINAL_TEXT:
|
|
racing_penguin_act_show_final_text();
|
|
break;
|
|
}
|
|
|
|
cur_obj_move_standard(78);
|
|
cur_obj_align_gfx_with_floor();
|
|
cur_obj_push_mario_away_from_cylinder(sRacingPenguinData[o->oBehParams2ndByte].radius,
|
|
sRacingPenguinData[o->oBehParams2ndByte].height);
|
|
}
|
|
|
|
void bhv_penguin_race_finish_line_update(void) {
|
|
if (o->parentObj->oRacingPenguinReachedBottom
|
|
|| (o->oDistanceToMario < 1000.0f && gMarioObject->oPosZ - o->oPosZ < 0.0f)) {
|
|
if (!o->parentObj->oRacingPenguinReachedBottom) {
|
|
o->parentObj->oRacingPenguinMarioWon = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
void bhv_penguin_race_shortcut_check_update(void) {
|
|
if (o->oDistanceToMario < 500.0f) {
|
|
o->parentObj->oRacingPenguinMarioCheated = TRUE;
|
|
}
|
|
}
|