summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/equipment.rs12
-rw-r--r--src/components/faction.rs15
-rw-r--r--src/components/mod.rs17
-rw-r--r--src/componentwrapper.rs11
-rw-r--r--src/fromtoparameter.rs5
-rw-r--r--src/item.rs2
-rw-r--r--src/playerstate.rs12
-rw-r--r--src/room.rs6
-rw-r--r--src/systems/controlai.rs11
-rw-r--r--src/systems/interact.rs20
-rw-r--r--src/systems/mod.rs2
-rw-r--r--src/systems/spawn.rs2
-rw-r--r--src/systems/spawncheck.rs39
13 files changed, 98 insertions, 56 deletions
diff --git a/src/components/equipment.rs b/src/components/equipment.rs
index e07aa0b..008e0c6 100644
--- a/src/components/equipment.rs
+++ b/src/components/equipment.rs
@@ -1,10 +1,6 @@
use std::collections::HashMap;
use serde::{Serialize, Deserialize};
-use specs::{
- Component,
- HashMapStorage
-};
use strum_macros::{EnumString, Display};
use crate::{
Sprite
@@ -27,7 +23,8 @@ pub enum Slot {
pub enum Stat {
Strength,
Defence,
- Mining
+ Mining,
+ Gathering
}
@@ -40,11 +37,6 @@ pub struct Equippable {
-#[derive(Component, Debug, Clone)]
-#[storage(HashMapStorage)]
-pub struct Equipment {
- pub slots: Vec<Slot>
-}
#[cfg(test)]
mod tests {
diff --git a/src/components/faction.rs b/src/components/faction.rs
index 5fc02a2..32184d5 100644
--- a/src/components/faction.rs
+++ b/src/components/faction.rs
@@ -1,4 +1,5 @@
+use strum_macros::{EnumString, Display};
use specs::{
Component,
HashMapStorage,
@@ -6,7 +7,8 @@ use specs::{
Entity,
};
-#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
+#[strum(serialize_all = "lowercase")]
#[storage(HashMapStorage)]
pub enum Faction {
Neutral,
@@ -19,17 +21,6 @@ use Faction::{Neutral, Good, Evil, None};
impl Faction {
- pub fn from_str(name: &str) -> Option<Faction> {
- match name.to_lowercase().as_str() {
- "neutral" => Some(Neutral),
- "good" => Some(Good),
- "evil" => Some(Evil),
- "none" => Some(None),
- "" => Some(None),
- _ => Option::None
- }
- }
-
pub fn is_enemy(&self, other: Faction) -> bool {
match self {
Neutral => false,
diff --git a/src/components/mod.rs b/src/components/mod.rs
index f3a91d5..d462fef 100644
--- a/src/components/mod.rs
+++ b/src/components/mod.rs
@@ -17,7 +17,7 @@ pub use messages::{
};
pub use faction::Faction;
pub use interactable::{Interactable};
-pub use equipment::Equipment;
+pub use equipment::{Equippable, Stat, Slot};
pub use inventory::Inventory;
pub use serialise::Serialise;
pub use flags::{
@@ -173,11 +173,6 @@ pub struct MonsterAI {
pub home: Option<Pos>
}
-#[derive(Component, Debug, Clone, Default)]
-#[storage(HashMapStorage)]
-pub struct Home {
- pub home: Pos
-}
#[derive(Component, Debug, Clone)]
#[storage(HashMapStorage)]
@@ -259,3 +254,13 @@ pub struct Substitute {
pub into: Template
}
+#[derive(Component, Debug, Clone)]
+pub struct Stats {
+ pub skills: HashMap<Stat, i64>
+}
+
+#[derive(Component, Debug, Clone)]
+pub struct Requirements {
+ pub required_flags: HashSet<Flag>,
+ pub blocking_flags: HashSet<Flag>
+}
diff --git a/src/componentwrapper.rs b/src/componentwrapper.rs
index 2f12a42..a45f3c0 100644
--- a/src/componentwrapper.rs
+++ b/src/componentwrapper.rs
@@ -15,7 +15,8 @@ use crate::{
AttackType,
Clan,
Flag,
- Trigger
+ Trigger,
+ Stat
},
parameter::{Parameter},
fromtoparameter::FromToParameter,
@@ -170,14 +171,12 @@ components!(all:
}
};
Clan (name: String);
- Home (home: Pos);
- Faction (faction: String) {Faction::from_str(faction.as_str()).ok_or(aerr!("invalid faction name"))?};
+ Faction (faction: String) {Faction::from_str(faction.as_str()).map_err(|_|aerr!("invalid faction name '{}'", faction))?};
Interactable (typ: String, arg: Parameter) {
- Interactable::parse_from_parameter(&typ, &arg).ok_or(aerr!("invalid interaction {:?} {:?}", typ, arg))?
+ Interactable::parse_from_parameter(&typ, &arg).ok_or(aerr!("invalid interaction {} {:?}", typ, arg))?
};
Loot (loot: Vec<(Template, f64)>);
Timer (trigger: Trigger, delay: i64, spread: f64, target_time: Option<Timestamp>);
- Equipment () {panic!("equipment from parameters not implemented")};
TimeOffset (dtime: i64);
Flags (flags: Vec<String>) {
Flags(
@@ -212,6 +211,8 @@ components!(all:
).collect::<std::result::Result<Vec<Trigger>, std::boxed::Box<errors::AError>>>()?
}
};
+ Stats (skills: HashMap<Stat, i64>);
+ Requirements (required_flags: HashSet<Flag>, blocking_flags: HashSet<Flag>);
);
diff --git a/src/fromtoparameter.rs b/src/fromtoparameter.rs
index 180632f..41665f4 100644
--- a/src/fromtoparameter.rs
+++ b/src/fromtoparameter.rs
@@ -10,7 +10,7 @@ use crate::{
Sprite,
ItemId,
RoomId,
- components::{Trigger},
+ components::{Trigger, Stat, Faction, Flag},
Timestamp
};
@@ -102,6 +102,9 @@ macro_rules! fromtostr {
}
fromtostr!(Trigger);
+fromtostr!(Stat);
+fromtostr!(Faction);
+fromtostr!(Flag);
impl<T> FromToParameter for Vec<T>
where T: FromToParameter {
diff --git a/src/item.rs b/src/item.rs
index c8337f9..7a494b7 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -7,7 +7,7 @@ use crate::{
Template,
components::{
Flag,
- equipment::Equippable
+ Equippable
}
};
diff --git a/src/playerstate.rs b/src/playerstate.rs
index 658aeb2..2bc0456 100644
--- a/src/playerstate.rs
+++ b/src/playerstate.rs
@@ -18,15 +18,17 @@ use crate::{
AttackType,
Autofight,
Faction,
- Equipment,
- equipment::Slot,
- Ear
+ Slot,
+ Ear,
+ Stats,
+ Stat
},
Result,
aerr,
Sprite,
Encyclopedia,
Pos,
+ hashmap
};
#[allow(non_upper_case_globals)]
@@ -96,8 +98,8 @@ impl PlayerState {
ComponentWrapper::Movable(Movable{cooldown: 2}),
ComponentWrapper::Autofight(Autofight::default()),
ComponentWrapper::Faction(Faction::Good),
- ComponentWrapper::Equipment(Equipment{slots: vec!(Slot::Hand, Slot::Body)}),
- ComponentWrapper::Ear(Ear::default())
+ ComponentWrapper::Ear(Ear::default()),
+ ComponentWrapper::Stats(Stats{skills: hashmap!{Stat::Gathering => 10}})
])
}
}
diff --git a/src/room.rs b/src/room.rs
index 400dfa2..4f0aa47 100644
--- a/src/room.rs
+++ b/src/room.rs
@@ -71,6 +71,7 @@ use crate::{
Building,
SpawnTrigger,
Replace,
+ SpawnCheck,
}
};
@@ -80,12 +81,13 @@ pub fn default_dispatcher<'a, 'b>() -> Dispatcher<'a, 'b> {
.with(Timeout, "timeout", &[])
.with(UpdateCooldowns, "cool_down", &[])
.with(Spawn, "spawn", &[])
+ .with(SpawnCheck, "spawncheck", &["spawn"])
.with(ControlInput, "controlinput", &["cool_down"])
.with(ControlAI, "controlai", &["cool_down"])
.with(Take, "take", &["controlinput", "controlai"])
.with(Use, "use", &["controlinput", "controlai"])
.with(Interact, "interact", &["controlinput", "controlai"])
- .with(SpawnTrigger, "spawntrigger", &["spawn", "replace"])
+ .with(SpawnTrigger, "spawntrigger", &["spawncheck", "replace"])
.with(Move, "move", &["controlinput", "controlai"])
.with(Trapping, "trapping", &["move"])
.with(Fight, "fight", &["move"])
@@ -124,7 +126,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, Minable, LootHolder, OnSpawn, Substitute),
+ (Position, Visible, Controller, Movable, New, Removed, Moved, Player, Inventory, Health, Serialise, RoomExit, Entered, TriggerBox, Trap, Fighter, Healing, ControlCooldown, Autofight, MonsterAI, AttackInbox, Item, Spawner, Clan, Faction, Interactable, Loot, Timer, TimeOffset, Flags, Ear, Build, Whitelist, Minable, LootHolder, OnSpawn, Substitute, Stats, Requirements),
(Ground, Input, Output, Size, Spawn, Players, Emigration, Time, RoomFlags)
);
diff --git a/src/systems/controlai.rs b/src/systems/controlai.rs
index ab72f77..5032cc4 100644
--- a/src/systems/controlai.rs
+++ b/src/systems/controlai.rs
@@ -11,7 +11,7 @@ use specs::{
};
use crate::{
- components::{Controller, ControlCooldown, Fighter, MonsterAI, Home, Health, Position, Faction},
+ components::{Controller, ControlCooldown, Fighter, MonsterAI, Health, Position, Faction},
controls::{Control, Direction::{self, North, South, East, West}},
Pos
};
@@ -25,12 +25,11 @@ impl <'a> System<'a> for ControlAI {
ReadStorage<'a, ControlCooldown>,
ReadStorage<'a, MonsterAI>,
ReadStorage<'a, Fighter>,
- ReadStorage<'a, Home>,
ReadStorage<'a, Health>,
ReadStorage<'a, Position>,
ReadStorage<'a, Faction>
);
- fn run(&mut self, (entities, mut controllers, cooldowns, ais, fighters, homes, healths, positions, factions): Self::SystemData) {
+ fn run(&mut self, (entities, mut controllers, cooldowns, ais, fighters, healths, positions, factions): Self::SystemData) {
for (entity, ai, position, ()) in (&entities, &ais, &positions, !&cooldowns).join() {
if let Some(fighter) = fighters.get(entity) {
@@ -60,9 +59,9 @@ impl <'a> System<'a> for ControlAI {
}
}
if rand::thread_rng().gen_range(0.0, 1.0) < ai.move_chance {
- if let Some(home) = homes.get(entity) {
- if rand::thread_rng().gen_range(0.0, 1.0) < ai.homesickness * (position.pos.distance_to(home.home) as f64) {
- let direction = step_to(position.pos, home.home).unwrap();
+ if let Some(home) = ai.home {
+ if rand::thread_rng().gen_range(0.0, 1.0) < ai.homesickness * (position.pos.distance_to(home) as f64) {
+ let direction = step_to(position.pos, home).unwrap();
controllers.insert(entity, Controller{control: Control::Move(direction)}).unwrap();
return;
}
diff --git a/src/systems/interact.rs b/src/systems/interact.rs
index 81563e8..204cd86 100644
--- a/src/systems/interact.rs
+++ b/src/systems/interact.rs
@@ -1,5 +1,5 @@
-use std::collections::HashSet;
+use std::collections::{HashSet, HashMap};
use rand::Rng;
use specs::{
@@ -25,7 +25,8 @@ use crate::{
Visible,
Player,
Whitelist,
- Minable
+ Minable,
+ Stats
},
controls::{Control},
resources::{Ground, Emigration, NewEntities},
@@ -52,10 +53,11 @@ impl <'a> System<'a> for Interact {
Write<'a, Emigration>,
WriteStorage<'a, Whitelist>,
WriteStorage<'a, Minable>,
+ ReadStorage<'a, Stats>,
Read<'a, NewEntities>
);
- fn run(&mut self, (entities, controllers, positions, ground, mut cooldowns, interactables, mut triggerbox, mut ears, mut inventories, visibles, players, mut emigration, mut whitelists, mut minables, new): Self::SystemData) {
+ fn run(&mut self, (entities, controllers, positions, ground, mut cooldowns, interactables, mut triggerbox, mut ears, mut inventories, visibles, players, mut emigration, mut whitelists, mut minables, stats, new): Self::SystemData) {
for (actor, controller, position) in (&entities, &controllers, &positions).join(){
let mut target = None;
let ear = ears.get_mut(actor);
@@ -121,9 +123,15 @@ 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) {
+ if let Some(minable) = minables.get_mut(ent) {
+ let mut skills = inventories.get(actor).map(Inventory::equipment_bonuses).unwrap_or_else(HashMap::new);
+ if let Some(skillset) = stats.get(actor) {
+ for (skill, val) in skillset.skills.iter() {
+ *skills.entry(*skill).or_insert(0) += val;
+ }
+ }
+ if let Some(skill_value) = skills.get(skill) {
+ println!("{:?} {:?}", skill, skill_value);
// todo: give player feedback
cooldown = 20;
minable.progress += rand::thread_rng().gen_range(0, skill_value+1);
diff --git a/src/systems/mod.rs b/src/systems/mod.rs
index e0ae2e8..598feaa 100644
--- a/src/systems/mod.rs
+++ b/src/systems/mod.rs
@@ -23,6 +23,7 @@ mod clear;
mod building;
mod spawntrigger;
mod replace;
+mod spawncheck;
pub use self::{
controlinput::ControlInput,
@@ -49,4 +50,5 @@ pub use self::{
building::Building,
spawntrigger::SpawnTrigger,
replace::Replace,
+ spawncheck::SpawnCheck
};
diff --git a/src/systems/spawn.rs b/src/systems/spawn.rs
index da0735d..c6db0e4 100644
--- a/src/systems/spawn.rs
+++ b/src/systems/spawn.rs
@@ -17,7 +17,6 @@ use crate::{
Position,
Spawner,
Clan,
- Home,
TriggerBox,
Trigger,
TimeOffset
@@ -62,7 +61,6 @@ impl <'a> System<'a> for Spawn {
match new.encyclopedia.construct(&spawner.template) {
Ok(mut preent) => {
preent.push(ComponentWrapper::Clan(spawner.clan.clone()));
- preent.push(ComponentWrapper::Home(Home{home: position.pos}));
let offset = Pos::new(
rng.gen::<i64>()%(spawner.radius*2+1)-spawner.radius,
rng.gen::<i64>()%(spawner.radius*2+1)-spawner.radius);
diff --git a/src/systems/spawncheck.rs b/src/systems/spawncheck.rs
new file mode 100644
index 0000000..52ff38e
--- /dev/null
+++ b/src/systems/spawncheck.rs
@@ -0,0 +1,39 @@
+
+use std::collections::HashSet;
+use specs::{
+ WriteStorage,
+ ReadStorage,
+ Entities,
+ System,
+ Join,
+ Read
+};
+
+use crate::{
+ components::{Removed, Requirements, New, Position, Flag, Flags},
+ resources::{Ground, RoomFlags}
+};
+
+
+pub struct SpawnCheck;
+impl <'a> System<'a> for SpawnCheck {
+ type SystemData = (
+ Entities<'a>,
+ ReadStorage<'a, Requirements>,
+ ReadStorage<'a, New>,
+ WriteStorage<'a, Removed>,
+ Read<'a, Ground>,
+ Read<'a, RoomFlags>,
+ ReadStorage<'a, Position>,
+ ReadStorage<'a, Flags>
+ );
+ fn run(&mut self, (entities, requirements, new, mut removeds, ground, roomflags, positions, flags): Self::SystemData) {
+ for (entity, requirements, _new, position) in (&entities, &requirements, &new, &positions).join() {
+ let ground_flags: HashSet<Flag> = ground.flags_on(position.pos, &flags).union(&roomflags.0).cloned().collect();
+ if !(requirements.required_flags.is_subset(&ground_flags) && requirements.blocking_flags.is_disjoint(&ground_flags)){
+ removeds.insert(entity, Removed).unwrap();
+ }
+ }
+ }
+}
+