summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortroido <troido@protonmail.com>2020-03-04 16:10:32 +0100
committertroido <troido@protonmail.com>2020-03-04 16:10:32 +0100
commitf8364fb636a8e9276939ae8523966b038388e4ff (patch)
tree8edd2f48cda4f2d605cec6df3ca4ec3a974de009
parent21919636f95a1214b7ed1a3e4aa6527f45b9d073 (diff)
added loot/harvest
-rw-r--r--content/encyclopediae/default_encyclopedia.json13
-rw-r--r--src/assemblage.rs2
-rw-r--r--src/components/mod.rs10
-rw-r--r--src/componentwrapper.rs5
-rw-r--r--src/parameter.rs14
-rw-r--r--src/playerstate.rs4
-rw-r--r--src/room.rs10
-rw-r--r--src/systems/droploot.rs41
-rw-r--r--src/systems/mod.rs4
9 files changed, 91 insertions, 12 deletions
diff --git a/content/encyclopediae/default_encyclopedia.json b/content/encyclopediae/default_encyclopedia.json
index c1b8c1e..56a0998 100644
--- a/content/encyclopediae/default_encyclopedia.json
+++ b/content/encyclopediae/default_encyclopedia.json
@@ -185,7 +185,18 @@
"height": 0.5,
"components": [
["Interactable", {"action": ["string", "harvest"]}],
- "Mortal"
+ "Mortal",
+ ["Loot", {"loot": ["lootlist", [["radishseed", 0.92], ["radishseed", 0.20], ["radishes", 0.8], ["radishes", 0.4]]]}]
]
+ },
+ "radishseed": {
+ "sprite": "seed",
+ "height": 0.2,
+ "name": "radishseed"
+ },
+ "radishes": {
+ "sprite": "food",
+ "height": 0.3,
+ "name": "radishes"
}
}
diff --git a/src/assemblage.rs b/src/assemblage.rs
index 60ead29..4c9dd82 100644
--- a/src/assemblage.rs
+++ b/src/assemblage.rs
@@ -75,7 +75,7 @@ impl Assemblage {
pub fn from_json(val: &Value) -> Result<Self, &'static str>{
let mut assemblage = Self {
arguments: Self::parse_definition_arguments(val.get("arguments").unwrap_or(&json!([])))?,
- components: Self::parse_definition_components(val.get("components").ok_or("property 'components' not found")?)?,
+ components: Self::parse_definition_components(val.get("components").unwrap_or(&json!([])))?,
save: val.get("save").unwrap_or(&json!(true)).as_bool().ok_or("assemblage save not a bool")?
};
// visible component is so common that shortcuts are very helpful
diff --git a/src/components/mod.rs b/src/components/mod.rs
index 66ac724..efaeb68 100644
--- a/src/components/mod.rs
+++ b/src/components/mod.rs
@@ -231,4 +231,14 @@ impl Interactable {
}
}
+#[derive(Component, Debug, Clone)]
+#[storage(HashMapStorage)]
+pub struct Loot {
+ pub loot: Vec<(Template, f64)>
+}
+
+
+
+
+
diff --git a/src/componentwrapper.rs b/src/componentwrapper.rs
index 638531b..e1389c4 100644
--- a/src/componentwrapper.rs
+++ b/src/componentwrapper.rs
@@ -134,8 +134,9 @@ components!(
};
Clan (name: String) Clan{name};
Home (home: Pos) Home{home};
- Faction (faction: String) {Faction::from_str(faction.as_str()).unwrap()};
- Interactable (action: String) {Interactable::from_str(action.as_str()).unwrap()};
+ Faction (faction: String) {Faction::from_str(faction.as_str())?};
+ Interactable (action: String) {Interactable::from_str(action.as_str())?};
+ Loot (loot: LootList) {Loot{loot}};
);
diff --git a/src/parameter.rs b/src/parameter.rs
index 9c72d69..d761331 100644
--- a/src/parameter.rs
+++ b/src/parameter.rs
@@ -9,7 +9,7 @@ use crate::{
macro_rules! parameters {
- ($($name: ident ($typ: ident) $stringname: ident, $v: ident ($fromjson: expr) ($tojson: expr));*;) => {
+ ($($name: ident ($typ: ty) $stringname: ident, $v: ident ($fromjson: expr) ($tojson: expr));*;) => {
#[derive(Debug, PartialEq, Clone)]
pub enum Parameter {
$(
@@ -70,6 +70,11 @@ parameters!(
Template (Template) template, v (Template::from_json(v).ok()?) (v.to_json());
Action (ItemAction) action, v (ItemAction::from_json(v)?) (v.to_json());
Bool (bool) bool, v (v.as_bool()?) (json!(v));
+ LootList (Vec<(Template, f64)>) lootlist, v
+ (v.as_array()?.iter().map(|item|
+ Some((Template::from_json(item.get(0)?).ok()?, item.get(1)?.as_f64()?))
+ ).collect::<Option<Vec<(Template, f64)>>>()?)
+ ({json!(v.iter().map(|(t, c)| (t.to_json(), *c)).collect::<Vec<(Value, f64)>>())});
);
@@ -80,6 +85,13 @@ impl Parameter {
}
pub fn guess_from_json(val: &Value) -> Option<Parameter> {
+ if let Some(arr) = val.as_array() {
+ if arr.len() == 2 && arr[0].is_string() {
+ let typestr = arr[0].as_str().unwrap();
+ let typ = ParameterType::from_str(typestr)?;
+ return Self::from_typed_json(typ, &arr[1]);
+ }
+ }
let typ =
if val.is_string() {
ParameterType::String
diff --git a/src/playerstate.rs b/src/playerstate.rs
index c7b5f8c..9d84e5c 100644
--- a/src/playerstate.rs
+++ b/src/playerstate.rs
@@ -105,14 +105,14 @@ impl PlayerState {
inventory: items,
health: val.get("health").ok_or(aerr!("player json does not have health"))?.as_i64().ok_or(aerr!("player health not a number"))?,
inventory_capacity: inventory.get("capacity").ok_or(aerr!("inventory does no have capacity"))?.as_i64().ok_or(aerr!("inventory capacity not a number"))? as usize,
- maximum_health: val.get("maxhealth").ok_or(aerr!("player json does not have maxhealth"))?.as_i64().ok_or(aerr!("maxhealh not a number"))?
+ maximum_health: val.get("maxhealth").ok_or(aerr!("player json does not have maxhealth"))?.as_i64().ok_or(aerr!("maxhealth not a number"))?
})
}
pub fn respawn(&mut self) {
self.room = None;
self.pos = RoomPos::Unknown;
- self.health = self.maximum_health;
+ self.health = self.maximum_health / 2;
}
pub fn construct(&self, encyclopedia: &Encyclopedia) -> PreEntity {
diff --git a/src/room.rs b/src/room.rs
index 02a3b75..e7153b7 100644
--- a/src/room.rs
+++ b/src/room.rs
@@ -63,7 +63,8 @@ use crate::{
ControlAI,
Die,
Spawn,
- Interact
+ Interact,
+ DropLoot
}
};
@@ -84,10 +85,11 @@ pub fn default_dispatcher<'a, 'b>() -> Dispatcher<'a, 'b> {
.with(Heal, "heal", &["registernew"])
.with(Attacking, "attacking", &["use", "trapping", "fight", "heal", "interact"])
.with(Die, "die", &["attacking"])
+ .with(DropLoot, "droploot", &["attacking"])
.with(View::default(), "view", &["move", "attacking", "volate", "die"])
.with(Migrate, "migrate", &["view"])
- .with(Create, "create", &["view", "spawn"])
- .with(Remove, "remove", &["view", "move"])
+ .with(Create, "create", &["view", "spawn", "droploot"])
+ .with(Remove, "remove", &["view", "move", "droploot"])
.build()
}
@@ -117,7 +119,7 @@ impl <'a, 'b>Room<'a, 'b> {
world.insert(NewEntities::new(encyclopedia));
register_insert!(
world,
- (Position, Visible, Controller, Movable, Blocking, Floor, New, Removed, Moved, Player, Inventory, Health, Serialise, RoomExit, Entered, Dead, Trap, Fighter, Healing, Volatile, ControlCooldown, Autofight, MonsterAI, Home, Mortal, AttackInbox, Item, Spawner, Clan, Faction, Interactable),
+ (Position, Visible, Controller, Movable, Blocking, Floor, New, Removed, Moved, Player, Inventory, Health, Serialise, RoomExit, Entered, Dead, Trap, Fighter, Healing, Volatile, ControlCooldown, Autofight, MonsterAI, Home, Mortal, AttackInbox, Item, Spawner, Clan, Faction, Interactable, Loot),
(Ground, Input, Output, Size, Spawn, Players, Emigration, TimeStamp)
);
diff --git a/src/systems/droploot.rs b/src/systems/droploot.rs
new file mode 100644
index 0000000..616d38d
--- /dev/null
+++ b/src/systems/droploot.rs
@@ -0,0 +1,41 @@
+
+use rand::Rng;
+
+use specs::{
+ ReadStorage,
+ WriteStorage,
+ System,
+ Join,
+ Write
+};
+
+use crate::{
+ components::{
+ Position,
+ Loot,
+ Dead
+ },
+ resources::{NewEntities}
+};
+
+
+pub struct DropLoot;
+impl <'a> System<'a> for DropLoot{
+ type SystemData = (
+ WriteStorage<'a, Position>,
+ Write<'a, NewEntities>,
+ ReadStorage<'a, Dead>,
+ ReadStorage<'a, Loot>
+ );
+
+ fn run(&mut self, (positions, mut new, deads, loots): Self::SystemData) {
+ for (position, _, loot) in (&positions, &deads, &loots).join(){
+ 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();
+ }
+ }
+ }
+ }
+}
diff --git a/src/systems/mod.rs b/src/systems/mod.rs
index 887a1f9..1735df9 100644
--- a/src/systems/mod.rs
+++ b/src/systems/mod.rs
@@ -18,6 +18,7 @@ mod controlai;
mod die;
mod spawn;
mod interact;
+mod droploot;
pub use self::{
controlinput::ControlInput,
@@ -38,5 +39,6 @@ pub use self::{
controlai::ControlAI,
die::Die,
spawn::Spawn,
- interact::Interact
+ interact::Interact,
+ droploot::DropLoot
};