From c71ecb48fa4368035a852e2d06869a21382a6876 Mon Sep 17 00:00:00 2001 From: troido Date: Tue, 18 Feb 2020 01:11:49 +0100 Subject: Players are now saved/loaded too --- src/room.rs | 104 +++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 86 insertions(+), 18 deletions(-) (limited to 'src/room.rs') diff --git a/src/room.rs b/src/room.rs index 28abfa7..83702fe 100644 --- a/src/room.rs +++ b/src/room.rs @@ -6,17 +6,20 @@ use specs::{ WorldExt, DispatcherBuilder, Dispatcher, - Join + Builder, + Join, + Entity }; -use super::controls::Action; +use super::controls::Control; use super::worldmessages::WorldMessage; use super::resources::{ Size, Output, Input, NewEntities, - Spawn + Spawn, + Players }; use super::systems::{ moving::Move, @@ -27,28 +30,38 @@ use super::systems::{ create::Create, take::Take }; -use crate::components::{Position, Serialise}; +use crate::components::{ + Position, + Serialise, + Player, + Inventory, + Health, + New, + Removed +}; use crate::encyclopedia::Encyclopedia; use crate::roomtemplate::RoomTemplate; use crate::savestate::SaveState; use crate::template::Template; -use crate::{Pos, PlayerId}; +use crate::playerstate::PlayerState; +use crate::{Pos, PlayerId, aerr}; +use crate::util::Result; pub struct Room<'a, 'b> { world: World, - dispatcher: Dispatcher<'a, 'b> + dispatcher: Dispatcher<'a, 'b>, + pub name: String } impl <'a, 'b>Room<'a, 'b> { - pub fn new(encyclopedia: Encyclopedia) -> Room<'a, 'b> { + pub fn new(name: &str, encyclopedia: Encyclopedia) -> Room<'a, 'b> { let mut world = World::new(); - world.insert(NewEntities{ - templates: Vec::new(), - encyclopedia - }); + world.insert(NewEntities::new(encyclopedia)); + world.insert(Players::default()); + world.insert(Spawn::default()); world.register::(); let mut dispatcher = DispatcherBuilder::new() @@ -66,7 +79,8 @@ impl <'a, 'b>Room<'a, 'b> { Room { world, - dispatcher + dispatcher, + name: name.to_string() } } @@ -83,7 +97,7 @@ impl <'a, 'b>Room<'a, 'b> { let y = (idx as i64) / width; for template in templates { - self.create_entity(template.clone().unsaved(), Pos{x, y}); + let _ = self.create_entity(template.clone().unsaved(), Pos{x, y}); } } } @@ -97,13 +111,31 @@ impl <'a, 'b>Room<'a, 'b> { self.world.maintain(); } - pub fn set_input(&mut self, actions: Vec){ + pub fn set_input(&mut self, actions: HashMap){ self.world.fetch_mut::().actions = actions; } + pub fn add_player(&mut self, id: PlayerId, state: &PlayerState){ + let pre_player = state.construct(id.clone()); + let spawn = self.world.fetch::().pos; + let mut builder = self.world.create_entity(); + let ent = builder.entity; + for comp in pre_player { + builder = comp.build(builder); + } + builder.with(Position::new(spawn)).with(New).build(); + self.world.fetch_mut::().entities.insert(id, ent); + } + + pub fn remove_player(&mut self, id: PlayerId) -> Result{ + let ent = self.world.fetch_mut::().entities.remove(&id).ok_or(aerr!("failed to remove player"))?; + self.world.write_component::().insert(ent, Removed)?; + self.save_player_ent(ent).ok_or(aerr!("failed to find player to remove")) + } + pub fn save(&self) -> SaveState { let positions = self.world.read_component::(); - let serialisers = self.world.write_component::(); + let serialisers = self.world.read_component::(); let mut state = SaveState::new(); for (pos, serialiser) in (&positions, &serialisers).join() { state.changes.entry(pos.pos).or_insert(Vec::new()).push(serialiser.template.clone()); @@ -114,13 +146,49 @@ impl <'a, 'b>Room<'a, 'b> { pub fn load_saved(&mut self, state: &SaveState) { for (pos, templates) in state.changes.iter() { for template in templates { - self.create_entity(template.clone(), *pos); + let _ = self.create_entity(template.clone(), *pos); } } } - fn create_entity(&mut self, template: Template, pos: Pos){ - self.world.fetch_mut::().templates.push((pos, template)); + pub fn save_players(&self) -> HashMap { + let players = self.world.read_component::(); + let inventories = self.world.read_component::(); + let healths = self.world.read_component::(); + let mut saved = HashMap::new(); + for (player, inventory, health) in (&players, &inventories, &healths).join() { + saved.insert(player.id.clone(), PlayerState::create( + player.id.name.clone(), + self.name.clone(), + inventory.items.iter().map(|item| item.ent.clone()).collect(), + inventory.capacity, + health.health, + health.maxhealth + )); + } + saved + } + + fn save_player_ent(&self, ent: Entity) -> Option { + let players = self.world.read_component::(); + let player = players.get(ent)?; + let inventories = self.world.read_component::(); + let inventory = inventories.get(ent)?; + let healths = self.world.read_component::(); + let health = healths.get(ent)?; + Some(PlayerState::create( + player.id.name.clone(), + self.name.clone(), + inventory.items.iter().map(|item| item.ent.clone()).collect(), + inventory.capacity, + health.health, + health.maxhealth + )) + } + + fn create_entity(&mut self, template: Template, pos: Pos) -> Result<()>{ + self.world.fetch_mut::().create(pos, template)?; + Ok(()) } } -- cgit