Browse Source

Implemented ship data depending on ship type and player race

master
Bergmann89 3 years ago
parent
commit
a1c55d712b
15 changed files with 211 additions and 106 deletions
  1. +5
    -2
      overview
  2. +11
    -3
      space-crush-app/src/debug/ships.rs
  3. +1
    -1
      space-crush-common/src/builder/asteroid.rs
  4. +1
    -1
      space-crush-common/src/builder/fleet.rs
  5. +1
    -1
      space-crush-common/src/builder/planet.rs
  6. +21
    -5
      space-crush-common/src/builder/player.rs
  7. +2
    -3
      space-crush-common/src/builder/ship.rs
  8. +2
    -2
      space-crush-common/src/components/mod.rs
  9. +30
    -12
      space-crush-common/src/components/player.rs
  10. +65
    -33
      space-crush-common/src/components/ship.rs
  11. +20
    -0
      space-crush-common/src/constants.rs
  12. +2
    -2
      space-crush-common/src/dispatcher.rs
  13. +2
    -2
      space-crush-common/src/systems/mod.rs
  14. +0
    -39
      space-crush-common/src/systems/movement.rs
  15. +48
    -0
      space-crush-common/src/systems/ship_movement.rs

+ 5
- 2
overview View File

@@ -1,3 +1,6 @@
x -> needed
o -> optional

___________________________________________________________ ___________________________________________________________
WorldPersistence________________________________________ \ WorldPersistence________________________________________ \
Planet_______________________________________________ \ \ Planet_______________________________________________ \ \
@@ -19,7 +22,7 @@ Player______________ \ \ \ \ \ \ \ \ \ \ \ \ \
| Player | x | | | | | | | | | | | | x | | Player | x | | | | | | | | | | | | x |
| Ship | | x | x | x | x | | | | | | | | x | | Ship | | x | x | x | x | | | | | | | | x |
| Fleet | | | | | | x | x | | | | | | x | | Fleet | | | | | | x | x | | | | | | x |
| Asteroid | | x | x | | | | | x | x | x | x | | x |
| Planet | | x | x | | | | | x | x | x | | x | x |
| Asteroid | | o | x | | | | | x | x | x | x | | x |
| Planet | | o | x | | | | | x | x | x | | x | x |
| MeetingPoint | | | x | | | | | | | x | | | x | | MeetingPoint | | | x | | | | | | | x | | | x |
+--------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+ +--------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+

+ 11
- 3
space-crush-app/src/debug/ships.rs View File

@@ -1,6 +1,6 @@
use glc::vector::Vector4f; use glc::vector::Vector4f;
use space_crush_common::{ use space_crush_common::{
components::{Position, Ship, ShipObstacle},
components::{Player, PlayerOwned, Position, Ship, ShipObstacle},
continue_if_none, continue_if_none,
}; };
use specs::{prelude::*, ReadStorage, System, World, WriteExpect}; use specs::{prelude::*, ReadStorage, System, World, WriteExpect};
@@ -14,6 +14,8 @@ 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>,
player_owned: ReadStorage<'a, PlayerOwned>,
players: ReadStorage<'a, Player>,
ships: ReadStorage<'a, Ship>, ships: ReadStorage<'a, Ship>,
} }


