veloren_world/site/economy/
cache.rs

1use super::{
2    good_list,
3    map_types::{GoodIndex, GoodMap},
4};
5use crate::{
6    assets::{self, AssetExt},
7    util::DHashMap,
8};
9use common::{
10    terrain::BiomeKind,
11    trade::Good::{self, Terrain, Territory},
12};
13use lazy_static::lazy_static;
14use serde::{Deserialize, Serialize};
15
16const fn default_one() -> f32 { 1.0 }
17const fn default_true() -> bool { true }
18
19#[derive(Debug, Serialize, Deserialize, Clone)]
20struct RawGoodProperties {
21    #[serde(default)]
22    pub decay_rate: f32,
23    #[serde(default = "default_one")]
24    pub transport_effort: f32,
25    #[serde(default = "default_true")]
26    pub storable: bool,
27}
28
29#[derive(Debug, Deserialize)]
30#[serde(transparent)]
31pub struct RawGoodPropertiesList(DHashMap<Good, RawGoodProperties>);
32
33impl assets::Asset for RawGoodPropertiesList {
34    type Loader = assets::RonLoader;
35
36    const EXTENSION: &'static str = "ron";
37}
38
39/// Contains caches used for economic simulation
40pub struct EconomyCache {
41    pub(crate) transport_effort: GoodMap<f32>,
42    pub(crate) decay_rate: GoodMap<f32>,
43    pub(crate) direct_use_goods: Vec<GoodIndex>,
44}
45
46lazy_static! {
47    static ref CACHE: EconomyCache = load_cache();
48}
49
50pub fn cache() -> &'static EconomyCache { &CACHE }
51
52fn load_cache() -> EconomyCache {
53    let good_properties = RawGoodPropertiesList::load_expect("common.economy.trading_goods")
54        .read()
55        .0
56        .clone();
57    let mut decay_rate: GoodMap<f32> = GoodMap::from_default(0.0);
58    let mut transport_effort: GoodMap<f32> = GoodMap::from_default(1.0);
59    let mut direct_use_goods: Vec<GoodIndex> = Vec::new();
60
61    for i in good_properties.iter() {
62        if let Ok(rawgood) = (*i.0).try_into() {
63            decay_rate[rawgood] = i.1.decay_rate;
64            if !i.1.storable {
65                direct_use_goods.push(rawgood);
66            }
67            transport_effort[rawgood] = i.1.transport_effort;
68        } else {
69            match *i.0 {
70                Territory(BiomeKind::Void) => {
71                    for j in good_list() {
72                        if let Territory(_) = Good::from(j) {
73                            decay_rate[j] = i.1.decay_rate;
74                            transport_effort[j] = i.1.transport_effort;
75                            if !i.1.storable {
76                                direct_use_goods.push(j);
77                            }
78                        }
79                    }
80                },
81                Terrain(BiomeKind::Void) => {
82                    for j in good_list() {
83                        if let Terrain(_) = Good::from(j) {
84                            decay_rate[j] = i.1.decay_rate;
85                            transport_effort[j] = i.1.transport_effort;
86                            if !i.1.storable {
87                                direct_use_goods.push(j);
88                            }
89                        }
90                    }
91                },
92                _ => tracing::warn!("Raw good not in index: {:?}", i.0),
93            }
94        }
95    }
96
97    EconomyCache {
98        transport_effort,
99        decay_rate,
100        direct_use_goods,
101    }
102}