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}