summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortroido <troido@protonmail.com>2020-02-21 17:49:50 +0100
committertroido <troido@protonmail.com>2020-02-21 17:49:50 +0100
commit07cc6d8919193c38cc13b2567ede5a510938db18 (patch)
tree83588f118036fa56905043eb23c5a1d79e0497da
parente69d9c3b5266fd6f9215d1e3f4a761b8027a785c (diff)
players can now go to different rooms
-rw-r--r--content/maps/broom.json28
-rw-r--r--content/maps/room.json6
-rw-r--r--src/components.rs6
-rw-r--r--src/componentwrapper.rs9
-rw-r--r--src/defaultencyclopedia.rs7
-rw-r--r--src/main.rs15
-rw-r--r--src/parameter.rs2
-rw-r--r--src/persistence.rs7
-rw-r--r--src/playerstate.rs22
-rw-r--r--src/resources.rs2
-rw-r--r--src/room.rs16
-rw-r--r--src/roomtemplate.rs10
-rw-r--r--src/savestate.rs11
-rw-r--r--src/systems/migrate.rs37
-rw-r--r--src/systems/mod.rs1
-rw-r--r--src/template.rs17
-rw-r--r--src/world.rs22
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 {