summaryrefslogtreecommitdiff
path: root/src/world.rs
diff options
context:
space:
mode:
authortroido <troido@protonmail.com>2020-02-21 15:03:43 +0100
committertroido <troido@protonmail.com>2020-02-21 15:03:43 +0100
commitada1c4571a9ba43b15027f126fada55e73901a11 (patch)
tree30b49fd4a4ad7460d439aa12e805fcddf33bcad9 /src/world.rs
parentd225dc6349670926a4adea932f0ea77b7af5acbc (diff)
create World for multiroom support
Diffstat (limited to 'src/world.rs')
-rw-r--r--src/world.rs107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/world.rs b/src/world.rs
new file mode 100644
index 0000000..891e22b
--- /dev/null
+++ b/src/world.rs
@@ -0,0 +1,107 @@
+
+use std::collections::HashMap;
+
+use crate::{
+ PlayerId,
+ RoomId,
+ room::Room,
+ worldloader::WorldLoader,
+ persistence::PersistentStorage,
+ playerstate::PlayerState,
+ encyclopedia::Encyclopedia,
+ controls::Control,
+ util::Result,
+ aerr,
+ worldmessages::WorldMessage
+};
+
+pub struct World<'a, 'b> {
+ template_loader: WorldLoader,
+ persistence: Box<dyn PersistentStorage>,
+ default_room: RoomId,
+ players: HashMap<PlayerId, RoomId>,
+ rooms: HashMap<RoomId, Room<'a, 'b>>,
+ encyclopedia: Encyclopedia
+}
+
+
+impl <'a, 'b>World<'a, 'b> {
+
+ pub fn new(encyclopedia: Encyclopedia, template_loader: WorldLoader, persistence: Box<dyn PersistentStorage>, default_room: RoomId) -> Self {
+ World {
+ template_loader,
+ persistence,
+ default_room,
+ encyclopedia,
+ players: HashMap::new(),
+ rooms: HashMap::new()
+ }
+ }
+
+ fn get_room_mut(&mut self, id: &RoomId) -> Option<&mut Room<'a, 'b>> {
+ if !self.rooms.contains_key(id){
+ let template = self.template_loader.load_room(id.clone()).ok()?;
+ 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)
+ }
+
+ pub fn add_player(&mut self, playerid: PlayerId) -> Result<()> {
+ let state = self.persistence.load_player(playerid.clone()).unwrap_or(PlayerState::new(playerid.clone()));
+ let roomid = state.clone().room.unwrap_or(self.default_room.clone());
+ let room = self.get_room_mut(&roomid).ok_or(aerr!("room not found"))?;
+ room.add_player(&state);
+ self.players.insert(playerid, roomid);
+ Ok(())
+ }
+
+ pub fn remove_player(&mut self, playerid: PlayerId) -> Result<()> {
+ 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 player_state = room.remove_player(playerid.clone())?;
+ self.persistence.save_player(playerid.clone(), player_state)?;
+ Ok(())
+ }
+
+ 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))
+ }
+
+ pub fn update(&mut self) {
+ for room in self.rooms.values_mut() {
+ room.update();
+ }
+ }
+
+ pub fn save(&self) {
+ for room in self.rooms.values() {
+ if let Err(err) = self.persistence.save_room(room.id.clone(), room.save()) {
+ println!("{:?}",err);
+ } else {
+ println!("{}", room.save().to_json());
+ }
+ for (playerid, state) in room.save_players() {
+ if let Err(err) = self.persistence.save_player(playerid.clone(), state.clone()) {
+ println!("{:?}",err);
+ } else {
+ println!("{:?} {}", playerid, state.to_json());
+ }
+ }
+ }
+ }
+
+ pub fn view(&self) -> HashMap<PlayerId, WorldMessage> {
+ let mut views = HashMap::new();
+ for room in self.rooms.values() {
+ for (player, message) in room.view().into_iter() {
+ views.insert(player, message);
+ }
+ }
+ views
+ }
+}