summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortroido <troido@protonmail.com>2020-04-02 16:07:32 +0200
committertroido <troido@protonmail.com>2020-04-02 16:07:32 +0200
commitb597d2279db7beb0d619fac472481b7f707609c8 (patch)
tree3d45ea9f45a8897a3aec5c30b16bb0db12b162b2
parent1e8fe74740fc4fb11b660415b2db182c6a63a3c2 (diff)
built doors
-rw-r--r--content/encyclopediae/default_encyclopedia.json18
-rw-r--r--content/maps/room.json3
-rw-r--r--src/components/interactable.rs16
-rw-r--r--src/components/item.rs2
-rw-r--r--src/componentwrapper.rs2
-rw-r--r--src/parameter.rs2
-rw-r--r--src/resources/newentities.rs4
-rw-r--r--src/room.rs2
-rw-r--r--src/systems/attacking.rs2
-rw-r--r--src/systems/droploot.rs2
-rw-r--r--src/systems/interact.rs25
-rw-r--r--src/systems/take.rs2
-rw-r--r--src/systems/useitem.rs2
-rw-r--r--todo.md2
14 files changed, 60 insertions, 24 deletions
diff --git a/content/encyclopediae/default_encyclopedia.json b/content/encyclopediae/default_encyclopedia.json
index 9b625b9..b3dc5d0 100644
--- a/content/encyclopediae/default_encyclopedia.json
+++ b/content/encyclopediae/default_encyclopedia.json
@@ -182,7 +182,7 @@
"name": "radishplant",
"height": 0.5,
"components": [
- ["Interactable", {"action": ["string", "harvest"]}],
+ ["Interactable", {"action": ["interaction", "harvest"]}],
"Mortal",
["Loot", {"loot": ["lootlist", [["radishseed", 0.92], ["radishseed", 0.20], ["radishes", 0.8], ["radishes", 0.4]]]}]
],
@@ -241,6 +241,22 @@
"slot": "hand",
"stats": {"strength": 50}
}]
+ },
+ "closeddoor": {
+ "sprite": "closeddoor",
+ "height": 2,
+ "flags": ["Blocking"],
+ "components": [
+ ["Interactable", {"action": ["interaction", ["change", {"type": "opendoor", "save": false}]]}]
+ ]
+ },
+ "opendoor": {
+ "sprite": "opendoor",
+ "height": 0.8,
+ "flags": ["Occupied"],
+ "components": [
+ ["Interactable", {"action": ["interaction", ["change", {"type": "closeddoor", "save": false}]]}]
+ ]
}
}
}
diff --git a/content/maps/room.json b/content/maps/room.json
index 39d504e..cbf7bdc 100644
--- a/content/maps/room.json
+++ b/content/maps/room.json
@@ -15,7 +15,7 @@
"X,,,,,.,,,,,,,,,,,,~~~,,,,,,,,,,,,,,,,,,,X",
"X,^,,,.,,,,,,,,,,,,~~~,,,,,T,,,,######,,,X",
"X,^,,,.,,,,,,,,,,,,bbb,,,,,,,,,,#++++#,,,X",
- "X,,,,,.............bbb...........++++#,,,X",
+ "X,,,,,.............bbb..........D++++#,,,X",
"X,**,,.,,,,,,,,,,,,bbb,,,,,,,,,,#++++#,,,X",
"X,*,*,.,,,,,V,,V,,,~~~,,,T,,,T,,#++++#,,,X",
"X,,*,,.,,,,,,,,,,,,~~~,,,,,,,,,,######,,,X",
@@ -46,6 +46,7 @@
"r": ["grass", {"type": "spawner", "kwargs": {"template": {"type": "rat"}, "amount": 3, "clan": "rats", "delay": 200}}],
"V": ["grass", "radishplant"],
"/": ["grass", "sword"],
+ "D": ["ground", "closeddoor"],
" ": []
}
}
diff --git a/src/components/interactable.rs b/src/components/interactable.rs
index f6ce8c4..2dca6ea 100644
--- a/src/components/interactable.rs
+++ b/src/components/interactable.rs
@@ -1,19 +1,27 @@
+use serde_json::{Value};
use specs::{
Component,
HashMapStorage
};
+use crate::{
+ Template
+};
-#[derive(Component, Debug, Clone, PartialEq, Eq)]
+#[derive(Component, Debug, Clone, PartialEq)]
#[storage(HashMapStorage)]
pub enum Interactable {
- Harvest
+ Harvest,
+ Change(Template)
}
impl Interactable {
- pub fn from_str(txt: &str) -> Option<Interactable> {
- match txt {
+ pub fn from_json(val: &Value) -> Option<Self> {
+ let typ = if val.is_string() {val} else {val.get(0)?};
+ let arg = if val.is_string() {&Value::Null} else {val.get(1)?};
+ match typ.as_str()? {
"harvest" => Some(Interactable::Harvest),
+ "change" => Some(Interactable::Change(Template::from_json(arg).ok()?)),
_ => None
}
}
diff --git a/src/components/item.rs b/src/components/item.rs
index 9793061..40be7f1 100644
--- a/src/components/item.rs
+++ b/src/components/item.rs
@@ -1,5 +1,6 @@
use std::collections::HashSet;
+use serde_json::{Value};
use specs::{Component, DenseVecStorage};
use crate::{
Template,
@@ -17,7 +18,6 @@ pub struct Item {
-use serde_json::{json, Value};
#[derive(Debug, Clone, PartialEq)]
pub enum ItemAction {
diff --git a/src/componentwrapper.rs b/src/componentwrapper.rs
index c4b70a5..898ab1b 100644
--- a/src/componentwrapper.rs
+++ b/src/componentwrapper.rs
@@ -181,7 +181,7 @@ components!(
Clan (name: String);
Home (home: Pos);
Faction (faction: String) {Faction::from_str(faction.as_str()).ok_or(aerr!("invalid faction name"))?};
- Interactable (action: String) {Interactable::from_str(action.as_str()).ok_or(aerr!("invalid interactable name"))?};
+ Interactable (action: Interaction) {action};
Loot (loot: LootList);
Grow (
into: Template (Grow.into.clone()),
diff --git a/src/parameter.rs b/src/parameter.rs
index 2ac9be1..a9ef898 100644
--- a/src/parameter.rs
+++ b/src/parameter.rs
@@ -3,6 +3,7 @@ use serde_json::{Value, json};
use crate::{
Template,
components::item::ItemAction,
+ components::interactable::Interactable,
Pos
};
@@ -69,6 +70,7 @@ parameters!(
Float (f64) float, v (v.as_f64()?) (json!(v));
Template (Template) template, v (Template::from_json(v).ok()?) (v.to_json());
Action (ItemAction) action, v (ItemAction::from_json(v)?) (panic!("item actions can't be serialized"));
+ Interaction (Interactable) interaction, v (Interactable::from_json(v)?) (panic!("interactions can't be serialized"));
Bool (bool) bool, v (v.as_bool()?) (json!(v));
LootList (Vec<(Template, f64)>) lootlist, v
(v.as_array()?.iter().map(|item|
diff --git a/src/resources/newentities.rs b/src/resources/newentities.rs
index a9c4ddc..f03fbbb 100644
--- a/src/resources/newentities.rs
+++ b/src/resources/newentities.rs
@@ -20,8 +20,8 @@ impl NewEntities {
encyclopedia
}
}
- pub fn create(&mut self, pos: Pos, template: Template) -> Result<()> {
- let components = self.encyclopedia.construct(&template)?;
+ pub fn create(&mut self, pos: Pos, template: &Template) -> Result<()> {
+ let components = self.encyclopedia.construct(template)?;
self.to_build.push((pos, components));
Ok(())
}
diff --git a/src/room.rs b/src/room.rs
index 6c92e8c..5b125c4 100644
--- a/src/room.rs
+++ b/src/room.rs
@@ -261,7 +261,7 @@ impl <'a, 'b>Room<'a, 'b> {
}
fn create_entity(&mut self, template: Template, pos: Pos) -> Result<()>{
- self.world.fetch_mut::<NewEntities>().create(pos, template)?;
+ self.world.fetch_mut::<NewEntities>().create(pos, &template)?;
Ok(())
}
diff --git a/src/systems/attacking.rs b/src/systems/attacking.rs
index 4318695..e4001c9 100644
--- a/src/systems/attacking.rs
+++ b/src/systems/attacking.rs
@@ -64,7 +64,7 @@ impl <'a> System<'a> for Attacking {
}
if let Some(position) = positions.get(ent){
if wounded {
- new.create(position.pos, Template::empty("wound")).unwrap();
+ new.create(position.pos, &Template::empty("wound")).unwrap();
}
}
}
diff --git a/src/systems/droploot.rs b/src/systems/droploot.rs
index 1b8f824..5eff7f7 100644
--- a/src/systems/droploot.rs
+++ b/src/systems/droploot.rs
@@ -32,7 +32,7 @@ impl <'a> System<'a> for DropLoot{
for (template, chance) in &loot.loot {
if *chance > rand::thread_rng().gen_range(0.0, 1.0) {
// todo: better error handling
- new.create(position.pos, template.clone()).unwrap();
+ new.create(position.pos, &template).unwrap();
}
}
}
diff --git a/src/systems/interact.rs b/src/systems/interact.rs
index 4c0245d..e3b8358 100644
--- a/src/systems/interact.rs
+++ b/src/systems/interact.rs
@@ -6,7 +6,8 @@ use specs::{
WriteStorage,
System,
Join,
- Read
+ Read,
+ Write
};
use crate::components::{
@@ -14,11 +15,12 @@ use crate::components::{
Position,
ControlCooldown,
Interactable,
- Dead
+ Dead,
+ Removed
};
use crate::controls::{Control};
-use crate::resources::{Ground};
+use crate::resources::{Ground, NewEntities};
@@ -31,18 +33,21 @@ impl <'a> System<'a> for Interact {
Read<'a, Ground>,
WriteStorage<'a, ControlCooldown>,
ReadStorage<'a, Interactable>,
- WriteStorage<'a, Dead>
+ WriteStorage<'a, Dead>,
+ WriteStorage<'a, Removed>,
+ Write<'a, NewEntities>
);
- fn run(&mut self, (entities, controllers, positions, ground, mut cooldowns, interactables, mut deads): Self::SystemData) {
+ fn run(&mut self, (entities, controllers, positions, ground, mut cooldowns, interactables, mut deads, mut removeds, mut new): Self::SystemData) {
for (entity, controller, position) in (&entities, &controllers, &positions).join(){
let mut target = None;
match &controller.control {
Control::Interact(directions) => {
'targets: for direction in directions {
- for ent in ground.cells.get(&(position.pos + direction.to_position())).unwrap_or(&HashSet::new()) {
+ let pos = position.pos + direction.to_position();
+ for ent in ground.cells.get(&pos).unwrap_or(&HashSet::new()) {
if let Some(interactable) = interactables.get(*ent) {
- target = Some((*ent, interactable));
+ target = Some((*ent, interactable, pos));
break 'targets;
}
}
@@ -50,11 +55,15 @@ impl <'a> System<'a> for Interact {
}
_ => {}
}
- if let Some((ent, interactable)) = target {
+ if let Some((ent, interactable, pos)) = target {
match interactable {
Interactable::Harvest => {
deads.insert(ent, Dead).unwrap();
}
+ Interactable::Change(into) => {
+ new.create(pos, into).unwrap();
+ removeds.insert(ent, Removed).unwrap();
+ }
}
cooldowns.insert(entity, ControlCooldown{amount: 2}).unwrap();
}
diff --git a/src/systems/take.rs b/src/systems/take.rs
index 0652fdb..9eb76e7 100644
--- a/src/systems/take.rs
+++ b/src/systems/take.rs
@@ -63,7 +63,7 @@ impl <'a> System<'a> for Take {
return
}
let (item, _is_equipped) = inventory.items.remove(*rank);
- let _ = new.create(position.pos, item.ent);
+ let _ = new.create(position.pos, &item.ent);
}
_ => {}
}
diff --git a/src/systems/useitem.rs b/src/systems/useitem.rs
index d96f6ef..8763843 100644
--- a/src/systems/useitem.rs
+++ b/src/systems/useitem.rs
@@ -48,7 +48,7 @@ impl <'a> System<'a> for Use {
Build(template, required_flags, blocking_flags) => {
let ground_flags = ground.flags_on(position.pos, &flags);
if required_flags.is_subset(&ground_flags) && blocking_flags.is_disjoint(&ground_flags){
- new.create(position.pos, template.clone()).unwrap();
+ new.create(position.pos, &template).unwrap();
inventory.items.remove(*rank);
}
}
diff --git a/todo.md b/todo.md
index ee36f49..8b4fc2c 100644
--- a/todo.md
+++ b/todo.md
@@ -3,10 +3,10 @@
- make readme
- more tests
+- command line options
- timer resource?
- log world events to player
- draw new entities
- relative room locations?
- improve error handling
-- doors