summaryrefslogtreecommitdiff
path: root/src/resources/ground.rs
blob: 7411a15625b5e1a3bce1ce70dc657b3854470657 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

use std::collections::{HashMap, HashSet};

use specs::{
	ReadStorage,
	Component,
	Entity
};

use crate::{
	components::{Visible, Flags, Flag},
	Pos
};

#[derive(Default)]
pub struct Ground {
	pub cells: HashMap<Pos, HashSet<Entity>>,
	pub changes: HashSet<Pos>
}

impl Ground {
	
	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 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
	}
	
	pub fn flags_on<'a>(&self, pos: Pos, flags: &'a ReadStorage<Flags>) -> HashSet<Flag> {
		self.components_on::<Flags>(pos, flags).into_iter().fold(HashSet::new(), |a, b| &a | &b.0)
	}
}