summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortroido <troido@protonmail.com>2020-02-22 12:55:10 +0100
committertroido <troido@protonmail.com>2020-02-22 12:55:10 +0100
commit2b0cc677f4092d94b31e95f3e9961ec6ed91327b (patch)
tree5c5e4683f5b8c9973ccfb260a876f88b599b0326 /src
parenta24e17014f37318d08fc8224d38e4062c959f34e (diff)
can now pick up specific object from ground
Diffstat (limited to 'src')
-rw-r--r--src/controls.rs7
-rw-r--r--src/defaultencyclopedia.rs2
-rw-r--r--src/main.rs1
-rw-r--r--src/resources.rs24
-rw-r--r--src/systems/take.rs20
-rw-r--r--src/systems/view.rs26
-rw-r--r--src/worldmessages.rs3
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 {