summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortroido <troido@protonmail.com>2020-04-06 16:01:00 +0200
committertroido <troido@protonmail.com>2020-04-06 16:01:00 +0200
commit66a3d3131f32e7bae2f0f7c4fd0b0c876eb3e8a0 (patch)
treeb6e7fe873be9c17b49596946543ee24f3771745d
parente8d3e3c4f69fc5bab2b32b16b7c8c2c4a8a89a4b (diff)
shortcut or defining some entities like crops
-rw-r--r--content/encyclopediae/default_encyclopedia.json137
-rw-r--r--src/assemblage.rs2
-rw-r--r--src/componentparameter.rs5
-rw-r--r--src/componentwrapper.rs10
-rw-r--r--src/encyclopedia.rs23
-rw-r--r--src/parameter.rs7
-rw-r--r--src/savestate.rs2
-rw-r--r--src/template.rs15
8 files changed, 152 insertions, 49 deletions
diff --git a/content/encyclopediae/default_encyclopedia.json b/content/encyclopediae/default_encyclopedia.json
index b7364d5..760779d 100644
--- a/content/encyclopediae/default_encyclopedia.json
+++ b/content/encyclopediae/default_encyclopedia.json
@@ -24,16 +24,16 @@
"components": [
["Visible", {
"sprite": ["random", [
- ["string", "grass1"],
- ["string", "grass2"],
- ["string", "grass3"],
- ["string", "grass1"],
- ["string", "grass2"],
- ["string", "grass3"],
- ["string", "ground"]
+ "grass1",
+ "grass2",
+ "grass3",
+ "grass1",
+ "grass2",
+ "grass3",
+ "ground"
]],
- "height": ["float", 0.1],
- "name": ["string", "grass"]
+ "height": 0.1,
+ "name": "grass"
}]
],
"flags": ["Floor", "Soil"]
@@ -42,12 +42,12 @@
"components": [
["Visible", {
"sprite": ["random", [
- ["string", "grass1"],
- ["string", "grass2"],
- ["string", "grass3"]
+ "grass1",
+ "grass2",
+ "grass3"
]],
- "height": ["float", 0.1],
- "name": ["string", "grass"]
+ "height": 0.1,
+ "name": "grass"
}]
],
"flags": ["Floor", "Soil"]
@@ -82,7 +82,7 @@
"builtwall": {
"arguments": [["health", "int", 100]],
"components": [
- ["Health", {"health": ["arg", "health"], "maxhealth": ["int", 100]}],
+ ["Health", {"health": ["arg", "health"], "maxhealth": 100}],
"Mortal"
],
"sprite": "wall",
@@ -91,7 +91,7 @@
"flags": ["Blocking"]
},
"spiketrap": {
- "components": [["Trap", {"damage": ["int", 8]}]],
+ "components": [["Trap", {"damage": 8}]],
"sprite": "spikes",
"height": 0.8
},
@@ -100,14 +100,14 @@
"sprite": "dummy",
"height": 1,
"components": [
- ["Health", {"health": ["arg", "health"], "maxhealth": ["int", 20]}],
+ ["Health", {"health": ["arg", "health"], "maxhealth": 20}],
"Mortal"
]
},
"wound": {
"sprite": "wound",
"height": 0.25,
- "components": [["Volatile", {"delay": ["int", 4]}]],
+ "components": [["Volatile", {"delay": 3}]],
"save": false
},
"rat": {
@@ -115,15 +115,15 @@
"height": 1,
"components": [
["MonsterAI", {
- "view_distance": ["int", 3],
- "move_chance": ["float", 0.08],
- "homesickness": ["float", 0.1]
+ "view_distance": 3,
+ "move_chance": 0.08,
+ "homesickness": 0.1
}],
- ["Health", {"health": ["int", 8], "maxhealth": ["int", 8]}],
- ["Fighter", {"damage": ["int", 2], "cooldown": ["int", 6]}],
- ["Movable", {"cooldown": ["int", 3]}],
+ ["Health", {"health": 8, "maxhealth": 8}],
+ ["Fighter", {"damage": 2, "cooldown": 6}],
+ ["Movable", {"cooldown": 3}],
"Mortal",
- ["Faction", {"faction": ["string", "evil"]}]
+ ["Faction", {"faction": "evil"}]
]
},
"spawner": {
@@ -141,9 +141,9 @@
"letter": {
"arguments": [["char", "string"]],
"components": [["Visible", {
- "name": ["concat", [["string", "letter_"], ["arg", "char"]]],
- "sprite": ["concat", [["string", "emptyletter-"], ["arg", "char"]]],
- "height": ["float", 1.0]
+ "name": ["concat", ["letter_", ["arg", "char"]]],
+ "sprite": ["concat", ["emptyletter-", ["arg", "char"]]],
+ "height": 1.0
}]]
},
"radishplant": {
@@ -169,7 +169,7 @@
"name": "seed",
"components": [
["Grow", {
- "delay": ["int", 600],
+ "delay": 600,
"target_time": ["arg", "target_time"],
"into": ["template", "radishseedling"]
}]
@@ -186,7 +186,7 @@
"name": "seedling",
"components": [
["Grow", {
- "delay": ["int", 600],
+ "delay": 600,
"target_time": ["arg", "target_time"],
"into": ["template", "radishplant"]
}]
@@ -234,9 +234,77 @@
"components": [
["Interactable", {"action": ["interaction", ["exchange", ["buy ", {
"pebble": [["radish", "radish"], ["pebble"]],
- "radishseed": [["radish"], ["radishseed", "radishseed"]]
+ "radishseed": [["radish"], ["radishseed", "radishseed"]],
+ "carrotseed": [["radish"], ["carrotseed"]]
}]]]}]
]
+ },
+ "plantedseed": {
+ "arguments": [["target_time", "int", 0], ["next", "template"], ["delay", "int"]],
+ "sprite": "seed",
+ "height": 0.05,
+ "name": "plantedseed",
+ "components": [
+ ["Grow", {
+ "delay": ["arg", "delay"],
+ "target_time": ["arg", "target_time"],
+ "into": ["arg", "next"]
+ }]
+ ],
+ "extract": {
+ "target_time": ["Grow", "target_time"]
+ },
+ "flags": ["Occupied"]
+ },
+ "seedling": {
+ "arguments": [["target_time", "int", 0], ["next", "template"], ["delay", "int"]],
+ "sprite": "seed",
+ "height": 0.09,
+ "name": "seedling",
+ "components": [
+ ["Grow", {
+ "delay": ["arg", "delay"],
+ "target_time": ["arg", "target_time"],
+ "into": ["arg", "next"]
+ }]
+ ],
+ "extract": {
+ "target_time": ["Grow", "target_time"]
+ },
+ "flags": ["Occupied"]
+ },
+ "youngplant": {
+ "arguments": [["target_time", "int", 0], ["next", "template"], ["crop", "string"], ["delay", "int"]],
+ "components": [
+ ["Grow", {
+ "delay": ["arg", "delay"],
+ "target_time": ["arg", "target_time"],
+ "into": ["arg", "next"]
+ }],
+ ["Visible", {
+ "name": ["concat", [["string", "young"], ["arg", "crop"], ["string", "plant"]]],
+ "sprite": "youngplant",
+ "height": 0.8
+ }]
+ ],
+ "extract": {
+ "target_time": ["Grow", "target_time"]
+ },
+ "flags": ["Occupied"]
+ },
+ "carrotplant": {
+ "sprite": "smallplant",
+ "name": "carrotplant",
+ "height": 1.0,
+ "components": [
+ ["Interactable", {"action": ["interaction", "harvest"]}],
+ "Mortal",
+ ["Loot", {"loot": ["list", [
+ ["list", [{"type": "carrotseed"}, 1.0]],
+ ["list", [{"type": "carrot"}, 1.0]]
+ ]]}]
+ ],
+ "flags": ["Occupied"]
}
},
"items": {
@@ -244,9 +312,16 @@
"stone": {"action": ["build", ["builtwall", ["Floor"], ["Blocking"]]]},
"radishseed": {"sprite": "seed", "action": ["build", ["plantedradishseed", ["Floor", "Soil"], ["Occupied", "Blocking"]]]},
"radish": {"sprite": "food", "action": ["eat", 3]},
+ "carrotseed": {"sprite": "seed", "action": ["build", ["plantedcarrotseed", ["Floor", "Soil"], ["Occupied", "Blocking"]]]},
+ "carrot": {"sprite": "food", "action": ["eat", 5]},
"sword": {"action": ["equip", {
"slot": "hand",
"stats": {"strength": 50}
}]}
+ },
+ "templates":{
+ "plantedcarrotseed": ["plantedseed", {"delay": 60, "next": "carrotseedling"}],
+ "carrotseedling": ["seedling", {"delay": 60, "next": "youngcarrotplant"}],
+ "youngcarrotplant": ["youngplant", {"crop": "carrot", "delay": 60, "next": "carrotplant"}]
}
}
diff --git a/src/assemblage.rs b/src/assemblage.rs
index 8f36556..e453471 100644
--- a/src/assemblage.rs
+++ b/src/assemblage.rs
@@ -142,7 +142,7 @@ impl Assemblage {
pub fn validate(&self) -> Result<()> {
for (comptype, parameters) in &self.components {
for (paramname, paramtype) in comptype.parameters() {
- let param = parameters.get(paramname).ok_or(aerr!("missing parameter"))?;
+ let param = parameters.get(paramname).ok_or(aerr!("missing parameter {} in {:?}", paramname, self))?;
let actualtype = param.get_type(&self.arguments)?;
if actualtype != paramtype {
return Err(aerr!("parameter type incorrect"));
diff --git a/src/componentparameter.rs b/src/componentparameter.rs
index 73c7b30..47c9a26 100644
--- a/src/componentparameter.rs
+++ b/src/componentparameter.rs
@@ -63,6 +63,9 @@ impl ComponentParameter {
}
pub fn from_json(value: &Value) -> PResult<Self> {
+ if !value.is_array() {
+ return Ok(Self::Constant(Parameter::guess_from_json(value).ok_or(perr!("invalid component parameter {:?}", value))?));
+ }
let paramvalue = value.get(1).ok_or(perr!("index 1 not in component parameter"))?;
let typename = value.get(0).ok_or(perr!("index 0 not in component parameter"))?.as_str().ok_or(perr!("compparam type not a string"))?;
if let Some(paramtype) = ParameterType::from_str(typename) {
@@ -101,7 +104,7 @@ impl ComponentParameter {
pub fn get_type(&self, arguments: &[(String, ParameterType, Option<Parameter>)]) -> Result<ParameterType>{
Ok(match self {
Self::Constant(param) => param.paramtype(),
- Self::Argument(argname) => arguments.iter().find(|(n, _t, _d)| n == argname).ok_or(aerr!("unknown argument name"))?.1,
+ Self::Argument(argname) => arguments.iter().find(|(n, _t, _d)| n == argname).ok_or(aerr!("unknown argument name {} in {:?}", argname, arguments))?.1,
Self::Random(options) => {
let typ: ParameterType = options.get(0).ok_or(aerr!("random has no options"))?.get_type(arguments)?;
for param in options {
diff --git a/src/componentwrapper.rs b/src/componentwrapper.rs
index d00b592..4b9401a 100644
--- a/src/componentwrapper.rs
+++ b/src/componentwrapper.rs
@@ -189,18 +189,18 @@ components!(
loot
.iter()
.map(|param| {match param {
- Parameter::Template(template) => Some((template.clone(), 1.0)),
+ Parameter::Template(template) => Ok((template.clone(), 1.0)),
Parameter::List(l) => {
if l.len() == 2 {
if let (Parameter::Template(template), Parameter::Float(chance)) = (l[0].clone(), l[1].clone()) {
- return Some((template.clone(), chance))
+ return Ok((template.clone(), chance))
}
}
- None?
+ Err(aerr!("loot list elements as list must only contain a template and a float: {:?}", l))?
},
- _ => None?
+ _ => Err(aerr!("loot list elements must be a template or a list: {:?}", param))?
}})
- .collect::<Option<Vec<(Template, f64)>>>().ok_or(aerr!("invalid loot definition"))?
+ .collect::<Result<Vec<(Template, f64)>>>()?
}
};
Grow (
diff --git a/src/encyclopedia.rs b/src/encyclopedia.rs
index c378b84..d396e0f 100644
--- a/src/encyclopedia.rs
+++ b/src/encyclopedia.rs
@@ -12,7 +12,8 @@ use crate::{
item::Item,
item::ItemAction,
PResult,
- perr
+ perr,
+ parameter::Parameter
};
#[derive(Default, Clone)]
@@ -79,6 +80,26 @@ impl Encyclopedia {
Ok((id, item))
})
.collect::<PResult<HashMap<ItemId, Item>>>()?;
+ for (name, v) in
+ val
+ .get("templates")
+ .unwrap_or(&json!({}))
+ .as_object().ok_or(perr!("templates not a json dict: {:?}", val.get("templates")))?
+ .iter() {
+ let enttype = EntityType(v
+ .get(0).ok_or(perr!("index 0 not in subtitution template"))?
+ .as_str().ok_or(perr!("subtitution origin name not a string"))?
+ .to_string());
+ let values = v.get(1).ok_or(perr!("index 0 not in subtitution template"))?;
+ let mut assemblage = assemblages.get(&enttype).ok_or(perr!("template name '{:?}' points not an assemblage", enttype))?.clone();
+ for arg in assemblage.arguments.iter_mut() {
+ if let Some(x) = values.get(&arg.0) {
+ let param = Parameter::from_typed_json(arg.1, x).ok_or(perr!("subtitution parameter has wrong type"))?;
+ arg.2 = Some(param);
+ }
+ }
+ assemblages.insert(EntityType(name.to_string()), assemblage);
+ }
Ok(Encyclopedia{
assemblages,
diff --git a/src/parameter.rs b/src/parameter.rs
index a7419ed..196f5fe 100644
--- a/src/parameter.rs
+++ b/src/parameter.rs
@@ -70,15 +70,15 @@ parameters!(
Template (Template) template, v (Template::from_json(v).ok()?) (v.to_json());
Interaction (Interactable) interaction, _v (Interactable::from_json(_v)?) (panic!("interactions can't be serialized"));
Bool (bool) bool, v (v.as_bool()?) (json!(v));
- List (Vec<Parameter>) list, _v
+ List (Vec<Parameter>) list, v
({
- _v
+ v
.as_array()?
.iter()
.map(|item| Parameter::guess_from_json(item))
.collect::<Option<Vec<Parameter>>>()?
})
- (panic!("can not serialise parameter list"));
+ (json!(["list", v.iter().map(Parameter::to_json).collect::<Vec<Value>>()]));
);
@@ -108,7 +108,6 @@ impl Parameter {
} else if val.is_object(){
ParameterType::Template
} else {
- println!("{:?}", val);
return None
};
Self::from_typed_json(typ, val)
diff --git a/src/savestate.rs b/src/savestate.rs
index 4482fca..c3b79cb 100644
--- a/src/savestate.rs
+++ b/src/savestate.rs
@@ -4,8 +4,6 @@ use serde_json::{json, Value};
use crate::{
Pos,
Template,
- Result,
- aerr,
PResult,
perr
};
diff --git a/src/template.rs b/src/template.rs
index c2f905f..850a323 100644
--- a/src/template.rs
+++ b/src/template.rs
@@ -49,10 +49,17 @@ impl Template {
self
}
- pub fn from_json(val: &Value) -> PResult<Template> {
- if val.is_string(){
- return Ok(Self::empty(val.as_str().unwrap()));
- }
+ pub fn from_json(v: &Value) -> PResult<Template> {
+ let val = match v {
+ Value::String(s) => json!({"type": s}),
+ Value::Array(_) => json!({
+ "type": v.get(0).ok_or(perr!("index 0 not in template array {:?}", v))?,
+ "kwargs": v.get(1).ok_or(perr!("index 1 not in template array {:?}", v))?
+ }),
+ Value::Object(_) => v.clone(),
+ _ => Err(perr!("invalid template {:?}", v))?
+ };
+
let name = EntityType(val.get("type").ok_or(perr!("template doesn't have 'type'"))?.as_str().ok_or(perr!("template type not a string"))?.to_string());
let mut args = Vec::new();
for arg in val.get("args").unwrap_or(&json!([])).as_array().ok_or(perr!("template args not an array"))? {