Explorar el Código

Renamed 'Orbit' to 'MeetingPoint'

master
Bergmann89 hace 5 años
padre
commit
b61ee04fd8
Se han modificado 18 ficheros con 302 adiciones y 272 borrados
  1. +5
    -5
      space-crush-app/src/debug/fleets.rs
  2. +15
    -12
      space-crush-app/src/debug/meeting_points.rs
  3. +2
    -2
      space-crush-app/src/debug/mod.rs
  4. +3
    -2
      space-crush-app/src/lib.rs
  5. +5
    -5
      space-crush-app/src/main.rs
  6. +13
    -11
      space-crush-app/src/render/fleet_move.rs
  7. +12
    -13
      space-crush-app/src/render/fleet_select.rs
  8. +10
    -8
      space-crush-common/src/components/fleet.rs
  9. +24
    -22
      space-crush-common/src/components/meeting_point.rs
  10. +3
    -3
      space-crush-common/src/components/mod.rs
  11. +1
    -0
      space-crush-common/src/components/obstacle.rs
  12. +6
    -2
      space-crush-common/src/dispatcher.rs
  13. +4
    -4
      space-crush-common/src/misc/persistence.rs
  14. +11
    -10
      space-crush-common/src/systems/fleet_control.rs
  15. +130
    -0
      space-crush-common/src/systems/meeting_point_owned_update.rs
  16. +2
    -2
      space-crush-common/src/systems/mod.rs
  17. +0
    -127
      space-crush-common/src/systems/orbit_owned_update.rs
  18. +56
    -44
      space-crush-common/src/systems/ships.rs

+ 5
- 5
space-crush-app/src/debug/fleets.rs Ver fichero

@@ -1,5 +1,5 @@
use space_crush_common::{
components::{Fleet, Orbit, Position},
components::{Fleet, MeetingPoint, Position},
continue_if_none,
misc::LogResult,
};
@@ -20,7 +20,7 @@ pub struct FleetData<'a> {
game_state: ReadExpect<'a, GameState>,
camera: ReadExpect<'a, Camera>,
positions: ReadStorage<'a, Position>,
orbits: ReadStorage<'a, Orbit>,
meeting_points: ReadStorage<'a, MeetingPoint>,
fleets: ReadStorage<'a, Fleet>,
}

@@ -49,7 +49,7 @@ impl<'a> System<'a> for Fleets {
game_state,
camera,
positions,
orbits,
meeting_points,
fleets,
} = data;

