diff --git a/space-crush-app/src/render/fleet_select.rs b/space-crush-app/src/render/fleet_select.rs index 0262e7b..516d9e5 100644 --- a/space-crush-app/src/render/fleet_select.rs +++ b/space-crush-app/src/render/fleet_select.rs @@ -10,7 +10,7 @@ use glc::{ }; use shrev::{EventChannel, ReaderId}; use space_crush_common::{ - components::{Fleet, MeetingPoint, MeetingPointOwned, Position, Shape, ShipCount}, + components::{Fleet, FleetOrbiting, MeetingPoint, Position, Shape, ShipCount}, constants::VECTOR_2F_POS_X, continue_if_none, misc::{LogResult, WorldHelper as _}, @@ -80,44 +80,12 @@ pub struct FleetSelectData<'a> { global: ReadExpect<'a, Global>, config: ReadExpect<'a, Config>, - meeting_point_owned: ReadStorage<'a, MeetingPointOwned>, positions: ReadStorage<'a, Position>, shapes: ReadStorage<'a, Shape>, meeting_points: ReadStorage<'a, MeetingPoint>, - fleets: ReadStorage<'a, Fleet>, -} - -macro_rules! selection { - (&$data:expr) => { - return_if_none!($data.game_state.selection()) - }; - (&mut $data:expr) => { - return_if_none!($data.game_state.selection_mut()) - }; -} - -macro_rules! fleet { - (&$data:expr, $id:expr) => { - return_if_none!($data.fleets.get($id)) - }; -} -macro_rules! position { - (&$data:expr, $id:expr) => { - return_if_none!($data.positions.get($id)) - }; -} - -macro_rules! shape { - (&$data:expr, $id:expr) => { - return_if_none!($data.shapes.get($id)) - }; -} - -macro_rules! meeting_point_owned { - (&$data:expr, $id:expr) => { - return_if_none!($data.meeting_point_owned.get($id)) - }; + fleets: ReadStorage<'a, Fleet>, + fleets_orbiting: ReadStorage<'a, FleetOrbiting>, } impl FleetSelect { @@ -215,8 +183,8 @@ impl FleetSelect { } }; - let selection = selection!(&d); - let fleet = fleet!(&d, selection.fleet); + let selection = d.game_state.selection().as_ref().unwrap(); + let fleet = d.fleets.get(selection.fleet).unwrap(); let timeout = Instant::now() + FLEET_SELECT_DETAIL_TIMEOUT; self.mouse_pos = d.input_state.mouse_pos; @@ -231,21 +199,22 @@ impl FleetSelect { MouseEvent::ButtonUp(button) if button == &d.config.input.fleet_select_button => { self.select_mode = match self.select_mode { SelectMode::Simple(progress) => { - selection!(&mut d).count = self.count; + continue_if_none!(d.game_state.selection_mut()).count = self.count; self.mouse_pos = d.input_state.mouse_pos; SelectMode::SimpleClose(progress) } SelectMode::Detail(progress) => { - selection!(&mut d).count = self.count; + continue_if_none!(d.game_state.selection_mut()).count = self.count; self.mouse_pos = d.input_state.mouse_pos; SelectMode::DetailClose(progress) } SelectMode::Init(_) if self.is_new_selection => { - selection!(&mut d).count = ShipCount::all(); + continue_if_none!(d.game_state.selection_mut()).count = + ShipCount::all(); SelectMode::None } @@ -277,11 +246,13 @@ impl FleetSelect { } /* calculate values */ - let selection = selection!(&d); - let meeting_point_owned = meeting_point_owned!(&d, selection.fleet); - let position = position!(&d, meeting_point_owned.owner()); - let shape = shape!(&d, meeting_point_owned.owner()); - let fleet = fleet!(&d, selection.fleet); + let selection = return_if_none!(d.game_state.selection()); + let fleet_id = selection.fleet; + let fleet = d.fleets.get(fleet_id).unwrap(); + let fleet_orbiting = d.fleets_orbiting.get(fleet_id).unwrap(); + let meeting_point_id = fleet_orbiting.meeting_point(); + let position = d.positions.get(meeting_point_id).unwrap(); + let shape = d.shapes.get(meeting_point_id).unwrap(); self.marker = d.camera.view_to_world(self.mouse_pos) - position.get(); self.zoom = d.camera.view().axis_x.as_vec3().length(); @@ -432,9 +403,14 @@ impl FleetSelect { }; /* extract system data */ - let selection = selection!(&d); - let meeting_point_owned = meeting_point_owned!(&d, selection.fleet); - let position = position!(&d, meeting_point_owned.owner()); + let selection = return_if_none!(d.game_state.selection()); + let fleet_id = selection.fleet; + let fleet_orbiting = d + .fleets_orbiting + .get(fleet_id) + .expect("Selection contains invalid fleet!"); + let meeting_point_id = fleet_orbiting.meeting_point(); + let position = d.positions.get(meeting_point_id).unwrap(); /* calculate shared values */ let size = self.ring1 + 50.0; diff --git a/space-crush-common/src/builder/fleet.rs b/space-crush-common/src/builder/fleet.rs index a81e3fe..d06ba68 100644 --- a/space-crush-common/src/builder/fleet.rs +++ b/space-crush-common/src/builder/fleet.rs @@ -1,7 +1,7 @@ use specs::{saveload::MarkedBuilder, Builder, Entity, World, WorldExt}; use crate::{ - components::{Fleet, MeetingPointOwned, PlayerOwned}, + components::{Fleet, FleetOrbiting, PlayerOwned}, misc::{Persistence, WorldPersistence}, }; @@ -21,14 +21,14 @@ impl FleetBuilder { .ok_or(Error::MissingValue("meeting_point"))?; let player_owned = PlayerOwned::new(player); - let meeting_point_owned = MeetingPointOwned::new(meeting_point); + let fleet_orbiting = FleetOrbiting::new(meeting_point); let fleet = Fleet::new(); let entity = world .create_entity() .marked::<::Marker>() - .with(meeting_point_owned) .with(player_owned) + .with(fleet_orbiting) .with(fleet) .build(); diff --git a/space-crush-common/src/components/fleet.rs b/space-crush-common/src/components/fleet.rs index 7566aa5..989844d 100644 --- a/space-crush-common/src/components/fleet.rs +++ b/space-crush-common/src/components/fleet.rs @@ -14,24 +14,32 @@ use crate::{ misc::FlaggedStorage, }; -/// A fleet is a group of ships that share the same operation #[derive(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 FleetOwned { owner: Entity, } +#[derive(Debug, Clone)] +pub struct FleetOrbiting { + meeting_point: Entity, +} + #[derive(Serialize, Deserialize)] pub struct FleetOwnedData { pub owner: M, } +#[derive(Serialize, Deserialize)] +pub struct FleetOrbitingData { + pub meeting_point: M, +} + /* Fleet */ impl Fleet { @@ -125,3 +133,47 @@ where Ok(FleetOwned { owner }) } } + +/* FleetOrbiting */ + +impl FleetOrbiting { + pub fn meeting_point(&self) -> Entity { + self.meeting_point + } +} + +impl FleetOrbiting { + pub(crate) fn new(meeting_point: Entity) -> Self { + Self { meeting_point } + } +} + +impl Component for FleetOrbiting { + type Storage = FlaggedStorage>; +} + +impl ConvertSaveload for FleetOrbiting +where + for<'de> M: Marker + Serialize + Deserialize<'de>, +{ + type Data = FleetOrbitingData; + type Error = NoError; + + fn convert_into(&self, mut ids: F) -> Result + where + F: FnMut(Entity) -> Option, + { + let meeting_point = ids(self.meeting_point).unwrap(); + + Ok(FleetOrbitingData { meeting_point }) + } + + fn convert_from(data: Self::Data, mut ids: F) -> Result + where + F: FnMut(M) -> Option, + { + let meeting_point = ids(data.meeting_point).unwrap(); + + Ok(FleetOrbiting { meeting_point }) + } +} diff --git a/space-crush-common/src/components/meeting_point.rs b/space-crush-common/src/components/meeting_point.rs index d8c4820..2bdf3de 100644 --- a/space-crush-common/src/components/meeting_point.rs +++ b/space-crush-common/src/components/meeting_point.rs @@ -84,7 +84,7 @@ impl MeetingPoint { } impl Component for MeetingPoint { - type Storage = HashMapStorage; + type Storage = FlaggedStorage>; } impl ConvertSaveload for MeetingPoint @@ -121,47 +121,3 @@ where Ok(MeetingPoint { min, max, fleets }) } } - -/* MeetingPointOwned */ - -impl MeetingPointOwned { - pub fn owner(&self) -> Entity { - self.owner - } -} - -impl MeetingPointOwned { - pub(crate) fn new(owner: Entity) -> Self { - Self { owner } - } -} - -impl Component for MeetingPointOwned { - type Storage = FlaggedStorage>; -} - -impl ConvertSaveload for MeetingPointOwned -where - for<'de> M: Marker + Serialize + Deserialize<'de>, -{ - type Data = MeetingPointOwnedData; - type Error = NoError; - - fn convert_into(&self, mut ids: F) -> Result - where - F: FnMut(Entity) -> Option, - { - let owner = ids(self.owner).unwrap(); - - Ok(MeetingPointOwnedData { owner }) - } - - fn convert_from(data: Self::Data, mut ids: F) -> Result - where - F: FnMut(M) -> Option, - { - let owner = ids(data.owner).unwrap(); - - Ok(MeetingPointOwned { owner }) - } -} diff --git a/space-crush-common/src/components/mod.rs b/space-crush-common/src/components/mod.rs index a2bdc83..bc58b33 100644 --- a/space-crush-common/src/components/mod.rs +++ b/space-crush-common/src/components/mod.rs @@ -9,8 +9,8 @@ mod shape; mod ship; pub use asteroid::{Asteroid, Type as AsteroidType}; -pub use fleet::{Fleet, FleetOwned}; -pub use meeting_point::{MeetingPoint, MeetingPointOwned}; +pub use fleet::{Fleet, FleetOrbiting, FleetOwned}; +pub use meeting_point::MeetingPoint; pub use obstacle::Obstacle; pub use planet::Planet; pub use player::{Player, PlayerOwned, Race}; diff --git a/space-crush-common/src/dispatcher.rs b/space-crush-common/src/dispatcher.rs index 226e051..dff3d6e 100644 --- a/space-crush-common/src/dispatcher.rs +++ b/space-crush-common/src/dispatcher.rs @@ -3,9 +3,7 @@ use specs::{Dispatcher as Inner, DispatcherBuilder, World, WorldExt}; use crate::{ components::Player, resources::Global, - systems::{ - FleetControl, FleetOwnedUpdate, MeetingPointOwnedUpdate, Process, ShipMovement, Ships, - }, + systems::{FleetControl, FleetOrbitingUpdate, FleetOwnedUpdate, Process, ShipMovement, Ships}, Error, }; @@ -25,11 +23,7 @@ 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( - MeetingPointOwnedUpdate::new(world), - "meeting_point_owned_update", - &[], - ) + .with(FleetOrbitingUpdate::new(world), "fleet_orbiting", &[]) .build(); dispatcher.setup(world); diff --git a/space-crush-common/src/misc/world.rs b/space-crush-common/src/misc/world.rs index bd05e18..fb28876 100644 --- a/space-crush-common/src/misc/world.rs +++ b/space-crush-common/src/misc/world.rs @@ -7,8 +7,8 @@ use specs::{saveload::SimpleMarker, World}; use crate::{ components::{ - Asteroid, MeetingPoint, MeetingPointOwned, Obstacle, Planet, Player, PlayerOwned, Position, - Ship, + Asteroid, FleetOrbiting, FleetOwned, MeetingPoint, Obstacle, Planet, Player, PlayerOwned, + Position, Ship, }, Error, }; @@ -93,10 +93,11 @@ impl Persistence for WorldPersistence { Position, Player, PlayerOwned, - MeetingPoint, - MeetingPointOwned, + FleetOwned, + FleetOrbiting, Ship, Obstacle, + MeetingPoint, Planet, Asteroid, ); diff --git a/space-crush-common/src/systems/fleet_control.rs b/space-crush-common/src/systems/fleet_control.rs index 0d7e64a..67eab80 100644 --- a/space-crush-common/src/systems/fleet_control.rs +++ b/space-crush-common/src/systems/fleet_control.rs @@ -11,7 +11,7 @@ use specs::{ use crate::{ components::{ - Fleet, FleetOwned, MeetingPoint, MeetingPointOwned, Player, PlayerOwned, Ship, ShipCount, + Fleet, FleetOrbiting, FleetOwned, MeetingPoint, Player, PlayerOwned, Ship, ShipCount, }, misc::WorldHelper, Error, @@ -37,7 +37,7 @@ pub struct FleetControlData<'a> { entities: Entities<'a>, fleet_control_events: ReadExpect<'a, EventChannel>, player_owned: WriteStorage<'a, PlayerOwned>, - meeting_point_owned: WriteStorage<'a, MeetingPointOwned>, + fleet_orbiting: WriteStorage<'a, FleetOrbiting>, fleet_owned: WriteStorage<'a, FleetOwned>, meeting_points: WriteStorage<'a, MeetingPoint>, fleets: WriteStorage<'a, Fleet>, @@ -66,7 +66,7 @@ impl<'a> System<'a> for FleetControl { entities, fleet_control_events, mut player_owned, - mut meeting_point_owned, + mut fleet_orbiting, mut fleet_owned, mut meeting_points, mut fleets, @@ -79,7 +79,7 @@ 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!(meeting_point_owned.get_mut(args.fleet)); + let orbit_owned = continue_if_none!(fleet_orbiting.get_mut(args.fleet)); orbit_owned.set_owner(args.target); } FleetControlEvent::Move(args) => { @@ -98,7 +98,7 @@ impl<'a> System<'a> for FleetControl { player_owned .insert(fleet, PlayerOwned::new(args.player)) .error("Unable to insert component: PlayerOwned"); - meeting_point_owned + fleet_orbiting .insert(fleet, MeetingPointOwned::new(args.target)) .error("Unable to insert component: MeetingPointOwned"); fleets diff --git a/space-crush-common/src/systems/meeting_point_owned_update.rs b/space-crush-common/src/systems/fleet_orbiting_update.rs similarity index 51% rename from space-crush-common/src/systems/meeting_point_owned_update.rs rename to space-crush-common/src/systems/fleet_orbiting_update.rs index 71ed179..af39438 100644 --- a/space-crush-common/src/systems/meeting_point_owned_update.rs +++ b/space-crush-common/src/systems/fleet_orbiting_update.rs @@ -7,98 +7,101 @@ use specs::{ }; use crate::{ - components::{MeetingPoint, MeetingPointOwned, Player, PlayerOwned}, + components::{FleetOrbiting, MeetingPoint, Player, PlayerOwned}, continue_if_none, misc::{ComponentEvent, StorageHelper, StorageHelperMut}, }; -pub struct MeetingPointOwnedUpdate { +pub struct FleetOrbitingUpdate { meeting_point_ids: BitSet, - meeting_point_owned_ids: BitSet, + fleet_orbiting_ids: BitSet, old_meeting_point_ids: HashMap, - meeting_point_owned_event_id: ReaderId>, + fleet_orbiting_event_id: ReaderId>, } #[derive(SystemData)] -pub struct MeetingPointOwnedUpdateData<'a> { +pub struct FleetOrbitingUpdateData<'a> { entities: Entities<'a>, players: ReadStorage<'a, Player>, player_owned: ReadStorage<'a, PlayerOwned>, - meeting_point_owned: ReadStorage<'a, MeetingPointOwned>, + fleet_orbiting: ReadStorage<'a, FleetOrbiting>, meeting_points: WriteStorage<'a, MeetingPoint>, } -impl MeetingPointOwnedUpdate { +impl FleetOrbitingUpdate { pub fn new(world: &mut World) -> Self { - WriteStorage::::setup(world); + WriteStorage::::setup(world); let meeting_point_ids = BitSet::new(); - let meeting_point_owned_ids = BitSet::new(); + let fleet_orbiting_ids = BitSet::new(); let old_meeting_point_ids = HashMap::new(); - let meeting_point_owned_event_id = world - .system_data::>() + let fleet_orbiting_event_id = world + .system_data::>() .register_event_reader(); Self { meeting_point_ids, - meeting_point_owned_ids, + fleet_orbiting_ids, old_meeting_point_ids, - meeting_point_owned_event_id, + fleet_orbiting_event_id, } } } -impl<'a> System<'a> for MeetingPointOwnedUpdate { - type SystemData = MeetingPointOwnedUpdateData<'a>; +impl<'a> System<'a> for FleetOrbitingUpdate { + type SystemData = FleetOrbitingUpdateData<'a>; fn run(&mut self, data: Self::SystemData) { - let MeetingPointOwnedUpdateData { + let FleetOrbitingUpdateData { entities, players, player_owned, - meeting_point_owned, + fleet_orbiting, mut meeting_points, } = data; self.meeting_point_ids.clear(); - self.meeting_point_owned_ids.clear(); + self.fleet_orbiting_ids.clear(); self.old_meeting_point_ids.clear(); /* handle events */ - let events = meeting_point_owned + let events = fleet_orbiting .channel() - .read(&mut self.meeting_point_owned_event_id); + .read(&mut self.fleet_orbiting_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::Inserted(id, fleet_orbiting) => { + self.meeting_point_ids + .add(fleet_orbiting.meeting_point().id()); + self.fleet_orbiting_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); + ComponentEvent::Modified(id, fleet_orbiting) => { + self.meeting_point_ids + .add(fleet_orbiting.meeting_point().id()); + self.fleet_orbiting_ids.add(*id); *self .old_meeting_point_ids .entry(*id) - .or_insert_with(|| meeting_point_owned.owner()) = - meeting_point_owned.owner(); + .or_insert_with(|| fleet_orbiting.meeting_point()) = + fleet_orbiting.meeting_point(); } - ComponentEvent::Removed(id, meeting_point_owned) => { - self.meeting_point_ids.add(meeting_point_owned.owner().id()); - self.meeting_point_owned_ids.add(*id); + ComponentEvent::Removed(id, fleet_orbiting) => { + self.meeting_point_ids + .add(fleet_orbiting.meeting_point().id()); + self.fleet_orbiting_ids.add(*id); *self .old_meeting_point_ids .entry(*id) - .or_insert_with(|| meeting_point_owned.owner()) = - meeting_point_owned.owner(); + .or_insert_with(|| fleet_orbiting.meeting_point()) = + fleet_orbiting.meeting_point(); } } } /* 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()); + for (fleet_orbiting, _) in (&fleet_orbiting, &self.fleet_orbiting_ids).join() { + self.meeting_point_ids + .add(fleet_orbiting.meeting_point().id()); } /* update meeting_points */ @@ -107,13 +110,13 @@ impl<'a> System<'a> for MeetingPointOwnedUpdate { { let data = ( &entities, - &meeting_point_owned, + &fleet_orbiting, &player_owned, - &self.meeting_point_owned_ids, + &self.fleet_orbiting_ids, ); - for (fleet_id, meeting_point_owned, player_owned, _) in data.join() { - let new_match = meeting_point_id == meeting_point_owned.owner(); + for (fleet_id, fleet_orbiting, player_owned, _) in data.join() { + let new_match = meeting_point_id == fleet_orbiting.meeting_point(); 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, diff --git a/space-crush-common/src/systems/mod.rs b/space-crush-common/src/systems/mod.rs index a05babf..75512fc 100644 --- a/space-crush-common/src/systems/mod.rs +++ b/space-crush-common/src/systems/mod.rs @@ -1,13 +1,13 @@ mod fleet_control; +mod fleet_orbiting_update; mod fleet_owned_update; -mod meeting_point_owned_update; mod process; mod ship_movement; mod ships; pub use fleet_control::{FleetControl, FleetControlEvent}; +pub use fleet_orbiting_update::FleetOrbitingUpdate; pub use fleet_owned_update::FleetOwnedUpdate; -pub use meeting_point_owned_update::MeetingPointOwnedUpdate; pub use process::Process; pub use ship_movement::ShipMovement; pub use ships::Ships; diff --git a/space-crush-common/src/systems/ships.rs b/space-crush-common/src/systems/ships.rs index dc76220..8be1684 100644 --- a/space-crush-common/src/systems/ships.rs +++ b/space-crush-common/src/systems/ships.rs @@ -12,7 +12,7 @@ use specs::{ use crate::{ components::{ - FleetOwned, MeetingPoint, MeetingPointOwned, Obstacle, Position, Shape, Ship, ShipObstacle, + FleetOrbiting, FleetOwned, MeetingPoint, Obstacle, Position, Shape, Ship, ShipObstacle, }, constants::{ SHIP_ORBIT_AGILITY, SHIP_ORBIT_ANGLE_DELTA_MIN, SHIP_ORBIT_ANGLE_DELTA_RND, @@ -34,7 +34,7 @@ pub struct ShipsData<'a> { entities: Entities<'a>, ships: WriteStorage<'a, Ship>, fleet_owned: ReadStorage<'a, FleetOwned>, - meeting_point_owned: ReadStorage<'a, MeetingPointOwned>, + fleet_orbiting: ReadStorage<'a, FleetOrbiting>, positions: ReadStorage<'a, Position>, shapes: ReadStorage<'a, Shape>, obstacles: ReadStorage<'a, Obstacle>, @@ -48,7 +48,7 @@ struct Processor<'a> { shapes: &'a ReadStorage<'a, Shape>, obstacles: &'a ReadStorage<'a, Obstacle>, meeting_points: &'a ReadStorage<'a, MeetingPoint>, - meeting_point_owned: &'a ReadStorage<'a, MeetingPointOwned>, + fleet_orbiting: &'a ReadStorage<'a, FleetOrbiting>, delta: f32, } @@ -91,7 +91,7 @@ impl<'a> System<'a> for Ships { entities, mut ships, fleet_owned, - meeting_point_owned, + fleet_orbiting, positions, shapes, obstacles, @@ -107,7 +107,7 @@ impl<'a> System<'a> for Ships { positions: &positions, shapes: &shapes, obstacles: &obstacles, - meeting_point_owned: &meeting_point_owned, + fleet_orbiting: &fleet_orbiting, meeting_points: &meeting_points, delta: global.delta * global.world_speed, }; @@ -134,8 +134,8 @@ impl Processor<'_> { fleet_owned: &FleetOwned, ) { let fleet_id = fleet_owned.owner(); - let meeting_point_owned = return_if_none!(self.meeting_point_owned.get(fleet_id)); - let meeting_point_id = meeting_point_owned.owner(); + let fleet_orbiting = return_if_none!(self.fleet_orbiting.get(fleet_id)); + let meeting_point_id = fleet_orbiting.meeting_point(); 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)).get(); let ship_pos = position.get();