veloren_rtsim/data/
mod.rs1pub mod airship;
2pub mod faction;
3pub mod nature;
4pub mod npc;
5pub mod report;
6pub mod sentiment;
7pub mod site;
8
9pub use self::{
10 faction::{Faction, FactionId, Factions},
11 nature::Nature,
12 npc::{Npc, NpcId, Npcs},
13 report::{Report, ReportId, ReportKind, Reports},
14 sentiment::{Sentiment, Sentiments},
15 site::{Site, SiteId, Sites},
16};
17use airship::AirshipSim;
18use common::resources::TimeOfDay;
19use enum_map::{EnumArray, EnumMap, enum_map};
20use serde::{Deserialize, Serialize, de, ser};
21use std::{
22 cmp::PartialEq,
23 fmt,
24 io::{Read, Write},
25 marker::PhantomData,
26};
27
28pub const CURRENT_VERSION: u32 = 8;
34
35#[derive(Clone, Serialize, Deserialize)]
36pub struct Data {
37 #[serde(default)]
39 pub version: u32,
40
41 pub nature: Nature,
42 #[serde(default)]
43 pub npcs: Npcs,
44 #[serde(default)]
45 pub sites: Sites,
46 #[serde(default)]
47 pub factions: Factions,
48 #[serde(default)]
49 pub reports: Reports,
50
51 #[serde(default)]
52 pub tick: u64,
53 #[serde(default)]
54 pub time_of_day: TimeOfDay,
55
56 #[serde(default)]
58 pub should_purge: bool,
59
60 #[serde(skip)]
61 pub airship_sim: AirshipSim,
62}
63
64pub enum ReadError {
65 Load(rmp_serde::decode::Error),
66 VersionMismatch(Box<Data>),
68}
69
70impl fmt::Debug for ReadError {
71 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72 match self {
73 Self::Load(err) => err.fmt(f),
74 Self::VersionMismatch(_) => write!(f, "VersionMismatch"),
75 }
76 }
77}
78
79pub type WriteError = rmp_serde::encode::Error;
80
81impl Data {
82 pub fn spawn_npc(&mut self, npc: Npc) -> NpcId {
83 let home = npc.home;
84 let id = self.npcs.create_npc(npc);
85 if let Some(home) = home.and_then(|home| self.sites.get_mut(home)) {
86 home.population.insert(id);
87 }
88 id
89 }
90
91 pub fn from_reader<R: Read>(reader: R) -> Result<Box<Self>, ReadError> {
92 rmp_serde::decode::from_read(reader)
93 .map_err(ReadError::Load)
94 .and_then(|data: Data| {
95 if data.version == CURRENT_VERSION {
96 Ok(Box::new(data))
97 } else {
98 Err(ReadError::VersionMismatch(Box::new(data)))
99 }
100 })
101 }
102
103 pub fn write_to<W: Write>(&self, mut writer: W) -> Result<(), WriteError> {
104 rmp_serde::encode::write_named(&mut writer, self)
105 }
106}
107
108fn rugged_ser_enum_map<
109 K: EnumArray<V> + Serialize,
110 V: From<i16> + PartialEq + Serialize,
111 S: ser::Serializer,
112 const DEFAULT: i16,
113>(
114 map: &EnumMap<K, V>,
115 ser: S,
116) -> Result<S::Ok, S::Error> {
117 ser.collect_map(map.iter().filter(|(_, v)| v != &&V::from(DEFAULT)))
118}
119
120fn rugged_de_enum_map<
121 'a,
122 K: EnumArray<V> + EnumArray<Option<V>> + Deserialize<'a>,
123 V: From<i16> + Deserialize<'a>,
124 D: de::Deserializer<'a>,
125 const DEFAULT: i16,
126>(
127 de: D,
128) -> Result<EnumMap<K, V>, D::Error> {
129 struct Visitor<K, V, const DEFAULT: i16>(PhantomData<(K, V)>);
130
131 impl<'de, K, V, const DEFAULT: i16> de::Visitor<'de> for Visitor<K, V, DEFAULT>
132 where
133 K: EnumArray<V> + EnumArray<Option<V>> + Deserialize<'de>,
134 V: From<i16> + Deserialize<'de>,
135 {
136 type Value = EnumMap<K, V>;
137
138 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
139 write!(formatter, "a map")
140 }
141
142 fn visit_map<M: de::MapAccess<'de>>(self, mut access: M) -> Result<Self::Value, M::Error> {
143 let mut entries = EnumMap::default();
144 while let Some((key, value)) = access.next_entry()? {
145 entries[key] = Some(value);
146 }
147 Ok(enum_map! { key => entries[key].take().unwrap_or_else(|| V::from(DEFAULT)) })
148 }
149 }
150
151 de.deserialize_map(Visitor::<_, _, DEFAULT>(PhantomData))
152}