racing_penguin.inc.c (6907B)
1 // racing_penguin.inc.c 2 3 struct RacingPenguinData { 4 s16 dialogID; 5 f32 radius; 6 f32 height; 7 }; 8 9 static struct RacingPenguinData sRacingPenguinData[] = { 10 /* RACING_PENGUIN_BP_THIN */ { DIALOG_055, 200.0f, 200.0f }, 11 /* RACING_PENGUIN_BP_FAT */ { DIALOG_164, 350.0f, 250.0f }, 12 }; 13 14 void bhv_racing_penguin_init(void) { 15 if (gMarioState->numStars == 120) { 16 cur_obj_scale(8.0f); 17 o->header.gfx.scale[1] = 5.0f; 18 o->oBhvParams2ndByte = RACING_PENGUIN_BP_FAT; 19 } 20 } 21 22 static void racing_penguin_act_wait_for_mario(void) { 23 if (o->oTimer > o->oRacingPenguinInitTextCooldown && o->oPosY - gMarioObject->oPosY <= 0.0f 24 && cur_obj_can_mario_activate_textbox_2(400.0f, 400.0f)) { 25 o->oAction = RACING_PENGUIN_ACT_SHOW_INIT_TEXT; 26 } 27 } 28 29 static void racing_penguin_act_show_init_text(void) { 30 s32 response = obj_update_race_proposition_dialog(sRacingPenguinData[o->oBhvParams2ndByte].dialogID); 31 32 if (response == DIALOG_RESPONSE_YES) { 33 struct Object *child; 34 35 child = cur_obj_nearest_object_with_behavior(bhvPenguinRaceFinishLine); 36 child->parentObj = o; 37 38 child = cur_obj_nearest_object_with_behavior(bhvPenguinRaceShortcutCheck); 39 child->parentObj = o; 40 41 o->oPathedStartWaypoint = o->oPathedPrevWaypoint = 42 segmented_to_virtual(ccm_seg7_trajectory_penguin_race); 43 o->oPathedPrevWaypointFlags = 0; 44 45 o->oAction = RACING_PENGUIN_ACT_PREPARE_FOR_RACE; 46 o->oVelY = 60.0f; 47 } else if (response == DIALOG_RESPONSE_NO) { 48 o->oAction = RACING_PENGUIN_ACT_WAIT_FOR_MARIO; 49 o->oRacingPenguinInitTextCooldown = 60; 50 } 51 } 52 53 static void racing_penguin_act_prepare_for_race(void) { 54 if (obj_begin_race(TRUE)) { 55 o->oAction = RACING_PENGUIN_ACT_RACE; 56 o->oForwardVel = 20.0f; 57 } 58 59 cur_obj_rotate_yaw_toward(0x4000, 2500); 60 } 61 62 static void racing_penguin_act_race(void) { 63 if (cur_obj_follow_path(0) == PATH_REACHED_END) { 64 o->oRacingPenguinReachedBottom = TRUE; 65 o->oAction = RACING_PENGUIN_ACT_FINISH_RACE; 66 } else { 67 f32 targetSpeed = o->oPosY - gMarioObject->oPosY; 68 f32 minSpeed = 70.0f; 69 70 cur_obj_play_sound_1(SOUND_AIR_ROUGH_SLIDE); 71 72 if (targetSpeed < 100.0f || (o->oPathedPrevWaypointFlags & WAYPOINT_MASK_00FF) >= 35) { 73 if ((o->oPathedPrevWaypointFlags & WAYPOINT_MASK_00FF) >= 35) { 74 minSpeed = 60.0f; 75 } 76 77 approach_f32_ptr(&o->oRacingPenguinWeightedNewTargetSpeed, -500.0f, 100.0f); 78 } else { 79 approach_f32_ptr(&o->oRacingPenguinWeightedNewTargetSpeed, 1000.0f, 30.0f); 80 } 81 82 targetSpeed = 0.1f * (o->oRacingPenguinWeightedNewTargetSpeed + targetSpeed); 83 clamp_f32(&targetSpeed, minSpeed, 150.0f); 84 obj_forward_vel_approach(targetSpeed, 0.4f); 85 86 cur_obj_init_animation_with_sound(1); 87 cur_obj_rotate_yaw_toward(o->oPathedTargetYaw, (s32)(15.0f * o->oForwardVel)); 88 89 if (cur_obj_check_if_at_animation_end() && (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND)) { 90 spawn_object_relative_with_scale(0, 0, -100, 0, 4.0f, o, MODEL_SMOKE, bhvWhitePuffSmoke2); 91 } 92 } 93 94 if (mario_is_in_air_action()) { 95 if (o->oTimer > 60) { 96 o->oRacingPenguinMarioCheated = TRUE; 97 } 98 } else { 99 o->oTimer = 0; 100 } 101 } 102 103 static void racing_penguin_act_finish_race(void) { 104 if (o->oForwardVel != 0.0f) { 105 if (o->oTimer > 5 && (o->oMoveFlags & OBJ_MOVE_HIT_WALL)) { 106 cur_obj_play_sound_2(SOUND_OBJ_POUNDING_LOUD); 107 set_camera_shake_from_point(SHAKE_POS_SMALL, o->oPosX, o->oPosY, o->oPosZ); 108 o->oForwardVel = 0.0f; 109 } 110 } else if (cur_obj_init_anim_and_check_if_end(2)) { 111 o->oAction = RACING_PENGUIN_ACT_SHOW_FINAL_TEXT; 112 } 113 } 114 115 static void racing_penguin_act_show_final_text(void) { 116 if (o->oRacingPenguinFinalTextbox == 0) { 117 if (cur_obj_rotate_yaw_toward(0, 200)) { 118 cur_obj_init_animation_with_sound(3); 119 o->oForwardVel = 0.0f; 120 121 if (cur_obj_can_mario_activate_textbox_2(400.0f, 400.0f)) { 122 if (o->oRacingPenguinMarioWon) { 123 if (o->oRacingPenguinMarioCheated) { 124 o->oRacingPenguinFinalTextbox = DIALOG_132; 125 o->oRacingPenguinMarioWon = FALSE; 126 } else { 127 o->oRacingPenguinFinalTextbox = DIALOG_056; 128 } 129 } else { 130 o->oRacingPenguinFinalTextbox = DIALOG_037; 131 } 132 } 133 } else { 134 cur_obj_init_animation_with_sound(0); 135 136 #ifndef VERSION_JP 137 play_penguin_walking_sound(1); 138 #endif 139 140 o->oForwardVel = 4.0f; 141 } 142 } else if (o->oRacingPenguinFinalTextbox > 0) { 143 s32 textResult; 144 if ((textResult = cur_obj_update_dialog_with_cutscene(MARIO_DIALOG_LOOK_UP, 145 DIALOG_FLAG_TURN_TO_MARIO, CUTSCENE_DIALOG, o->oRacingPenguinFinalTextbox))) { 146 o->oRacingPenguinFinalTextbox = -1; 147 o->oTimer = 0; 148 } 149 } else if (o->oRacingPenguinMarioWon) { 150 #ifdef VERSION_JP 151 spawn_default_star(-7339.0f, -5700.0f, -6774.0f); 152 #else 153 cur_obj_spawn_star_at_y_offset(-7339.0f, -5700.0f, -6774.0f, 200.0f); 154 #endif 155 o->oRacingPenguinMarioWon = FALSE; 156 } 157 } 158 159 void bhv_racing_penguin_update(void) { 160 cur_obj_update_floor_and_walls(); 161 162 switch (o->oAction) { 163 case RACING_PENGUIN_ACT_WAIT_FOR_MARIO: 164 racing_penguin_act_wait_for_mario(); 165 break; 166 case RACING_PENGUIN_ACT_SHOW_INIT_TEXT: 167 racing_penguin_act_show_init_text(); 168 break; 169 case RACING_PENGUIN_ACT_PREPARE_FOR_RACE: 170 racing_penguin_act_prepare_for_race(); 171 break; 172 case RACING_PENGUIN_ACT_RACE: 173 racing_penguin_act_race(); 174 break; 175 case RACING_PENGUIN_ACT_FINISH_RACE: 176 racing_penguin_act_finish_race(); 177 break; 178 case RACING_PENGUIN_ACT_SHOW_FINAL_TEXT: 179 racing_penguin_act_show_final_text(); 180 break; 181 } 182 183 cur_obj_move_standard(78); 184 cur_obj_align_gfx_with_floor(); 185 cur_obj_push_mario_away_from_cylinder(sRacingPenguinData[o->oBhvParams2ndByte].radius, 186 sRacingPenguinData[o->oBhvParams2ndByte].height); 187 } 188 189 void bhv_penguin_race_finish_line_update(void) { 190 if ((o->parentObj->oRacingPenguinReachedBottom 191 || (o->oDistanceToMario < 1000.0f && gMarioObject->oPosZ - o->oPosZ < 0.0f)) 192 && !o->parentObj->oRacingPenguinReachedBottom) { 193 o->parentObj->oRacingPenguinMarioWon = TRUE; 194 } 195 } 196 197 void bhv_penguin_race_shortcut_check_update(void) { 198 if (o->oDistanceToMario < 500.0f) { 199 o->parentObj->oRacingPenguinMarioCheated = TRUE; 200 } 201 }