summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/controls.rs64
-rw-r--r--src/gameserver.rs5
-rw-r--r--src/main.rs6
-rw-r--r--src/room.rs52
4 files changed, 115 insertions, 12 deletions
diff --git a/src/controls.rs b/src/controls.rs
new file mode 100644
index 0000000..58c83b0
--- /dev/null
+++ b/src/controls.rs
@@ -0,0 +1,64 @@
+
+
+use serde_json::Value;
+
+#[derive(Debug)]
+pub enum Direction {
+ North,
+ South,
+ East,
+ West,
+ None
+}
+
+impl Direction {
+ fn from_json(val: &Value) -> Option<Direction>{
+ match val {
+ Value::String(txt) => match txt.as_str() {
+ "north" => Some(Direction::North),
+ "south" => Some(Direction::South),
+ "east" => Some(Direction::East),
+ "west"=> Some(Direction::West),
+ "" => Some(Direction::None),
+ _ => None
+ }
+ Value::Null => Some(Direction::None),
+ _ => None
+ }
+ }
+
+ pub fn to_position(&self) -> (i32, i32) {
+ match self {
+ Direction::North => (0, -1),
+ Direction::South => (0, 1),
+ Direction::East => (1, 0),
+ Direction::West => (-1, 0),
+ Direction::None => (0, 0)
+ }
+ }
+}
+
+#[derive(Debug)]
+pub enum Control {
+ Move(Direction),
+ Take(u64)
+}
+
+
+impl Control {
+ pub fn from_json(val: Value) -> Option<Control>{
+ if let Value::String(control_type) = &val[0] {
+ match control_type.as_str() {
+ "move" => match Direction::from_json(&val[1]) {
+ Some(dir) => Some(Control::Move(dir)),
+ None => None
+ },
+ "take" => match val[1].as_u64() {
+ Some(rank) => Some(Control::Take(rank)),
+ _ => None
+ }
+ _ => None
+ }
+ } else {None}
+ }
+}
diff --git a/src/gameserver.rs b/src/gameserver.rs
index bd9ed67..1124c49 100644
--- a/src/gameserver.rs
+++ b/src/gameserver.rs
@@ -7,6 +7,7 @@ use std::io;
use serde_json::{Value, json};
+use super::controls::Control;
use super::server::Server;
@@ -22,7 +23,7 @@ enum Message {
pub enum Action {
Join(String),
Leave(String),
- Input(String, Value)
+ Input(String, Control)
}
pub struct GameServer {
@@ -141,7 +142,7 @@ impl GameServer {
Message::Input(inp) => {
if let Some(nameref) = self.players.get(&id) {
let name = nameref.clone();
- Some(Action::Input(name, inp))
+ Some(Action::Input(name, Control::from_json(inp).unwrap()))
} else {
let _ = self.send_error(id, "invalidaction", &format!("Set a name before you send other messages"));
None
diff --git a/src/main.rs b/src/main.rs
index ca2947c..c3a02e9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -8,7 +8,7 @@ pub mod server;
pub mod gameserver;
pub mod room;
pub mod util;
-// pub mod controls;
+pub mod controls;
use self::gameserver::{GameServer, Action};
use self::server::unixserver::UnixServer;
@@ -40,7 +40,7 @@ fn main() {
match action {
Action::Join(name) => {room.add_player(&name);}
Action::Leave(name) => {room.remove_player(&name);}
- _ => {}
+ Action::Input(name, control) => {room.control(name, control);}
}
}
room.update();
@@ -67,7 +67,5 @@ fn create_update_message((width, height): (i32, i32), field: Vec<usize>, mapping
]
]
]);
-// updatemsg[1][0][1]["field"] = json::from(field);
-// updatemsg[1][0][1]["mapping"] = json::from(mapping);
updatemsg.to_string()
}
diff --git a/src/room.rs b/src/room.rs
index ad73e9f..2d2fa48 100644
--- a/src/room.rs
+++ b/src/room.rs
@@ -10,6 +10,7 @@ use specs::{
Builder,
Join,
ReadStorage,
+ WriteStorage,
DispatcherBuilder,
Dispatcher,
Write,
@@ -17,6 +18,8 @@ use specs::{
Entity
};
+use super::controls::Control;
+
// Components
@@ -36,9 +39,7 @@ struct Visible {
#[derive(Component, Debug)]
#[storage(VecStorage)]
-struct InputController {
- key: String
-}
+struct Controller(Option<Control>);
// Resources
@@ -72,6 +73,34 @@ impl <'a> System<'a> for Draw {
}
}
+// struct Control;
+// impl <'a> System <'a> for Control {
+// type SystemData = WriteStorage<'a, Controller>;
+// fn run (&mut self, mut controller: Self::SystemData) {
+// for controller in &mut controller.join()
+// }
+// }
+
+struct Move;
+impl <'a> System<'a> for Move {
+ type SystemData = (WriteStorage<'a, Controller>, WriteStorage<'a, Position>);
+ fn run(&mut self, (mut controller, mut pos): Self::SystemData) {
+ for (controller, pos) in (&mut controller, &mut pos).join(){
+ if let Some(control) = &controller.0 {
+ match control {
+ Control::Move(direction) => {
+ let (dx, dy) = direction.to_position();
+ pos.x += dx;
+ pos.y += dy;
+ }
+ _ => {}
+ }
+ controller.0 = None
+ }
+ }
+ }
+}
+
// Higher level stuff
@@ -89,12 +118,13 @@ impl <'a, 'b>Room<'a, 'b> {
let mut world = World::new();
world.register::<Position>();
world.register::<Visible>();
- world.register::<InputController>();
+ world.register::<Controller>();
world.insert(Size(width, height));
world.insert(TopView{width: width, height: height, cells: HashMap::new()});
let dispatcher = DispatcherBuilder::new()
.with(Draw, "draw", &[])
+ .with(Move, "move", &["draw"])
.build();
let mut room = Room {
@@ -113,7 +143,7 @@ impl <'a, 'b>Room<'a, 'b> {
let height = tv.height;
let size = width * height;
let mut values :Vec<usize> = Vec::with_capacity(size as usize);
- let mut mapping: Vec<Vec<String>> = 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 tv.cells.get(&Position{x: x, y: y}) {
@@ -160,6 +190,16 @@ impl <'a, 'b>Room<'a, 'b> {
let ent = self.players.remove(name).expect("unknown player name");
self.world.delete_entity(ent).expect("player in world does not have entity");
}
+
+// pub fn clear_controls(&mut self){
+// (*self.world.fetch_mut::<Controls>()).0.clear();
+// }
+
+ pub fn control(&mut self, name: String, control: Control){
+ if let Some(ent) = self.players.get(&name){
+ self.world.write_component::<Controller>().get_mut(*ent).unwrap().0 = Some(control);//.insert(*ent, Controller(control));
+ }
+ }
}
fn gen_room(room: &mut Room){
@@ -228,6 +268,6 @@ impl Player {
impl Assemblage for Player {
fn build<'a>(&self, builder: EntityBuilder<'a>) -> EntityBuilder<'a>{
- builder.with(Visible{sprite: "player".to_string(), height: 1.0}).with(InputController{key: self.name.to_string()})
+ builder.with(Visible{sprite: "player".to_string(), height: 1.0}).with(Controller(None))
}
}