Skip to main content

jagua_rs/collision_detection/hazards/
filter.rs

1use crate::collision_detection::hazards::{BasicHazardEntity, HazKey};
2use slotmap::SecondaryMap;
3
4/// Decides which [`Hazard`](super::Hazard)s a collision query ignores, by key or by the entity inducing them.
5pub trait HazardFilter<E> {
6    /// Whether the hazard registered under `key` and induced by `entity` is ignored.
7    fn is_irrelevant(&self, key: HazKey, entity: &E) -> bool;
8}
9
10/// Deems hazards with specific [`HazKey`]'s as irrelevant.
11#[derive(Clone, Debug)]
12pub struct HazKeyFilter(pub SecondaryMap<HazKey, ()>);
13
14impl HazKeyFilter {
15    pub fn from_keys(keys: impl IntoIterator<Item = HazKey>) -> Self {
16        HazKeyFilter(keys.into_iter().map(|k| (k, ())).collect())
17    }
18}
19
20impl<E> HazardFilter<E> for HazKeyFilter {
21    fn is_irrelevant(&self, key: HazKey, _: &E) -> bool {
22        self.0.contains_key(key)
23    }
24}
25
26/// Deems hazards induced by itself as irrelevant.
27impl<E> HazardFilter<E> for HazKey {
28    fn is_irrelevant(&self, key: HazKey, _: &E) -> bool {
29        *self == key
30    }
31}
32
33/// Ignores the hazards either filter ignores.
34impl<E, A: HazardFilter<E>, B: HazardFilter<E>> HazardFilter<E> for (A, B) {
35    fn is_irrelevant(&self, key: HazKey, entity: &E) -> bool {
36        self.0.is_irrelevant(key, entity) || self.1.is_irrelevant(key, entity)
37    }
38}
39
40/// Deems no hazards as irrelevant.
41#[derive(Clone, Debug)]
42pub struct NoFilter;
43
44impl<E> HazardFilter<E> for NoFilter {
45    fn is_irrelevant(&self, _: HazKey, _: &E) -> bool {
46        false
47    }
48}
49
50/// Ignores inferior quality zones that meet an item's minimum quality.
51/// Holes and zones below the minimum keep blocking it.
52#[derive(Clone, Copy, Debug)]
53pub struct QualityZoneFilter {
54    pub min_quality: usize,
55}
56
57impl HazardFilter<BasicHazardEntity> for QualityZoneFilter {
58    fn is_irrelevant(&self, _: HazKey, entity: &BasicHazardEntity) -> bool {
59        matches!(
60            entity,
61            BasicHazardEntity::InferiorQualityZone { quality, .. } if *quality >= self.min_quality
62        )
63    }
64}