source2_demo/entity/
container.rs

1use crate::error::EntityError;
2use crate::Entity;
3
4/// Container for entities.
5pub struct Entities {
6    pub(crate) entities_vec: Vec<Entity>,
7}
8
9impl Default for Entities {
10    fn default() -> Self {
11        Entities {
12            entities_vec: vec![Entity::default(); 8192],
13        }
14    }
15}
16
17impl Entities {
18    /// Iterator over all entities.
19    /// # Examples
20    ///
21    /// ```
22    /// use source2_demo::prelude::*;
23    /// use source2_demo::proto::*;
24    ///
25    /// #[derive(Default)]
26    /// struct MyObs;
27    ///
28    /// impl Observer for MyObs {
29    ///     fn on_tick_start(&mut self, ctx: &Context) -> ObserverResult {
30    ///         let dire_heroes = ctx
31    ///             .entities()
32    ///             .iter()
33    ///             .filter(|&e| {
34    ///                 e.class().name().starts_with("CDOTA_Hero_Unit")
35    ///                     && try_property!(e, u32, "m_iTeamNum") == Some(3)
36    ///                     && try_property!(e, u32, "m_hReplicatingOtherHeroModel") == Some(u32::MAX)
37    ///             })
38    ///             .collect::<Vec<_>>();
39    ///         Ok(())
40    ///     }
41    /// }
42    /// ```
43    pub fn iter(&self) -> impl Iterator<Item = &Entity> {
44        self.entities_vec.iter().filter(|e| e.index != u32::MAX)
45    }
46
47    /// Returns [`Entity`] for given index.
48    pub fn get_by_index(&self, index: usize) -> Result<&Entity, EntityError> {
49        if let Some(e) = self.entities_vec.get(index) {
50            if e.index != u32::MAX {
51                return Ok(e);
52            }
53        }
54        Err(EntityError::IndexNotFound(index))
55    }
56
57    /// Returns [`Entity`] for given handle.
58    pub fn get_by_handle(&self, handle: usize) -> Result<&Entity, EntityError> {
59        self.get_by_index(handle & 0x3fff)
60            .map_err(|_| EntityError::HandleNotFound(handle))
61    }
62
63    /// Returns [`Entity`] for given class id.
64    pub fn get_by_class_id(&self, id: i32) -> Result<&Entity, EntityError> {
65        self.iter()
66            .find(|&entity| entity.class().id() == id)
67            .ok_or(EntityError::ClassIdNotFound(id))
68    }
69
70    /// Returns [`Entity`] for given class name.
71    pub fn get_by_class_name(&self, name: &str) -> Result<&Entity, EntityError> {
72        self.iter()
73            .find(|&entity| entity.class().name() == name)
74            .ok_or(EntityError::ClassNameNotFound(name.to_string()))
75    }
76}