| @@ -0,0 +1,25 @@ | |||||
| ___________________________________________________________ | |||||
| WorldPersistence________________________________________ \ | |||||
| Planet_______________________________________________ \ \ | |||||
| Asteroid__________________________________________ \ \ \ | |||||
| MeetingPoint___________________________________ \ \ \ \ | |||||
| Obstacle____________________________________ \ \ \ \ \ | |||||
| Shape____________________________________ \ \ \ \ \ \ | |||||
| MeetingPointOwned_____________________ \ \ \ \ \ \ \ | |||||
| Fleet______________________________ \ \ \ \ \ \ \ \ | |||||
| Ship____________________________ \ \ \ \ \ \ \ \ \ | |||||
| FleetOwned___________________ \ \ \ \ \ \ \ \ \ \ | |||||
| Position__________________ \ \ \ \ \ \ \ \ \ \ \ | |||||
| PlayerOwned____________ \ \ \ \ \ \ \ \ \ \ \ \ | |||||
| Player______________ \ \ \ \ \ \ \ \ \ \ \ \ \ | |||||
| \ \ \ \ \ \ \ \ \ \ \ \ \ \ | |||||
| +--------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+ | |||||
| | Game Objects | | | | | | | | | | | | | | | |||||
| +--------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+ | |||||
| | Player | x | | | | | | | | | | | | x | | |||||
| | Ship | | x | x | x | x | | | | | | | | x | | |||||
| | Fleet | | | | | | x | x | | | | | | x | | |||||
| | Asteroid | | x | x | | | | | x | x | x | x | | x | | |||||
| | Planet | | x | x | | | | | x | x | x | | x | x | | |||||
| | MeetingPoint | | | x | | | | | | | x | | | x | | |||||
| +--------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+ | |||||
| @@ -1,6 +1,6 @@ | |||||
| use glc::vector::Vector4f; | use glc::vector::Vector4f; | ||||
| use space_crush_common::{ | use space_crush_common::{ | ||||
| components::{Position, Ship, ShipObstacle, Velocity}, | |||||
| components::{Position, Ship, ShipObstacle}, | |||||
| continue_if_none, | continue_if_none, | ||||
| }; | }; | ||||
| use specs::{prelude::*, ReadStorage, System, World, WriteExpect}; | use specs::{prelude::*, ReadStorage, System, World, WriteExpect}; | ||||
| @@ -14,7 +14,6 @@ pub struct Ships; | |||||
| pub struct ShipsData<'a> { | pub struct ShipsData<'a> { | ||||
| geometry: WriteExpect<'a, Geometry>, | geometry: WriteExpect<'a, Geometry>, | ||||
| positions: ReadStorage<'a, Position>, | positions: ReadStorage<'a, Position>, | ||||
| velocities: ReadStorage<'a, Velocity>, | |||||
| ships: ReadStorage<'a, Ship>, | ships: ReadStorage<'a, Ship>, | ||||
| } | } | ||||
| @@ -25,19 +24,18 @@ impl<'a> System<'a> for Ships { | |||||
| let ShipsData { | let ShipsData { | ||||
| mut geometry, | mut geometry, | ||||
| positions, | positions, | ||||
| velocities, | |||||
| ships, | ships, | ||||
| } = data; | } = data; | ||||
| gl::enable(gl::BLEND); | gl::enable(gl::BLEND); | ||||
| gl::blend_func(gl::SRC_ALPHA, gl::ONE); | gl::blend_func(gl::SRC_ALPHA, gl::ONE); | ||||
| for (position, velocity, ship) in (&positions, &velocities, &ships).join() { | |||||
| for (position, ship) in (&positions, &ships).join() { | |||||
| let ship_pos = position.get(); | let ship_pos = position.get(); | ||||
| geometry.render_lines( | geometry.render_lines( | ||||
| Vector4f::new(0.0, 0.0, 1.0, 0.2), | Vector4f::new(0.0, 0.0, 1.0, 0.2), | ||||
| &[*ship_pos, ship_pos + velocity.dir() * velocity.speed()], | |||||
| &[*ship_pos, ship_pos + ship.dir() * ship.speed()], | |||||
| ); | ); | ||||
| geometry.render_lines( | geometry.render_lines( | ||||
| Vector4f::new(1.0, 0.0, 0.0, 0.2), | Vector4f::new(1.0, 0.0, 0.0, 0.2), | ||||
| @@ -12,7 +12,7 @@ use glc::{ | |||||
| vertex_array::{DataType, VertexArray}, | vertex_array::{DataType, VertexArray}, | ||||
| }; | }; | ||||
| use space_crush_common::{ | use space_crush_common::{ | ||||
| components::{Player, PlayerOwned, Position, Ship, ShipType, Velocity}, | |||||
| components::{Player, PlayerOwned, Position, Ship, ShipType}, | |||||
| misc::{ComponentEvent, LogResult, StorageHelper, StorageHelperMut}, | misc::{ComponentEvent, LogResult, StorageHelper, StorageHelperMut}, | ||||
| }; | }; | ||||
| use specs::{ | use specs::{ | ||||
| @@ -55,7 +55,6 @@ pub struct Ships { | |||||
| #[derive(SystemData)] | #[derive(SystemData)] | ||||
| pub struct ShipsData<'a> { | pub struct ShipsData<'a> { | ||||
| positions: ReadStorage<'a, Position>, | positions: ReadStorage<'a, Position>, | ||||
| velocities: ReadStorage<'a, Velocity>, | |||||
| players: ReadStorage<'a, Player>, | players: ReadStorage<'a, Player>, | ||||
| owned: ReadStorage<'a, PlayerOwned>, | owned: ReadStorage<'a, PlayerOwned>, | ||||
| ships: ReadStorage<'a, Ship>, | ships: ReadStorage<'a, Ship>, | ||||
| @@ -217,16 +216,15 @@ impl Ships { | |||||
| let data = ( | let data = ( | ||||
| &ids as &dyn BitSetLike, | &ids as &dyn BitSetLike, | ||||
| &d.positions, | &d.positions, | ||||
| &d.velocities, | |||||
| &d.ships, | &d.ships, | ||||
| d.owned.maybe(), | d.owned.maybe(), | ||||
| ); | ); | ||||
| for (id, position, velocity, ship, owned) in data.join() { | |||||
| for (id, position, ship, owned) in data.join() { | |||||
| let index = self.id_to_index[id as usize]; | let index = self.id_to_index[id as usize]; | ||||
| let mut s = &mut buf_ship[index as usize]; | let mut s = &mut buf_ship[index as usize]; | ||||
| s.pos = *position.get(); | s.pos = *position.get(); | ||||
| s.dir = *velocity.dir(); | |||||
| s.dir = *ship.dir(); | |||||
| if self.need_init.contains(id) { | if self.need_init.contains(id) { | ||||
| s.color = match owned.and_then(|owned| d.players.get(owned.owner())) { | s.color = match owned.and_then(|owned| d.players.get(owned.owner())) { | ||||
| @@ -3,7 +3,7 @@ use rand::random; | |||||
| use specs::{saveload::MarkedBuilder, Builder, Entity, World, WorldExt}; | use specs::{saveload::MarkedBuilder, Builder, Entity, World, WorldExt}; | ||||
| use crate::{ | use crate::{ | ||||
| components::{FleetOwned, PlayerOwned, Position, Ship, ShipType, Velocity}, | |||||
| components::{FleetOwned, PlayerOwned, Position, Ship, ShipType}, | |||||
| misc::{Persistence, WorldPersistence}, | misc::{Persistence, WorldPersistence}, | ||||
| }; | }; | ||||
| @@ -30,8 +30,7 @@ impl ShipBuilder { | |||||
| let player_owned = PlayerOwned::new(player); | let player_owned = PlayerOwned::new(player); | ||||
| let fleet_owned = FleetOwned::new(fleet); | let fleet_owned = FleetOwned::new(fleet); | ||||
| let position = Position::new(position); | let position = Position::new(position); | ||||
| let velocity = Velocity::new(direction, speed); | |||||
| let ship = Ship::new(type_); | |||||
| let ship = Ship::new(type_, direction, speed); | |||||
| let entity = world | let entity = world | ||||
| .create_entity() | .create_entity() | ||||
| @@ -39,7 +38,6 @@ impl ShipBuilder { | |||||
| .with(player_owned) | .with(player_owned) | ||||
| .with(fleet_owned) | .with(fleet_owned) | ||||
| .with(position) | .with(position) | ||||
| .with(velocity) | |||||
| .with(ship) | .with(ship) | ||||
| .build(); | .build(); | ||||
| @@ -81,13 +81,15 @@ impl Component for Fleet { | |||||
| /* FleetOwned */ | /* FleetOwned */ | ||||
| impl FleetOwned { | impl FleetOwned { | ||||
| pub fn new(owner: Entity) -> Self { | |||||
| Self { owner } | |||||
| } | |||||
| pub fn owner(&self) -> Entity { | pub fn owner(&self) -> Entity { | ||||
| self.owner | self.owner | ||||
| } | } | ||||
| } | |||||
| impl FleetOwned { | |||||
| pub(crate) fn new(owner: Entity) -> Self { | |||||
| Self { owner } | |||||
| } | |||||
| pub(crate) fn set_owner(&mut self, owner: Entity) { | pub(crate) fn set_owner(&mut self, owner: Entity) { | ||||
| self.owner = owner; | self.owner = owner; | ||||
| @@ -7,7 +7,6 @@ mod player; | |||||
| mod position; | mod position; | ||||
| mod shape; | mod shape; | ||||
| mod ship; | mod ship; | ||||
| mod velocity; | |||||
| pub use asteroid::{Asteroid, Type as AsteroidType}; | pub use asteroid::{Asteroid, Type as AsteroidType}; | ||||
| pub use fleet::{Fleet, FleetOwned}; | pub use fleet::{Fleet, FleetOwned}; | ||||
| @@ -18,4 +17,3 @@ pub use player::{Player, PlayerOwned}; | |||||
| pub use position::Position; | pub use position::Position; | ||||
| pub use shape::Shape; | pub use shape::Shape; | ||||
| pub use ship::{Count as ShipCount, Obstacle as ShipObstacle, Ship, Type as ShipType}; | pub use ship::{Count as ShipCount, Obstacle as ShipObstacle, Ship, Type as ShipType}; | ||||
| pub use velocity::Velocity; | |||||
| @@ -10,6 +10,8 @@ use crate::{builder::ShipBuilder, misc::FlaggedStorage}; | |||||
| #[derive(Clone, Debug, Serialize, Deserialize)] | #[derive(Clone, Debug, Serialize, Deserialize)] | ||||
| pub struct Ship { | pub struct Ship { | ||||
| type_: Type, | type_: Type, | ||||
| dir: Vector2f, | |||||
| speed: f32, | |||||
| #[serde(skip)] | #[serde(skip)] | ||||
| obstacle: Obstacle, | obstacle: Obstacle, | ||||
| @@ -55,6 +57,16 @@ impl Ship { | |||||
| self.type_ | self.type_ | ||||
| } | } | ||||
| #[inline] | |||||
| pub fn dir(&self) -> &Vector2f { | |||||
| &self.dir | |||||
| } | |||||
| #[inline] | |||||
| pub fn speed(&self) -> f32 { | |||||
| self.speed | |||||
| } | |||||
| #[inline] | #[inline] | ||||
| pub fn target_pos(&self) -> &Vector2f { | pub fn target_pos(&self) -> &Vector2f { | ||||
| &self.target_pos | &self.target_pos | ||||
| @@ -73,9 +85,11 @@ impl Ship { | |||||
| impl Ship { | impl Ship { | ||||
| #[inline] | #[inline] | ||||
| pub(crate) fn new(type_: Type) -> Self { | |||||
| pub(crate) fn new(type_: Type, dir: Vector2f, speed: f32) -> Self { | |||||
| Self { | Self { | ||||
| type_, | type_, | ||||
| dir, | |||||
| speed, | |||||
| obstacle: Default::default(), | obstacle: Default::default(), | ||||
| target_pos: Default::default(), | target_pos: Default::default(), | ||||
| target_dir: Default::default(), | target_dir: Default::default(), | ||||
| @@ -89,8 +103,13 @@ impl Ship { | |||||
| } | } | ||||
| #[inline] | #[inline] | ||||
| pub(crate) fn set_obstacle(&mut self, value: Obstacle) { | |||||
| self.obstacle = value; | |||||
| pub(crate) fn dir_mut(&mut self) -> &mut Vector2f { | |||||
| &mut self.dir | |||||
| } | |||||
| #[inline] | |||||
| pub(crate) fn obstacle_mut(&mut self) -> &mut Obstacle { | |||||
| &mut self.obstacle | |||||
| } | } | ||||
| } | } | ||||
| @@ -1,35 +0,0 @@ | |||||
| use glc::vector::Vector2f; | |||||
| use serde::{Deserialize, Serialize}; | |||||
| use specs::{Component, VecStorage}; | |||||
| #[derive(Clone, Debug, Default, Serialize, Deserialize)] | |||||
| pub struct Velocity { | |||||
| dir: Vector2f, | |||||
| speed: f32, | |||||
| } | |||||
| /* Velocity */ | |||||
| impl Velocity { | |||||
| pub fn dir(&self) -> &Vector2f { | |||||
| &self.dir | |||||
| } | |||||
| pub fn speed(&self) -> f32 { | |||||
| self.speed | |||||
| } | |||||
| } | |||||
| impl Velocity { | |||||
| pub(crate) fn new(dir: Vector2f, speed: f32) -> Self { | |||||
| Self { dir, speed } | |||||
| } | |||||
| pub(crate) fn dir_mut(&mut self) -> &mut Vector2f { | |||||
| &mut self.dir | |||||
| } | |||||
| } | |||||
| impl Component for Velocity { | |||||
| type Storage = VecStorage<Self>; | |||||
| } | |||||
| @@ -8,7 +8,7 @@ use specs::{saveload::SimpleMarker, World}; | |||||
| use crate::{ | use crate::{ | ||||
| components::{ | components::{ | ||||
| Asteroid, MeetingPoint, MeetingPointOwned, Obstacle, Planet, Player, PlayerOwned, Position, | Asteroid, MeetingPoint, MeetingPointOwned, Obstacle, Planet, Player, PlayerOwned, Position, | ||||
| Ship, Velocity, | |||||
| Ship, | |||||
| }, | }, | ||||
| Error, | Error, | ||||
| }; | }; | ||||
| @@ -91,7 +91,6 @@ impl Persistence for WorldPersistence { | |||||
| type Marker = SimpleMarker<PersistWorldMarker>; | type Marker = SimpleMarker<PersistWorldMarker>; | ||||
| type Components = ( | type Components = ( | ||||
| Position, | Position, | ||||
| Velocity, | |||||
| Player, | Player, | ||||
| PlayerOwned, | PlayerOwned, | ||||
| MeetingPoint, | MeetingPoint, | ||||
| @@ -3,7 +3,7 @@ | |||||
| use specs::{prelude::*, ParJoin, Read, ReadStorage, System, WriteStorage}; | use specs::{prelude::*, ParJoin, Read, ReadStorage, System, WriteStorage}; | ||||
| use crate::{ | use crate::{ | ||||
| components::{Position, Velocity}, | |||||
| components::{Position, Ship}, | |||||
| resources::Global, | resources::Global, | ||||
| }; | }; | ||||
| @@ -12,8 +12,8 @@ pub struct Movement; | |||||
| #[derive(SystemData)] | #[derive(SystemData)] | ||||
| pub struct MovementData<'a> { | pub struct MovementData<'a> { | ||||
| position: WriteStorage<'a, Position>, | |||||
| velocity: ReadStorage<'a, Velocity>, | |||||
| positions: WriteStorage<'a, Position>, | |||||
| ships: ReadStorage<'a, Ship>, | |||||
| global: Read<'a, Global>, | global: Read<'a, Global>, | ||||
| } | } | ||||
| @@ -22,18 +22,18 @@ impl<'a> System<'a> for Movement { | |||||
| fn run(&mut self, data: Self::SystemData) { | fn run(&mut self, data: Self::SystemData) { | ||||
| let MovementData { | let MovementData { | ||||
| mut position, | |||||
| velocity, | |||||
| mut positions, | |||||
| ships, | |||||
| global, | global, | ||||
| } = data; | } = data; | ||||
| (&mut position, &velocity) | |||||
| (&mut positions, &ships) | |||||
| .par_join() | .par_join() | ||||
| .for_each(|(position, velocity)| { | |||||
| .for_each(|(position, ship)| { | |||||
| let delta = global.delta * global.world_speed; | let delta = global.delta * global.world_speed; | ||||
| let position = position.get_mut(); | let position = position.get_mut(); | ||||
| *position += velocity.dir() * velocity.speed() * delta; | |||||
| *position += ship.dir() * ship.speed() * delta; | |||||
| }); | }); | ||||
| } | } | ||||
| } | } | ||||
| @@ -13,7 +13,6 @@ use specs::{ | |||||
| use crate::{ | use crate::{ | ||||
| components::{ | components::{ | ||||
| FleetOwned, MeetingPoint, MeetingPointOwned, Obstacle, Position, Shape, Ship, ShipObstacle, | FleetOwned, MeetingPoint, MeetingPointOwned, Obstacle, Position, Shape, Ship, ShipObstacle, | ||||
| Velocity, | |||||
| }, | }, | ||||
| constants::{ | constants::{ | ||||
| SHIP_ORBIT_AGILITY, SHIP_ORBIT_ANGLE_DELTA_MIN, SHIP_ORBIT_ANGLE_DELTA_RND, | SHIP_ORBIT_AGILITY, SHIP_ORBIT_ANGLE_DELTA_MIN, SHIP_ORBIT_ANGLE_DELTA_RND, | ||||
| @@ -34,7 +33,6 @@ pub struct ShipsData<'a> { | |||||
| global: Read<'a, Global>, | global: Read<'a, Global>, | ||||
| entities: Entities<'a>, | entities: Entities<'a>, | ||||
| ships: WriteStorage<'a, Ship>, | ships: WriteStorage<'a, Ship>, | ||||
| velocities: WriteStorage<'a, Velocity>, | |||||
| fleet_owned: ReadStorage<'a, FleetOwned>, | fleet_owned: ReadStorage<'a, FleetOwned>, | ||||
| meeting_point_owned: ReadStorage<'a, MeetingPointOwned>, | meeting_point_owned: ReadStorage<'a, MeetingPointOwned>, | ||||
| positions: ReadStorage<'a, Position>, | positions: ReadStorage<'a, Position>, | ||||
| @@ -92,7 +90,6 @@ impl<'a> System<'a> for Ships { | |||||
| global, | global, | ||||
| entities, | entities, | ||||
| mut ships, | mut ships, | ||||
| mut velocities, | |||||
| fleet_owned, | fleet_owned, | ||||
| meeting_point_owned, | meeting_point_owned, | ||||
| positions, | positions, | ||||
| @@ -117,17 +114,11 @@ impl<'a> System<'a> for Ships { | |||||
| ships.set_event_emission(false); | ships.set_event_emission(false); | ||||
| let data = ( | |||||
| positions.mask(), | |||||
| &mut ships, | |||||
| &mut velocities, | |||||
| &positions, | |||||
| &fleet_owned, | |||||
| ); | |||||
| let data = (positions.mask(), &mut ships, &positions, &fleet_owned); | |||||
| data.par_join() | data.par_join() | ||||
| .for_each(|(id, ship, velocity, position, fleet_owned)| { | |||||
| processor.progress_ship(id, ship, velocity, position, fleet_owned); | |||||
| .for_each(|(id, ship, position, fleet_owned)| { | |||||
| processor.progress_ship(id, ship, position, fleet_owned); | |||||
| }); | }); | ||||
| ships.set_event_emission(true); | ships.set_event_emission(true); | ||||
| @@ -139,7 +130,6 @@ impl Processor<'_> { | |||||
| &self, | &self, | ||||
| id: Index, | id: Index, | ||||
| ship: &mut Ship, | ship: &mut Ship, | ||||
| velocity: &mut Velocity, | |||||
| position: &Position, | position: &Position, | ||||
| fleet_owned: &FleetOwned, | fleet_owned: &FleetOwned, | ||||
| ) { | ) { | ||||
| @@ -179,7 +169,7 @@ impl Processor<'_> { | |||||
| let target_pos = if ship_in_meeting_point && meeting_point_max > 0.0 { | let target_pos = if ship_in_meeting_point && meeting_point_max > 0.0 { | ||||
| let meeting_point_to_ship_vec3 = | let meeting_point_to_ship_vec3 = | ||||
| Vector3f::new(meeting_point_to_ship.x, meeting_point_to_ship.y, 0.0); | Vector3f::new(meeting_point_to_ship.x, meeting_point_to_ship.y, 0.0); | ||||
| let ship_dir_vec3 = velocity.dir().into_vec3(); | |||||
| let ship_dir_vec3 = ship.dir().into_vec3(); | |||||
| let dir = if meeting_point_to_ship_vec3.cross(&ship_dir_vec3).z > 0.0 { | let dir = if meeting_point_to_ship_vec3.cross(&ship_dir_vec3).z > 0.0 { | ||||
| 1.0 | 1.0 | ||||
| @@ -201,7 +191,7 @@ impl Processor<'_> { | |||||
| meeting_point_pos.y + radius * angle.sin(), | meeting_point_pos.y + radius * angle.sin(), | ||||
| ) | ) | ||||
| } else { | } else { | ||||
| ship.set_obstacle(ShipObstacle::Search); | |||||
| *ship.obstacle_mut() = ShipObstacle::Search; | |||||
| *meeting_point_pos | *meeting_point_pos | ||||
| }; | }; | ||||
| @@ -213,7 +203,7 @@ impl Processor<'_> { | |||||
| /* check if obstacle is still valid */ | /* check if obstacle is still valid */ | ||||
| if ship_in_meeting_point { | if ship_in_meeting_point { | ||||
| ship.set_obstacle(ShipObstacle::Done); | |||||
| *ship.obstacle_mut() = ShipObstacle::Done; | |||||
| } else if let ShipObstacle::Known(obstacle) = ship.obstacle() { | } else if let ShipObstacle::Known(obstacle) = ship.obstacle() { | ||||
| if let Some(position) = self.positions.get(obstacle) { | if let Some(position) = self.positions.get(obstacle) { | ||||
| let obstacle_meeting_point = self.meeting_points.get(obstacle).unwrap(); | let obstacle_meeting_point = self.meeting_points.get(obstacle).unwrap(); | ||||
| @@ -230,10 +220,10 @@ impl Processor<'_> { | |||||
| if (obstacle_angle > 90.0 && ship_to_obstacle.length_sqr() > meeting_point_sqr) | if (obstacle_angle > 90.0 && ship_to_obstacle.length_sqr() > meeting_point_sqr) | ||||
| || obstacle_angle > 170.0 | || obstacle_angle > 170.0 | ||||
| { | { | ||||
| ship.set_obstacle(ShipObstacle::Search); | |||||
| *ship.obstacle_mut() = ShipObstacle::Search; | |||||
| } | } | ||||
| } else { | } else { | ||||
| ship.set_obstacle(ShipObstacle::Search); | |||||
| *ship.obstacle_mut() = ShipObstacle::Search; | |||||
| } | } | ||||
| } | } | ||||
| @@ -251,13 +241,13 @@ impl Processor<'_> { | |||||
| let len_sqr = ship_to_obstacle.length_sqr(); | let len_sqr = ship_to_obstacle.length_sqr(); | ||||
| if len_sqr < dist_sqr { | if len_sqr < dist_sqr { | ||||
| dist_sqr = len_sqr; | dist_sqr = len_sqr; | ||||
| ship.set_obstacle(ShipObstacle::Known(e)); | |||||
| *ship.obstacle_mut() = ShipObstacle::Known(e); | |||||
| } | } | ||||
| } | } | ||||
| if let ShipObstacle::Known(e) = ship.obstacle() { | if let ShipObstacle::Known(e) = ship.obstacle() { | ||||
| if e == fleet_owned.owner() { | if e == fleet_owned.owner() { | ||||
| ship.set_obstacle(ShipObstacle::Done); | |||||
| *ship.obstacle_mut() = ShipObstacle::Done; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -296,13 +286,13 @@ impl Processor<'_> { | |||||
| } | } | ||||
| /* update ship direction */ | /* update ship direction */ | ||||
| let angle = expected_dir.angle2(&velocity.dir()); | |||||
| let angle = expected_dir.angle2(ship.dir()); | |||||
| if angle.into_inner().abs() > 0.0001 { | if angle.into_inner().abs() > 0.0001 { | ||||
| let dir = angle.into_inner() / angle.abs().into_inner(); | let dir = angle.into_inner() / angle.abs().into_inner(); | ||||
| let agility = SHIP_ORBIT_AGILITY; | let agility = SHIP_ORBIT_AGILITY; | ||||
| let rot_speed = agility * linear_step(0.0, 45.0, angle.abs().into_deg().into_inner()); | let rot_speed = agility * linear_step(0.0, 45.0, angle.abs().into_deg().into_inner()); | ||||
| *velocity.dir_mut() *= Matrix3f::rotate(rot_speed * -dir * self.delta); | |||||
| *ship.dir_mut() *= Matrix3f::rotate(rot_speed * -dir * self.delta); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||