summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortroido <troido@protonmail.com>2020-05-12 21:51:37 +0200
committertroido <troido@protonmail.com>2020-05-12 21:51:37 +0200
commit1b380b31f50035f10f651e220effe8a2970c0fd5 (patch)
tree5a25b839a4ee70ba96f7f096161ea59c08842492
parent6c5b15758fbceef7987b40ee50a71ddc9624372d (diff)
removed 'substitute' part of encyclopedia
-rw-r--r--content/encyclopediae/default_encyclopedia.json7
-rw-r--r--content/maps/room.json17
-rw-r--r--src/assemblage.rs5
-rw-r--r--src/components/mod.rs12
-rw-r--r--src/componentwrapper.rs6
-rw-r--r--src/encyclopedia.rs70
-rw-r--r--src/parameter.rs2
-rw-r--r--src/playerstate.rs5
-rw-r--r--src/room.rs10
-rw-r--r--src/systems/mod.rs6
-rw-r--r--src/systems/replace.rs46
-rw-r--r--src/systems/spawntrigger.rs34
-rw-r--r--src/template.rs14
-rw-r--r--todo.md2
14 files changed, 148 insertions, 88 deletions
diff --git a/content/encyclopediae/default_encyclopedia.json b/content/encyclopediae/default_encyclopedia.json
index 204b104..2571997 100644
--- a/content/encyclopediae/default_encyclopedia.json
+++ b/content/encyclopediae/default_encyclopedia.json
@@ -424,6 +424,9 @@
["list", [{"type": "stone"}, 1.0]]
]]}]
]
+ },
+ "radishes": {
+ "substitute": "radish"
}
},
"items": {
@@ -431,6 +434,7 @@
"stone": {"action": ["build", ["builtwall", ["Floor"], ["Blocking"]]]},
"radishseed": {"sprite": "seed", "action": ["build", ["plantedradishseed", ["Floor", "Soil"], ["Occupied", "Blocking"]]]},
"radish": {"sprite": "food", "action": ["eat", 3]},
+ "radishes": {"sprite": "food", "name": "radish", "entity": "radish", "action": ["eat", 3]},
"eldritch_radish": {"sprite": "food", "name": "eldritch_radish", "action": ["eat", 20]},
"carrotseed": {"sprite": "seed", "action": ["build", ["plantedcarrotseed", ["Floor", "Soil"], ["Occupied", "Blocking"]]]},
"carrot": {"sprite": "food", "action": ["eat", 5]},
@@ -466,8 +470,5 @@
"plantedcarrotseed": ["plantedseed", {"delay": 60, "next": "carrotseedling"}],
"carrotseedling": ["seedling", {"delay": 60, "next": "youngcarrotplant"}],
"youngcarrotplant": ["youngplant", {"crop": "carrot", "delay": 60, "next": "carrotplant"}]
- },
- "substitute": {
- "radishes": "radish"
}
}
diff --git a/content/maps/room.json b/content/maps/room.json
index 853e7a3..f89b46a 100644
--- a/content/maps/room.json
+++ b/content/maps/room.json
@@ -16,14 +16,14 @@
" X,^,,,.,,,,,,,,,,,,~~~,,,,,T,,,,######,,,X",
" X,^,,,.,,,,,,,,,,,,bbb,,,,,,,,,,#++++#,,,X",
" X,,,t..............bbb..........D++++#,,,X",
- " X,**,,.,,,,,,,,,,,,bbb,,,,,,,,,,#++++#,,,X",
- " X,*,*,.,u,,,V,,V,,,~~~,,,T,,,T,,#++++#,,,X",
- " X,,*,,.,,,,,,,,,,,,~~~,,,,,,,,,,######,,,X",
- " X,oo,,.,s,d,,,,,,,~~~~,,,,,,,,,,f,,,,f,,,X",
- " X,,*,,.,,,,,,,,,,,~~~''''''''''''''''f'''X",
- " X*,,,,.,,,d,VVV,,,~~~'''''''''''f''''f'''X",
- "1.......,,,,,VVV,,,~~~'''''''''''ffffff'''X",
- " X/,,,,.,P,Q,VVV,,,~~~''''''''''''''''''''X",
+ " X,,,,,.,,,,,,,,,,,,bbb,,,,,,,,,,#++++#,,,X",
+ " X,,,,,.,,,,,,,,,,,,~~~,,,T,,,T,,#++++#,,,X",
+ " X,,,,,.,,,,,,,,,,,,~~~,,,,,,,,,,######,,,X",
+ " X,,,,,.,s,d,,,,,,,~~~~,,,,,,,,,,f,,,,f,,,X",
+ " X,,,,,.,,,,,,,,,,,~~~''''''''''''''''f'''X",
+ " X,,,,,.,,,d,,,,,,,~~~'''''''''''f''''f'''X",
+ "1.......,,,,,,,,,,,~~~'''''''''''ffffff'''X",
+ " X,,,,,.,,,Q,,,,,,,~~~''''''''''''''''''''X",
" XXXXX,.,XXXXXXXXXX~~~XXXXXXXXXXXXXXXXXXXXX",
" %%% "
],
@@ -52,6 +52,7 @@
"u": ["ground", "dude"],
"t": ["ground", "trader"],
"P": ["ground", "pickaxe"],
+ "u": ["ground", "radishes"],
"Q": "quarry",
" ": []
}
diff --git a/src/assemblage.rs b/src/assemblage.rs
index 2ef62f0..96e44e9 100644
--- a/src/assemblage.rs
+++ b/src/assemblage.rs
@@ -58,7 +58,7 @@ impl Assemblage {
.as_str().ok_or(perr!("component name not a string"))?;
let comptype = ComponentType::from_str(name).ok_or(perr!("{} not a valid componenttype", name))?;
let mut parameters: HashMap<String, ComponentParameter> = HashMap::new();
- for (key, value) in tup.get(1).ok_or(perr!("index 1 not in component"))?.as_object().ok_or(perr!("component parameters not a json object"))? {
+ for (key, value) in tup.get(1).ok_or(perr!("index 1 not in component"))?.as_object().ok_or(perr!("component parameters not a json object: {:?}", tup.get(1)))? {
let param = ComponentParameter::from_json(value)?;
parameters.insert(key.clone(), param);
}
@@ -100,6 +100,9 @@ impl Assemblage {
}]));
}
+ if let Some(substitute) = val.get("substitute") {
+ components.push(json!(["Substitute", {"into": ["template", substitute]}]));
+ }
Ok(components)
}
diff --git a/src/components/mod.rs b/src/components/mod.rs
index 394284a..ee5176e 100644
--- a/src/components/mod.rs
+++ b/src/components/mod.rs
@@ -253,3 +253,15 @@ pub struct Minable {
pub total: i64,
pub trigger: Trigger
}
+
+#[derive(Component, Debug, Clone)]
+pub struct OnSpawn {
+ pub trigger: Trigger
+}
+
+
+#[derive(Component, Debug, Clone)]
+pub struct Substitute {
+ pub into: Template
+}
+
diff --git a/src/componentwrapper.rs b/src/componentwrapper.rs
index 392c0dc..ee2f22f 100644
--- a/src/componentwrapper.rs
+++ b/src/componentwrapper.rs
@@ -293,6 +293,12 @@ components!(all:
};
Removed;
LootHolder () {panic!("LootHolder from parameters not implemented")};
+ OnSpawn (trigger: String) {
+ OnSpawn {
+ trigger: Trigger::from_str(&trigger).ok_or(aerr!("invalid trigger name {}", trigger))?
+ }
+ };
+ Substitute (into: Template);
);
diff --git a/src/encyclopedia.rs b/src/encyclopedia.rs
index ba9ad94..54fa82b 100644
--- a/src/encyclopedia.rs
+++ b/src/encyclopedia.rs
@@ -19,9 +19,7 @@ use crate::{
#[derive(Default, Clone)]
pub struct Encyclopedia {
assemblages: HashMap<EntityType, Assemblage>,
- items: HashMap<ItemId, Item>,
- assemblage_substitute: HashMap<EntityType, EntityType>,
- item_substitute: HashMap<ItemId, ItemId>,
+ items: HashMap<ItemId, Item>
}
impl Encyclopedia {
@@ -93,7 +91,7 @@ impl Encyclopedia {
.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();
+ let mut assemblage = assemblages.get(&enttype).ok_or(perr!("template name '{:?}' does not point to 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"))?;
@@ -103,51 +101,11 @@ impl Encyclopedia {
assemblages.insert(EntityType(name.to_string()), assemblage);
}
- let assemblage_substitute = val
- .get("assemblage_substitute")
- .unwrap_or(&json!({}))
- .as_object().ok_or(perr!("assemblage_subtitute not a json dict"))?
- .iter()
- .chain(
- val
- .get("substitute")
- .unwrap_or(&json!({}))
- .as_object().ok_or(perr!("substitute not a json dict"))?
- .iter()
- )
- .map(|(from, into)| {
- Ok((
- EntityType(from.to_string()),
- EntityType(into.as_str().ok_or(perr!("substitution value not a string: {:?}", into))?.to_string())
- ))
- })
- .collect::<PResult<HashMap<EntityType, EntityType>>>()?;
-
- let item_substitute = val
- .get("item_substitute")
- .unwrap_or(&json!({}))
- .as_object().ok_or(perr!("item_subtitute not a json dict"))?
- .iter()
- .chain(
- val
- .get("substitute")
- .unwrap_or(&json!({}))
- .as_object().ok_or(perr!("substitute not a json dict"))?
- .iter()
- )
- .map(|(from, into)| {
- Ok((
- ItemId(from.to_string()),
- ItemId(into.as_str().ok_or(perr!("substitution value not a string: {:?}", into))?.to_string())
- ))
- })
- .collect::<PResult<HashMap<ItemId, ItemId>>>()?;
Ok(Encyclopedia{
assemblages,
- items,
- assemblage_substitute,
- item_substitute
+ items
})
+
}
pub fn validate(&self) -> Result<()> {
@@ -158,11 +116,6 @@ impl Encyclopedia {
}
pub fn construct(&self, template: &Template) -> Result<PreEntity> {
- if let Some(new_name) = self.assemblage_substitute.get(&template.name){
- let mut into = template.clone();
- into.name = new_name.clone();
- return self.construct(&into);
- }
let assemblage = self.assemblages
.get(&template.name)
.ok_or(aerr!("unknown assemblage name: '{:?}' in {:?}", template.name, template))?;
@@ -170,20 +123,7 @@ impl Encyclopedia {
}
pub fn get_item(&self, id: &ItemId) -> Option<Item> {
- let actual_id = if let Some(into) = self.item_substitute.get(id) {
- into
- } else {
- id
- };
- self.items.get(actual_id).map(|item| item.clone())
- }
-
- pub fn substitute_item(&self, id: &ItemId) -> ItemId {
- if let Some(into) = self.item_substitute.get(id) {
- into.clone()
- } else {
- id.clone()
- }
+ self.items.get(id).map(|item| item.clone())
}
}
diff --git a/src/parameter.rs b/src/parameter.rs
index 196f5fe..01a7f40 100644
--- a/src/parameter.rs
+++ b/src/parameter.rs
@@ -67,7 +67,7 @@ parameters!(
Int (i64) int, v (v.as_i64()?) (json!(v));
Pos (Pos) pos, v (Pos::from_json(v)?) (json!(v));
Float (f64) float, v (v.as_f64()?) (json!(v));
- Template (Template) template, v (Template::from_json(v).ok()?) (v.to_json());
+ Template (Template) template, v (Template::from_json(v).ok()?) (json!(["template", 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
diff --git a/src/playerstate.rs b/src/playerstate.rs
index 778fc7f..f9f6a4e 100644
--- a/src/playerstate.rs
+++ b/src/playerstate.rs
@@ -164,9 +164,8 @@ impl PlayerState {
ComponentWrapper::Player(Player::new(self.id.clone())),
ComponentWrapper::Inventory(Inventory{
items: self.inventory.iter().map( |(itemid, is_equipped)| {
- let id = encyclopedia.substitute_item(itemid);
- let item = encyclopedia.get_item(&id).ok_or(aerr!("failed to load item '{:?} in inventory of player {:?}", itemid, self))?;
- Ok(InventoryEntry{itemid: id, item, is_equipped: *is_equipped})
+ let item = encyclopedia.get_item(&itemid).ok_or(aerr!("failed to load item '{:?} in inventory of player {:?}", itemid, self))?;
+ Ok(InventoryEntry{itemid: itemid.clone(), item, is_equipped: *is_equipped})
}).collect::<Result<Vec<InventoryEntry>>>()?,
capacity: self.inventory_capacity
}),
diff --git a/src/room.rs b/src/room.rs
index 9583a93..d0f22df 100644
--- a/src/room.rs
+++ b/src/room.rs
@@ -67,13 +67,16 @@ use crate::{
Timeout,
Clear,
Building,
- Deduplicate
+ Deduplicate,
+ SpawnTrigger,
+ Replace
}
};
pub fn default_dispatcher<'a, 'b>() -> Dispatcher<'a, 'b> {
DispatcherBuilder::new()
.with(Deduplicate, "deduplicate", &[])
+ .with(Replace, "replace", &[])
.with(Timeout, "timeout", &[])
.with(UpdateCooldowns, "cool_down", &[])
.with(Spawn, "spawn", &[])
@@ -82,11 +85,12 @@ pub fn default_dispatcher<'a, 'b>() -> Dispatcher<'a, 'b> {
.with(Take, "take", &["controlinput", "controlai"])
.with(Use, "use", &["controlinput", "controlai"])
.with(Interact, "interact", &["controlinput", "controlai"])
+ .with(SpawnTrigger, "spawntrigger", &["spawn", "deduplicate", "replace"])
.with(Move, "move", &["controlinput", "controlai"])
.with(Trapping, "trapping", &["move"])
.with(Fight, "fight", &["move"])
.with(Heal, "heal", &[])
- .with(Attacking, "attacking", &["use", "trapping", "fight", "heal", "interact"])
+ .with(Attacking, "attacking", &["use", "trapping", "fight", "heal", "interact", "spawntrigger"])
.with(Die, "die", &["attacking"])
.with(DropLoot, "droploot", &["attacking"])
.with(Building, "building", &["attacking"])
@@ -120,7 +124,7 @@ impl <'a, 'b>Room<'a, 'b> {
world.insert(NewEntities::new(encyclopedia));
register_insert!(
world,
- (Position, Visible, Controller, Movable, New, Removed, Moved, Player, Inventory, Health, Serialise, RoomExit, Entered, TriggerBox, Trap, Fighter, Healing, ControlCooldown, Autofight, MonsterAI, Home, AttackInbox, Item, Spawner, Clan, Faction, Interactable, Loot, Timer, Equipment, TimeOffset, Flags, Ear, Build, Whitelist, Dedup, Minable, LootHolder),
+ (Position, Visible, Controller, Movable, New, Removed, Moved, Player, Inventory, Health, Serialise, RoomExit, Entered, TriggerBox, Trap, Fighter, Healing, ControlCooldown, Autofight, MonsterAI, Home, AttackInbox, Item, Spawner, Clan, Faction, Interactable, Loot, Timer, Equipment, TimeOffset, Flags, Ear, Build, Whitelist, Dedup, Minable, LootHolder, OnSpawn, Substitute),
(Ground, Input, Output, Size, Spawn, Players, Emigration, Time)
);
diff --git a/src/systems/mod.rs b/src/systems/mod.rs
index 024f54f..7323dee 100644
--- a/src/systems/mod.rs
+++ b/src/systems/mod.rs
@@ -22,6 +22,8 @@ mod timeout;
mod clear;
mod building;
mod deduplicate;
+mod spawntrigger;
+mod replace;
pub use self::{
controlinput::ControlInput,
@@ -46,5 +48,7 @@ pub use self::{
timeout::Timeout,
clear::Clear,
building::Building,
- deduplicate::Deduplicate
+ deduplicate::Deduplicate,
+ spawntrigger::SpawnTrigger,
+ replace::Replace
};
diff --git a/src/systems/replace.rs b/src/systems/replace.rs
new file mode 100644
index 0000000..4ed516b
--- /dev/null
+++ b/src/systems/replace.rs
@@ -0,0 +1,46 @@
+
+use specs::{
+ ReadStorage,
+ System,
+ Join,
+ Write,
+ WriteStorage,
+ Entities
+};
+
+use crate::{
+ components::{
+ Position,
+ Substitute,
+ Removed,
+ Serialise
+ },
+ resources::{NewEntities}
+};
+
+
+pub struct Replace;
+impl <'a> System<'a> for Replace {
+ type SystemData = (
+ Entities<'a>,
+ ReadStorage<'a, Position>,
+ Write<'a, NewEntities>,
+ ReadStorage<'a, Substitute>,
+ WriteStorage<'a, Removed>,
+ ReadStorage<'a, Serialise>
+ );
+
+ fn run(&mut self, (entities, positions, mut new, substitutes, mut removeds, serialisations): Self::SystemData) {
+ for (entity, position, substitute, serialisation) in (&entities, &positions, &substitutes, (&serialisations).maybe()).join(){
+ // todo: better error handling
+ let mut template = substitute.into.clone();
+ if let Some(serialise) = serialisation {
+ // todo: extraction?
+ template = template.merge(serialise.template.clone());
+ }
+ let preent = new.encyclopedia.construct(&template).unwrap();
+ new.to_build.push((position.pos, preent));
+ removeds.insert(entity, Removed).unwrap();
+ }
+ }
+}
diff --git a/src/systems/spawntrigger.rs b/src/systems/spawntrigger.rs
new file mode 100644
index 0000000..95e95a8
--- /dev/null
+++ b/src/systems/spawntrigger.rs
@@ -0,0 +1,34 @@
+
+
+use specs::{
+ WriteStorage,
+ ReadStorage,
+ Entities,
+ System,
+ Join
+};
+
+use crate::{
+ components::{
+ TriggerBox,
+ OnSpawn,
+ New
+ }
+};
+
+
+pub struct SpawnTrigger;
+impl <'a> System<'a> for SpawnTrigger {
+ type SystemData = (
+ Entities<'a>,
+ WriteStorage<'a, TriggerBox>,
+ ReadStorage<'a, OnSpawn>,
+ ReadStorage<'a, New>
+ );
+
+ fn run(&mut self, (entities, mut triggerboxes, onspawns, news): Self::SystemData) {
+ for (entity, onspawn, _new) in (&entities, &onspawns, &news).join(){
+ TriggerBox::add_message(&mut triggerboxes, entity, onspawn.trigger);
+ }
+ }
+}
diff --git a/src/template.rs b/src/template.rs
index 6b2dec3..0ac03cd 100644
--- a/src/template.rs
+++ b/src/template.rs
@@ -12,7 +12,7 @@ use crate::{
pub struct EntityType(pub String);
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
-enum SaveOption {
+pub enum SaveOption {
Default,
False,
Always
@@ -23,7 +23,7 @@ pub struct Template {
pub name: EntityType,
pub args: Vec<Parameter>,
pub kwargs: HashMap<String, Parameter>,
- save: SaveOption,
+ pub save: SaveOption,
}
@@ -65,6 +65,16 @@ impl Template {
self
}
+ pub fn merge(mut self, other: Template) -> Self {
+ if self.save == SaveOption::Default {
+ self.save = other.save;
+ }
+ for (key, value) in other.kwargs {
+ self.kwargs.entry(key).or_insert(value);
+ }
+ self
+ }
+
pub fn from_json(v: &Value) -> PResult<Template> {
let val = match v {
Value::String(s) => json!({"type": s}),
diff --git a/todo.md b/todo.md
index cc39662..0be0d97 100644
--- a/todo.md
+++ b/todo.md
@@ -1,7 +1,7 @@
# TODO
-- document assemblage and room definition
+- make content creation tutorial
- more tests
- improved tutorial
- timer resource?