1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
use std::collections::HashMap;
use serde_json::{Value, json};
use crate::{
assemblage::Assemblage,
componentwrapper::PreEntity,
Template,
template::EntityType,
Result,
aerr,
ItemId,
item::Item,
item::ItemAction,
PResult,
perr
};
#[derive(Default, Clone)]
pub struct Encyclopedia {
assemblages: HashMap<EntityType, Assemblage>,
items: HashMap<ItemId, Item>
}
impl Encyclopedia {
pub fn from_json(val: Value) -> PResult<Encyclopedia> {
let mut assemblages =
val
.get("assemblages")
.ok_or(perr!("no assemblages in encyclopedia json"))?
.as_object()
.ok_or(perr!("encyclopedia assemblages not a json object"))?
.into_iter()
.map(|(k, v)| Ok((EntityType(k.clone()), Assemblage::from_json(v)?)))
.collect::<PResult<HashMap<EntityType, Assemblage>>>()?;
let items =
val
.get("items")
.ok_or(perr!("no items in encyclopedia json"))?
.as_object()
.ok_or(perr!("encyclopedia items not a json object"))?
.into_iter()
.map(|(k, v)| {
let id = ItemId(k.clone());
let sprite =
if let Some(sprite) = v.get("sprite") {
sprite.as_str().ok_or(perr!("item sprite not a string: {:?}", v))?
} else {
k
};
let name =
if let Some(name) = v.get("name") {
name.as_str().ok_or(perr!("item name not a string: {:?}", v))?.to_string()
} else {
k.to_string()
};
let item = Item {
name: name.clone(),
ent:
if let Some(ent) = v.get("entity") {
Template::from_json(ent)?
} else {
let enttyp = EntityType(k.clone());
assemblages.insert(enttyp.clone(), Assemblage::from_json(&json!({
"height": 0.3,
"sprite": sprite,
"name": name,
"item": k
}))?);
Template::from_entity_type(enttyp)
},
action:
if let Some(action) = v.get("action") {
ItemAction::from_json(action).ok_or(perr!("failed to parse ItemAction: {:?}", v))?
} else {
ItemAction::None
}
};
Ok((id, item))
})
.collect::<PResult<HashMap<ItemId, Item>>>()?;
Ok(Encyclopedia{
assemblages,
items
})
}
pub fn validate(&self) -> Result<()> {
for assemblage in self.assemblages.values() {
assemblage.validate()?;
}
Ok(())
}
pub fn construct(&self, template: &Template) -> Result<PreEntity> {
let assemblage = self.assemblages
.get(&template.name)
.ok_or(aerr!("unknown assemblage name: '{:?}' in {:?}", template.name, template))?;
assemblage.instantiate(template)
}
pub fn get_item(&self, id: &ItemId) -> Option<Item> {
self.items.get(id).map(|item| item.clone())
}
}
|