2 Commits

20 changed files with 270 additions and 173 deletions
Split View
  1. +28
    -0
      overview
  2. +11
    -5
      space-crush-app/src/debug/ships.rs
  3. +3
    -5
      space-crush-app/src/render/ships.rs
  4. +1
    -1
      space-crush-common/src/builder/asteroid.rs
  5. +1
    -1
      space-crush-common/src/builder/fleet.rs
  6. +1
    -1
      space-crush-common/src/builder/planet.rs
  7. +21
    -5
      space-crush-common/src/builder/player.rs
  8. +3
    -6
      space-crush-common/src/builder/ship.rs
  9. +6
    -4
      space-crush-common/src/components/fleet.rs
  10. +2
    -4
      space-crush-common/src/components/mod.rs
  11. +30
    -12
      space-crush-common/src/components/player.rs
  12. +78
    -27
      space-crush-common/src/components/ship.rs
  13. +0
    -35
      space-crush-common/src/components/velocity.rs
  14. +20
    -0
      space-crush-common/src/constants.rs
  15. +2
    -2
      space-crush-common/src/dispatcher.rs
  16. +1
    -2
      space-crush-common/src/misc/world.rs
  17. +2
    -2
      space-crush-common/src/systems/mod.rs
  18. +0
    -39
      space-crush-common/src/systems/movement.rs
  19. +48
    -0
      space-crush-common/src/systems/ship_movement.rs
  20. +12
    -22
      space-crush-common/src/systems/ships.rs

+ 28
- 0
overview View File

@@ -0,0 +1,28 @@
x -> needed
o -> optional

___________________________________________________________
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 | | o | x | | | | | x | x | x | x | | x |
| Planet | | o | x | | | | | x | x | x | | x | x |
| MeetingPoint | | | x | | | | | | | x | | | x |
+--------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+

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

@@ -1,6 +1,6 @@
use glc::vector::Vector4f;
use space_crush_common::{
components::{Position, Ship, ShipObstacle, Velocity},
components::{Player, PlayerOwned, Position, Ship, ShipObstacle},
continue_if_none,
};
use specs::{prelude::*, ReadStorage, System, World, WriteExpect};
@@ -14,7 +14,8 @@ pub struct Ships;
pub struct ShipsData<'a> {
geometry: WriteExpect<'a, Geometry>,
positions: ReadStorage<'a, Position>,
velocities: ReadStorage<'a, Velocity>,
player_owned: ReadStorage<'a, PlayerOwned>,
players: ReadStorage<'a, Player>,
ships: ReadStorage<'a, Ship>,
}

