sm64pc/src/game/behaviors/intro_lakitu.inc.c

227 lines
9.2 KiB
C
Raw Normal View History

2019-11-03 19:36:27 +00:00
/**
* @file intro_lakitu.inc.c
* This file implements lakitu's behvaior during the intro cutscene.
* It's also used during the ending cutscene.
*/
/**
* Add the camera's position to `offset`, rotate the point to be relative to the camera's focus, then
* set lakitu's location.
*/
void intro_lakitu_set_offset_from_camera(struct Object *o, Vec3f offset) {
f32 dist;
Vec3s focusAngles;
s16 offsetPitch, offsetYaw;
2020-01-03 15:38:57 +00:00
vec3f_add(offset, gCamera->pos);
vec3f_get_dist_and_angle(gCamera->pos, gCamera->focus,
2019-11-03 19:36:27 +00:00
&dist, &focusAngles[0], &focusAngles[1]);
2020-01-03 15:38:57 +00:00
vec3f_get_dist_and_angle(gCamera->pos, offset, &dist, &offsetPitch, &offsetYaw);
vec3f_set_dist_and_angle(gCamera->pos, offset, dist,
2019-11-03 19:36:27 +00:00
focusAngles[0] + offsetPitch, focusAngles[1] + offsetYaw);
vec3f_to_object_pos(o, offset);
2019-09-01 19:50:50 +00:00
}
2019-11-03 19:36:27 +00:00
void intro_lakitu_set_focus(struct Object *o, Vec3f newFocus) {
UNUSED Vec3f unusedVec3f;
Vec3f origin;
f32 dist;
s16 pitch, yaw;
UNUSED u32 unused;
// newFocus is an offset from lakitu's origin, not a point in the world.
vec3f_set(origin, 0.f, 0.f, 0.f);
vec3f_get_dist_and_angle(origin, newFocus, &dist, &pitch, &yaw);
o->oFaceAnglePitch = pitch;
o->oFaceAngleYaw = yaw;
2019-09-01 19:50:50 +00:00
}
2019-11-03 19:36:27 +00:00
/**
* Move lakitu along the spline `offset`, relative to the camera, and face him towards the corresponding
* location along the spline `focus`.
*/
s32 intro_lakitu_set_pos_and_focus(struct Object *o, struct CutsceneSplinePoint offset[],
struct CutsceneSplinePoint focus[]) {
Vec3f newOffset, newFocus;
s32 splineFinished = 0;
s16 splineSegment = o->oIntroLakituSplineSegment;
2019-09-01 19:50:50 +00:00
2019-11-03 19:36:27 +00:00
if ((move_point_along_spline(newFocus, offset, &splineSegment, &(o->oIntroLakituSplineSegmentProgress)) == 1)
|| (move_point_along_spline(newOffset, focus, &splineSegment, &(o->oIntroLakituSplineSegmentProgress)) == 1))
splineFinished += 1;
2019-09-01 19:50:50 +00:00
2019-11-03 19:36:27 +00:00
o->oIntroLakituSplineSegment = splineSegment;
intro_lakitu_set_offset_from_camera(o, newOffset);
intro_lakitu_set_focus(o, newFocus);
return splineFinished;
2019-09-01 19:50:50 +00:00
}
void bhv_intro_lakitu_loop(void) {
Vec3f sp64, sp58, sp4C;
UNUSED u32 pad[4];
switch (gCurrentObject->oAction) {
case 0:
2020-03-02 03:42:52 +00:00
cur_obj_disable_rendering();
2019-11-03 19:36:27 +00:00
gCurrentObject->oIntroLakituSplineSegment = 0.f;
gCurrentObject->oIntroLakituSplineSegmentProgress = 0.f;
gCurrentObject->oIntroLakituCloud =
2019-09-01 19:50:50 +00:00
spawn_object_relative_with_scale(1, 0, 0, 0, 2.f, gCurrentObject, MODEL_MIST, bhvCloud);
2020-01-03 15:38:57 +00:00
if (gCamera->cutscene == CUTSCENE_END_WAVING)
2019-09-01 19:50:50 +00:00
gCurrentObject->oAction = 100;
else
gCurrentObject->oAction += 1;
break;
case 1:
2020-03-02 03:42:52 +00:00
cur_obj_enable_rendering();
2019-09-01 19:50:50 +00:00
if ((gCutsceneTimer > 350) && (gCutsceneTimer < 458)) {
2020-01-03 15:38:57 +00:00
gCurrentObject->oPosX = gCamera->pos[0];
gCurrentObject->oPosY = gCamera->pos[1] + 500.f;
gCurrentObject->oPosZ = gCamera->pos[2];
2019-09-01 19:50:50 +00:00
}
if (gCutsceneTimer > 52)
2020-03-02 03:42:52 +00:00
cur_obj_play_sound_1(SOUND_AIR_LAKITU_FLY_HIGHPRIO);
2019-11-03 19:36:27 +00:00
if (intro_lakitu_set_pos_and_focus(gCurrentObject, gIntroLakituStartToPipeOffsetFromCamera,
gIntroLakituStartToPipeFocus) == 1)
2019-09-01 19:50:50 +00:00
gCurrentObject->oAction += 1;
switch (gCurrentObject->oTimer) {
2020-04-03 18:57:26 +00:00
#if defined(VERSION_US) || defined(VERSION_SH)
2019-09-01 19:50:50 +00:00
case 534:
2020-03-02 03:42:52 +00:00
cur_obj_play_sound_2(SOUND_ACTION_FLYING_FAST);
2019-09-01 19:50:50 +00:00
break;
case 581:
2020-03-02 03:42:52 +00:00
cur_obj_play_sound_2(SOUND_ACTION_INTRO_UNK45E);
2019-09-01 19:50:50 +00:00
break;
#endif
case 73:
gCurrentObject->oAnimState += 1;
break;
case 74:
gCurrentObject->oAnimState -= 1;
break;
case 82:
gCurrentObject->oAnimState += 1;
break;
case 84:
gCurrentObject->oAnimState -= 1;
break;
}
#ifdef VERSION_EU
if (gCurrentObject->oTimer == 446)
2020-03-02 03:42:52 +00:00
cur_obj_play_sound_2(SOUND_ACTION_FLYING_FAST);
2019-09-01 19:50:50 +00:00
if (gCurrentObject->oTimer == 485)
2020-03-02 03:42:52 +00:00
cur_obj_play_sound_2(SOUND_ACTION_INTRO_UNK45E);
2019-09-01 19:50:50 +00:00
#endif
break;
case 2:
2020-02-03 05:51:26 +00:00
#ifdef VERSION_EU
if (gCutsceneTimer > 599) {
#else
2019-09-01 19:50:50 +00:00
if (gCutsceneTimer > 720) {
2020-02-03 05:51:26 +00:00
#endif
2019-09-01 19:50:50 +00:00
gCurrentObject->oAction += 1;
gCurrentObject->oIntroLakituUnk100 = 1400.f;
gCurrentObject->oIntroLakituUnk104 = -4096.f;
gCurrentObject->oIntroLakituUnk108 = 2048.f;
gCurrentObject->oIntroLakituUnk10C = -200.f;
gCurrentObject->oMoveAngleYaw = 0x8000;
gCurrentObject->oFaceAngleYaw = gCurrentObject->oMoveAngleYaw + 0x4000;
gCurrentObject->oMoveAnglePitch = 0x800;
}
2020-03-02 03:42:52 +00:00
cur_obj_play_sound_1(SOUND_AIR_LAKITU_FLY_HIGHPRIO);
2019-09-01 19:50:50 +00:00
break;
case 3:
2020-03-02 03:42:52 +00:00
cur_obj_play_sound_1(SOUND_AIR_LAKITU_FLY_HIGHPRIO);
2019-09-01 19:50:50 +00:00
vec3f_set(sp58, -1128.f, 560.f, 4664.f);
gCurrentObject->oMoveAngleYaw += 0x200;
gCurrentObject->oIntroLakituUnk100 =
2020-01-03 15:38:57 +00:00
approach_f32_asymptotic(gCurrentObject->oIntroLakituUnk100, 100.f, 0.03f);
2019-09-01 19:50:50 +00:00
gCurrentObject->oFaceAnglePitch = atan2s(200.f, gCurrentObject->oPosY - 400.f);
2020-01-03 15:38:57 +00:00
gCurrentObject->oFaceAngleYaw = approach_s16_asymptotic(
2019-09-01 19:50:50 +00:00
gCurrentObject->oFaceAngleYaw, gCurrentObject->oMoveAngleYaw + 0x8000, 4);
vec3f_set_dist_and_angle(sp58, sp4C, gCurrentObject->oIntroLakituUnk100, 0,
gCurrentObject->oMoveAngleYaw);
sp4C[1] += 150.f * coss((s16) gCurrentObject->oIntroLakituUnk104);
gCurrentObject->oIntroLakituUnk104 += gCurrentObject->oIntroLakituUnk108;
gCurrentObject->oIntroLakituUnk108 =
2020-01-03 15:38:57 +00:00
approach_f32_asymptotic(gCurrentObject->oIntroLakituUnk108, 512.f, 0.05f);
2019-09-01 19:50:50 +00:00
sp4C[0] += gCurrentObject->oIntroLakituUnk10C;
gCurrentObject->oIntroLakituUnk10C =
2020-01-03 15:38:57 +00:00
approach_f32_asymptotic(gCurrentObject->oIntroLakituUnk10C, 0.f, 0.05f);
2019-09-01 19:50:50 +00:00
vec3f_to_object_pos(gCurrentObject, sp4C);
if (gCurrentObject->oTimer == 31) {
gCurrentObject->oPosY -= 158.f;
2019-11-03 19:36:27 +00:00
// Spawn white ground particles
2020-03-02 03:42:52 +00:00
spawn_mist_from_global();
2019-09-01 19:50:50 +00:00
gCurrentObject->oPosY += 158.f;
}
#ifdef VERSION_EU
#define TIMER 74
#else
#define TIMER 98
#endif
if (gCurrentObject->oTimer == TIMER) {
2020-03-02 03:42:52 +00:00
obj_mark_for_deletion(gCurrentObject);
obj_mark_for_deletion(gCurrentObject->oIntroLakituCloud);
2019-09-01 19:50:50 +00:00
}
#ifndef VERSION_JP
if (gCurrentObject->oTimer == 14)
2020-03-02 03:42:52 +00:00
cur_obj_play_sound_2(SOUND_ACTION_INTRO_UNK45F);
2019-09-01 19:50:50 +00:00
#endif
break;
case 100:
2020-03-02 03:42:52 +00:00
cur_obj_enable_rendering();
2019-09-01 19:50:50 +00:00
vec3f_set(sp64, -100.f, 100.f, 300.f);
2020-01-03 15:38:57 +00:00
offset_rotated(sp4C, gCamera->pos, sp64, sMarioCamState->faceAngle);
2019-09-01 19:50:50 +00:00
vec3f_to_object_pos(gCurrentObject, sp4C);
gCurrentObject->oMoveAnglePitch = 0x1000;
gCurrentObject->oMoveAngleYaw = 0x9000;
gCurrentObject->oFaceAnglePitch = gCurrentObject->oMoveAnglePitch / 2;
gCurrentObject->oFaceAngleYaw = gCurrentObject->oMoveAngleYaw;
gCurrentObject->oAction += 1;
break;
case 101:
object_pos_to_vec3f(sp4C, gCurrentObject);
if (gCurrentObject->oTimer > 60) {
gCurrentObject->oForwardVel =
2020-01-03 15:38:57 +00:00
approach_f32_asymptotic(gCurrentObject->oForwardVel, -10.f, 0.05f);
2019-09-01 19:50:50 +00:00
gCurrentObject->oMoveAngleYaw += 0x78;
gCurrentObject->oMoveAnglePitch += 0x40;
gCurrentObject->oFaceAngleYaw = camera_approach_s16_symmetric(
2020-01-03 15:38:57 +00:00
gCurrentObject->oFaceAngleYaw, (s16) calculate_yaw(sp4C, gCamera->pos),
2019-09-01 19:50:50 +00:00
0x200);
}
if (gCurrentObject->oTimer > 105) {
gCurrentObject->oAction += 1;
gCurrentObject->oMoveAnglePitch = 0xE00;
}
gCurrentObject->oFaceAnglePitch = 0;
2020-03-02 03:42:52 +00:00
cur_obj_set_pos_via_transform();
2019-09-01 19:50:50 +00:00
break;
case 102:
object_pos_to_vec3f(sp4C, gCurrentObject);
gCurrentObject->oForwardVel =
2020-01-03 15:38:57 +00:00
approach_f32_asymptotic(gCurrentObject->oForwardVel, 60.f, 0.05f);
2019-09-01 19:50:50 +00:00
gCurrentObject->oFaceAngleYaw = camera_approach_s16_symmetric(
2020-01-03 15:38:57 +00:00
gCurrentObject->oFaceAngleYaw, (s16) calculate_yaw(sp4C, gCamera->pos), 0x200);
2019-09-01 19:50:50 +00:00
if (gCurrentObject->oTimer < 62)
gCurrentObject->oMoveAngleYaw =
2020-01-03 15:38:57 +00:00
approach_s16_asymptotic(gCurrentObject->oMoveAngleYaw, 0x1800, 0x1E);
2019-09-01 19:50:50 +00:00
gCurrentObject->oMoveAnglePitch =
camera_approach_s16_symmetric(gCurrentObject->oMoveAnglePitch, -0x2000, 0x5A);
gCurrentObject->oFaceAnglePitch = 0;
2020-03-02 03:42:52 +00:00
cur_obj_set_pos_via_transform();
2019-09-01 19:50:50 +00:00
break;
}
}
#undef TIMER