@@ -57,8 +57,8 @@ impl<'a> System<'a> for Fleets {

gl::enable(gl::BLEND);

for (position, orbit) in (&positions, &orbits).join() {
let fleet_id = continue_if_none!(orbit.fleet(player_index));
for (position, meeting_point) in (&positions, &meeting_points).join() {
let fleet_id = continue_if_none!(meeting_point.fleet(player_index));
let fleet = continue_if_none!(fleets.get(fleet_id));

gl::blend_func(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);


space-crush-app/src/debug/orbits.rs → space-crush-app/src/debug/meeting_points.rs Ver fichero

@@ -1,6 +1,6 @@
use glc::vector::{Angle, Vector2f, Vector4f};
use space_crush_common::{
components::{Orbit, Position},
components::{MeetingPoint, Position},
constants::SHIP_ORBIT_DISTANCE_MAX,
};
use specs::{prelude::*, ReadStorage, System, World, WriteExpect};
@@ -8,41 +8,44 @@ use specs::{prelude::*, ReadStorage, System, World, WriteExpect};
use crate::resources::Geometry;

#[derive(Default)]
pub struct Orbits {}
pub struct MeetingPoints {}

#[derive(SystemData)]
pub struct OrbitsData<'a> {
pub struct MeetingPointsData<'a> {
geometry: WriteExpect<'a, Geometry>,
positions: ReadStorage<'a, Position>,
orbits: ReadStorage<'a, Orbit>,
meeting_points: ReadStorage<'a, MeetingPoint>,
}

impl<'a> System<'a> for Orbits {
type SystemData = OrbitsData<'a>;
impl<'a> System<'a> for MeetingPoints {
type SystemData = MeetingPointsData<'a>;

fn run(&mut self, data: Self::SystemData) {
let OrbitsData {
let MeetingPointsData {
mut geometry,
positions,
orbits,
meeting_points,
} = data;

gl::enable(gl::BLEND);

for (position, orbit) in (&positions, &orbits).join() {
for (position, meeting_point) in (&positions, &meeting_points).join() {
gl::blend_func(gl::SRC_ALPHA, gl::ONE);
gl::blend_equation(gl::FUNC_ADD);
geometry.render_lines(
Vector4f::new(0.5, 0.5, 0.5, 0.05),
&create_circle(position.pos(), orbit.min()),
&create_circle(position.pos(), meeting_point.min()),
);
geometry.render_lines(
Vector4f::new(0.5, 0.5, 0.5, 0.05),
&create_circle(position.pos(), orbit.max()),
&create_circle(position.pos(), meeting_point.max()),
);
geometry.render_lines(
Vector4f::new(0.5, 0.5, 0.5, 0.05),
&create_circle(position.pos(), SHIP_ORBIT_DISTANCE_MAX * orbit.max()),
&create_circle(
position.pos(),
SHIP_ORBIT_DISTANCE_MAX * meeting_point.max(),
),
);
}


+ 2
- 2
space-crush-app/src/debug/mod.rs Ver fichero

@@ -1,9 +1,9 @@
mod fleets;
mod orbits;
mod meeting_points;
mod ships;
mod summary;

pub use fleets::Fleets;
pub use orbits::Orbits;
pub use meeting_points::MeetingPoints;
pub use ships::Ships;
pub use summary::Summary;

+ 3
- 2
space-crush-app/src/lib.rs Ver fichero

@@ -12,7 +12,8 @@ use specs::{Dispatcher, DispatcherBuilder, Entity, World};
pub use error::Error;

use debug::{
Fleets as DebugFleets, Orbits as DebugOrbits, Ships as DebugShips, Summary as DebugSummary,
Fleets as DebugFleets, MeetingPoints as DebugMeetingPoints, Ships as DebugShips,
Summary as DebugSummary,
};
use misc::{Events, TextManager, Window};
use render::{Asteroids, FleetMove, FleetSelect, Init, Planets, Ships};
@@ -58,7 +59,7 @@ impl<'a, 'b> App<'a, 'b> {
.with_thread_local(FleetSelect::new(world, &text_manager)?)
.with_thread_local(FleetMove::new(world)?)
.with_thread_local(DebugShips::default())
.with_thread_local(DebugOrbits::default())
.with_thread_local(DebugMeetingPoints::default())
.with_thread_local(DebugFleets::new(&text_manager)?)
.with_thread_local(DebugSummary::new(&text_manager)?)
.build();


+ 5
- 5
space-crush-app/src/main.rs Ver fichero

@@ -60,8 +60,8 @@ fn create_world(world: &mut World, player_id: Entity) {
use glc::{matrix::Angle, vector::Vector2f};
use space_crush_common::{
components::{
Asteroid, AsteroidType, Fleet, FleetOwned, Obstacle, Orbit, OrbitOwned, Planet,
PlayerOwned, Position, Ship, ShipType, Velocity,
Asteroid, AsteroidType, Fleet, FleetOwned, MeetingPoint, MeetingPointOwned, Obstacle,
Planet, PlayerOwned, Position, Ship, ShipType, Velocity,
},
misc::{PersistWorld, Persistence},
};
@@ -79,7 +79,7 @@ fn create_world(world: &mut World, player_id: Entity) {
.marked::<<PersistWorld as Persistence>::Marker>()
.with(PlayerOwned::new(player_id))
.with(Position::circle(Vector2f::new(x, y), 250.0))
.with(Orbit::new(325.0, 425.0))
.with(MeetingPoint::new(325.0, 425.0))
.with(Obstacle {})
.with(Planet {})
.build()
@@ -97,7 +97,7 @@ fn create_world(world: &mut World, player_id: Entity) {
.create_entity()
.marked::<<PersistWorld as Persistence>::Marker>()
.with(Position::circle(Vector2f::new(x, y), 100.0))
.with(Orbit::new(125.0, 175.0))
.with(MeetingPoint::new(125.0, 175.0))
.with(Obstacle {})
.with(Asteroid::new(match i_x * i_y {
-1 => AsteroidType::Metal,
@@ -111,7 +111,7 @@ fn create_world(world: &mut World, player_id: Entity) {
.create_entity()
.marked::<<PersistWorld as Persistence>::Marker>()
.with(PlayerOwned::new(player_id))
.with(OrbitOwned::new(planets[1]))
.with(MeetingPointOwned::new(planets[1]))
.with(Fleet::default())
.build();



+ 13
- 11
space-crush-app/src/render/fleet_move.rs Ver fichero

@@ -1,6 +1,6 @@
use shrev::{EventChannel, ReaderId};
use space_crush_common::{
components::{Orbit, Position},
components::{MeetingPoint, Position},
continue_if_none,
misc::WorldHelper,
systems::FleetControlEvent,
@@ -15,7 +15,7 @@ use crate::{

pub struct FleetMove {
mouse_event_id: ReaderId<MouseEvent>,
target_orbit: Option<Entity>,
target_meeting_point: Option<Entity>,
}

#[derive(SystemData)]
@@ -29,17 +29,17 @@ pub struct FleetMoveData<'a> {

entities: Entities<'a>,
positions: ReadStorage<'a, Position>,
orbits: ReadStorage<'a, Orbit>,
meeting_points: ReadStorage<'a, MeetingPoint>,
}

impl FleetMove {
pub fn new(world: &mut World) -> Result<Self, Error> {
let mouse_event_id = world.register_event_reader::<MouseEvent>()?;
let target_orbit = None;
let target_meeting_point = None;

Ok(Self {
mouse_event_id,
target_orbit,
target_meeting_point,
})
}
}
@@ -57,7 +57,7 @@ impl<'a> System<'a> for FleetMove {
config,
entities,
positions,
orbits,
meeting_points,
} = data;

let events = mouse_events.read(&mut self.mouse_event_id);
@@ -65,10 +65,12 @@ impl<'a> System<'a> for FleetMove {
match event {
MouseEvent::ButtonDown(button) if button == &config.input.fleet_move_button => {
let pos = camera.view_to_world(input_state.mouse_pos);
for (id, position, orbit) in (&entities, &positions, &orbits).join() {
let r = orbit.max() * orbit.max();
for (id, position, meeting_point) in
(&entities, &positions, &meeting_points).join()
{
let r = meeting_point.max() * meeting_point.max();
if (position.pos() - pos).length_sqr() <= r {
self.target_orbit = Some(id);
self.target_meeting_point = Some(id);

break;
}
@@ -78,14 +80,14 @@ impl<'a> System<'a> for FleetMove {
let selection = game_state.selection_mut().take();
let selection = continue_if_none!(selection);
let Selection { fleet, count } = selection;
let target = continue_if_none!(self.target_orbit);
let target = continue_if_none!(self.target_meeting_point);
let player = game_state.player_id();
let event = FleetControlEvent::move_(player, target, fleet, count);

fleet_control.single_write(event);
}
MouseEvent::Move(_, _) => {
self.target_orbit = None;
self.target_meeting_point = None;
}
_ => (),
}


+ 12
- 13
space-crush-app/src/render/fleet_select.rs Ver fichero

@@ -10,7 +10,7 @@ use glc::{
};
use shrev::{EventChannel, ReaderId};
use space_crush_common::{
components::{Fleet, Orbit, OrbitOwned, Position, ShipCount},
components::{Fleet, MeetingPoint, MeetingPointOwned, Position, ShipCount},
constants::VECTOR_2F_POS_X,
continue_if_none,
misc::{LogResult, WorldHelper as _},
@@ -80,9 +80,9 @@ pub struct FleetSelectData<'a> {
global: ReadExpect<'a, Global>,
config: ReadExpect<'a, Config>,

orbit_owned: ReadStorage<'a, OrbitOwned>,
meeting_point_owned: ReadStorage<'a, MeetingPointOwned>,
positions: ReadStorage<'a, Position>,
orbits: ReadStorage<'a, Orbit>,
meeting_points: ReadStorage<'a, MeetingPoint>,
fleets: ReadStorage<'a, Fleet>,
}

@@ -107,9 +107,9 @@ macro_rules! position {
};
}

macro_rules! orbit_owned {
macro_rules! meeting_point_owned {
(&$data:expr, $id:expr) => {
return_if_none!($data.orbit_owned.get($id))
return_if_none!($data.meeting_point_owned.get($id))
};
}

@@ -186,12 +186,11 @@ impl FleetSelect {
MouseEvent::ButtonDown(button) if button == &d.config.input.fleet_select_button => {
let pos = d.camera.view_to_world(d.input_state.mouse_pos);
let selection = d.game_state.selection_mut().take();
for (position, orbit) in (&d.positions, &d.orbits).join() {
let r = orbit.max() * orbit.max();
for (position, meeting_point) in (&d.positions, &d.meeting_points).join() {
let r = meeting_point.max() * meeting_point.max();
if (position.pos() - pos).length_sqr() <= r {
let player_index = d.game_state.player_index();
let fleet_id = continue_if_none!(orbit.fleets().get(player_index));
let fleet_id = *continue_if_none!(fleet_id);
let fleet_id = continue_if_none!(meeting_point.fleet(player_index));

*d.game_state.selection_mut() = match selection {
Some(s) if s.fleet == fleet_id => {
@@ -272,8 +271,8 @@ impl FleetSelect {

/* calculate values */
let selection = selection!(&d);
let orbit_owned = orbit_owned!(&d, selection.fleet);
let position = position!(&d, orbit_owned.owner());
let meeting_point_owned = meeting_point_owned!(&d, selection.fleet);
let position = position!(&d, meeting_point_owned.owner());
let fleet = fleet!(&d, selection.fleet);

self.marker = d.camera.view_to_world(self.mouse_pos) - position.pos();
@@ -426,8 +425,8 @@ impl FleetSelect {

/* extract system data */
let selection = selection!(&d);
let orbit_owned = orbit_owned!(&d, selection.fleet);
let position = position!(&d, orbit_owned.owner());
let meeting_point_owned = meeting_point_owned!(&d, selection.fleet);
let position = position!(&d, meeting_point_owned.owner());

/* calculate shared values */
let size = self.ring1 + 50.0;


+ 10
- 8
space-crush-common/src/components/fleet.rs Ver fichero

@@ -10,19 +10,21 @@ use specs::{

use crate::{components::ShipCount, misc::FlaggedStorage};

/// A fleet is a group of ships that share the same operation
#[derive(Default, Debug, Clone)]
pub struct Fleet {
owned: BitSet,
count: ShipCount,
}

/// Entities with this component are owned by a certain fleet entity
#[derive(Copy, Clone, Debug)]
pub struct Owned {
pub struct FleetOwned {
owner: Entity,
}

#[derive(Serialize, Deserialize)]
pub struct OwnedData<M> {
pub struct FleetOwnedData<M> {
pub owner: M,
}

@@ -52,7 +54,7 @@ impl Component for Fleet {
type Storage = HashMapStorage<Self>;
}

impl Owned {
impl FleetOwned {
pub fn new(owner: Entity) -> Self {
Self { owner }
}
@@ -66,15 +68,15 @@ impl Owned {
}
}

impl Component for Owned {
impl Component for FleetOwned {
type Storage = FlaggedStorage<Self, VecStorage<Self>>;
}

impl<M> ConvertSaveload<M> for Owned
impl<M> ConvertSaveload<M> for FleetOwned
where
for<'de> M: Marker + Serialize + Deserialize<'de>,
{
type Data = OwnedData<M>;
type Data = FleetOwnedData<M>;
type Error = NoError;

fn convert_into<F>(&self, mut ids: F) -> Result<Self::Data, Self::Error>
@@ -83,7 +85,7 @@ where
{
let owner = ids(self.owner).unwrap();

Ok(OwnedData { owner })
Ok(FleetOwnedData { owner })
}

fn convert_from<F>(data: Self::Data, mut ids: F) -> Result<Self, Self::Error>
@@ -92,6 +94,6 @@ where
{
let owner = ids(data.owner).unwrap();

Ok(Owned { owner })
Ok(FleetOwned { owner })
}
}

space-crush-common/src/components/orbit.rs → space-crush-common/src/components/meeting_point.rs Ver fichero

@@ -9,33 +9,35 @@ use specs::{

use crate::misc::FlaggedStorage;

/// Point in the universe fleets can meet
#[derive(Clone, Debug, Default)]
pub struct Orbit {
pub struct MeetingPoint {
min: f32,
max: f32,
fleets: Fleets,
}

/// Entities with this component are fleets by an meeting point
#[derive(Copy, Clone, Debug)]
pub struct MeetingPointOwned {
owner: Entity,
}

#[derive(Serialize, Deserialize)]
pub struct OrbitData<M> {
pub struct MeetingPointData<M> {
pub min: f32,
pub max: f32,
pub fleets: Vec<Option<M>>,
}

#[derive(Copy, Clone, Debug)]
pub struct Owned {
owner: Entity,
}

#[derive(Serialize, Deserialize)]
pub struct OwnedData<M> {
pub struct MeetingPointOwnedData<M> {
pub owner: M,
}

type Fleets = SmallVec<[Option<Entity>; 8]>;

impl Orbit {
impl MeetingPoint {
#[inline]
pub fn new(min: f32, max: f32) -> Self {
Self {
@@ -78,22 +80,22 @@ impl Orbit {
}
}

impl Component for Orbit {
impl Component for MeetingPoint {
type Storage = HashMapStorage<Self>;
}

impl<M> ConvertSaveload<M> for Orbit
impl<M> ConvertSaveload<M> for MeetingPoint
where
for<'de> M: Marker + Serialize + Deserialize<'de>,
{
type Data = OrbitData<M>;
type Data = MeetingPointData<M>;
type Error = NoError;

fn convert_into<F>(&self, mut ids: F) -> Result<Self::Data, Self::Error>
where
F: FnMut(Entity) -> Option<M>,
{
let Orbit { min, max, fleets } = self;
let MeetingPoint { min, max, fleets } = self;

let min = *min;
let max = *max;
@@ -103,21 +105,21 @@ where
.map(|e| e.and_then(|e| ids(e)))
.collect();

Ok(OrbitData { min, max, fleets })
Ok(MeetingPointData { min, max, fleets })
}

fn convert_from<F>(data: Self::Data, mut ids: F) -> Result<Self, Self::Error>
where
F: FnMut(M) -> Option<Entity>,
{
let OrbitData { min, max, fleets } = data;
let MeetingPointData { min, max, fleets } = data;
let fleets = fleets.into_iter().map(|e| e.and_then(|e| ids(e))).collect();

Ok(Orbit { min, max, fleets })
Ok(MeetingPoint { min, max, fleets })
}
}

impl Owned {
impl MeetingPointOwned {
pub fn new(owner: Entity) -> Self {
Self { owner }
}
@@ -131,15 +133,15 @@ impl Owned {
}
}

impl Component for Owned {
impl Component for MeetingPointOwned {
type Storage = FlaggedStorage<Self, HashMapStorage<Self>>;
}

impl<M> ConvertSaveload<M> for Owned
impl<M> ConvertSaveload<M> for MeetingPointOwned
where
for<'de> M: Marker + Serialize + Deserialize<'de>,
{
type Data = OwnedData<M>;
type Data = MeetingPointOwnedData<M>;
type Error = NoError;

fn convert_into<F>(&self, mut ids: F) -> Result<Self::Data, Self::Error>
@@ -148,7 +150,7 @@ where
{
let owner = ids(self.owner).unwrap();

Ok(OwnedData { owner })
Ok(MeetingPointOwnedData { owner })
}

fn convert_from<F>(data: Self::Data, mut ids: F) -> Result<Self, Self::Error>
@@ -157,6 +159,6 @@ where
{
let owner = ids(data.owner).unwrap();

Ok(Owned { owner })
Ok(MeetingPointOwned { owner })
}
}

+ 3
- 3
space-crush-common/src/components/mod.rs Ver fichero

@@ -1,7 +1,7 @@
mod asteroid;
mod fleet;
mod meeting_point;
mod obstacle;
mod orbit;
mod planet;
mod player;
mod position;
@@ -9,9 +9,9 @@ mod ship;
mod velocity;

pub use asteroid::{Asteroid, Type as AsteroidType};
pub use fleet::{Fleet, Owned as FleetOwned};
pub use fleet::{Fleet, FleetOwned};
pub use meeting_point::{MeetingPoint, MeetingPointOwned};
pub use obstacle::Obstacle;
pub use orbit::{Orbit, Owned as OrbitOwned};
pub use planet::Planet;
pub use player::{Owned as PlayerOwned, Player};
pub use position::{Position, Shape};


+ 1
- 0
space-crush-common/src/components/obstacle.rs Ver fichero

@@ -1,6 +1,7 @@
use serde::{Deserialize, Serialize};
use specs::{Component, NullStorage};

/// Objects that ships can not pass through
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct Obstacle {}



+ 6
- 2
space-crush-common/src/dispatcher.rs Ver fichero

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

@@ -23,7 +23,11 @@ impl<'a, 'b> Dispatcher<'a, 'b> {
.with(Ships::new(world), "ships", &[])
.with(FleetControl::new(world)?, "fleet_control", &[])
.with(FleetOwnedUpdate::new(world), "fleet_owned_update", &[])
.with(OrbitOwnedUpdate::new(world), "orbit_owned_update", &[])
.with(
MeetingPointOwnedUpdate::new(world),
"meeting_point_owned_update",
&[],
)
.build();
dispatcher.setup(world);



+ 4
- 4
space-crush-common/src/misc/persistence.rs Ver fichero

@@ -6,8 +6,8 @@ use specs::{
};

use crate::components::{
Asteroid, FleetOwned, Obstacle, Orbit, OrbitOwned, Planet, Player, PlayerOwned, Position, Ship,
Velocity,
Asteroid, FleetOwned, MeetingPoint, MeetingPointOwned, Obstacle, Planet, Player, PlayerOwned,
Position, Ship, Velocity,
};

/* PersistWorld */
@@ -22,8 +22,8 @@ impl Persistence for PersistWorld {
Velocity,
Player,
PlayerOwned,
Orbit,
OrbitOwned,
MeetingPoint,
MeetingPointOwned,
FleetOwned,
Ship,
Obstacle,


+ 11
- 10
space-crush-common/src/systems/fleet_control.rs Ver fichero

@@ -6,7 +6,8 @@ use specs::{

use crate::{
components::{
Fleet, FleetOwned, Orbit, OrbitOwned, Player, PlayerOwned, Ship, ShipCount, ShipType,
Fleet, FleetOwned, MeetingPoint, MeetingPointOwned, Player, PlayerOwned, Ship, ShipCount,
ShipType,
},
continue_if_none,
misc::{LogResult, PersistWorld, Persistence, WorldHelper},
@@ -36,9 +37,9 @@ pub struct FleetControlData<'a> {
entities: Entities<'a>,
fleet_control_events: ReadExpect<'a, EventChannel<FleetControlEvent>>,
player_owned: WriteStorage<'a, PlayerOwned>,
orbit_owned: WriteStorage<'a, OrbitOwned>,
meeting_point_owned: WriteStorage<'a, MeetingPointOwned>,
fleet_owned: WriteStorage<'a, FleetOwned>,
orbits: WriteStorage<'a, Orbit>,
meeting_points: WriteStorage<'a, MeetingPoint>,
fleets: WriteStorage<'a, Fleet>,
players: ReadStorage<'a, Player>,
ships: ReadStorage<'a, Ship>,
@@ -65,9 +66,9 @@ impl<'a> System<'a> for FleetControl {
entities,
fleet_control_events,
mut player_owned,
mut orbit_owned,
mut meeting_point_owned,
mut fleet_owned,
mut orbits,
mut meeting_points,
mut fleets,
players,
ships,
@@ -77,11 +78,11 @@ impl<'a> System<'a> for FleetControl {
for event in events {
match event {
FleetControlEvent::Move(args) if args.count.is_all() => {
let orbit_owned = continue_if_none!(orbit_owned.get_mut(args.fleet));
let orbit_owned = continue_if_none!(meeting_point_owned.get_mut(args.fleet));
orbit_owned.set_owner(args.target);
}
FleetControlEvent::Move(args) => {
let target_orbit = continue_if_none!(orbits.get_mut(args.target));
let target_orbit = continue_if_none!(meeting_points.get_mut(args.target));
let player = continue_if_none!(players.get(args.player));
let mut count = args.count;

@@ -96,9 +97,9 @@ impl<'a> System<'a> for FleetControl {
player_owned
.insert(fleet, PlayerOwned::new(args.player))
.error("Unable to insert component: PlayerOwned");
orbit_owned
.insert(fleet, OrbitOwned::new(args.target))
.error("Unable to insert component: OrbitOwned");
meeting_point_owned
.insert(fleet, MeetingPointOwned::new(args.target))
.error("Unable to insert component: MeetingPointOwned");
fleets
.insert(fleet, Fleet::default())
.error("Unable to insert component: Fleet");


+ 130
- 0
space-crush-common/src/systems/meeting_point_owned_update.rs Ver fichero

@@ -0,0 +1,130 @@
use std::collections::HashMap;

use shrev::ReaderId;
use specs::{
hibitset::BitSet, prelude::*, world::Index, Entities, Entity, ReadStorage, System, World,
WriteStorage,
};

use crate::{
components::{MeetingPoint, MeetingPointOwned, PlayerOwned},
misc::{ComponentEvent, StorageHelper, StorageHelperMut},
};

pub struct MeetingPointOwnedUpdate {
meeting_point_ids: BitSet,
meeting_point_owned_ids: BitSet,
old_meeting_point_ids: HashMap<Index, Entity>,
meeting_point_owned_event_id: ReaderId<crate::misc::ComponentEvent<MeetingPointOwned>>,
}

impl MeetingPointOwnedUpdate {
pub fn new(world: &mut World) -> Self {
WriteStorage::<MeetingPointOwned>::setup(world);

let meeting_point_ids = BitSet::new();
let meeting_point_owned_ids = BitSet::new();
let old_meeting_point_ids = HashMap::new();
let meeting_point_owned_event_id = world
.system_data::<WriteStorage<MeetingPointOwned>>()
.register_event_reader();

Self {
meeting_point_ids,
meeting_point_owned_ids,
old_meeting_point_ids,
meeting_point_owned_event_id,
}
}
}

#[derive(SystemData)]
pub struct MeetingPointOwnedUpdateData<'a> {
entities: Entities<'a>,
meeting_points: WriteStorage<'a, MeetingPoint>,
player_owned: ReadStorage<'a, PlayerOwned>,
meeting_point_owned: ReadStorage<'a, MeetingPointOwned>,
}

impl<'a> System<'a> for MeetingPointOwnedUpdate {
type SystemData = MeetingPointOwnedUpdateData<'a>;

fn run(&mut self, data: Self::SystemData) {
let MeetingPointOwnedUpdateData {
entities,
mut meeting_points,
player_owned,
meeting_point_owned,
} = data;

self.meeting_point_ids.clear();
self.meeting_point_owned_ids.clear();
self.old_meeting_point_ids.clear();

/* handle events */
let events = meeting_point_owned
.channel()
.read(&mut self.meeting_point_owned_event_id);
for event in events {
match event {
ComponentEvent::Inserted(id, meeting_point_owned) => {
self.meeting_point_ids.add(meeting_point_owned.owner().id());
self.meeting_point_owned_ids.add(*id);
}
ComponentEvent::Modified(id, meeting_point_owned) => {
self.meeting_point_ids.add(meeting_point_owned.owner().id());
self.meeting_point_owned_ids.add(*id);
*self
.old_meeting_point_ids
.entry(*id)
.or_insert_with(|| meeting_point_owned.owner()) =
meeting_point_owned.owner();
}
ComponentEvent::Removed(id, meeting_point_owned) => {
self.meeting_point_ids.add(meeting_point_owned.owner().id());
self.meeting_point_owned_ids.add(*id);
*self
.old_meeting_point_ids
.entry(*id)
.or_insert_with(|| meeting_point_owned.owner()) =
meeting_point_owned.owner();
}
}
}

/* find new meeting_point ids */
for (meeting_point_owned, _) in (&meeting_point_owned, &self.meeting_point_owned_ids).join()
{
self.meeting_point_ids.add(meeting_point_owned.owner().id());
}

/* update meeting_points */
for (meeting_point_id, meeting_point, _) in
(&entities, &mut meeting_points, &self.meeting_point_ids).join()
{
let data = (
&entities,
&meeting_point_owned,
&player_owned,
&self.meeting_point_owned_ids,
);

for (fleet_id, meeting_point_owned, player_owned, _) in data.join() {
let new_match = meeting_point_id == meeting_point_owned.owner();
let old_match = match self.old_meeting_point_ids.get(&fleet_id.id()) {
Some(old_meeting_point_id) => meeting_point_id == *old_meeting_point_id,
None => false,
};

let player_id = player_owned.owner().id() as usize;
if old_match && !new_match {
if let Some(fleet) = meeting_point.fleets_mut().get_mut(player_id) {
*fleet = None;
}
} else if !old_match && new_match {
*meeting_point.fleet_mut(player_id) = Some(fleet_id);
}
}
}
}
}

+ 2
- 2
space-crush-common/src/systems/mod.rs Ver fichero

@@ -1,13 +1,13 @@
mod fleet_control;
mod fleet_owned_update;
mod meeting_point_owned_update;
mod movement;
mod orbit_owned_update;
mod process;
mod ships;

pub use fleet_control::{FleetControl, FleetControlEvent};
pub use fleet_owned_update::FleetOwnedUpdate;
pub use meeting_point_owned_update::MeetingPointOwnedUpdate;
pub use movement::Movement;
pub use orbit_owned_update::OrbitOwnedUpdate;
pub use process::Process;
pub use ships::Ships;

+ 0
- 127
space-crush-common/src/systems/orbit_owned_update.rs Ver fichero

@@ -1,127 +0,0 @@
use std::collections::HashMap;

use shrev::ReaderId;
use specs::{
hibitset::BitSet, prelude::*, world::Index, Entities, Entity, ReadStorage, System, World,
WriteStorage,
};

use crate::{
components::{Orbit, OrbitOwned, PlayerOwned},
misc::{ComponentEvent, StorageHelper, StorageHelperMut},
};

pub struct OrbitOwnedUpdate {
orbit_ids: BitSet,
orbit_owned_ids: BitSet,
old_orbit_ids: HashMap<Index, Entity>,
orbit_owned_event_id: ReaderId<crate::misc::ComponentEvent<OrbitOwned>>,
}

impl OrbitOwnedUpdate {
pub fn new(world: &mut World) -> Self {
WriteStorage::<OrbitOwned>::setup(world);

let orbit_ids = BitSet::new();
let orbit_owned_ids = BitSet::new();
let old_orbit_ids = HashMap::new();
let orbit_owned_event_id = world
.system_data::<WriteStorage<OrbitOwned>>()
.register_event_reader();

Self {
orbit_ids,
orbit_owned_ids,
old_orbit_ids,
orbit_owned_event_id,
}
}
}

#[derive(SystemData)]
pub struct OrbitOwnedUpdateData<'a> {
entities: Entities<'a>,
orbits: WriteStorage<'a, Orbit>,
player_owned: ReadStorage<'a, PlayerOwned>,
orbit_owned: ReadStorage<'a, OrbitOwned>,
}

impl<'a> System<'a> for OrbitOwnedUpdate {
type SystemData = OrbitOwnedUpdateData<'a>;

fn run(&mut self, data: Self::SystemData) {
let OrbitOwnedUpdateData {
entities,
mut orbits,
player_owned,
orbit_owned,
} = data;

self.orbit_ids.clear();
self.orbit_owned_ids.clear();
self.old_orbit_ids.clear();

/* handle events */
let events = orbit_owned.channel().read(&mut self.orbit_owned_event_id);
for event in events {
match event {
ComponentEvent::Inserted(id, orbit_owned) => {
self.orbit_ids.add(orbit_owned.owner().id());
self.orbit_owned_ids.add(*id);
}
ComponentEvent::Modified(id, orbit_owned) => {
self.orbit_ids.add(orbit_owned.owner().id());
self.orbit_owned_ids.add(*id);
*self
.old_orbit_ids
.entry(*id)
.or_insert_with(|| orbit_owned.owner()) = orbit_owned.owner();
}
ComponentEvent::Removed(id, orbit_owned) => {
self.orbit_ids.add(orbit_owned.owner().id());
self.orbit_owned_ids.add(*id);
*self
.old_orbit_ids
.entry(*id)
.or_insert_with(|| orbit_owned.owner()) = orbit_owned.owner();
}
}
}

/* find new orbit ids */
for (orbit_owned, _) in (&orbit_owned, &self.orbit_owned_ids).join() {
self.orbit_ids.add(orbit_owned.owner().id());
}

/* update orbits */
for (orbit_id, orbit, _) in (&entities, &mut orbits, &self.orbit_ids).join() {
let data = (
&entities,
&orbit_owned,
&player_owned,
&self.orbit_owned_ids,
);

for (fleet_id, orbit_owned, player_owned, _) in data.join() {
let new_match = orbit_id == orbit_owned.owner();
let old_match = match self.old_orbit_ids.get(&fleet_id.id()) {
Some(old_orbit_id) => orbit_id == *old_orbit_id,
None => false,
};

let player_id = player_owned.owner().id() as usize;
if old_match && !new_match {
if let Some(fleet) = orbit.fleets_mut().get_mut(player_id) {
*fleet = None;
}
} else if !old_match && new_match {
orbit
.fleets_mut()
.resize_with(player_id + 1, Default::default);
// TODO: merge fleets if player already have a fleet on this orbit
orbit.fleets_mut()[player_id] = Some(fleet_id);
}
}
}
}
}

+ 56
- 44
space-crush-common/src/systems/ships.rs Ver fichero

@@ -11,7 +11,10 @@ use specs::{
};

use crate::{
components::{FleetOwned, Obstacle, Orbit, OrbitOwned, Position, Ship, ShipObstacle, Velocity},
components::{
FleetOwned, MeetingPoint, MeetingPointOwned, Obstacle, Position, Ship, ShipObstacle,
Velocity,
},
constants::{
SHIP_ORBIT_AGILITY, SHIP_ORBIT_ANGLE_DELTA_MIN, SHIP_ORBIT_ANGLE_DELTA_RND,
SHIP_ORBIT_DISTANCE_MAX, VECTOR_2F_POS_X,
@@ -33,10 +36,10 @@ pub struct ShipsData<'a> {
ships: WriteStorage<'a, Ship>,
velocities: WriteStorage<'a, Velocity>,
fleet_owned: ReadStorage<'a, FleetOwned>,
orbit_owned: ReadStorage<'a, OrbitOwned>,
meeting_point_owned: ReadStorage<'a, MeetingPointOwned>,
positions: ReadStorage<'a, Position>,
obstacles: ReadStorage<'a, Obstacle>,
orbits: ReadStorage<'a, Orbit>,
meeting_points: ReadStorage<'a, MeetingPoint>,
}

struct Processor<'a> {
@@ -44,8 +47,8 @@ struct Processor<'a> {
entities: &'a Entities<'a>,
positions: &'a ReadStorage<'a, Position>,
obstacles: &'a ReadStorage<'a, Obstacle>,
orbits: &'a ReadStorage<'a, Orbit>,
orbit_owned: &'a ReadStorage<'a, OrbitOwned>,
meeting_points: &'a ReadStorage<'a, MeetingPoint>,
meeting_point_owned: &'a ReadStorage<'a, MeetingPointOwned>,
delta: f32,
}

@@ -89,10 +92,10 @@ impl<'a> System<'a> for Ships {
mut ships,
mut velocities,
fleet_owned,
orbit_owned,
meeting_point_owned,
positions,
obstacles,
orbits,
meeting_points,
} = data;

self.progress_events(&fleet_owned);
@@ -103,8 +106,8 @@ impl<'a> System<'a> for Ships {
entities: &entities,
positions: &positions,
obstacles: &obstacles,
orbit_owned: &orbit_owned,
orbits: &orbits,
meeting_point_owned: &meeting_point_owned,
meeting_points: &meeting_points,
delta: global.delta * global.world_speed,
};

@@ -137,58 +140,66 @@ impl Processor<'_> {
fleet_owned: &FleetOwned,
) {
let fleet_id = fleet_owned.owner();
let orbit_owned = return_if_none!(self.orbit_owned.get(fleet_id));
let orbit_id = orbit_owned.owner();
let orbit = return_if_none!(self.orbits.get(orbit_id));
let orbit_pos = return_if_none!(self.positions.get(orbit_id)).pos();
let meeting_point_owned = return_if_none!(self.meeting_point_owned.get(fleet_id));
let meeting_point_id = meeting_point_owned.owner();
let meeting_point = return_if_none!(self.meeting_points.get(meeting_point_id));
let meeting_point_pos = return_if_none!(self.positions.get(meeting_point_id)).pos();
let ship_pos = position.pos();
let target_pos = ship.target_pos();
let target_dir = ship.target_dir();

let orbit_to_target = target_pos - orbit_pos;
let orbit_to_ship = ship_pos - orbit_pos;
let meeting_point_to_target = target_pos - meeting_point_pos;
let meeting_point_to_ship = ship_pos - meeting_point_pos;
let mut ship_to_target = target_pos - ship_pos;

let r_ship = orbit_to_ship.length_sqr();
let r_target = orbit_to_target.length_sqr();
let r_ship = meeting_point_to_ship.length_sqr();
let r_target = meeting_point_to_target.length_sqr();

let orbit_min = orbit.min();
let orbit_max = orbit.max();
let meeting_point_min = meeting_point.min();
let meeting_point_max = meeting_point.max();

let target_in_orbit = (r_target <= sqr(orbit_max)) && (r_target >= sqr(orbit_min));
let ship_in_orbit = r_ship < sqr(SHIP_ORBIT_DISTANCE_MAX * orbit_max);
let target_in_meeting_point =
(r_target <= sqr(meeting_point_max)) && (r_target >= sqr(meeting_point_min));
let ship_in_meeting_point = r_ship < sqr(SHIP_ORBIT_DISTANCE_MAX * meeting_point_max);

let need_update = self.need_update.contains(id);
let has_target = target_dir.length_sqr() != 0.0;
let passed_target = target_dir * ship_to_target <= 0.0;

/* check and update target posistion */
if need_update || !has_target || passed_target || ship_in_orbit != target_in_orbit {
let target_pos = if ship_in_orbit && orbit_max > 0.0 {
let orbit_to_ship_vec3 = Vector3f::new(orbit_to_ship.x, orbit_to_ship.y, 0.0);
if need_update
|| !has_target
|| passed_target
|| ship_in_meeting_point != target_in_meeting_point
{
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 dir = if orbit_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
} else {
-1.0
};

let orbit_min = orbit.min();
let orbit_max = orbit.max();
let meeting_point_min = meeting_point.min();
let meeting_point_max = meeting_point.max();

let add = SHIP_ORBIT_ANGLE_DELTA_MIN + SHIP_ORBIT_ANGLE_DELTA_RND * random::<f32>();
let angle = orbit_to_ship.angle2(&VECTOR_2F_POS_X) + (add * dir / orbit_max);
let radius = orbit_min + (orbit_max - orbit_min) * random::<f32>();
let angle = meeting_point_to_ship.angle2(&VECTOR_2F_POS_X)
+ (add * dir / meeting_point_max);
let radius =
meeting_point_min + (meeting_point_max - meeting_point_min) * random::<f32>();

Vector2f::new(
orbit_pos.x + radius * angle.cos(),
orbit_pos.y + radius * angle.sin(),
meeting_point_pos.x + radius * angle.cos(),
meeting_point_pos.y + radius * angle.sin(),
)
} else {
ship.set_obstacle(ShipObstacle::Search);

*orbit_pos
*meeting_point_pos
};

ship.set_target(target_pos, (target_pos - ship_pos).normalize());
@@ -197,11 +208,11 @@ impl Processor<'_> {
}

/* check if obstacle is still valid */
if ship_in_orbit {
if ship_in_meeting_point {
ship.set_obstacle(ShipObstacle::Done);
} else if let ShipObstacle::Known(obstacle) = ship.obstacle() {
if let Some(position) = self.positions.get(obstacle) {
let obstacle_orbit = self.orbits.get(obstacle).unwrap();
let obstacle_meeting_point = self.meeting_points.get(obstacle).unwrap();
let obstacle_pos = position.pos();
let ship_to_obstacle = obstacle_pos - ship_pos;

@@ -211,8 +222,8 @@ impl Processor<'_> {
.into_inner()
.abs();

let orbit_sqr = obstacle_orbit.max() * obstacle_orbit.max();
if (obstacle_angle > 90.0 && ship_to_obstacle.length_sqr() > orbit_sqr)
let meeting_point_sqr = obstacle_meeting_point.max() * obstacle_meeting_point.max();
if (obstacle_angle > 90.0 && ship_to_obstacle.length_sqr() > meeting_point_sqr)
|| obstacle_angle > 170.0
{
ship.set_obstacle(ShipObstacle::Search);
@@ -223,7 +234,7 @@ impl Processor<'_> {
}

/* find obstacle */
if !ship_in_orbit && ship.obstacle() == ShipObstacle::Search {
if !ship_in_meeting_point && ship.obstacle() == ShipObstacle::Search {
let mut dist_sqr = f32::MAX;
for (e, position, _) in (self.entities, self.positions, self.obstacles).join() {
let obstacle_pos = position.pos();
@@ -251,19 +262,20 @@ impl Processor<'_> {
let mut expected_dir = ship_to_target;
if let ShipObstacle::Known(obstacle) = ship.obstacle() {
let obstacle_pos = self.positions.get(obstacle).unwrap();
let obstacle_orbit = self.orbits.get(obstacle).unwrap();
let obstacle_meeting_point = self.meeting_points.get(obstacle).unwrap();
let ship_to_obstacle = obstacle_pos.pos() - ship_pos;

let orbit_min = obstacle_orbit.min();
let orbit_max = obstacle_orbit.max();
let meeting_point_min = obstacle_meeting_point.min();
let meeting_point_max = obstacle_meeting_point.max();

let orbit = ship_to_obstacle.length();
if orbit < orbit_max {
let meeting_point = ship_to_obstacle.length();
if meeting_point < meeting_point_max {
let mut tangent = Vector2f::new(-ship_to_obstacle.y, ship_to_obstacle.x);

let radius = obstacle_pos.shape().radius();
let mut adjust_low = linear_step(orbit_min, radius, orbit);
let adjust_high = 1.0 - linear_step(orbit_max, orbit_min, orbit);
let mut adjust_low = linear_step(meeting_point_min, radius, meeting_point);
let adjust_high =
1.0 - linear_step(meeting_point_max, meeting_point_min, meeting_point);

if ship_to_target * tangent < 0.0 {
tangent = -tangent;


Cargando…
Cancelar
Guardar