diff options
| author | troido <troido@protonmail.com> | 2020-04-05 23:22:36 +0200 |
|---|---|---|
| committer | troido <troido@protonmail.com> | 2020-04-05 23:22:36 +0200 |
| commit | ff457701ff56072914acb8a7160cd02c2a07095a (patch) | |
| tree | a9f7c9130ce274887924ee140824dc15af061b73 | |
| parent | 48c24ec8b011d081550dc78329cbe61de67b30e9 (diff) | |
trading now works
| -rw-r--r-- | content/encyclopediae/default_encyclopedia.json | 14 | ||||
| -rw-r--r-- | content/maps/room.json | 3 | ||||
| -rw-r--r-- | src/components/interactable.rs | 29 | ||||
| -rw-r--r-- | src/components/inventory.rs | 9 | ||||
| -rw-r--r-- | src/exchange.rs | 45 | ||||
| -rw-r--r-- | src/item.rs | 1 | ||||
| -rw-r--r-- | src/main.rs | 1 | ||||
| -rw-r--r-- | src/playerstate.rs | 2 | ||||
| -rw-r--r-- | src/systems/interact.rs | 70 | ||||
| -rw-r--r-- | src/systems/take.rs | 7 |
10 files changed, 147 insertions, 34 deletions
diff --git a/content/encyclopediae/default_encyclopedia.json b/content/encyclopediae/default_encyclopedia.json index 1c48a6b..b7364d5 100644 --- a/content/encyclopediae/default_encyclopedia.json +++ b/content/encyclopediae/default_encyclopedia.json @@ -227,13 +227,23 @@ "components": [ ["Interactable", {"action": ["interaction", ["reply", "did you say '{}'?"]]}] ] + }, + "trader": { + "sprite": "human", + "height": 1.5, + "components": [ + ["Interactable", {"action": ["interaction", ["exchange", ["buy ", { + "pebble": [["radish", "radish"], ["pebble"]], + "radishseed": [["radish"], ["radishseed", "radishseed"]] + }]]]}] + ] } }, "items": { "pebble": {}, "stone": {"action": ["build", ["builtwall", ["Floor"], ["Blocking"]]]}, - "radishseed": {"action": ["build", ["plantedradishseed", ["Floor", "Soil"], ["Occupied", "Blocking"]]]}, - "radish": {"action": ["eat", 3]}, + "radishseed": {"sprite": "seed", "action": ["build", ["plantedradishseed", ["Floor", "Soil"], ["Occupied", "Blocking"]]]}, + "radish": {"sprite": "food", "action": ["eat", 3]}, "sword": {"action": ["equip", { "slot": "hand", "stats": {"strength": 50} diff --git a/content/maps/room.json b/content/maps/room.json index ca50eff..5d69b72 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..........D++++#,,,X", + "X,,,t..............bbb..........D++++#,,,X", "X,**,,.,,,,,,,,,,,,bbb,,,,,,,,,,#++++#,,,X", "X,*,*,.,u,,,V,,V,,,~~~,,,T,,,T,,#++++#,,,X", "X,,*,,.,,,,,,,,,,,,~~~,,,,,,,,,,######,,,X", @@ -50,6 +50,7 @@ "D": ["ground", "closeddoor"], "s": ["ground", "sign"], "u": ["ground", "dude"], + "t": ["ground", "trader"], " ": [] } } diff --git a/src/components/interactable.rs b/src/components/interactable.rs index a59cc90..33e3a12 100644 --- a/src/components/interactable.rs +++ b/src/components/interactable.rs @@ -1,11 +1,14 @@ +use std::collections::HashMap; use serde_json::{Value}; use specs::{ Component, HashMapStorage }; use crate::{ - Template + Template, + exchange::Exchange, + ItemId }; #[derive(Component, Debug, Clone, PartialEq)] @@ -14,7 +17,8 @@ pub enum Interactable { Harvest, Change(Template), Say(String), - Reply(String) + Reply(String), + Exchange(String, HashMap<String, Exchange>) } use Interactable::*; @@ -28,6 +32,20 @@ impl Interactable { "change" => Change(Template::from_json(arg).ok()?), "say" => Say(arg.as_str()?.to_string()), "reply" => Reply(arg.as_str()?.to_string()), + "exchange" => Exchange( + arg.get(0)?.as_str()?.to_string(), + arg.get(1)? + .as_object()? + .iter() + .map(|(id, ex)| { + let exchange = Exchange { + cost: ex.get(0)?.as_array()?.iter().map(|i| Some(ItemId(i.as_str()?.to_string()))).collect::<Option<Vec<ItemId>>>()?, + offer: ex.get(1)?.as_array()?.iter().map(|i| Some(ItemId(i.as_str()?.to_string()))).collect::<Option<Vec<ItemId>>>()? + }; + Some((id.clone(), exchange)) + }) + .collect::<Option<HashMap<String, Exchange>>>()? + ), _ => None? }) } @@ -38,6 +56,13 @@ impl Interactable { Change(_) => arg.is_none(), Say(_) => arg.is_none(), Reply(_) => arg.is_some(), + Exchange(prefix, _exchanges) => { + if let Some(txt) = arg { + txt.starts_with(prefix) + } else { + true + } + } } } } diff --git a/src/components/inventory.rs b/src/components/inventory.rs index c3282e9..fa65b03 100644 --- a/src/components/inventory.rs +++ b/src/components/inventory.rs @@ -5,6 +5,7 @@ use crate::{ ItemId, item::{Item, ItemAction}, components::equipment::{Stat, Equippable}, + Encyclopedia }; #[derive(Debug, Clone)] @@ -25,6 +26,14 @@ impl Component for Inventory { impl Inventory { + pub fn add_item(&mut self, itemid: ItemId, enc: &Encyclopedia) { + self.items.insert(0, InventoryEntry{ + itemid: itemid.clone(), + item: enc.get_item(&itemid).unwrap(), + is_equipped: false + }); + } + fn equipped(&self) -> Vec<Equippable> { let mut equippables = Vec::new(); for entry in self.items.iter() { diff --git a/src/exchange.rs b/src/exchange.rs new file mode 100644 index 0000000..5e87ef2 --- /dev/null +++ b/src/exchange.rs @@ -0,0 +1,45 @@ + +use crate::{ + components::Inventory, + ItemId, + Encyclopedia +}; + +#[derive(Debug, Clone, PartialEq)] +pub struct Exchange { + pub cost: Vec<ItemId>, + pub offer: Vec<ItemId> +} + +impl Exchange { + pub fn show(&self) -> String { + format!( + "offer: [{}], price: [{}]", + self.offer.iter().map(|i| i.0.clone()).collect::<Vec<String>>().join(", "), + self.cost.iter().map(|i| i.0.clone()).collect::<Vec<String>>().join(", ") + ) + } + + pub fn can_trade(&self, inventory: &Inventory) -> bool { + if self.offer.len() as isize - self.cost.len() as isize > inventory.capacity as isize - inventory.items.len() as isize{ + return false; + } + let mut costs = self.cost.clone(); + for entry in inventory.items.iter() { + if let Some(pos) = costs.iter().position(|x| *x == entry.itemid){ + costs.remove(pos); + } + } + costs.is_empty() + } + + pub fn trade(&self, inventory: &mut Inventory, enc: &Encyclopedia) { + for item in self.cost.iter() { + let pos = inventory.items.iter().position(|entry| entry.itemid == item.clone()).unwrap(); + inventory.items.remove(pos); + } + for item in self.offer.iter() { + inventory.add_item(item.clone(), enc); + } + } +} diff --git a/src/item.rs b/src/item.rs index d5ffaa1..420f341 100644 --- a/src/item.rs +++ b/src/item.rs @@ -2,7 +2,6 @@ use std::collections::HashSet; use serde_json::{Value}; -use specs::{Component, DenseVecStorage}; use crate::{ Template, components::{ diff --git a/src/main.rs b/src/main.rs index 34819e3..21d3ccc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,6 +36,7 @@ mod timestamp; mod purgatory; mod config; mod item; +mod exchange; use self::{ pos::Pos, diff --git a/src/playerstate.rs b/src/playerstate.rs index 852c04f..9dec879 100644 --- a/src/playerstate.rs +++ b/src/playerstate.rs @@ -149,7 +149,7 @@ impl PlayerState { pub fn construct(&self, encyclopedia: &Encyclopedia) -> PreEntity { vec