diff options
| author | troido <troido@protonmail.com> | 2020-04-04 23:48:07 +0200 |
|---|---|---|
| committer | troido <troido@protonmail.com> | 2020-04-04 23:48:07 +0200 |
| commit | 068f98cec100772defce8ba966e5b917558b191c (patch) | |
| tree | 80124cf89852dbedec9322258af36167cc99277b | |
| parent | 2cc5b468cfd4c28bf1ad17ef1b3600c3d42f8b83 (diff) | |
draw the room after new entities have been added
| -rw-r--r-- | src/components/mod.rs | 14 | ||||
| -rw-r--r-- | src/playerstate.rs | 1 | ||||
| -rw-r--r-- | src/pos.rs | 1 | ||||
| -rw-r--r-- | src/purgatory.rs | 10 | ||||
| -rw-r--r-- | src/resources/ground.rs | 30 | ||||
| -rw-r--r-- | src/room.rs | 36 | ||||
| -rw-r--r-- | src/systems/clear.rs | 19 | ||||
| -rw-r--r-- | src/systems/mod.rs | 4 | ||||
| -rw-r--r-- | src/systems/moving.rs | 21 | ||||
| -rw-r--r-- | src/systems/registernew.rs | 19 | ||||
| -rw-r--r-- | src/systems/remove.rs | 2 | ||||
| -rw-r--r-- | src/systems/view.rs | 36 | ||||
| -rw-r--r-- | todo.md | 6 |
13 files changed, 101 insertions, 98 deletions
diff --git a/src/components/mod.rs b/src/components/mod.rs index b7e3875..1a590b2 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -33,7 +33,6 @@ use specs::{ DenseVecStorage, VecStorage, HashMapStorage, - FlaggedStorage, NullStorage, Component, Entity @@ -50,7 +49,8 @@ use crate::{ Timestamp }; -#[derive(Debug, Clone)] +#[derive(Component, Debug, Clone)] +#[storage(VecStorage)] pub struct Position{ pub pos: Pos } @@ -60,19 +60,13 @@ impl Position { } } -impl Component for Position { - type Storage = FlaggedStorage<Self, VecStorage<Self>>; -} - -#[derive(Debug, Clone)] +#[derive(Component, Debug, Clone)] +#[storage(VecStorage)] pub struct Visible { pub sprite: Sprite, pub height: f64, pub name: String } -impl Component for Visible { - type Storage = FlaggedStorage<Self, VecStorage<Self>>; -} #[derive(Component, Debug)] pub struct Controller { diff --git a/src/playerstate.rs b/src/playerstate.rs index f146cd2..f05332b 100644 --- a/src/playerstate.rs +++ b/src/playerstate.rs @@ -30,6 +30,7 @@ use crate::{ }; #[derive(Debug, Clone)] +#[allow(dead_code)] pub enum RoomPos { Pos(Pos), Name(String), @@ -18,6 +18,7 @@ impl Pos { Pos {x, y} } + #[allow(dead_code)] pub fn clamp(self, smaller: Pos, larger: Pos) -> Pos { Pos { x: clamp(self.x, smaller.x, larger.x), diff --git a/src/purgatory.rs b/src/purgatory.rs index 04024db..e5803d0 100644 --- a/src/purgatory.rs +++ b/src/purgatory.rs @@ -11,9 +11,7 @@ use crate::{ roomtemplate::RoomTemplate, systems::{ Move, - RegisterNew, ControlInput, - View, Remove, Create, Volate, @@ -29,14 +27,12 @@ pub fn purgatory_id() -> RoomId { pub fn create_purgatory<'a, 'b>(encyclopedia: &Encyclopedia) -> Room<'a, 'b> { let dispatcher = DispatcherBuilder::new() .with(Volate, "volate", &[]) - .with(RegisterNew::default(), "registernew", &[]) - .with(UpdateCooldowns, "cool_down", &["registernew"]) + .with(UpdateCooldowns, "cool_down", &[]) .with(ControlInput, "controlinput", &["cool_down"]) .with(ControlAI, "controlai", &["cool_down"]) .with(Move, "move", &["controlinput", "controlai"]) - .with(View::default(), "view", &["move", "volate"]) - .with(Create, "create", &["view"]) - .with(Remove, "remove", &["view", "move"]) + .with(Create, "create", &["move", "volate"]) + .with(Remove, "remove", &["volate", "move"]) .build(); let mut room = Room::new(purgatory_id(), encyclopedia.clone(), dispatcher); room.load_from_template(&RoomTemplate::from_json(&json!({ diff --git a/src/resources/ground.rs b/src/resources/ground.rs index 8194a44..7411a15 100644 --- a/src/resources/ground.rs +++ b/src/resources/ground.rs @@ -8,27 +8,33 @@ use specs::{ }; use crate::{ - components::{Visible, Removed, Flags, Flag}, + components::{Visible, Flags, Flag}, Pos }; #[derive(Default)] pub struct Ground { - pub cells: HashMap<Pos, HashSet<Entity>> + pub cells: HashMap<Pos, HashSet<Entity>>, + pub changes: HashSet<Pos> } impl Ground { - pub fn components_on<'a, C: Component>(&self, pos: Pos, component_type: &'a ReadStorage<C>, removals: &'a ReadStorage<Removed>) -> Vec<&'a C> { - self.cells - .get(&pos) - .unwrap_or(&HashSet::new()) - .iter() - .filter(|e| !removals.contains(**e)) - .filter_map(|e| component_type.get(*e)) - .collect() + + pub fn insert(&mut self, pos: Pos, ent: Entity){ + self.cells.entry(pos).or_insert_with(HashSet::new).insert(ent); + self.changes.insert(pos); + } + + pub fn remove(&mut self, pos: &Pos, ent: Entity) -> bool{ + if let Some(cell) = self.cells.get_mut(pos) { + self.changes.insert(*pos); + cell.remove(&ent) + } else { + false + } } - pub fn all_components_on<'a, C: Component>(&self, pos: Pos, component_type: &'a ReadStorage<C>) -> Vec<&'a C> { + pub fn components_on<'a, C: Component>(&self, pos: Pos, component_type: &'a ReadStorage<C>) -> Vec<&'a C> { self.cells .get(&pos) .unwrap_or(&HashSet::new()) @@ -51,6 +57,6 @@ impl Ground { } pub fn flags_on<'a>(&self, pos: Pos, flags: &'a ReadStorage<Flags>) -> HashSet<Flag> { - self.all_components_on::<Flags>(pos, flags).into_iter().fold(HashSet::new(), |a, b| &a | &b.0) + self.components_on::<Flags>(pos, flags).into_iter().fold(HashSet::new(), |a, b| &a | &b.0) } } diff --git a/src/room.rs b/src/room.rs index fa46d47..2b4fb7e 100644 --- a/src/room.rs +++ b/src/room.rs @@ -6,7 +6,6 @@ use specs::{ WorldExt, DispatcherBuilder, Dispatcher, - Builder, Join, Entity }; @@ -30,7 +29,6 @@ use crate::{ Player, Inventory, Health, - New, Removed }, Encyclopedia, @@ -66,17 +64,17 @@ use crate::{ Spawn, Interact, DropLoot, - Growth + Growth, + Clear } }; pub fn default_dispatcher<'a, 'b>() -> Dispatcher<'a, 'b> { DispatcherBuilder::new() .with(Volate, "volate", &[]) - .with(RegisterNew::default(), "registernew", &[]) - .with(Growth, "growth", &["registernew"]) - .with(UpdateCooldowns, "cool_down", &["registernew"]) - .with(Spawn, "spawn", &["registernew"]) + .with(Growth, "growth", &[]) + .with(UpdateCooldowns, "cool_down", &[]) + .with(Spawn, "spawn", &[]) .with(ControlInput, "controlinput", &["cool_down"]) .with(ControlAI, "controlai", &["cool_down"]) .with(Take, "take", &["controlinput", "controlai"]) @@ -85,20 +83,20 @@ pub fn default_dispatcher<'a, 'b>() -> Dispatcher<'a, 'b> { .with(Move, "move", &["controlinput", "controlai"]) .with(Trapping, "trapping", &["move"]) .with(Fight, "fight", &["move"]) - .with(Heal, "heal", &["registernew"]) + .with(Heal, "heal", &[]) .with(Attacking, "attacking", &["use", "trapping", "fight", "heal", "interact"]) .with(Die, "die", &["attacking"]) .with(DropLoot, "droploot", &["attacking"]) - .with(View::default(), "view", &["move", "attacking", "volate", "die"]) - .with(Migrate, "migrate", &["view"]) - .with(Create, "create", &["view", "spawn", "droploot", "growth"]) - .with(Remove, "remove", &["view", "move", "droploot"]) + .with(Migrate, "migrate", &["move", "attacking", "volate", "die"]) + .with(Create, "create", &["migrate", "spawn", "droploot", "growth"]) + .with(Remove, "remove", &["migrate", "move", "droploot"]) .build() } pub struct Room<'a, 'b> { world: World, dispatcher: Dispatcher<'a, 'b>, + view_dispatcher: Dispatcher<'a, 'b>, pub id: RoomId, places: HashMap<String, Pos> } @@ -129,6 +127,11 @@ impl <'a, 'b>Room<'a, 'b> { Room { world, dispatcher, + view_dispatcher: DispatcherBuilder::new() + .with(RegisterNew, "registernew", &[]) + .with(View, "view", &["registernew"]) + .with(Clear, "clear", &["view"]) + .build(), id, places: HashMap::new() } @@ -170,6 +173,7 @@ impl <'a, 'b>Room<'a, 'b> { self.world.fetch_mut::<Time>().time = timestamp; self.dispatcher.dispatch(&self.world); self.world.maintain(); + self.view_dispatcher.dispatch(&self.world); } @@ -184,13 +188,7 @@ impl <'a, 'b>Room<'a, 'b> { RoomPos::Pos(pos) => *pos, RoomPos::Name(name) => *self.places.get(name).unwrap() }; - 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::<Players>().entities.insert(state.id.clone(), ent); + self.world.fetch_mut::<NewEntities>().to_build.push((spawn, pre_player)); } pub fn remove_player(&mut self, id: &PlayerId) -> Result<PlayerState>{ diff --git a/src/systems/clear.rs b/src/systems/clear.rs new file mode 100644 index 0000000..64588d3 --- /dev/null +++ b/src/systems/clear.rs @@ -0,0 +1,19 @@ + +use specs::{ + Write, + System +}; + +use crate::{ + resources::Ground +}; + +pub struct Clear; +impl <'a> System<'a> for Clear { + type SystemData = + Write<'a, Ground>; + fn run(&mut self, mut ground: Self::SystemData) { + ground.changes.clear(); + } +} + diff --git a/src/systems/mod.rs b/src/systems/mod.rs index 318d5ee..3f990a7 100644 --- a/src/systems/mod.rs +++ b/src/systems/mod.rs @@ -20,6 +20,7 @@ mod spawn; mod interact; mod droploot; mod growth; +mod clear; pub use self::{ controlinput::ControlInput, @@ -42,5 +43,6 @@ pub use self::{ spawn::Spawn, interact::Interact, droploot::DropLoot, - growth::Growth + growth::Growth, + clear::Clear }; diff --git a/src/systems/moving.rs b/src/systems/moving.rs index 6ecf040..ccd29d6 100644 --- a/src/systems/moving.rs +++ b/src/systems/moving.rs @@ -1,18 +1,14 @@ -use std::collections::HashSet; - use specs::{ Entities, ReadStorage, WriteStorage, - Read, System, Join, Write }; use crate::{ - Pos, components::{ Controller, Position, @@ -27,7 +23,6 @@ use crate::{ Control }, resources::{ - Size, Ground }, }; @@ -39,7 +34,6 @@ impl <'a> System<'a> for Move { Entities<'a>, ReadStorage<'a, Controller>, WriteStorage<'a, Position>, - Read<'a, Size>, ReadStorage<'a, Flags>, Write<'a, Ground>, WriteStorage<'a, Moved>, @@ -48,20 +42,19 @@ impl <'a> System<'a> for Move { WriteStorage<'a, ControlCooldown> ); - fn run(&mut self, (entities, controllers, mut positions, size, flags, mut ground, mut moved, mut entered, movables, mut cooldowns): Self::SystemData) { + fn run(&mut self, (entities, controllers, mut positions, flags, mut ground, mut moved, mut entered, movables, mut cooldowns): Self::SystemData) { moved.clear(); entered.clear(); - for (ent, controller, mut pos, movable) in (&entities, &controllers, &mut positions.restrict_mut(), &movables).join(){ + for (ent, controller, mut position, movable) in (&entities, &controllers, &mut positions, &movables).join(){ match &controller.control { Control::Move(direction) => { - let newpos = (pos.get_unchecked().pos + direction.to_position()).clamp(Pos::new(0, 0), Pos::new(size.width - 1, size.height - 1)); + let newpos = position.pos + direction.to_position(); let ground_flags = ground.flags_on(newpos, &flags); if !ground_flags.contains(&Flag::Blocking) && ground_flags.contains(&Flag::Floor) { - let mut pos_mut = pos.get_mut_unchecked(); - moved.insert(ent, Moved{from: pos_mut.pos}).expect("can't insert Moved"); - ground.cells.get_mut(&pos_mut.pos).unwrap().remove(&ent); - pos_mut.pos = newpos; - ground.cells.entry(newpos).or_insert_with(HashSet::new).insert(ent); + moved.insert(ent, Moved{from: position.pos}).expect("can't insert Moved"); + ground.remove(&position.pos, ent); + position.pos = newpos; + ground.insert(newpos, ent); for ent in ground.cells.get(&newpos).unwrap() { let _ = entered.insert(*ent, Entered); } diff --git a/src/systems/registernew.rs b/src/systems/registernew.rs index c53309f..0091296 100644 --- a/src/systems/registernew.rs +++ b/src/systems/registernew.rs @@ -1,5 +1,4 @@ -use std::collections::HashSet; use specs::{ ReadStorage, @@ -11,26 +10,32 @@ use specs::{ use crate::components::{ Position, - New + New, + Player }; use crate::resources::{ - Ground + Ground, + Players }; -#[derive(Default)] pub struct RegisterNew; impl <'a> System<'a> for RegisterNew { type SystemData = ( Entities<'a>, + ReadStorage<'a, New>, Write<'a, Ground>, ReadStorage<'a, Position>, - ReadStorage<'a, New>, + Write<'a, Players>, + ReadStorage<'a, Player> ); - fn run(&mut self, (entities, mut ground, positions, new): Self::SystemData) { + fn run(&mut self, (entities, new, mut ground, positions, mut player_list, players): Self::SystemData) { for (ent, pos, _new) in (&entities, &positions, &new).join() { - ground.cells.entry(pos.pos).or_insert_with(HashSet::new).insert(ent); + ground.insert(pos.pos, ent); + } + for (ent, player, _new) in (&entities, &players, &new).join(){ + player_list.entities.insert(player.id.clone(), ent); } } } diff --git a/src/systems/remove.rs b/src/systems/remove.rs index b73a2fb..a228a32 100644 --- a/src/systems/remove.rs +++ b/src/systems/remove.rs @@ -26,7 +26,7 @@ impl <'a> System<'a> for Remove { println!("{:?}", msg); } if let Some(position) = positions.get(ent) { - ground.cells.get_mut(&position.pos).unwrap().remove(&ent); + ground.remove(&position.pos, ent); } } } diff --git a/src/systems/view.rs b/src/systems/view.rs index 49338ac..4419203 100644 --- a/src/systems/view.rs +++ b/src/systems/view.rs @@ -1,5 +1,4 @@ -use std::collections::{HashSet}; use specs::{ ReadStorage, @@ -14,12 +13,11 @@ use specs::{ use crate::{ Pos, Sprite, - components::{Visible, Player, Position, Inventory, New, Moved, Removed, Health, Ear}, + components::{Visible, Player, Position, Inventory, New, Health, Ear}, resources::{Size, Output, Ground}, worldmessages::{WorldMessage, FieldMessage} }; -#[derive(Default)] pub struct View; impl <'a> System<'a> for View { @@ -33,37 +31,23 @@ impl <'a> System<'a> for View { ReadStorage<'a, Player>, Write<'a, Output>, ReadStorage<'a, New>, - ReadStorage<'a, Moved>, - ReadStorage<'a, Removed>, Read<'a, Ground>, WriteStorage<'a, Ear> ); - fn run(&mut self, (entities, positions, inventories, healths, visible, size, players, mut output, new, moved, removed, ground, mut ears): Self::SystemData) { + fn run(&mut self, (entities, positions, inventories, healths, visible, size, players, mut output, new, ground, mut ears): Self::SystemData) { - let mut changed = HashSet::new(); - for (pos, _new) in (&positions, &new).join() { - changed.insert(pos.pos); - } - for (pos, mov) in (&positions, &moved).join() { - changed.insert(pos.pos); - changed.insert(mov.from); - } - for (pos, _removed) in (&positions, &removed).join() { - changed.insert(pos.pos); - } + let changes: Vec<(Pos, Vec<Sprite>)> = ground.changes + .iter() + .map(|pos| (*pos, cell_sprites(ground.components_on(*pos, &visible)))) + .collect(); - - let has_changed: bool = !changed.is_empty(); - let mut changes: Vec<(Pos, Vec<Sprite>)> = Vec::new(); - for pos in changed { - changes.push((pos, cell_sprites(ground.components_on(pos, &visible, &removed)))); - } + let has_changed: bool = !changes.is_empty(); output.output.clear(); for (ent, player, pos) in (&entities, &players, &positions).join() { let mut updates = WorldMessage::default(); if new.get(ent).is_some() { - let (values, mapping) = draw_room(&ground, (size.width, size.height), &visible, &removed); + let (values, mapping) = draw_room(&ground, (size.width, size.height), &visible); let field = FieldMessage{ width: size.width, height: size.height, @@ -105,14 +89,14 @@ fn cell_sprites(mut visibles: Vec<&Visible>) -> Vec<Sprite> { visibles.iter().map(|vis| vis.sprite.clone()).collect() } -fn draw_room(ground: &Read<Ground>, (width, height): (i64, i64), visible: &ReadStorage<Visible>, removals: &ReadStorage<Removed>) -> (Vec<usize>, Vec<Vec<Sprite>>){ +fn draw_room(ground: &Read<Ground>, (width, height): (i64, i64), visible: &ReadStorage<Visible>) -> (Vec<usize>, Vec<Vec<Sprite>>){ let size = width * height; let mut values :Vec<usize> = Vec::with_capacity(size as usize); let mut mapping: Vec<Vec<Sprite>> = Vec::new(); for y in 0..height { for x in 0..width { - let sprites: Vec<Sprite> = cell_sprites(ground.components_on(Pos{x, y}, visible, removals)); + let sprites: Vec<Sprite> = cell_sprites(ground.components_on(Pos{x, y}, visible)); values.push( match mapping.iter().position(|x| x == &sprites) { Some(index) => { @@ -3,9 +3,13 @@ - make readme - more tests +- parameterised interactions +- trader +- visitors +- improved tutorial +- port over rooms/saves - timer resource? - log world events to player -- draw new entities - relative room locations? - improve error handling |
