diff options
| author | troido <troido@protonmail.com> | 2020-02-22 12:55:10 +0100 |
|---|---|---|
| committer | troido <troido@protonmail.com> | 2020-02-22 12:55:10 +0100 |
| commit | 2b0cc677f4092d94b31e95f3e9961ec6ed91327b (patch) | |
| tree | 5c5e4683f5b8c9973ccfb260a876f88b599b0326 /src | |
| parent | a24e17014f37318d08fc8224d38e4062c959f34e (diff) | |
can now pick up specific object from ground
Diffstat (limited to 'src')
| -rw-r--r-- | src/controls.rs | 7 | ||||
| -rw-r--r-- | src/defaultencyclopedia.rs | 2 | ||||
| -rw-r--r-- | src/main.rs | 1 | ||||
| -rw-r--r-- | src/resources.rs | 24 | ||||
| -rw-r--r-- | src/systems/take.rs | 20 | ||||
| -rw-r--r-- | src/systems/view.rs | 26 | ||||
| -rw-r--r-- | src/worldmessages.rs | 3 |
7 files changed, 54 insertions, 29 deletions
diff --git a/src/controls.rs b/src/controls.rs index b944a93..36d7c77 100644 --- a/src/controls.rs +++ b/src/controls.rs @@ -42,7 +42,7 @@ impl Direction { #[derive(Debug, Clone)] pub enum Control { Move(Direction), - Take(Option<u64>), + Take(Option<usize>), Drop(usize) } @@ -55,10 +55,7 @@ impl Control { Some(dir) => Some(Control::Move(dir)), None => None }, - "take" => Some(Control::Take(val.get(1)?.as_u64())), /*match val[1].as_u64() { - Some(rank) => Some(Control::Take(rank)), - _ => None - }*/ + "take" => Some(Control::Take(val.get(1)?.as_u64().map(|idx| idx as usize))), "drop" => Some(Control::Drop(val.get(1)?.as_u64().unwrap_or(0) as usize)), _ => None } diff --git a/src/defaultencyclopedia.rs b/src/defaultencyclopedia.rs index 9f93e40..cce8931 100644 --- a/src/defaultencyclopedia.rs +++ b/src/defaultencyclopedia.rs @@ -83,7 +83,7 @@ pub fn default_encyclopedia() -> Encyclopedia { ["Item", {"ent": ["template", "pebble"], "name": ["string", "pebble"]}] ], "sprite": "pebble", - "height": 0.4 + "height": 0.3 }, "stone": { "components": [ diff --git a/src/main.rs b/src/main.rs index 21b6b71..def2ee7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -103,7 +103,6 @@ fn main() -> Result<()>{ if message.is_empty(){ continue; } - println!("{}: {}", player.name, message.to_json()); let _ = gameserver.send(&player, message.to_json()); } diff --git a/src/resources.rs b/src/resources.rs index 6e4bffb..0e9a1e3 100644 --- a/src/resources.rs +++ b/src/resources.rs @@ -1,6 +1,6 @@ use std::collections::{HashMap, HashSet}; -use specs::Entity; +use specs::{Entity, ReadStorage, Component}; use crate::{ pos::Pos, @@ -11,7 +11,8 @@ use crate::{ PlayerId, RoomId, util::Result, - template::Template + template::Template, + components::Visible }; @@ -40,6 +41,25 @@ pub struct Spawn { pub struct Ground { pub cells: HashMap<Pos, HashSet<Entity>> } +impl Ground { + 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()).iter().filter_map(|e| component_type.get(*e)).collect() + } + + pub fn by_height(&self, pos: &Pos, visibles: &ReadStorage<Visible>, ignore: &Entity) -> Vec<Entity> { + let mut entities: Vec<Entity> = self.cells + .get(&pos).unwrap_or(&HashSet::new()) + .iter() + .cloned() + .filter(|e| e != ignore && visibles.contains(*e)) + .collect(); + entities.sort_by(|a, b| + visibles.get(*b).unwrap().height.partial_cmp(&visibles.get(*a).unwrap().height).unwrap() + ); + entities + } +} + #[derive(Default)] pub struct NewEntities { diff --git a/src/systems/take.rs b/src/systems/take.rs index 31634d2..99c66d5 100644 --- a/src/systems/take.rs +++ b/src/systems/take.rs @@ -1,5 +1,4 @@ -use std::collections::HashSet; use specs::{ Entities, @@ -15,7 +14,8 @@ use crate::components::{ Position, Removed, Inventory, - Item + Item, + Visible }; use crate::controls::{Control}; @@ -33,15 +33,21 @@ impl <'a> System<'a> for Take { WriteStorage<'a, Removed>, ReadStorage<'a, Item>, WriteStorage<'a, Inventory>, - Write<'a, NewEntities> + Write<'a, NewEntities>, + ReadStorage<'a, Visible> ); - fn run(&mut self, (entities, controllers, positions, ground, mut removed, items, mut inventories, mut new): Self::SystemData) { + fn run(&mut self, (entities, controllers, positions, ground, mut removed, items, mut inventories, mut new, visibles): Self::SystemData) { for (ent, controller, position, inventory) in (&entities, &controllers, &positions, &mut inventories).join(){ match &controller.0 { - Control::Take(_rank) if inventory.items.len() < inventory.capacity => { - let mut ents = ground.cells.get(&position.pos).unwrap_or(&HashSet::new()).clone(); - ents.remove(&ent); + Control::Take(rank) if inventory.items.len() < inventory.capacity => { + let mut ents = ground.by_height(&position.pos, &visibles, &ent); + if let Some(idx) = rank { + if *idx >= ents.len() { + return + } + ents = vec!(ents[*idx]); + } for ent in ents { if let Some(item) = items.get(ent) { inventory.items.insert(0, item.clone()); diff --git a/src/systems/view.rs b/src/systems/view.rs index 6e53eb1..7d41820 100644 --- a/src/systems/view.rs +++ b/src/systems/view.rs @@ -1,5 +1,5 @@ -use std::collections::{HashMap, HashSet}; +use std::collections::{HashSet}; use specs::{ ReadStorage, @@ -7,8 +7,7 @@ use specs::{ Write, System, Join, - Entities, - Entity + Entities }; use crate::{Pos, Sprite}; @@ -53,14 +52,14 @@ impl <'a> System<'a> for View { 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.cells.get(&pos).unwrap_or(&HashSet::new()), &visible))); + changes.push((pos, cell_sprites(ground.components_on(pos, &visible)))); } 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.cells, (size.width, size.height), &visible); + let (values, mapping) = draw_room(&ground, (size.width, size.height), &visible); let field = FieldMessage{ width: size.width, height: size.height, @@ -77,6 +76,13 @@ impl <'a> System<'a> for View { if let Some(health) = healths.get(ent){ updates.health = Some((health.health, health.maxhealth)); } + updates.ground = Some( + ground + .by_height(&pos.pos, &visible, &ent) + .into_iter() + .map(|ent| visible.get(ent).unwrap().name.clone()) + .collect() + ); updates.pos = Some(pos.pos); if !updates.is_empty() { output.output.insert(player.id.clone(), updates); @@ -85,23 +91,19 @@ impl <'a> System<'a> for View { } } -fn cell_sprites(entities: &HashSet<Entity>, visible: &ReadStorage<Visible>) -> Vec<Sprite> { - let mut visibles: Vec<&Visible> = entities.iter().filter_map(|ent| visible.get(*ent)).collect(); +fn cell_sprites(mut visibles: Vec<&Visible>) -> Vec<Sprite> { visibles.sort_by(|a, b| b.height.partial_cmp(&a.height).unwrap()); visibles.iter().map(|vis| vis.sprite.clone()).collect() } -fn draw_room(ground: &HashMap<Pos, HashSet<Entity>>, (width, height): (i64, i64), visible: &ReadStorage<Visible>) -> (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> = match ground.get(&Pos{x, y}) { - Some(ents) => {cell_sprites(ents, visible)} - None => {vec![]} - }; + let sprites: Vec<Sprite> = cell_sprites(ground.components_on(Pos{x, y}, visible)); values.push( match mapping.iter().position(|x| x == &sprites) { Some(index) => { diff --git a/src/worldmessages.rs b/src/worldmessages.rs index 1efe477..c70b8b0 100644 --- a/src/worldmessages.rs +++ b/src/worldmessages.rs @@ -58,13 +58,14 @@ worldmessages!( change, ChangeMessage, "changecells"; inventory, InventoryMessage, "inventory"; health, HealthMessage, "health"; + ground, GroundMessage, "ground"; ); pub type ChangeMessage = Vec<(Pos, Vec<Sprite>)>; pub type HealthMessage = (i64, i64); pub type InventoryMessage = Vec<String>; - +pub type GroundMessage = Vec<String>; #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)] pub struct FieldMessage { |
