diff options
| -rw-r--r-- | src/controls.rs | 64 | ||||
| -rw-r--r-- | src/gameserver.rs | 5 | ||||
| -rw-r--r-- | src/main.rs | 6 | ||||
| -rw-r--r-- | src/room.rs | 52 |
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)) } } |
