summaryrefslogtreecommitdiff
path: root/src/systems
diff options
context:
space:
mode:
Diffstat (limited to 'src/systems')
-rw-r--r--src/systems/clearcontrols.rs25
-rw-r--r--src/systems/controlinput.rs57
-rw-r--r--src/systems/draw.rs31
-rw-r--r--src/systems/makefloor.rs29
-rw-r--r--src/systems/mod.rs9
-rw-r--r--src/systems/moving.rs50
-rw-r--r--src/systems/view.rs82
7 files changed, 283 insertions, 0 deletions
diff --git a/src/systems/clearcontrols.rs b/src/systems/clearcontrols.rs
new file mode 100644
index 0000000..ec2bb68
--- /dev/null
+++ b/src/systems/clearcontrols.rs
@@ -0,0 +1,25 @@
+
+use specs::{
+ WriteStorage,
+ Entities,
+ System,
+ Join
+};
+
+use super::super::components::Controller;
+
+pub struct ClearControllers;
+impl <'a> System<'a> for ClearControllers {
+ type SystemData = (Entities<'a>, WriteStorage<'a, Controller>);
+ fn run(&mut self, (entities, mut controllers): Self::SystemData) {
+ let mut ents = Vec::new();
+ for (ent, _controller) in (&*entities, &controllers).join() {
+ ents.push(ent);
+ }
+ for ent in ents {
+ controllers.remove(ent);
+ }
+ }
+}
+
+
diff --git a/src/systems/controlinput.rs b/src/systems/controlinput.rs
new file mode 100644
index 0000000..663174e
--- /dev/null
+++ b/src/systems/controlinput.rs
@@ -0,0 +1,57 @@
+
+use std::collections::{HashMap, HashSet};
+
+use specs::{
+ ReadStorage,
+ WriteStorage,
+ Read,
+ Write,
+ Entities,
+ System,
+ Join
+};
+
+use super::super::components::{
+ Controller,
+ Played,
+ Position
+};
+
+use super::super::controls::{
+ Control,
+ Action
+};
+
+use super::super::resources::{
+ Input,
+ NewEntities
+};
+
+
+use super::super::assemblages::Player;
+
+
+pub struct ControlInput;
+impl <'a> System<'a> for ControlInput {
+ type SystemData = (Entities<'a>, Read<'a, Input>, WriteStorage<'a, Controller>, ReadStorage<'a, Played>, Write<'a, NewEntities>);
+ fn run(&mut self, (entities, input, mut controllers, players, mut new): Self::SystemData) {
+ let mut playercontrols: HashMap<&str, Control> = HashMap::new();
+ let mut leaving = HashSet::new();
+ for action in &input.actions {
+ match action {
+ Action::Join(name) => {new.assemblages.push((Position{x:10, y:10}, Box::new(Player::new(&name))));}
+ Action::Leave(name) => {leaving.insert(name);}
+ Action::Input(name, control) => {playercontrols.insert(name, control.clone());}
+ }
+ }
+ for (player, entity) in (&players, &entities).join() {
+ if let Some(control) = playercontrols.get(player.name.as_str()){
+ let _ = controllers.insert(entity, Controller(control.clone()));
+ }
+ if leaving.contains(&player.name) {
+ let _ = entities.delete(entity);
+ }
+ }
+ }
+}
+
diff --git a/src/systems/draw.rs b/src/systems/draw.rs
new file mode 100644
index 0000000..82400e3
--- /dev/null
+++ b/src/systems/draw.rs
@@ -0,0 +1,31 @@
+
+use specs::{
+ ReadStorage,
+ Write,
+ System,
+ Join
+};
+
+use super::super::components::{
+ Position,
+ Visible
+};
+
+use super::super::resources::{
+ TopView
+};
+
+
+pub struct Draw;
+impl <'a> System<'a> for Draw {
+
+ type SystemData = (ReadStorage<'a, Position>, ReadStorage<'a, Visible>, Write<'a, TopView>);
+
+ fn run(&mut self, (pos, vis, mut view): Self::SystemData) {
+ view.cells.clear();
+ for (pos, vis) in (&pos, &vis).join(){
+ view.cells.entry(*pos).or_insert(Vec::new()).push(vis.clone());
+ view.cells.get_mut(pos).unwrap().sort_by(|a, b| b.height.partial_cmp(&a.height).unwrap());
+ }
+ }
+}
diff --git a/src/systems/makefloor.rs b/src/systems/makefloor.rs
new file mode 100644
index 0000000..864f204
--- /dev/null
+++ b/src/systems/makefloor.rs
@@ -0,0 +1,29 @@
+
+
+use specs::{
+ ReadStorage,
+ Write,
+ Entities,
+ System,
+ Join
+};
+
+use super::super::components::{
+ Position
+};
+
+use super::super::resources::{
+ Floor
+};
+
+
+pub struct MakeFloor;
+impl <'a> System<'a> for MakeFloor {
+ type SystemData = (Entities<'a>, Write<'a, Floor>, ReadStorage<'a, Position>);
+ fn run(&mut self, (entities, mut floor, positions): Self::SystemData) {
+ floor.cells.clear();
+ for (ent, pos) in (&entities, &positions).join() {
+ floor.cells.entry(*pos).or_insert(Vec::new()).push(ent);
+ }
+ }
+}
diff --git a/src/systems/mod.rs b/src/systems/mod.rs
new file mode 100644
index 0000000..678941a
--- /dev/null
+++ b/src/systems/mod.rs
@@ -0,0 +1,9 @@
+
+pub mod clearcontrols;
+pub mod controlinput;
+pub mod draw;
+pub mod makefloor;
+pub mod moving;
+pub mod view;
+
+
diff --git a/src/systems/moving.rs b/src/systems/moving.rs
new file mode 100644
index 0000000..c81a766
--- /dev/null
+++ b/src/systems/moving.rs
@@ -0,0 +1,50 @@
+
+use specs::{
+ ReadStorage,
+ WriteStorage,
+ Read,
+ System,
+ Join
+};
+
+use super::super::components::{
+ Position,
+ Controller,
+ Blocking
+};
+
+use super::super::controls::{
+ Control
+};
+
+use super::super::resources::{
+ Size,
+ Floor
+};
+
+
+
+pub struct Move;
+impl <'a> System<'a> for Move {
+ type SystemData = (ReadStorage<'a, Controller>, WriteStorage<'a, Position>, Read<'a, Size>, ReadStorage<'a, Blocking>, Read<'a, Floor>);
+ fn run(&mut self, (controller, mut pos, size, blocking, floor): Self::SystemData) {
+ for (controller, pos) in (&controller, &mut pos).join(){
+ match &controller.0 {
+ Control::Move(direction) => {
+ let newpos = (*pos + direction.to_position()).clamp(Position::new(0, 0), Position::new(size.width - 1, size.height - 1));
+ let mut blocked = false;
+ for ent in floor.cells.get(&newpos).unwrap_or(&Vec::new()) {
+ if blocking.get(*ent).is_some(){
+ blocked = true;
+ break;
+ }
+ }
+ if !blocked {
+ pos.clone_from(&newpos);
+ }
+ }
+ _ => {}
+ }
+ }
+ }
+}
diff --git a/src/systems/view.rs b/src/systems/view.rs
new file mode 100644
index 0000000..da6d6c4
--- /dev/null
+++ b/src/systems/view.rs
@@ -0,0 +1,82 @@
+
+use std::collections::HashMap;
+
+use specs::{
+ ReadStorage,
+ Read,
+ Write,
+ System,
+ Join
+};
+
+use super::super::components::{
+ Position,
+ Visible,
+ Played
+};
+
+
+use super::super::resources::{
+ TopView,
+ Size,
+ Output,
+};
+
+use super::super::worldmessages::{
+ WorldMessage,
+ WorldUpdate,
+ FieldMessage
+};
+
+
+
+pub struct View;
+impl <'a> System<'a> for View {
+ type SystemData = (Read<'a, TopView>, Read<'a, Size>, ReadStorage<'a, Played>, Write<'a, Output>);
+ fn run(&mut self, (topview, size, players, mut output): Self::SystemData) {
+
+
+ let width = size.width;
+ let height = size.height;
+ let (values, mapping) = draw_room(&topview.cells, (width, height));
+
+ let message = WorldMessage{updates: vec![WorldUpdate::Field(FieldMessage{
+ width,
+ height,
+ field: values,
+ mapping
+ })]};
+ output.output.clear();
+ for player in (&players).join() {
+ output.output.insert(player.name.clone(), message.clone());
+ }
+ }
+}
+
+
+
+fn draw_room(cells: &HashMap<Position, Vec<Visible>>, (width, height): (i32, i32)) -> (Vec<usize>, Vec<Vec<String>>){
+ let size = width * height;
+ let mut values :Vec<usize> = Vec::with_capacity(size as usize);
+ let mut mapping: Vec<Vec<String>> = Vec::new();
+ for y in 0..height {
+ for x in 0..width {
+ let sprites: Vec<String> = match cells.get(&Position{x: x, y: y}) {
+ Some(sprites) => {sprites.iter().map(|v| v.sprite.clone()).collect()}
+ None => {vec![]}
+ };
+ values.push(
+ match mapping.iter().position(|x| x == &sprites) {
+ Some(index) => {
+ index
+ }
+ None => {
+ mapping.push(sprites);
+ mapping.len() - 1
+ }
+ }
+ )
+ }
+ }
+ (values, mapping)
+}