@@ -24,18 +26,24 @@ impl<'a> System<'a> for Ships {
let ShipsData { let ShipsData {
mut geometry, mut geometry,
positions, positions,
player_owned,
players,
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, ship) in (&positions, &ships).join() {
for (position, player_owned, ship) in (&positions, &player_owned, &ships).join() {
let ship_pos = position.get(); let ship_pos = position.get();
let type_ = ship.type_();
let player_id = player_owned.owner();
let player = continue_if_none!(players.get(player_id));
let ship_data = player.ship_data(type_);


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 + ship.dir() * ship.speed()],
&[*ship_pos, ship_pos + ship.dir() * ship_data.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),


+ 1
- 1
space-crush-common/src/builder/asteroid.rs View File

@@ -19,7 +19,7 @@ pub struct AsteroidBuilder {
} }


impl AsteroidBuilder { impl AsteroidBuilder {
pub fn build(self, world: &mut World) -> Result<Entity, Error> {
pub fn build(&self, world: &mut World) -> Result<Entity, Error> {
let type_ = self.type_.ok_or(Error::MissingValue("type"))?; let type_ = self.type_.ok_or(Error::MissingValue("type"))?;
let position = self.position.ok_or(Error::MissingValue("position"))?; let position = self.position.ok_or(Error::MissingValue("position"))?;
let size = self.size.ok_or(Error::MissingValue("size"))?; let size = self.size.ok_or(Error::MissingValue("size"))?;


+ 1
- 1
space-crush-common/src/builder/fleet.rs View File

@@ -13,7 +13,7 @@ pub struct FleetBuilder {
} }


impl FleetBuilder { impl FleetBuilder {
pub fn build(self, world: &mut World) -> Result<Entity, Error> {
pub fn build(&self, world: &mut World) -> Result<Entity, Error> {
let owner = self.owner.ok_or(Error::MissingValue("owner"))?; let owner = self.owner.ok_or(Error::MissingValue("owner"))?;


let meeting_point_owned = MeetingPointOwned::new(owner); let meeting_point_owned = MeetingPointOwned::new(owner);


+ 1
- 1
space-crush-common/src/builder/planet.rs View File

@@ -18,7 +18,7 @@ pub struct PlanetBuilder {
} }


impl PlanetBuilder { impl PlanetBuilder {
pub fn build(self, world: &mut World) -> Result<Entity, Error> {
pub fn build(&self, world: &mut World) -> Result<Entity, Error> {
let position = self.position.ok_or(Error::MissingValue("position"))?; let position = self.position.ok_or(Error::MissingValue("position"))?;
let size = self.size.ok_or(Error::MissingValue("size"))?; let size = self.size.ok_or(Error::MissingValue("size"))?;
let (orbit_min, orbit_max) = self.orbit.ok_or(Error::MissingValue("orbit"))?; let (orbit_min, orbit_max) = self.orbit.ok_or(Error::MissingValue("orbit"))?;


+ 21
- 5
space-crush-common/src/builder/player.rs View File

@@ -3,22 +3,26 @@ use specs::{saveload::MarkedBuilder, Builder, Entity, World, WorldExt};
use glc::vector::Vector3f; use glc::vector::Vector3f;


use crate::{ use crate::{
components::Player,
components::{Player, Race},
misc::{Persistence, WorldPersistence}, misc::{Persistence, WorldPersistence},
}; };


use super::Error; use super::Error;


#[derive(Default, Clone)]
#[derive(Clone)]
pub struct PlayerBuilder { pub struct PlayerBuilder {
index: usize,
race: Race,
color: Option<Vector3f>, color: Option<Vector3f>,
} }


impl PlayerBuilder { impl PlayerBuilder {
pub fn build(self, world: &mut World) -> Result<Entity, Error> {
let color = self.color.ok_or(Error::MissingValue("color"))?;
pub fn build(&mut self, world: &mut World) -> Result<Entity, Error> {
let index = self.index;
let race = self.race;
let color = self.color.take().ok_or(Error::MissingValue("color"))?;


let player = Player::new(color);
let player = Player::new(index, race, color);


let entity = world let entity = world
.create_entity() .create_entity()
@@ -26,6 +30,8 @@ impl PlayerBuilder {
.with(player) .with(player)
.build(); .build();


self.index += 1;

Ok(entity) Ok(entity)
} }


@@ -35,3 +41,13 @@ impl PlayerBuilder {
self self
} }
} }

impl Default for PlayerBuilder {
fn default() -> Self {
Self {
index: 0,
race: Race::Fighter,
color: None,
}
}
}

+ 2
- 3
space-crush-common/src/builder/ship.rs View File

@@ -19,18 +19,17 @@ pub struct ShipBuilder {
} }


impl ShipBuilder { impl ShipBuilder {
pub fn build(self, world: &mut World) -> Result<Entity, Error> {
pub fn build(&self, world: &mut World) -> Result<Entity, Error> {
let player = self.player.ok_or(Error::MissingValue("player"))?; let player = self.player.ok_or(Error::MissingValue("player"))?;
let fleet = self.fleet.ok_or(Error::MissingValue("fleet"))?; let fleet = self.fleet.ok_or(Error::MissingValue("fleet"))?;
let position = self.position.ok_or(Error::MissingValue("position"))?; let position = self.position.ok_or(Error::MissingValue("position"))?;
let type_ = self.type_.ok_or(Error::MissingValue("type"))?; let type_ = self.type_.ok_or(Error::MissingValue("type"))?;
let direction = self.direction; let direction = self.direction;
let speed = 100.0;


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 ship = Ship::new(type_, direction, speed);
let ship = Ship::new(type_, direction);


let entity = world let entity = world
.create_entity() .create_entity()


+ 2
- 2
space-crush-common/src/components/mod.rs View File

@@ -13,7 +13,7 @@ pub use fleet::{Fleet, FleetOwned};
pub use meeting_point::{MeetingPoint, MeetingPointOwned}; pub use meeting_point::{MeetingPoint, MeetingPointOwned};
pub use obstacle::Obstacle; pub use obstacle::Obstacle;
pub use planet::Planet; pub use planet::Planet;
pub use player::{Player, PlayerOwned};
pub use player::{Player, PlayerOwned, Race};
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::{Ship, ShipCount, ShipData, ShipObstacle, ShipType, ShipsData};

+ 30
- 12
space-crush-common/src/components/player.rs View File

@@ -6,12 +6,27 @@ use specs::{
Component, Entity, HashMapStorage, Component, Entity, HashMapStorage,
}; };


use crate::builder::PlayerBuilder;
use crate::{
builder::PlayerBuilder,
components::{ShipData, ShipType, ShipsData},
constants::{SHIPS_DATA_FIGHTER, SHIPS_DATA_RESEARCHER, SHIPS_DATA_TRADER},
};


#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Player { pub struct Player {
index: usize, index: usize,
race: Race,
color: Vector3f, color: Vector3f,

#[serde(skip)]
ships_data: ShipsData,
}

#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
pub enum Race {
Fighter,
Trader,
Researcher,
} }


#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
@@ -41,14 +56,25 @@ impl Player {
pub fn color(&self) -> &Vector3f { pub fn color(&self) -> &Vector3f {
&self.color &self.color
} }

#[inline]
pub fn ship_data(&self, type_: ShipType) -> &ShipData {
&self.ships_data[type_]
}
} }


impl Player { impl Player {
#[inline] #[inline]
pub(crate) fn new(color: Vector3f) -> Self {
pub(crate) fn new(index: usize, race: Race, color: Vector3f) -> Self {
Self { Self {
index: next_index(),
index,
race,
color, color,
ships_data: match race {
Race::Fighter => SHIPS_DATA_FIGHTER,
Race::Trader => SHIPS_DATA_TRADER,
Race::Researcher => SHIPS_DATA_RESEARCHER,
},
} }
} }
} }
@@ -100,11 +126,3 @@ where
Ok(PlayerOwned { owner }) Ok(PlayerOwned { owner })
} }
} }

fn next_index() -> usize {
use std::sync::atomic::{AtomicUsize, Ordering};

static NEXT_INDEX: AtomicUsize = AtomicUsize::new(0);

NEXT_INDEX.fetch_add(1, Ordering::Relaxed)
}

+ 65
- 33
space-crush-common/src/components/ship.rs View File

@@ -9,12 +9,11 @@ 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_: ShipType,
dir: Vector2f, dir: Vector2f,
speed: f32,


#[serde(skip)] #[serde(skip)]
obstacle: Obstacle,
obstacle: ShipObstacle,


#[serde(skip)] #[serde(skip)]
target_pos: Vector2f, target_pos: Vector2f,
@@ -24,21 +23,33 @@ pub struct Ship {
} }


#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Obstacle {
pub enum ShipObstacle {
Known(Entity), Known(Entity),
Search, Search,
Done, Done,
} }


#[derive(Copy, Clone, Debug, Default)] #[derive(Copy, Clone, Debug, Default)]
pub struct Count {
pub struct ShipCount {
pub fighter: usize, pub fighter: usize,
pub bomber: usize, pub bomber: usize,
pub transporter: usize, pub transporter: usize,
} }


#[derive(Clone, Default, Debug)]
pub struct ShipsData {
pub fighter: ShipData,
pub bomber: ShipData,
pub transporter: ShipData,
}

#[derive(Clone, Default, Debug)]
pub struct ShipData {
pub speed: f32,
}

#[derive(Copy, Clone, Debug, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, Serialize, Deserialize)]
pub enum Type {
pub enum ShipType {
Fighter, Fighter,
Bomber, Bomber,
Transporter, Transporter,
@@ -53,7 +64,7 @@ impl Ship {
} }


#[inline] #[inline]
pub fn type_(&self) -> Type {
pub fn type_(&self) -> ShipType {
self.type_ self.type_
} }


@@ -62,11 +73,6 @@ impl Ship {
&self.dir &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
@@ -78,18 +84,17 @@ impl Ship {
} }


#[inline] #[inline]
pub fn obstacle(&self) -> Obstacle {
pub fn obstacle(&self) -> ShipObstacle {
self.obstacle self.obstacle
} }
} }


impl Ship { impl Ship {
#[inline] #[inline]
pub(crate) fn new(type_: Type, dir: Vector2f, speed: f32) -> Self {
pub(crate) fn new(type_: ShipType, dir: Vector2f) -> Self {
Self { Self {
type_, type_,
dir, dir,
speed,
obstacle: Default::default(), obstacle: Default::default(),
target_pos: Default::default(), target_pos: Default::default(),
target_dir: Default::default(), target_dir: Default::default(),
@@ -108,7 +113,7 @@ impl Ship {
} }


#[inline] #[inline]
pub(crate) fn obstacle_mut(&mut self) -> &mut Obstacle {
pub(crate) fn obstacle_mut(&mut self) -> &mut ShipObstacle {
&mut self.obstacle &mut self.obstacle
} }
} }
@@ -119,7 +124,7 @@ impl Component for Ship {


/* Obstacle */ /* Obstacle */


impl Default for Obstacle {
impl Default for ShipObstacle {
fn default() -> Self { fn default() -> Self {
Self::Search Self::Search
} }
@@ -127,7 +132,7 @@ impl Default for Obstacle {


/* Count */ /* Count */


impl Count {
impl ShipCount {
pub fn all() -> Self { pub fn all() -> Self {
Self { Self {
fighter: usize::MAX, fighter: usize::MAX,
@@ -163,7 +168,7 @@ impl Count {
} }
} }


impl Index<usize> for Count {
impl Index<usize> for ShipCount {
type Output = usize; type Output = usize;


fn index(&self, index: usize) -> &Self::Output { fn index(&self, index: usize) -> &Self::Output {
@@ -176,7 +181,7 @@ impl Index<usize> for Count {
} }
} }


impl IndexMut<usize> for Count {
impl IndexMut<usize> for ShipCount {
fn index_mut(&mut self, index: usize) -> &mut Self::Output { fn index_mut(&mut self, index: usize) -> &mut Self::Output {
match index { match index {
0 => &mut self.fighter, 0 => &mut self.fighter,
@@ -187,30 +192,30 @@ impl IndexMut<usize> for Count {
} }
} }


impl Index<Type> for Count {
impl Index<ShipType> for ShipCount {
type Output = usize; type Output = usize;


fn index(&self, index: Type) -> &Self::Output {
fn index(&self, index: ShipType) -> &Self::Output {
match index { match index {
Type::Fighter => &self.fighter,
Type::Bomber => &self.bomber,
Type::Transporter => &self.transporter,
ShipType::Fighter => &self.fighter,
ShipType::Bomber => &self.bomber,
ShipType::Transporter => &self.transporter,
} }
} }
} }


impl IndexMut<Type> for Count {
fn index_mut(&mut self, index: Type) -> &mut Self::Output {
impl IndexMut<ShipType> for ShipCount {
fn index_mut(&mut self, index: ShipType) -> &mut Self::Output {
match index { match index {
Type::Fighter => &mut self.fighter,
Type::Bomber => &mut self.bomber,
Type::Transporter => &mut self.transporter,
ShipType::Fighter => &mut self.fighter,
ShipType::Bomber => &mut self.bomber,
ShipType::Transporter => &mut self.transporter,
} }
} }
} }


impl Mul<f32> for Count {
type Output = Count;
impl Mul<f32> for ShipCount {
type Output = ShipCount;


#[allow(unused_assignments)] #[allow(unused_assignments)]
fn mul(self, rhs: f32) -> Self::Output { fn mul(self, rhs: f32) -> Self::Output {
@@ -238,10 +243,37 @@ impl Mul<f32> for Count {
actual += 1; actual += 1;
} }


Count {
ShipCount {
fighter, fighter,
bomber, bomber,
transporter, transporter,
} }
} }
} }

/* ShipsData */

impl Index<usize> for ShipsData {
type Output = ShipData;

fn index(&self, index: usize) -> &Self::Output {
match index {
0 => &self.fighter,
1 => &self.bomber,
2 => &self.transporter,
x => panic!("Invalid ships data index: {}", x),
}
}
}

impl Index<ShipType> for ShipsData {
type Output = ShipData;

fn index(&self, index: ShipType) -> &Self::Output {
match index {
ShipType::Fighter => &self.fighter,
ShipType::Bomber => &self.bomber,
ShipType::Transporter => &self.transporter,
}
}
}

+ 20
- 0
space-crush-common/src/constants.rs View File

@@ -1,5 +1,7 @@
use glc::{matrix::Angle, vector::Vector2f}; use glc::{matrix::Angle, vector::Vector2f};


use crate::components::{ShipData, ShipsData};

/// Distance to orbit before ship is handled as "in orbit" in % /// Distance to orbit before ship is handled as "in orbit" in %
pub const SHIP_ORBIT_DISTANCE_MAX: f32 = 1.10; pub const SHIP_ORBIT_DISTANCE_MAX: f32 = 1.10;


@@ -13,3 +15,21 @@ pub const SHIP_ORBIT_ANGLE_DELTA_RND: Angle<f32> = Angle::Deg(5000.0);
pub const SHIP_ORBIT_AGILITY: Angle<f32> = Angle::Deg(90.0); pub const SHIP_ORBIT_AGILITY: Angle<f32> = Angle::Deg(90.0);


pub const VECTOR_2F_POS_X: Vector2f = Vector2f::new(1.0, 0.0); pub const VECTOR_2F_POS_X: Vector2f = Vector2f::new(1.0, 0.0);

pub const SHIPS_DATA_FIGHTER: ShipsData = ShipsData {
fighter: ShipData { speed: 120.0 },
bomber: ShipData { speed: 80.0 },
transporter: ShipData { speed: 100.0 },
};

pub const SHIPS_DATA_TRADER: ShipsData = ShipsData {
fighter: ShipData { speed: 100.0 },
bomber: ShipData { speed: 70.0 },
transporter: ShipData { speed: 120.0 },
};

pub const SHIPS_DATA_RESEARCHER: ShipsData = ShipsData {
fighter: ShipData { speed: 90.0 },
bomber: ShipData { speed: 60.0 },
transporter: ShipData { speed: 100.0 },
};

+ 2
- 2
space-crush-common/src/dispatcher.rs View File

@@ -3,7 +3,7 @@ use specs::{Dispatcher as Inner, DispatcherBuilder, World, WorldExt};
use crate::{ use crate::{
components::Player, components::Player,
resources::Global, resources::Global,
systems::{FleetControl, FleetOwnedUpdate, Movement, Process, Ships},
systems::{FleetControl, FleetOwnedUpdate, Process, ShipMovement, Ships},
Error, Error,
}; };


@@ -19,7 +19,7 @@ impl<'a, 'b> Dispatcher<'a, 'b> {


let mut dispatcher = DispatcherBuilder::new() let mut dispatcher = DispatcherBuilder::new()
.with(Process::default(), "process", &[]) .with(Process::default(), "process", &[])
.with(Movement::default(), "movement", &[])
.with(ShipMovement::default(), "ship_movement", &[])
.with(Ships::new(world), "ships", &[]) .with(Ships::new(world), "ships", &[])
.with(FleetControl::new(world)?, "fleet_control", &[]) .with(FleetControl::new(world)?, "fleet_control", &[])
.with(FleetOwnedUpdate::new(world), "fleet_owned_update", &[]) .with(FleetOwnedUpdate::new(world), "fleet_owned_update", &[])


+ 2
- 2
space-crush-common/src/systems/mod.rs View File

@@ -1,11 +1,11 @@
mod fleet_control; mod fleet_control;
mod fleet_owned_update; mod fleet_owned_update;
mod movement;
mod process; mod process;
mod ship_movement;
mod ships; mod ships;


pub use fleet_control::{FleetControl, FleetControlEvent}; pub use fleet_control::{FleetControl, FleetControlEvent};
pub use fleet_owned_update::FleetOwnedUpdate; pub use fleet_owned_update::FleetOwnedUpdate;
pub use movement::Movement;
pub use process::Process; pub use process::Process;
pub use ship_movement::ShipMovement;
pub use ships::Ships; pub use ships::Ships;

+ 0
- 39
space-crush-common/src/systems/movement.rs View File

@@ -1,39 +0,0 @@
#![allow(dead_code)]

use specs::{prelude::*, ParJoin, Read, ReadStorage, System, WriteStorage};

use crate::{
components::{Position, Ship},
resources::Global,
};

#[derive(Default)]
pub struct Movement;

#[derive(SystemData)]
pub struct MovementData<'a> {
positions: WriteStorage<'a, Position>,
ships: ReadStorage<'a, Ship>,
global: Read<'a, Global>,
}

impl<'a> System<'a> for Movement {
type SystemData = MovementData<'a>;

fn run(&mut self, data: Self::SystemData) {
let MovementData {
mut positions,
ships,
global,
} = data;

(&mut positions, &ships)
.par_join()
.for_each(|(position, ship)| {
let delta = global.delta * global.world_speed;
let position = position.get_mut();

*position += ship.dir() * ship.speed() * delta;
});
}
}

+ 48
- 0
space-crush-common/src/systems/ship_movement.rs View File

@@ -0,0 +1,48 @@
#![allow(dead_code)]

use specs::{prelude::*, ParJoin, Read, ReadStorage, System, WriteStorage};

use crate::{
components::{Player, PlayerOwned, Position, Ship},
resources::Global,
return_if_none,
};

#[derive(Default)]
pub struct ShipMovement;

#[derive(SystemData)]
pub struct ShipMovementData<'a> {
positions: WriteStorage<'a, Position>,
ships: ReadStorage<'a, Ship>,
player_owned: ReadStorage<'a, PlayerOwned>,
players: ReadStorage<'a, Player>,
global: Read<'a, Global>,
}

impl<'a> System<'a> for ShipMovement {
type SystemData = ShipMovementData<'a>;

fn run(&mut self, data: Self::SystemData) {
let ShipMovementData {
mut positions,
ships,
player_owned,
players,
global,
} = data;

(&mut positions, &player_owned, &ships).par_join().for_each(
|(position, player_owned, ship)| {
let delta = global.delta * global.world_speed;
let position = position.get_mut();
let type_ = ship.type_();
let player_id = player_owned.owner();
let player = return_if_none!(players.get(player_id));
let ship_data = player.ship_data(type_);

*position += ship.dir() * ship_data.speed * delta;
},
);
}
}

Loading…
Cancel
Save