/** * @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; } }