Browse Source

Fixed 'MeetingPointOwned' component

master
Bergmann89 3 years ago
parent
commit
8fe07cb550
7 changed files with 179 additions and 9 deletions
  1. +1
    -1
      overview
  2. +5
    -1
      space-crush-app/src/main.rs
  3. +18
    -6
      space-crush-common/src/builder/fleet.rs
  4. +11
    -0
      space-crush-common/src/components/meeting_point.rs
  5. +8
    -1
      space-crush-common/src/dispatcher.rs
  6. +134
    -0
      space-crush-common/src/systems/meeting_point_owned_update.rs
  7. +2
    -0
      space-crush-common/src/systems/mod.rs

+ 1
- 1
overview View File

@@ -21,7 +21,7 @@ Player______________ \ \ \ \ \ \ \ \ \ \ \ \ \
+--------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+
| Player | x | | | | | | | | | | | | x |
| Ship | | x | x | x | x | | | | | | | | x |
| Fleet | | | | | | x | x | | | | | | x |
| Fleet | | x | | | | x | x | | | | | | x |
| Asteroid | | o | x | | | | | x | x | x | x | | x |
| Planet | | o | x | | | | | x | x | x | | x | x |
| MeetingPoint | | | x | | | | | | | x | | | x |


+ 5
- 1
space-crush-app/src/main.rs View File

@@ -92,7 +92,11 @@ fn create_world(world: &mut World, player_id: Entity) {
.unwrap();
}

let fleet_id = Fleet::builder().owner(planets[1]).build(world).unwrap();
let fleet_id = Fleet::builder()
.player(player_id)
.meeting_point(planets[1])
.build(world)
.unwrap();

for i in 0..9 {
let r = 325.0 + 100.0 * random::<f32>();


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

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

use crate::{
components::{Fleet, MeetingPointOwned},
components::{Fleet, MeetingPointOwned, PlayerOwned},
misc::{Persistence, WorldPersistence},
};

@@ -9,28 +9,40 @@ use super::Error;

#[derive(Default, Clone)]
pub struct FleetBuilder {
owner: Option<Entity>,
player: Option<Entity>,
meeting_point: Option<Entity>,
}

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

let meeting_point_owned = MeetingPointOwned::new(owner);
let player_owned = PlayerOwned::new(player);
let meeting_point_owned = MeetingPointOwned::new(meeting_point);
let fleet = Fleet::new();

let entity = world
.create_entity()
.marked::<<WorldPersistence as Persistence>::Marker>()
.with(meeting_point_owned)
.with(player_owned)
.with(fleet)
.build();

Ok(entity)
}

pub fn owner(mut self, meeting_point: Entity) -> Self {
self.owner = Some(meeting_point);
pub fn player(mut self, player: Entity) -> Self {
self.player = Some(player);

self
}

pub fn meeting_point(mut self, meeting_point: Entity) -> Self {
self.meeting_point = Some(meeting_point);

self
}


+ 11
- 0
space-crush-common/src/components/meeting_point.rs View File

@@ -70,6 +70,17 @@ impl MeetingPoint {
fleets: smallvec![],
}
}

pub(crate) fn add_fleet(&mut self, player: usize, fleet: Entity) {
self.fleets.resize_with(player + 1, Default::default);
self.fleets[player] = Some(fleet);
}

pub(crate) fn remove_fleet(&mut self, player: usize) {
if let Some(fleet) = self.fleets.get_mut(player) {
*fleet = None;
}
}
}

impl Component for MeetingPoint {


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

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

@@ -23,6 +25,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(
MeetingPointOwnedUpdate::new(world),
"meeting_point_owned_update",
&[],
)
.build();
dispatcher.setup(world);



+ 134
- 0
space-crush-common/src/systems/meeting_point_owned_update.rs View File

@@ -0,0 +1,134 @@
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, Player, PlayerOwned},
continue_if_none,
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>>,
}

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

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

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

fn run(&mut self, data: Self::SystemData) {
let MeetingPointOwnedUpdateData {
entities,
players,
player_owned,
meeting_point_owned,
mut meeting_points,
} = 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();
let player = continue_if_none!(players.get(player_id));
let player_index = player.index();

if old_match && !new_match {
meeting_point.remove_fleet(player_index);
} else if !old_match && new_match {
meeting_point.add_fleet(player_index, fleet_id);
}
}
}
}
}

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

@@ -1,11 +1,13 @@
mod fleet_control;
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_owned_update::FleetOwnedUpdate;
pub use meeting_point_owned_update::MeetingPointOwnedUpdate;
pub use process::Process;
pub use ship_movement::ShipMovement;
pub use ships::Ships;

Loading…
Cancel
Save