veloren_rtsim/data/
site.rs

1use crate::data::{ReportId, Reports};
2pub use common::rtsim::SiteId;
3use common::{
4    rtsim::{FactionId, NpcId},
5    store::Id,
6};
7use hashbrown::{HashMap, HashSet};
8use serde::{Deserialize, Serialize};
9use slotmap::HopSlotMap;
10use std::ops::{Deref, DerefMut};
11use vek::*;
12use world::site::Site as WorldSite;
13
14#[derive(Clone, Serialize, Deserialize)]
15pub struct Site {
16    pub uid: u64,
17    pub seed: u32,
18    pub wpos: Vec2<i32>,
19    pub faction: Option<FactionId>,
20
21    /// The [`crate::data::Report`]s that the site tracks (you can imagine them
22    /// being on a noticeboard or something).
23    pub known_reports: HashSet<ReportId>,
24
25    /// How many chunks this site is loaded in.
26    #[serde(skip)]
27    pub count_loaded_chunks: usize,
28
29    /// The site generated during initial worldgen that this site corresponds
30    /// to.
31    ///
32    /// Eventually, rtsim should replace initial worldgen's site system and this
33    /// will not be necessary.
34    ///
35    /// When setting up rtsim state, we try to 'link' these two definitions of a
36    /// site: but if initial worldgen has changed, this might not be
37    /// possible. We try to delete sites that no longer exist during setup, but
38    /// this is an inherent fallible process. If linking fails, we try to
39    /// delete the site in rtsim2 in order to avoid an 'orphaned' site.
40    /// (TODO: create new sites for new initial worldgen sites that come into
41    /// being too).
42    #[serde(skip_serializing, skip_deserializing)]
43    pub world_site: Option<Id<WorldSite>>,
44
45    // Note: there's currently no guarantee that site populations are non-intersecting
46    #[serde(skip_serializing, skip_deserializing)]
47    pub population: HashSet<NpcId>,
48
49    /// A list of the nearby sites where each elements is both further and
50    /// larger (currently based on number of plots) than the next.
51    /// Effectively, this is a list of nearby sites that might be deemed
52    /// 'important' to the current one
53    #[serde(skip_serializing, skip_deserializing)]
54    pub nearby_sites_by_size: Vec<SiteId>,
55}
56
57impl Site {
58    pub fn with_faction(mut self, faction: impl Into<Option<FactionId>>) -> Self {
59        self.faction = faction.into();
60        self
61    }
62
63    pub fn cleanup(&mut self, reports: &Reports) {
64        // Clear reports that have been forgotten
65        self.known_reports
66            .retain(|report| reports.contains_key(*report));
67        // TODO: Limit number of reports
68    }
69
70    pub fn is_loaded(&self) -> bool { self.count_loaded_chunks > 0 }
71}
72
73#[derive(Clone, Default, Serialize, Deserialize)]
74pub struct Sites {
75    pub uid_counter: u64,
76    pub sites: HopSlotMap<SiteId, Site>,
77
78    #[serde(skip_serializing, skip_deserializing)]
79    pub world_site_map: HashMap<Id<WorldSite>, SiteId>,
80}
81
82impl Sites {
83    pub fn create(&mut self, mut site: Site) -> SiteId {
84        let world_site = site.world_site;
85
86        site.uid = self.uid_counter;
87        self.uid_counter = self.uid_counter.wrapping_add(1);
88
89        let key = self.sites.insert(site);
90        if let Some(world_site) = world_site {
91            self.world_site_map.insert(world_site, key);
92        }
93        key
94    }
95}
96
97impl Deref for Sites {
98    type Target = HopSlotMap<SiteId, Site>;
99
100    fn deref(&self) -> &Self::Target { &self.sites }
101}
102
103impl DerefMut for Sites {
104    fn deref_mut(&mut self) -> &mut Self::Target { &mut self.sites }
105}