summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--content/encyclopediae/default_encyclopedia.json20
-rw-r--r--content/maps/room.json4
-rw-r--r--src/assemblage.rs8
-rw-r--r--src/components/equipment.rs4
-rw-r--r--src/components/interactable.rs9
-rw-r--r--src/components/mod.rs7
-rw-r--r--src/componentwrapper.rs7
-rw-r--r--src/room.rs4
-rw-r--r--src/systems/interact.rs35
9 files changed, 78 insertions, 20 deletions
diff --git a/content/encyclopediae/default_encyclopedia.json b/content/encyclopediae/default_encyclopedia.json
index b4007d5..5f127cd 100644
--- a/content/encyclopediae/default_encyclopedia.json
+++ b/content/encyclopediae/default_encyclopedia.json
@@ -413,6 +413,17 @@
]]}]
],
"flags": ["Occupied"]
+ },
+ "quarry": {
+ "sprite": "quarry",
+ "height": 2,
+ "components": [
+ ["Interactable", {"action": ["interaction", ["mine", "mining"]]}],
+ ["Minable", {"total": 20, "trigger": "loot"}],
+ ["Loot", {"spread": true, "loot": ["list", [
+ ["list", [{"type": "stone"}, 1.0]]
+ ]]}]
+ ]
}
},
"items": {
@@ -442,7 +453,14 @@
"armour": {"action": ["equip", {
"slot": "body",
"stats": {"defence": 3}
- }]}
+ }]},
+ "pickaxe": {
+ "sprite": "sword",
+ "action": ["equip", {
+ "slot": "hand",
+ "stats": {"mining": 5}
+ }]
+ }
},
"templates":{
"plantedcarrotseed": ["plantedseed", {"delay": 60, "next": "carrotseedling"}],
diff --git a/content/maps/room.json b/content/maps/room.json
index 052e65b..853e7a3 100644
--- a/content/maps/room.json
+++ b/content/maps/room.json
@@ -23,7 +23,7 @@
" X,,*,,.,,,,,,,,,,,~~~''''''''''''''''f'''X",
" X*,,,,.,,,d,VVV,,,~~~'''''''''''f''''f'''X",
"1.......,,,,,VVV,,,~~~'''''''''''ffffff'''X",
- " X/,,,,.,,,,,VVV,,,~~~''''''''''''''''''''X",
+ " X/,,,,.,P,Q,VVV,,,~~~''''''''''''''''''''X",
" XXXXX,.,XXXXXXXXXX~~~XXXXXXXXXXXXXXXXXXXXX",
" %%% "
],
@@ -51,6 +51,8 @@
"s": ["ground", "sign"],
"u": ["ground", "dude"],
"t": ["ground", "trader"],
+ "P": ["ground", "pickaxe"],
+ "Q": "quarry",
" ": []
}
}
diff --git a/src/assemblage.rs b/src/assemblage.rs
index d572c7f..2ef62f0 100644
--- a/src/assemblage.rs
+++ b/src/assemblage.rs
@@ -51,12 +51,12 @@ impl Assemblage {
let mut components = Vec::new();
for tup in comps {
if let Some(name) = tup.as_str() {
- components.push((ComponentType::from_str(name).ok_or(perr!("not a valid componenttype"))?, HashMap::new()));
+ components.push((ComponentType::from_str(name).ok_or(perr!("{} not a valid componenttype", name))?, HashMap::new()));
} else {
- let comptype = ComponentType::from_str(tup
+ let name = tup
.get(0).ok_or(perr!("index 0 not in component"))?
- .as_str().ok_or(perr!("component name not a string"))?
- ).ok_or(perr!("not a valid componenttype"))?;
+ .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"))? {
let param = ComponentParameter::from_json(value)?;
diff --git a/src/components/equipment.rs b/src/components/equipment.rs
index 386ef38..ab573d8 100644
--- a/src/components/equipment.rs
+++ b/src/components/equipment.rs
@@ -27,7 +27,8 @@ impl Slot {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Stat {
Strength,
- Defence
+ Defence,
+ Mining
}
impl Stat {
@@ -35,6 +36,7 @@ impl Stat {
match txt {
"strength" => Some(Self::Strength),
"defence" => Some(Self::Defence),
+ "mining" => Some(Self::Mining),
_ => None
}
}
diff --git a/src/components/interactable.rs b/src/components/interactable.rs
index f1f0508..f48fb9d 100644
--- a/src/components/interactable.rs
+++ b/src/components/interactable.rs
@@ -8,7 +8,7 @@ use specs::{
use crate::{
exchange::Exchange,
ItemId,
- components::Trigger,
+ components::{Trigger, equipment::Stat},
RoomId
};
@@ -19,7 +19,8 @@ pub enum Interactable {
Say(String),
Reply(String),
Exchange(String, HashMap<String, Exchange>),
- Visit(RoomId)
+ Visit(RoomId),
+ Mine(Stat)
}
use Interactable::*;
@@ -47,6 +48,7 @@ impl Interactable {
.collect::<Option<HashMap<String, Exchange>>>()?
),
"visit" => Visit(RoomId::from_str(arg.as_str()?)),
+ "mine" => Mine(Stat::from_str(arg.as_str()?)?),
_ => None?
})
}
@@ -62,7 +64,7 @@ impl Interactable {
} else {
true
}
- }
+ },
Visit(_) => {
if let Some(txt) = arg {
txt.starts_with("visit ") || txt.starts_with("disallow ") || txt.starts_with("allow ") || txt.starts_with("whitelist")
@@ -70,6 +72,7 @@ impl Interactable {
false
}
}
+ Mine(_) => arg.is_none()
}
}
}
diff --git a/src/components/mod.rs b/src/components/mod.rs
index 64fa717..8ffe30d 100644
--- a/src/components/mod.rs
+++ b/src/components/mod.rs
@@ -240,3 +240,10 @@ pub struct Dedup {
pub priority: i64
}
+
+#[derive(Component, Debug, Clone)]
+pub struct Minable {
+ pub progress: i64,
+ pub total: i64,
+ pub trigger: Trigger
+}
diff --git a/src/componentwrapper.rs b/src/componentwrapper.rs
index ecc8227..0eca576 100644
--- a/src/componentwrapper.rs
+++ b/src/componentwrapper.rs
@@ -284,6 +284,13 @@ components!(all:
}
};
Dedup (id: String, priority: Int);
+ Minable (trigger: String, total: Int) {
+ Minable {
+ trigger: Trigger::from_str(&trigger).ok_or(aerr!("invalid trigger name {}", trigger))?,
+ progress: 0,
+ total
+ }
+ };
);
diff --git a/src/room.rs b/src/room.rs
index 01a299a..3020241 100644
--- a/src/room.rs
+++ b/src/room.rs
@@ -120,9 +120,9 @@ 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),
+ (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),
(Ground, Input, Output, Size, Spawn, Players, Emigration, Time)
- );
+ );
Room {
world,
diff --git a/src/systems/interact.rs b/src/systems/interact.rs
index d00f3d7..ff41b71 100644
--- a/src/systems/interact.rs
+++ b/src/systems/interact.rs
@@ -1,5 +1,7 @@
use std::collections::HashSet;
+use rand::Rng;
+
use specs::{
Entities,
ReadStorage,
@@ -22,7 +24,8 @@ use crate::{
Inventory,
Visible,
Player,
- Whitelist
+ Whitelist,
+ Minable
},
controls::{Control},
resources::{Ground, NewEntities, Emigration},
@@ -47,13 +50,14 @@ impl <'a> System<'a> for Interact {
ReadStorage<'a, Visible>,
ReadStorage<'a, Player>,
Write<'a, Emigration>,
- WriteStorage<'a, Whitelist>
+ WriteStorage<'a, Whitelist>,
+ WriteStorage<'a, Minable>
);
- fn run(&mut self, (entities, controllers, positions, ground, mut cooldowns, interactables, mut triggerbox, new, mut ears, mut inventories, visibles, players, mut emigration, mut whitelists): Self::SystemData) {
- for (entity, controller, position) in (&entities, &controllers, &positions).join(){
+ fn run(&mut self, (entities, controllers, positions, ground, mut cooldowns, interactables, mut triggerbox, new, mut ears, mut inventories, visibles, players, mut emigration, mut whitelists, mut minables): Self::SystemData) {
+ for (actor, controller, position) in (&entities, &controllers, &positions).join(){
let mut target = None;
- let ear = ears.get_mut(entity);
+ let ear = ears.get_mut(actor);
match &controller.control {
Control::Interact(directions, arg) => {
'targets: for direction in directions {
@@ -71,6 +75,7 @@ impl <'a> System<'a> for Interact {
_ => {}
}
if let Some((ent, interactable, arg)) = target {
+ let mut cooldown = 2;
let name = visibles.get(ent).map(|v| v.name.as_str());
match interactable {
Interactable::Trigger(trigger) => {
@@ -84,7 +89,7 @@ impl <'a> System<'a> for Interact {
}
Interactable::Exchange(prefix, exchanges) => {
if let Some(txt) = arg {
- if let Some(inventory) = inventories.get_mut(entity) {
+ if let Some(inventory) = inventories.get_mut(actor) {
if txt.starts_with(prefix){
let action = txt.split_at(prefix.len()).1;
if let Some(exchange) = exchanges.get(action) {
@@ -110,7 +115,7 @@ impl <'a> System<'a> for Interact {
}
}
Interactable::Visit(dest) => {
- if let (Some(player), Some(whitelist)) = (players.get(entity), whitelists.get_mut(ent)){
+ if let (Some(player), Some(whitelist)) = (players.get(actor), whitelists.get_mut(ent)){
let argument = arg.unwrap();
if argument.starts_with("visit ") {
let playername = argument.split_at("visit ".len()).1;
@@ -141,8 +146,22 @@ impl <'a> System<'a> for Interact {
}
}
}
+ Interactable::Mine(skill) => {
+ if let (Some(inventory), Some(minable)) = (inventories.get(actor), minables.get_mut(ent)) {
+ let stats = inventory.equipment_bonuses();
+ if let Some(skill_value) = stats.get(skill) {
+ // todo: give player feedback
+ cooldown = 20;
+ minable.progress += rand::thread_rng().gen_range(0, skill_value+1);
+ if minable.progress >= minable.total {
+ TriggerBox::add_message(&mut triggerbox, ent, minable.trigger);
+ minable.progress = 0;
+ }
+ }
+ }
+ }
}
- cooldowns.insert(entity, ControlCooldown{amount: 2}).unwrap();
+ cooldowns.insert(actor, ControlCooldown{amount: cooldown}).unwrap();
}
}
}