@@ -25,19 +26,24 @@ impl<'a> System<'a> for Ships {
let ShipsData {
mut geometry,
positions,
velocities,
player_owned,
players,
ships,
} = data;

gl::enable(gl::BLEND);
gl::blend_func(gl::SRC_ALPHA, gl::ONE);

for (position, velocity, ship) in (&positions, &velocities, &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 + velocity.dir() * velocity.speed()],
&[*ship_pos, ship_pos + ship.dir() * ship_data.speed],
);
geometry.render_lines(
Vector4f::new(1.0, 0.0, 0.0, 0.2),


+ 3
- 5
space-crush-app/src/render/ships.rs View File

@@ -12,7 +12,7 @@ use glc::{
vertex_array::{DataType, VertexArray},
};
use space_crush_common::{
components::{Player, PlayerOwned, Position, Ship, ShipType, Velocity},
components::{Player, PlayerOwned, Position, Ship, ShipType},
misc::{ComponentEvent, LogResult, StorageHelper, StorageHelperMut},
};
use specs::{
@@ -55,7 +55,6 @@ pub struct Ships {
#[derive(SystemData)]
pub struct ShipsData<'a> {
positions: ReadStorage<'a, Position>,
velocities: ReadStorage<'a, Velocity>,
players: ReadStorage<'a, Player>,
owned: ReadStorage<'a, PlayerOwned>,
ships: ReadStorage<'a, Ship>,
@@ -217,16 +216,15 @@ impl Ships {
let data = (
&ids as &dyn BitSetLike,
&d.positions,
&d.velocities,
&d.ships,
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 mut s = &mut buf_ship[index as usize];
s.pos = *position.get();
s.dir = *velocity.dir();
s.dir = *ship.dir();

if self.need_init.contains(id) {
s.color = match owned.and_then(|owned| d.players.get(owned.owner())) {


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

@@ -19,7 +19,7 @@ pub struct 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 position = self.position.ok_or(Error::MissingValue("position"))?;
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 {
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 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 {
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 size = self.size.ok_or(Error::MissingValue("size"))?;
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 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<Vector3f>,
}

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
.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,
}
}
}

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

@@ -3,7 +3,7 @@ use rand::random;
use specs::{saveload::MarkedBuilder, Builder, Entity, World, WorldExt};

use crate::{
components::{FleetOwned, PlayerOwned, Position, Ship, ShipType, Velocity},
components::{FleetOwned, PlayerOwned, Position, Ship, ShipType},
misc::{Persistence, WorldPersistence},
};

@@ -19,19 +19,17 @@ pub struct 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 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 velocity = Velocity::new(direction, speed);
let ship = Ship::new(type_);
let ship = Ship::new(type_, direction);

let entity = world
.create_entity()
@@ -39,7 +37,6 @@ impl ShipBuilder {
.with(player_owned)
.with(fleet_owned)
.with(position)
.with(velocity)
.with(ship)
.build();



+ 6
- 4
space-crush-common/src/components/fleet.rs View File

@@ -81,13 +81,15 @@ impl Component for Fleet {
/* FleetOwned */

impl FleetOwned {
pub fn new(owner: Entity) -> Self {
Self { owner }
}

pub fn owner(&self) -> Entity {
self.owner
}
}

impl FleetOwned {
pub(crate) fn new(owner: Entity) -> Self {
Self { owner }
}

pub(crate) fn set_owner(&mut self, owner: Entity) {
self.owner = owner;


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

@@ -7,15 +7,13 @@ mod player;
mod position;
mod shape;
mod ship;
mod velocity;

pub use asteroid::{Asteroid, Type as AsteroidType};
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 velocity::Velocity;
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,
};

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)
}

+ 78
- 27
space-crush-common/src/components/ship.rs View File

@@ -9,10 +9,11 @@ use crate::{builder::ShipBuilder, misc::FlaggedStorage};

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Ship {
type_: Type,
type_: ShipType,
dir: Vector2f,

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

#[serde(skip)]
target_pos: Vector2f,
@@ -22,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,
@@ -51,10 +64,15 @@ impl Ship {
}

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

#[inline]
pub fn dir(&self) -> &Vector2f {
&self.dir
}

#[inline]
pub fn target_pos(&self) -> &Vector2f {
&self.target_pos
@@ -66,16 +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) -> Self {
pub(crate) fn new(type_: ShipType, dir: Vector2f) -> Self {
Self {
type_,
dir,
obstacle: Default::default(),
target_pos: Default::default(),
target_dir: Default::default(),
@@ -89,8 +108,13 @@ impl Ship {
}

#[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 ShipObstacle {
&mut self.obstacle
}
}

@@ -100,7 +124,7 @@ impl Component for Ship {

/* Obstacle */

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

/* Count */

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

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

fn index(&self, index: usize) -> &Self::Output {
@@ -157,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 {
match index {
0 => &mut self.fighter,
@@ -168,30 +192,30 @@ impl IndexMut<usize> for Count {
}
}

impl Index<Type> for Count {
impl Index<ShipType> 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<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 {
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)]
fn mul(self, rhs: f32) -> Self::Output {
@@ -219,10 +243,37 @@ impl Mul<f32> for Count {
actual += 1;
}

Count {
ShipCount {
fighter,
bomber,
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,
}
}
}

+ 0
- 35
space-crush-common/src/components/velocity.rs View File

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

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

@@ -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<f32> = Angle::Deg(5000.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 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::{
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", &[])


+ 1
- 2
space-crush-common/src/misc/world.rs View File

@@ -8,7 +8,7 @@ use specs::{saveload::SimpleMarker, World};
use crate::{
components::{
Asteroid, MeetingPoint, MeetingPointOwned, Obstacle, Planet, Player, PlayerOwned, Position,
Ship, Velocity,
Ship,
},
Error,
};
@@ -91,7 +91,6 @@ impl Persistence for WorldPersistence {
type Marker = SimpleMarker<PersistWorldMarker>;
type Components = (
Position,
Velocity,
Player,
PlayerOwned,
MeetingPoint,


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

@@ -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;

+ 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, Velocity},
resources::Global,
};

#[derive(Default)]
pub struct Movement;

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

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

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

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

*position += velocity.dir() * velocity.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;
},
);
}
}

+ 12
- 22
space-crush-common/src/systems/ships.rs View File

@@ -13,7 +13,6 @@ use specs::{
use crate::{
components::{
FleetOwned, MeetingPoint, MeetingPointOwned, Obstacle, Position, Shape, Ship, ShipObstacle,
Velocity,
},
constants::{
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>,
entities: Entities<'a>,
ships: WriteStorage<'a, Ship>,
velocities: WriteStorage<'a, Velocity>,
fleet_owned: ReadStorage<'a, FleetOwned>,
meeting_point_owned: ReadStorage<'a, MeetingPointOwned>,
positions: ReadStorage<'a, Position>,
@@ -92,7 +90,6 @@ impl<'a> System<'a> for Ships {
global,
entities,
mut ships,
mut velocities,
fleet_owned,
meeting_point_owned,
positions,
@@ -117,17 +114,11 @@ impl<'a> System<'a> for Ships {

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()
.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);
@@ -139,7 +130,6 @@ impl Processor<'_> {
&self,
id: Index,
ship: &mut Ship,
velocity: &mut Velocity,
position: &Position,
fleet_owned: &FleetOwned,
) {
@@ -179,7 +169,7 @@ impl Processor<'_> {
let target_pos = if ship_in_meeting_point && meeting_point_max > 0.0 {
let meeting_point_to_ship_vec3 =
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 {
1.0
@@ -201,7 +191,7 @@ impl Processor<'_> {
meeting_point_pos.y + radius * angle.sin(),
)
} else {
ship.set_obstacle(ShipObstacle::Search);
*ship.obstacle_mut() = ShipObstacle::Search;

*meeting_point_pos
};
@@ -213,7 +203,7 @@ impl Processor<'_> {

/* check if obstacle is still valid */
if ship_in_meeting_point {
ship.set_obstacle(ShipObstacle::Done);
*ship.obstacle_mut() = ShipObstacle::Done;
} else if let ShipObstacle::Known(obstacle) = ship.obstacle() {
if let Some(position) = self.positions.get(obstacle) {
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)
|| obstacle_angle > 170.0
{
ship.set_obstacle(ShipObstacle::Search);
*ship.obstacle_mut() = ShipObstacle::Search;
}
} 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();
if len_sqr < dist_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 e == fleet_owned.owner() {
ship.set_obstacle(ShipObstacle::Done);
*ship.obstacle_mut() = ShipObstacle::Done;
}
}
}
@@ -296,13 +286,13 @@ impl Processor<'_> {
}

/* update ship direction */
let angle = expected_dir.angle2(&velocity.dir());
let angle = expected_dir.angle2(ship.dir());
if angle.into_inner().abs() > 0.0001 {
let dir = angle.into_inner() / angle.abs().into_inner();
let agility = SHIP_ORBIT_AGILITY;
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);
}
}
}

Loading…
Cancel
Save