diff options
| author | troido <troido@protonmail.com> | 2020-02-21 17:49:50 +0100 |
|---|---|---|
| committer | troido <troido@protonmail.com> | 2020-02-21 17:49:50 +0100 |
| commit | 07cc6d8919193c38cc13b2567ede5a510938db18 (patch) | |
| tree | 83588f118036fa56905043eb23c5a1d79e0497da | |
| parent | e69d9c3b5266fd6f9215d1e3f4a761b8027a785c (diff) | |
players can now go to different rooms
| -rw-r--r-- | content/maps/broom.json | 28 | ||||
| -rw-r--r-- | content/maps/room.json | 6 | ||||
| -rw-r--r-- | src/components.rs | 6 | ||||
| -rw-r--r-- | src/componentwrapper.rs | 9 | ||||
| -rw-r--r-- | src/defaultencyclopedia.rs | 7 | ||||
| -rw-r--r-- | src/main.rs | 15 | ||||
| -rw-r--r-- | src/parameter.rs | 2 | ||||
| -rw-r--r-- | src/persistence.rs | 7 | ||||
| -rw-r--r-- | src/playerstate.rs | 22 | ||||
| -rw-r--r-- | src/resources.rs | 2 | ||||
| -rw-r--r-- | src/room.rs | 16 | ||||
| -rw-r--r-- | src/roomtemplate.rs | 10 | ||||
| -rw-r--r-- | src/savestate.rs | 11 | ||||
| -rw-r--r-- | src/systems/migrate.rs | 37 | ||||
| -rw-r--r-- | src/systems/mod.rs | 1 | ||||
| -rw-r--r-- | src/template.rs | 17 | ||||
| -rw-r--r-- | src/world.rs | 22 |
17 files changed, 144 insertions, 74 deletions
diff --git a/content/maps/broom.json b/content/maps/broom.json index c72496d..f6044a6 100644 --- a/content/maps/broom.json +++ b/content/maps/broom.json @@ -1,24 +1,25 @@ { "width": 42, - "height": 22, - "spawn": [5, 15], + "height": 23, + "spawn": [5, 5], "field": [ + " %%% ", "XXXXX,.,XXXXXXXXXX~~~XXXXXXXXXXXXXXXXXXXXX", - "XT,,,,,,,,,,T,,,,,~~~,,,,,,,,,,,,,,,,,,,,X", - "X,,T,,,,,,,,,,T,,,~~~,,,,,,,,,,,,,,,,,,,,X", - "X,,,,,,,,,T,,,,,,,~~~,,,,,,,,,,,,,,,,,,,,X", - "X,,,,,,T,,,,T,,T,,~~~,,,,,,,,,,,,,,,,,,,,X", + "XT,,,,.,,,,,T,,,,,~~~,,,,,,,,,,,,,,,,,,,,X", + "X,,T,,.,,,,,,,T,,,~~~,,,,,,,,,,,,,,,,,,,,X", + "X,,,,,.,,,T,,,,,,,~~~,,,,,,,,,,,,,,,,,,,,X", + "X,,,,,,,,,,,T,,T,,~~~,,,,,,,,,,,,,,,,,,,,X", "X,,,,,.,,,,,,,,,,,~~~~,,,,,,,,,,,,,,,,,,,X", "X,,,T,.,T,,T,,,,,,~~~~~~~~~~~~~~~~~~~~~~~~", "X,,,,,.,,,,,T,,,,,~~~~~~~~~~~~~~~~~~~~~~~~", "X,,,T,.,,T,,,,,,,,~~~~~~~~~~~~~~~~~~~~~~~~", - "X,,,,,.,,,,,,T,,,,,,,,,,,,,,,,,,,,,,,,,,,X", - "X,,,T,.,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,X", - "X,T,,,.,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,X", - "X,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,X", - "X,T,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,X", - "X,,,T,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,X", - "X,,T,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,X", + "X,,,,,.,,,,,,T,,,,,,,,T,,,,T,,,,TT,,,,,,,X", + "X,,,T,.,,,T,,,,,,,T,,,,,,,,,,,,,,,,,,,T,,X", + "X,T,,,.,,,,,,,T,,,,,,,T,,,,,,T,,,,T,,,,,,X", + "X,,,,,,,,,,,T,,,,,,,T,,,,,,,,,,,,,,,,,T,,X", + "X,T,,,,,,T,,,,T,,T,,,,,,,,T,,,,,T,,,,,,,,X", + "X,,,T,,,,,,,,,,,,,,,,,,T,,,,,,T,,,,,,T,,,X", + "X,,T,,,,,,,,T,,,T,,,,,,,,,,,,,,,,,T,,,,,,X", "X,,,,,,T,,,,,,,,,,,,,,,T,T,,,,,,,,,,,,,,TX", "X,,,T,,,,,,,,,,T,,,,,,,,,,,,,,,,T,,,,,,,,X", "X,T,,,,T,,,T,,,,,,,T,,,,,,,T,,,,,,,,,,,T,X", @@ -38,6 +39,7 @@ "f": ["grass", "fence"], "X": "rock", "*": ["grass", "pebble"], + "%": {"type": "portal", "kwargs": {"destination": "room"}}, " ": [] } } diff --git a/content/maps/room.json b/content/maps/room.json index 4025639..94afbb8 100644 --- a/content/maps/room.json +++ b/content/maps/room.json @@ -1,6 +1,6 @@ { "width": 42, - "height": 22, + "height": 23, "spawn": [5, 15], "field": [ " XXXXXXXXXXXX~~~XXXXXXXXXXXXXXXXXXXXXX", @@ -24,7 +24,8 @@ "X*,,,,.,,,,,,,,,,,~~~'''''''''''f''''f'''X", "X,,,,,.,,,,,,,,,,,~~~'''''''''''ffffff'''X", "X,,,,,.,,,,,,,,,,,~~~''''''''''''''''''''X", - "XXXXX,.,XXXXXXXXXX~~~XXXXXXXXXXXXXXXXXXXXX" + "XXXXX,.,XXXXXXXXXX~~~XXXXXXXXXXXXXXXXXXXXX", + " %%% " ], "mapping": { "#": "wall", @@ -38,6 +39,7 @@ "f": ["grass", "fence"], "X": "rock", "*": ["grass", "pebble"], + "%": {"type": "portal", "kwargs": {"destination": "broom"}}, " ": [] } } diff --git a/src/components.rs b/src/components.rs index 126f20e..60b32d6 100644 --- a/src/components.rs +++ b/src/components.rs @@ -7,7 +7,7 @@ use specs::{ Component }; -use crate::{Pos, PlayerId}; +use crate::{Pos, PlayerId, RoomId}; use crate::controls::Control; use crate::template::Template; @@ -93,3 +93,7 @@ pub struct Serialise { pub template: Template } +#[derive(Component, Debug, Clone)] +pub struct RoomExit { + pub destination: RoomId +} diff --git a/src/componentwrapper.rs b/src/componentwrapper.rs index e5f9b9f..9e98332 100644 --- a/src/componentwrapper.rs +++ b/src/componentwrapper.rs @@ -2,14 +2,14 @@ use std::collections::HashMap; use specs::Builder; -use crate::PlayerId; -use crate::components::{Visible, Blocking, Player, Floor, Item, Inventory, Health, Serialise}; +use crate::{PlayerId, RoomId}; +use crate::components::{Visible, Blocking, Player, Floor, Item, Inventory, Health, Serialise, RoomExit}; use crate::parameter::{Parameter, ParameterType}; macro_rules! components { - ($($comp: ident ($($paramname: ident : $paramtype: ident),*) {$creation: expr});*) => { + ($($comp: ident ($($paramname: ident : $paramtype: ident),*) {$creation: expr});*;) => { #[derive(Clone)] pub enum ComponentWrapper{ @@ -96,7 +96,8 @@ components!( Item (ent: Template, name: String) {Item{ent, name}}; Inventory (capacity: Int) {Inventory{items: Vec::new(), capacity: capacity as usize}}; Health (health: Int, maxhealth: Int) {Health{health, maxhealth}}; - Serialise (template: Template) {Serialise{template}} + Serialise (template: Template) {Serialise{template}}; + RoomExit (destination: String) {RoomExit{destination: RoomId::from_str(&destination)}}; ); diff --git a/src/defaultencyclopedia.rs b/src/defaultencyclopedia.rs index bbc9d21..853fbfb 100644 --- a/src/defaultencyclopedia.rs +++ b/src/defaultencyclopedia.rs @@ -96,6 +96,13 @@ pub fn default_encyclopedia() -> Encyclopedia { ["Inventory", {"capacity": ["int", 3]}], ["Health", {"health": ["int", 9], "maxhealth": ["int", 10]}] ] + }, + "portal": { + "arguments": [["destination", "string", null]], + "components": [ + ["RoomExit", {"destination": ["arg", "destination"]}], + "Floor" + ] } })).unwrap() } diff --git a/src/main.rs b/src/main.rs index 310fd0e..a0afece 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,6 +34,7 @@ mod world; pub use self::pos::Pos; pub use self::playerid::PlayerId; pub use self::roomid::RoomId; +pub use self::util::Result; use self::gameserver::GameServer; use self::server::unixserver::UnixServer; @@ -48,21 +49,21 @@ use crate::world::World; -fn main() { +fn main() -> Result<()>{ let mut servers: Vec<Box<dyn Server>> = Vec::new(); let addr = Path::new("\0rustifarm"); - let unixserver = UnixServer::new(&addr).expect("binding unix server failed"); + let unixserver = UnixServer::new(&addr)?; servers.push(Box::new(unixserver)); - let addr = "127.0.0.1:1234".parse().unwrap(); - let inetserver = TcpServer::new(&addr).expect("binding inet server failed"); + let addr = "127.0.0.1:1234".parse()?; + let inetserver = TcpServer::new(&addr)?; servers.push(Box::new(inetserver)); let mut gameserver = GameServer::new(servers); - let loader = WorldLoader::new(PathBuf::from_str(&(env!("CARGO_MANIFEST_DIR").to_owned() + "/content/maps/")).unwrap()); + let loader = WorldLoader::new(PathBuf::from_str(&(env!("CARGO_MANIFEST_DIR").to_owned() + "/content/maps/"))?); let storage = FileStorage::new(FileStorage::savedir().expect("couldn't find any save directory")); @@ -80,10 +81,10 @@ fn main() { let _ = world.control_player(player, control); } Action::Join(player) => { - world.add_player(&player).unwrap(); + world.add_player(&player)?; } Action::Leave(player) => { - world.remove_player(&player).unwrap(); + world.remove_player(&player)?; } } } diff --git a/src/parameter.rs b/src/parameter.rs index cca0681..e82915b 100644 --- a/src/parameter.rs +++ b/src/parameter.rs @@ -23,7 +23,7 @@ impl Parameter { ParameterType::String => Some(Self::String(val.as_str()?.to_string())), ParameterType::Int => Some(Self::Int(val.as_i64()?)), ParameterType::Float => Some(Self::Float(val.as_f64()?)), - ParameterType::Template => Some(Self::Template(Template::from_json(val)?)) + ParameterType::Template => Some(Self::Template(Template::from_json(val).ok()?)) } } diff --git a/src/persistence.rs b/src/persistence.rs index 07ff89b..aab4088 100644 --- a/src/persistence.rs +++ b/src/persistence.rs @@ -9,8 +9,7 @@ use crate::{ RoomId, savestate::SaveState, playerstate::PlayerState, - util::Result, - aerr + util::Result }; pub trait PersistentStorage { @@ -65,7 +64,7 @@ impl PersistentStorage for FileStorage { path.push(fname); let text = fs::read_to_string(path)?; let json: Value = serde_json::from_str(&text)?; - SaveState::from_json(&json).ok_or(aerr!("not a valid save state")) + SaveState::from_json(&json) } fn load_player(&self, id: PlayerId) -> Result<PlayerState> { @@ -75,7 +74,7 @@ impl PersistentStorage for FileStorage { path.push(fname); let text = fs::read_to_string(path)?; let json: Value = serde_json::from_str(&text)?; - PlayerState::from_json(&json).ok_or(aerr!("not a valid save state")) + PlayerState::from_json(&json) } fn save_room(&self, id: RoomId, state: SaveState) -> Result<()> { diff --git a/src/playerstate.rs b/src/playerstate.rs index f179fcc..f167d36 100644 --- a/src/playerstate.rs +++ b/src/playerstate.rs @@ -6,7 +6,9 @@ use crate::{ componentwrapper::{ComponentWrapper, PreEntity}, PlayerId, RoomId, - components::{Visible, Player, Inventory, Health, Item} + components::{Visible, Player, Inventory, Health, Item}, + Result, + aerr }; #[derive(Debug, Clone)] @@ -63,22 +65,22 @@ impl PlayerState { }) } - pub fn from_json(val: &Value) -> Option<Self> { - let inventory = val.get("inventory")?; + pub fn from_json(val: &Value) -> Result<Self> { + let inventory = val.get("inventory").ok_or(aerr!("player json does not have inventory"))?; let mut items = vec![]; - for item in inventory.get("items")?.as_array()? { + for item in inventory.get("items").ok_or(aerr!("inventory does not have items"))?.as_array().ok_or(aerr!("inventory items not an array"))? { items.push(Template::from_json(item)?); } - Some(Self { - id: PlayerId{name: val.get("name")?.as_str()?.to_string()}, - room: match val.get("roomname")? { + Ok(Self { + id: PlayerId{name: val.get("name").ok_or(aerr!("player json does not have name"))?.as_str().ok_or(aerr!("player name not a string"))?.to_string()}, + room: match val.get("roomname").ok_or(aerr!("player json does not have room name"))? { Value::String(name) => Some(RoomId::from_str(name)), _ => None }, inventory: items, - health: val.get("health")?.as_i64()?, - inventory_capacity: inventory.get("capacity")?.as_i64()? as usize, - maximum_health: val.get("maxhealth")?.as_i64()? + health: val.get("health").ok_or(aerr!("player json does not have health"))?.as_i64().ok_or(aerr!("player health not a number"))?, + inventory_capacity: inventory.get("capacity").ok_or(aerr!("inventory does no have capacity"))?.as_i64().ok_or(aerr!("inventory capacity not a number"))? as usize, + maximum_health: val.get("maxhealth").ok_or(aerr!("player json does not have maxhealth"))?.as_i64().ok_or(aerr!("maxhealh not a number"))? }) } diff --git a/src/resources.rs b/src/resources.rs index e0ac197..6e4bffb 100644 --- a/src/resources.rs +++ b/src/resources.rs @@ -66,7 +66,7 @@ pub struct Players { } #[derive(Default)] -pub struct Emigrating { +pub struct Emigration { pub emigrants: Vec<(PlayerId, RoomId)> } diff --git a/src/room.rs b/src/room.rs index 44608c8..b4ae5e5 100644 --- a/src/room.rs +++ b/src/room.rs @@ -20,7 +20,7 @@ use super::resources::{ NewEntities, Spawn, Players, - Emigrating + Emigration }; use super::systems::{ moving::Move, @@ -29,7 +29,8 @@ use super::systems::{ view::View, remove::Remove, create::Create, - take::Take + take::Take, + migrate::Migrate }; use crate::components::{ Position, @@ -63,7 +64,7 @@ impl <'a, 'b>Room<'a, 'b> { world.insert(NewEntities::new(encyclopedia)); world.insert(Players::default()); world.insert(Spawn::default()); - world.insert(Emigrating::default()); + world.insert(Emigration::default()); world.register::<Serialise>(); let mut dispatcher = DispatcherBuilder::new() @@ -72,6 +73,7 @@ impl <'a, 'b>Room<'a, 'b> { .with(Take, "take", &["controlinput"]) .with(Move, "move", &["registernew", "controlinput"]) .with(View::default(), "view", &["move"]) + .with(Migrate, "migrate", &["view"]) .with(Create, "create", &["view", "controlinput"]) .with(Remove, "remove", &["view", "move"]) .build(); @@ -139,8 +141,10 @@ impl <'a, 'b>Room<'a, 'b> { pub fn remove_player(&mut self, id: &PlayerId) -> Result<PlayerState>{ let ent = self.world.fetch_mut::<Players>().entities.remove(id).ok_or(aerr!("failed to remove player"))?; + let state = self.save_player_ent(ent).ok_or(aerr!("failed to find player to remove"))?; self.world.write_component::<Removed>().insert(ent, Removed)?; - self.save_player_ent(ent).ok_or(aerr!("failed to find player to remove")) + self.world.write_component::<Player>().remove(ent); + Ok(state) } pub fn save(&self) -> SaveState { @@ -202,8 +206,8 @@ impl <'a, 'b>Room<'a, 'b> { } pub fn emigrate(&mut self) -> Vec<(PlayerId, RoomId)> { - let emigrants = self.world.remove::<Emigrating>().expect("World does not have Emigrating resource").emigrants; - self.world.insert(Emigrating::default()); + let emigrants = self.world.remove::<Emigration>().expect("World does not have Emigrating resource").emigrants; + self.world.insert(Emigration::default()); emigrants } } diff --git a/src/roomtemplate.rs b/src/roomtemplate.rs index cb8ae6a..49dd7af 100644 --- a/src/roomtemplate.rs +++ b/src/roomtemplate.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use serde_json::Value; use crate::Pos; use crate::template::Template; +use crate::{Result, aerr}; pub struct RoomTemplate { pub size: (i64, i64), @@ -12,7 +13,7 @@ pub struct RoomTemplate { impl RoomTemplate { - pub fn from_json(jsonroom: &Value) -> Result<RoomTemplate, &'static str>{ + pub fn from_json(jsonroom: &Value) -> Result<RoomTemplate>{ let size = ( jsonroom.get("width").ok_or("no with")?.as_i64().ok_or("with not a number")?, jsonroom.get("height").ok_or("no height")?.as_i64().ok_or("height not a number")? @@ -24,10 +25,10 @@ impl RoomTemplate { let mut templates: Vec<Template> = Vec::new(); if value.is_array() { for template in value.as_array().ok_or("weird")? { - templates.push(Template::from_json(template).ok_or("not a valid template")?); + templates.push(Template::from_json(template)?); } } else { - templates.push(Template::from_json(value).ok_or("not a valid template")?); + templates.push(Template::from_json(value)?); } mapping.insert(key.chars().next().ok_or("mapping key is empty string")?, templates); } @@ -35,9 +36,10 @@ impl RoomTemplate { let mut field = Vec::new(); field.resize((size.0 * size.1) as usize, Vec::new()); let jsonfield: &Vec<Value> = jsonroom.get("field").ok_or("no field")?.as_array().ok_or("field not an array")?; + // todo: what if size doesn't match actual dimensions for (y, row) in jsonfield.iter().enumerate() { for (x, ch) in row.as_str().ok_or("field row not a string")?.chars().enumerate() { - field[x + y * (size.0 as usize)] = mapping.get(&ch).ok_or("char not found in mapping")?.clone(); + field[x + y * (size.0 as usize)] = mapping.get(&ch).ok_or(aerr!("char not found in mapping"))?.clone(); } } Ok(RoomTemplate { diff --git a/src/savestate.rs b/src/savestate.rs index 8afbbf1..68af12c 100644 --- a/src/savestate.rs +++ b/src/savestate.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use serde_json::{json, Value}; use crate::Pos; use crate::template::Template; +use crate::{Result, aerr}; pub struct SaveState { pub changes: HashMap<Pos, Vec<Template>> @@ -25,16 +26,16 @@ impl SaveState { }) } - pub fn from_json(val: &Value) -> Option<Self> { + pub fn from_json(val: &Value) -> Result<Self> { let mut changes = HashMap::new(); - for v in val.get("changes")?.as_array()? { - let pos = Pos::from_json(v.get(0)?)?; + for v in val.get("changes").ok_or(aerr!("save does not have changes"))?.as_array().ok_or(aerr!("changes not an array"))? { + let pos = Pos::from_json(v.get(0).ok_or(aerr!("change does not have index 0"))?).ok_or(aerr!("change index 0 is not a pos"))?; let mut templates = Vec::new(); - for t in v.get(1)?.as_array()? { + for t in v.get(1).ok_or(aerr!("change does not have index 1"))?.as_array().ok_or(aerr!("change index 1 not an array"))? { templates.push(Template::from_json(t)?); } changes.insert(pos, templates); } - Some(Self {changes}) + Ok(Self {changes}) } } diff --git a/src/systems/migrate.rs b/src/systems/migrate.rs new file mode 100644 index 0000000..aecffd0 --- /dev/null +++ b/src/systems/migrate.rs @@ -0,0 +1,37 @@ + +use specs::{ + ReadStorage, + Read, + Write, + System, + Join +}; + +use crate::components::{Player, Position, Moved, RoomExit}; +use crate::resources::{Emigration, Ground}; + + +pub struct Migrate; +impl <'a> System<'a> for Migrate { + type SystemData = ( + Write<'a, Emigration>, + Read<'a, Ground>, + ReadStorage<'a, Player>, + ReadStorage<'a, Position>, + ReadStorage<'a, Moved>, + ReadStorage<'a, RoomExit>, + + ); + fn run(&mut self, (mut emigration, ground, players, positions, moved, exits): Self::SystemData) { + + for (player, position, _moved) in (&players, &positions, &moved).join() { + for ent in ground.cells.get(&position.pos).unwrap() { + if let Some(exit) = exits.get(*ent) { + emigration.emigrants.push((player.id.clone(), exit.destination.clone())); + break; + } + } + } + } +} + diff --git a/src/systems/mod.rs b/src/systems/mod.rs index 7e75706..68de813 100644 --- a/src/systems/mod.rs +++ b/src/systems/mod.rs @@ -6,3 +6,4 @@ pub mod view; pub mod remove; pub mod create; pub mod take; +pub mod migrate; diff --git a/src/template.rs b/src/template.rs index 9072032..52f7d2d 100644 --- a/src/template.rs +++ b/src/template.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use serde_json::{json, Value}; use crate::parameter::Parameter; +use crate::{Result, aerr}; #[derive(Debug, Clone, PartialEq)] pub struct Template { @@ -33,20 +34,20 @@ impl Template { Self::new(name, HashMap::new()) } - pub fn from_json(val: &Value) -> Option<Template> { + pub fn from_json(val: &Value) -> Result<Template> { if val.is_string(){ - return Some(Self::empty(val.as_str()?)); + return Ok(Self::empty(val.as_str().ok_or(aerr!("json string is not a string?"))?)); } - let name = val.get("type")?.as_str()?.to_string(); + let name = val.get("type").ok_or(aerr!("template doesn't have 'type'"))?.as_str().ok_or(aerr!("template type not a string"))?.to_string(); let mut args = Vec::new(); - for arg in val.get("args").unwrap_or(&json!({})).as_array()? { - args.push(Parameter::guess_from_json(arg)?); + for arg in val.get("args").unwrap_or(&json!([])).as_array().ok_or(aerr!("template args not an array"))? { + args.push(Parameter::guess_from_json(arg).ok_or(aerr!("template arg not a parameter"))?); } let mut kwargs = HashMap::new(); - for (key, arg) in val.get("kwargs").unwrap_or(&json!({})).as_object()? { - kwargs.insert(key.to_string(), Parameter::guess_from_json(arg)?); + for (key, arg) in val.get("kwargs").unwrap_or(&json!({})).as_object().ok_or(aerr!("template kwargs not a json object"))? { + kwargs.insert(key.to_string(), Parameter::guess_from_json(arg).ok_or(aerr!("template arg not a parameter"))?); } - Some(Template {name, args, kwargs, save: true}) + Ok(Template {name, args, kwargs, save: true}) } pub fn to_json(&self) -> Value { diff --git a/src/world.rs b/src/world.rs index 62d80be..7524eee 100644 --- a/src/world.rs +++ b/src/world.rs @@ -38,21 +38,21 @@ impl <'a, 'b>World<'a, 'b> { } } - fn get_room_mut(&mut self, id: &RoomId) -> Option<&mut Room<'a, 'b>> { + fn get_room_mut(&mut self, id: &RoomId) -> Result<&mut Room<'a, 'b>> { if !self.rooms.contains_key(id){ - let template = self.template_loader.load_room(id.clone()).ok()?; + let template = self.template_loader.load_room(id.clone())?; let mut room: Room = Room::create(id.clone(), &self.encyclopedia, &template); if let Ok(state) = self.persistence.load_room(id.clone()){ room.load_saved(&state); } self.rooms.insert(id.clone(), room); } - self.rooms.get_mut(id) + self.rooms.get_mut(id).ok_or(aerr!("can't get room after loading it")) } fn add_loaded_player(&mut self, state: PlayerState) -> Result<()> { let roomid = state.clone().room.unwrap_or(self.default_room.clone()); - let room = self.get_room_mut(&roomid).ok_or(aerr!("room not found"))?; + let room = self.get_room_mut(&roomid)?; room.add_player(&state); self.players.insert(state.id.clone(), roomid); Ok(()) @@ -65,7 +65,7 @@ impl <'a, 'b>World<'a, 'b> { fn discorporate_player(&mut self, playerid: &PlayerId) -> Result<PlayerState> { let roomid = self.players.remove(playerid).ok_or(aerr!("player not found"))?; - let room = self.get_room_mut(&roomid).ok_or(aerr!("room not found"))?; + let room = self.get_room_mut(&roomid)?; room.remove_player(playerid) } @@ -78,7 +78,7 @@ impl <'a, 'b>World<'a, 'b> { pub fn control_player(&mut self, player: PlayerId, control: Control) -> Result<()>{ let roomid = self.players.get(&player).ok_or(aerr!("player not found"))?.clone(); - Ok(self.get_room_mut(&roomid).ok_or(aerr!("room not found"))?.control_player(player, control)) + Ok(self.get_room_mut(&roomid)?.control_player(player, control)) } fn migrate_player(&mut self, player: &PlayerId, destination: RoomId) -> Result<()> { @@ -86,12 +86,18 @@ impl <'a, 'b>World<'a, 'b> { state.room = Some(destination); self.add_loaded_player(state) } - + pub fn update(&mut self) { - let mut migrants = Vec::new(); + self.migrate(); for room in self.rooms.values_mut() { room.update(); + } + } + + fn migrate(&mut self) { + let mut migrants = Vec::new(); + for room in self.rooms.values_mut() { migrants.append(&mut room.emigrate()); } for (player, destination) in migrants { |
