From a1c55d712bd1f2fe1c9e701b1dc1532bd9b8f9c0 Mon Sep 17 00:00:00 2001 From: Bergmann89 Date: Tue, 12 Jan 2021 22:00:05 +0100 Subject: [PATCH] Implemented ship data depending on ship type and player race --- overview | 7 +- space-crush-app/src/debug/ships.rs | 14 ++- space-crush-common/src/builder/asteroid.rs | 2 +- space-crush-common/src/builder/fleet.rs | 2 +- space-crush-common/src/builder/planet.rs | 2 +- space-crush-common/src/builder/player.rs | 26 ++++- space-crush-common/src/builder/ship.rs | 5 +- space-crush-common/src/components/mod.rs | 4 +- space-crush-common/src/components/player.rs | 42 +++++--- space-crush-common/src/components/ship.rs | 98 ++++++++++++------- space-crush-common/src/constants.rs | 20 ++++ space-crush-common/src/dispatcher.rs | 4 +- space-crush-common/src/systems/mod.rs | 4 +- space-crush-common/src/systems/movement.rs | 39 -------- .../src/systems/ship_movement.rs | 48 +++++++++ 15 files changed, 211 insertions(+), 106 deletions(-) delete mode 100644 space-crush-common/src/systems/movement.rs create mode 100644 space-crush-common/src/systems/ship_movement.rs diff --git a/overview b/overview index 919328f..3c0d515 100644 --- a/overview +++ b/overview @@ -1,3 +1,6 @@ +x -> needed +o -> optional + ___________________________________________________________ WorldPersistence________________________________________ \ Planet_______________________________________________ \ \ @@ -19,7 +22,7 @@ Player______________ \ \ \ \ \ \ \ \ \ \ \ \ \ | 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 | +| Asteroid | | o | x | | | | | x | x | x | x | | x | +| Planet | | o | x | | | | | x | x | x | | x | x | | MeetingPoint | | | x | | | | | | | x | | | x | +--------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+ diff --git a/space-crush-app/src/debug/ships.rs b/space-crush-app/src/debug/ships.rs index 388c2de..ee991a5 100644 --- a/space-crush-app/src/debug/ships.rs +++ b/space-crush-app/src/debug/ships.rs @@ -1,6 +1,6 @@ use glc::vector::Vector4f; use space_crush_common::{ - components::{Position, Ship, ShipObstacle}, + components::{Player, PlayerOwned, Position, Ship, ShipObstacle}, continue_if_none, }; use specs::{prelude::*, ReadStorage, System, World, WriteExpect}; @@ -14,6 +14,8 @@ pub struct Ships; pub struct ShipsData<'a> { geometry: WriteExpect<'a, Geometry>, positions: ReadStorage<'a, Position>, + player_owned: ReadStorage<'a, PlayerOwned>, + players: ReadStorage<'a, Player>, ships: ReadStorage<'a, Ship>, } @@ -24,18 +26,24 @@ impl<'a> System<'a> for Ships { let ShipsData { mut geometry, positions, + player_owned, + players, ships, } = data; gl::enable(gl::BLEND); 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 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( 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( Vector4f::new(1.0, 0.0, 0.0, 0.2), diff --git a/space-crush-common/src/builder/asteroid.rs b/space-crush-common/src/builder/asteroid.rs index 32dd665..6a17ac8 100644 --- a/space-crush-common/src/builder/asteroid.rs +++ b/space-crush-common/src/builder/asteroid.rs @@ -19,7 +19,7 @@ pub struct AsteroidBuilder { } impl AsteroidBuilder { - pub fn build(self, world: &mut World) -> Result { + pub fn build(&self, world: &mut World) -> Result { let type_ = self.type_.ok_or(Error::MissingValue("type"))?; let position = self.position.ok_or(Error::MissingValue("position"))?; let size = self.size.ok_or(Error::MissingValue("size"))?; diff --git a/space-crush-common/src/builder/fleet.rs b/space-crush-common/src/builder/fleet.rs index 9e85446..a04a68e 100644 --- a/space-crush-common/src/builder/fleet.rs +++ b/space-crush-common/src/builder/fleet.rs @@ -13,7 +13,7 @@ pub struct FleetBuilder { } impl FleetBuilder { - pub fn build(self, world: &mut World) -> Result { + pub fn build(&self, world: &mut World) -> Result { let owner = self.owner.ok_or(Error::MissingValue("owner"))?; let meeting_point_owned = MeetingPointOwned::new(owner); diff --git a/space-crush-common/src/builder/planet.rs b/space-crush-common/src/builder/planet.rs index a2ce679..80540f4 100644 --- a/space-crush-common/src/builder/planet.rs +++ b/space-crush-common/src/builder/planet.rs @@ -18,7 +18,7 @@ pub struct PlanetBuilder { } impl PlanetBuilder { - pub fn build(self, world: &mut World) -> Result { + pub fn build(&self, world: &mut World) -> Result { let position = self.position.ok_or(Error::MissingValue("position"))?; let size = self.size.ok_or(Error::MissingValue("size"))?; let (orbit_min, orbit_max) = self.orbit.ok_or(Error::MissingValue("orbit"))?; diff --git a/space-crush-common/src/builder/player.rs b/space-crush-common/src/builder/player.rs index 82783b7..40e0747 100644 --- a/space-crush-common/src/builder/player.rs +++ b/space-crush-common/src/builder/player.rs @@ -3,22 +3,26 @@ use specs::{saveload::MarkedBuilder, Builder, Entity, World, WorldExt}; use glc::vector::Vector3f; use crate::{ - components::Player, + components::{Player, Race}, misc::{Persistence, WorldPersistence}, }; use super::Error; -#[derive(Default, Clone)] +#[derive(Clone)] pub struct PlayerBuilder { + index: usize, + race: Race, color: Option, } impl PlayerBuilder { - pub fn build(self, world: &mut World) -> Result { - let color = self.color.ok_or(Error::MissingValue("color"))?; + pub fn build(&mut self, world: &mut World) -> Result { + 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 .create_entity() @@ -26,6 +30,8 @@ impl PlayerBuilder { .with(player) .build(); + self.index += 1; + Ok(entity) } @@ -35,3 +41,13 @@ impl PlayerBuilder { self } } + +impl Default for PlayerBuilder { + fn default() -> Self { + Self { + index: 0, + race: Race::Fighter, + color: None, + } + } +} diff --git a/space-crush-common/src/builder/ship.rs b/space-crush-common/src/builder/ship.rs index 526eb8a..00bccbb 100644 --- a/space-crush-common/src/builder/ship.rs +++ b/space-crush-common/src/builder/ship.rs @@ -19,18 +19,17 @@ pub struct ShipBuilder { } impl ShipBuilder { - pub fn build(self, world: &mut World) -> Result { + pub fn build(&self, world: &mut World) -> Result { let player = self.player.ok_or(Error::MissingValue("player"))?; let fleet = self.fleet.ok_or(Error::MissingValue("fleet"))?; let position = self.position.ok_or(Error::MissingValue("position"))?; let type_ = self.type_.ok_or(Error::MissingValue("type"))?; let direction = self.direction; - let speed = 100.0; let player_owned = PlayerOwned::new(player); let fleet_owned = FleetOwned::new(fleet); let position = Position::new(position); - let ship = Ship::new(type_, direction, speed); + let ship = Ship::new(type_, direction); let entity = world .create_entity() diff --git a/space-crush-common/src/components/mod.rs b/space-crush-common/src/components/mod.rs index fe8cda1..a2bdc83 100644 --- a/space-crush-common/src/components/mod.rs +++ b/space-crush-common/src/components/mod.rs @@ -13,7 +13,7 @@ pub use fleet::{Fleet, FleetOwned}; pub use meeting_point::{MeetingPoint, MeetingPointOwned}; pub use obstacle::Obstacle; pub use planet::Planet; -pub use player::{Player, PlayerOwned}; +pub use player::{Player, PlayerOwned, Race}; pub use position::Position; 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}; diff --git a/space-crush-common/src/components/player.rs b/space-crush-common/src/components/player.rs index 3c6e14f..6410eb0 100644 --- a/space-crush-common/src/components/player.rs +++ b/space-crush-common/src/components/player.rs @@ -6,12 +6,27 @@ use specs::{ 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 { index: usize, + race: Race, color: Vector3f, + + #[serde(skip)] + ships_data: ShipsData, +} + +#[derive(Copy, Clone, Debug, Serialize, Deserialize)] +pub enum Race { + Fighter, + Trader, + Researcher, } #[derive(Copy, Clone, Debug)] @@ -41,14 +56,25 @@ impl Player { pub fn color(&self) -> &Vector3f { &self.color } + + #[inline] + pub fn ship_data(&self, type_: ShipType) -> &ShipData { + &self.ships_data[type_] + } } impl Player { #[inline] - pub(crate) fn new(color: Vector3f) -> Self { + pub(crate) fn new(index: usize, race: Race, color: Vector3f) -> Self { Self { - index: next_index(), + index, + race, 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 }) } } - -fn next_index() -> usize { - use std::sync::atomic::{AtomicUsize, Ordering}; - - static NEXT_INDEX: AtomicUsize = AtomicUsize::new(0); - - NEXT_INDEX.fetch_add(1, Ordering::Relaxed) -} diff --git a/space-crush-common/src/components/ship.rs b/space-crush-common/src/components/ship.rs index c115aeb..8afe015 100644 --- a/space-crush-common/src/components/ship.rs +++ b/space-crush-common/src/components/ship.rs @@ -9,12 +9,11 @@ use crate::{builder::ShipBuilder, misc::FlaggedStorage}; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Ship { - type_: Type, + type_: ShipType, dir: Vector2f, - speed: f32, #[serde(skip)] - obstacle: Obstacle, + obstacle: ShipObstacle, #[serde(skip)] target_pos: Vector2f, @@ -24,21 +23,33 @@ pub struct Ship { } #[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum Obstacle { +pub enum ShipObstacle { Known(Entity), Search, Done, } #[derive(Copy, Clone, Debug, Default)] -pub struct Count { +pub struct ShipCount { pub fighter: usize, pub bomber: 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)] -pub enum Type { +pub enum ShipType { Fighter, Bomber, Transporter, @@ -53,7 +64,7 @@ impl Ship { } #[inline] - pub fn type_(&self) -> Type { + pub fn type_(&self) -> ShipType { self.type_ } @@ -62,11 +73,6 @@ impl Ship { &self.dir } - #[inline] - pub fn speed(&self) -> f32 { - self.speed - } - #[inline] pub fn target_pos(&self) -> &Vector2f { &self.target_pos @@ -78,18 +84,17 @@ impl Ship { } #[inline] - pub fn obstacle(&self) -> Obstacle { + pub fn obstacle(&self) -> ShipObstacle { self.obstacle } } impl Ship { #[inline] - pub(crate) fn new(type_: Type, dir: Vector2f, speed: f32) -> Self { + pub(crate) fn new(type_: ShipType, dir: Vector2f) -> Self { Self { type_, dir, - speed, obstacle: Default::default(), target_pos: Default::default(), target_dir: Default::default(), @@ -108,7 +113,7 @@ impl Ship { } #[inline] - pub(crate) fn obstacle_mut(&mut self) -> &mut Obstacle { + pub(crate) fn obstacle_mut(&mut self) -> &mut ShipObstacle { &mut self.obstacle } } @@ -119,7 +124,7 @@ impl Component for Ship { /* Obstacle */ -impl Default for Obstacle { +impl Default for ShipObstacle { fn default() -> Self { Self::Search } @@ -127,7 +132,7 @@ impl Default for Obstacle { /* Count */ -impl Count { +impl ShipCount { pub fn all() -> Self { Self { fighter: usize::MAX, @@ -163,7 +168,7 @@ impl Count { } } -impl Index for Count { +impl Index for ShipCount { type Output = usize; fn index(&self, index: usize) -> &Self::Output { @@ -176,7 +181,7 @@ impl Index for Count { } } -impl IndexMut for Count { +impl IndexMut for ShipCount { fn index_mut(&mut self, index: usize) -> &mut Self::Output { match index { 0 => &mut self.fighter, @@ -187,30 +192,30 @@ impl IndexMut for Count { } } -impl Index for Count { +impl Index for ShipCount { type Output = usize; - fn index(&self, index: Type) -> &Self::Output { + fn index(&self, index: ShipType) -> &Self::Output { 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 for Count { - fn index_mut(&mut self, index: Type) -> &mut Self::Output { +impl IndexMut for ShipCount { + fn index_mut(&mut self, index: ShipType) -> &mut Self::Output { 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 for Count { - type Output = Count; +impl Mul for ShipCount { + type Output = ShipCount; #[allow(unused_assignments)] fn mul(self, rhs: f32) -> Self::Output { @@ -238,10 +243,37 @@ impl Mul for Count { actual += 1; } - Count { + ShipCount { fighter, bomber, transporter, } } } + +/* ShipsData */ + +impl Index 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 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, + } + } +} diff --git a/space-crush-common/src/constants.rs b/space-crush-common/src/constants.rs index 64921d0..08cea06 100644 --- a/space-crush-common/src/constants.rs +++ b/space-crush-common/src/constants.rs @@ -1,5 +1,7 @@ use glc::{matrix::Angle, vector::Vector2f}; +use crate::components::{ShipData, ShipsData}; + /// Distance to orbit before ship is handled as "in orbit" in % pub const SHIP_ORBIT_DISTANCE_MAX: f32 = 1.10; @@ -13,3 +15,21 @@ pub const SHIP_ORBIT_ANGLE_DELTA_RND: Angle = Angle::Deg(5000.0); pub const SHIP_ORBIT_AGILITY: Angle = Angle::Deg(90.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 }, +}; diff --git a/space-crush-common/src/dispatcher.rs b/space-crush-common/src/dispatcher.rs index 6a8fa78..8243607 100644 --- a/space-crush-common/src/dispatcher.rs +++ b/space-crush-common/src/dispatcher.rs @@ -3,7 +3,7 @@ use specs::{Dispatcher as Inner, DispatcherBuilder, World, WorldExt}; use crate::{ components::Player, resources::Global, - systems::{FleetControl, FleetOwnedUpdate, Movement, Process, Ships}, + systems::{FleetControl, FleetOwnedUpdate, Process, ShipMovement, Ships}, Error, }; @@ -19,7 +19,7 @@ impl<'a, 'b> Dispatcher<'a, 'b> { let mut dispatcher = DispatcherBuilder::new() .with(Process::default(), "process", &[]) - .with(Movement::default(), "movement", &[]) + .with(ShipMovement::default(), "ship_movement", &[]) .with(Ships::new(world), "ships", &[]) .with(FleetControl::new(world)?, "fleet_control", &[]) .with(FleetOwnedUpdate::new(world), "fleet_owned_update", &[]) diff --git a/space-crush-common/src/systems/mod.rs b/space-crush-common/src/systems/mod.rs index 91af7d4..a028e42 100644 --- a/space-crush-common/src/systems/mod.rs +++ b/space-crush-common/src/systems/mod.rs @@ -1,11 +1,11 @@ mod fleet_control; mod fleet_owned_update; -mod movement; mod process; +mod ship_movement; mod ships; pub use fleet_control::{FleetControl, FleetControlEvent}; pub use fleet_owned_update::FleetOwnedUpdate; -pub use movement::Movement; pub use process::Process; +pub use ship_movement::ShipMovement; pub use ships::Ships; diff --git a/space-crush-common/src/systems/movement.rs b/space-crush-common/src/systems/movement.rs deleted file mode 100644 index 1185071..0000000 --- a/space-crush-common/src/systems/movement.rs +++ /dev/null @@ -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; - }); - } -} diff --git a/space-crush-common/src/systems/ship_movement.rs b/space-crush-common/src/systems/ship_movement.rs new file mode 100644 index 0000000..142069e --- /dev/null +++ b/space-crush-common/src/systems/ship_movement.rs @@ -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; + }, + ); + } +}