sm64pc/src/game/behaviors/blue_fish.inc.c
2020-04-03 14:57:26 -04:00

128 lines
4.6 KiB
C

/**
* @file blue_fish.inc.c
* Implements behaviour and spawning for bhvBlueFish located in the castle aquarium outside of SA.
*/
/**
* Determines fish movement.
*/
void bhv_blue_fish_movement_loop(void) {
f32 randomSwitch;
switch (o->oAction) {
// Initial dive phase after spawning
case BLUE_FISH_ACT_DIVE:
cur_obj_init_animation_with_accel_and_sound(0, 1.0f);
// Assigns random values to variables that help determine natural motion.
if (o->oTimer == 0) {
o->oBlueFishRandomAngle = random_sign() << 11;
o->oBlueFishRandomVel = random_float() * 2;
o->oBlueFishRandomTime = (s32)(random_float() * 30) & 0xFE;
// Adjusts pitch velocity or sets to zero dependant on outcome of randomSwitch.
randomSwitch = random_float() * 5;
if (randomSwitch < 2.0f) {
o->oAngleVelPitch = random_f32_around_zero(128);
} else {
o->oAngleVelPitch = 0;
}
}
// Set forward velocity and progress oAction to BLUE_FISH_ACT_TURN.
o->oForwardVel = o->oBlueFishRandomVel + 3.0f;
if (o->oTimer >= o->oBlueFishRandomTime + 60) {
o->oAction++;
}
// Set pitch velocity
if (o->oTimer < (o->oBlueFishRandomTime + 60) / 2) {
o->oFaceAnglePitch += o->oAngleVelPitch;
} else {
o->oFaceAnglePitch -= o->oAngleVelPitch;
}
// Calculate new Y velocity
o->oVelY = -sins(o->oFaceAnglePitch) * o->oForwardVel;
break;
// Animates and adjusts fish yaw angle.
case BLUE_FISH_ACT_TURN:
cur_obj_init_animation_with_accel_and_sound(0, 2.0f);
o->oMoveAngleYaw = (s32)(o->oBlueFishRandomAngle + o->oMoveAngleYaw);
if (o->oTimer == 15) {
o->oAction++;
}
break;
// Animates and adjusts pitch to an upward direction.
case BLUE_FISH_ACT_ASCEND:
cur_obj_init_animation_with_accel_and_sound(0, 1.0f);
// Progresses oAction to BLUE_FISH_ACT_TURN_BACK after elapsed time.
if (o->oTimer >= o->oBlueFishRandomTime + 60) {
o->oAction++;
}
// Adjusts pitch angle. Direction relies on time not passed.
if (o->oTimer < (o->oBlueFishRandomTime + 60) / 2) {
o->oFaceAnglePitch -= o->oAngleVelPitch;
} else {
o->oFaceAnglePitch += o->oAngleVelPitch;
}
break;
// Animates and turns fish around
case BLUE_FISH_ACT_TURN_BACK:
cur_obj_init_animation_with_accel_and_sound(0, 2.0f);
o->oMoveAngleYaw = (s32)(o->oBlueFishRandomAngle + o->oMoveAngleYaw);
// Sets the fish back to the BLUE_FISH_ACT_DIVE phase.
if (o->oTimer == 15) {
o->oAction = BLUE_FISH_ACT_DIVE;
}
break;
}
// Calculates Y velocity and calls physics engine.
o->oVelY = -sins(o->oFaceAnglePitch) * o->oForwardVel;
cur_obj_move_using_fvel_and_gravity();
// Deletes object if the parent has oAction set to BLUE_FISH_ACT_DUPLICATE.
if (o->parentObj->oAction == BLUE_FISH_ACT_DUPLICATE) {
obj_mark_for_deletion(o);
}
}
/**
* Spawns fifteen fish if Mario resides in room fifteen or seven.
* They move at random within 200.0f
*/
void bhv_tank_fish_group_loop(void) {
struct Object *fish;
s32 i;
switch (o->oAction) {
case BLUE_FISH_ACT_SPAWN:
if (gMarioCurrentRoom == 15 || gMarioCurrentRoom == 7) {
// spawns fifteen fish and moves them within 200.0f
for (i = 0; i < 15; i++) {
fish = spawn_object_relative(0, 300, 0, -200, o, MODEL_FISH, bhvBlueFish);
obj_translate_xyz_random(fish, 200.0f);
}
// Proceed to BLUE_FISH_ACT_ROOM phase.
o->oAction++;
}
break;
// Sets next oAction phase if Mario is not in rooms fifteen and seven.
case BLUE_FISH_ACT_ROOM:
if (gMarioCurrentRoom != 15 && gMarioCurrentRoom != 7) {
o->oAction++;
}
break;
// Sets oAction to the BLUE_FISH_ACT_SPAWN phase.
case BLUE_FISH_ACT_DUPLICATE:
o->oAction = BLUE_FISH_ACT_SPAWN;
break;
}
}