diff options
| -rw-r--r-- | content/maps/room.json | 5 | ||||
| -rw-r--r-- | src/components/mod.rs | 25 | ||||
| -rw-r--r-- | src/componentwrapper.rs | 4 | ||||
| -rw-r--r-- | src/controls.rs | 10 | ||||
| -rw-r--r-- | src/defaultencyclopedia.rs | 6 | ||||
| -rw-r--r-- | src/playerstate.rs | 8 | ||||
| -rw-r--r-- | src/room.rs | 6 | ||||
| -rw-r--r-- | src/systems/attacking.rs | 16 | ||||
| -rw-r--r-- | src/systems/fight.rs | 55 | ||||
| -rw-r--r-- | src/systems/mod.rs | 4 | ||||
| -rw-r--r-- | src/systems/trapping.rs | 10 | ||||
| -rw-r--r-- | src/systems/useitem.rs | 10 |
12 files changed, 127 insertions, 32 deletions
diff --git a/content/maps/room.json b/content/maps/room.json index c410bc1..1aa72af 100644 --- a/content/maps/room.json +++ b/content/maps/room.json @@ -19,9 +19,9 @@ "X,**,,.,,,,,,,,,,,,bbb,,,,,,,,,,#++++#,,,X", "X,*,*,.,,,,,,,,,,,,~~~,,,T,,,T,,#++++#,,,X", "X,,*,,.,,,,,,,,,,,,~~~,,,,,,,,,,######,,,X", - "X,oo,,.,,,,,,,,,,,~~~~,,,,,,,,,,f,,,,f,,,X", + "X,oo,,.,,,d,,,,,,,~~~~,,,,,,,,,,f,,,,f,,,X", "X,,*,,.,,,,,,,,,,,~~~''''''''''''''''f'''X", - "X*,,,,.,,,,,,,,,,,~~~'''''''''''f''''f'''X", + "X*,,,,.,,,d,,,,,,,~~~'''''''''''f''''f'''X", "X,,,,,.,,,,,,,,,,,~~~'''''''''''ffffff'''X", "X,,,,,.,,,,,,,,,,,~~~''''''''''''''''''''X", "XXXXX,.,XXXXXXXXXX~~~XXXXXXXXXXXXXXXXXXXXX", @@ -42,6 +42,7 @@ "o": ["grass", "stone"], "%": {"type": "portal", "kwargs": {"destination": "broom", "dest_pos": "northentry"}}, "^": ["grass", "spiketrap"], + "d": ["grass", "dummy"], " ": [] } } diff --git a/src/components/mod.rs b/src/components/mod.rs index 0c258dc..330bc67 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -9,7 +9,9 @@ use specs::{ HashMapStorage, FlaggedStorage, NullStorage, - Component + Component, + Entity, + WriteStorage }; use crate::{ @@ -121,14 +123,33 @@ pub struct Attacked { pub attacks: Vec<Attack> } +pub fn add_attack(attacked: &mut WriteStorage<Attacked> , ent: Entity, attack: Attack) { + attacked + .entry(ent) + .unwrap() + .or_insert_with(Attacked::default) + .attacks + .push(attack); +} + #[derive(Default, Component, Debug, Clone)] #[storage(NullStorage)] pub struct Entered; +#[derive(Default, Component, Debug, Clone)] +#[storage(NullStorage)] +pub struct Dying; + +#[derive(Component, Debug, Clone)] +#[storage(HashMapStorage)] +pub struct Trap { + pub attack: Attack +} + #[derive(Component, Debug, Clone)] #[storage(HashMapStorage)] -pub struct Trap{ +pub struct Fighter { pub attack: Attack } diff --git a/src/componentwrapper.rs b/src/componentwrapper.rs index 1a61728..67f551f 100644 --- a/src/componentwrapper.rs +++ b/src/componentwrapper.rs @@ -8,7 +8,7 @@ use crate::{ Sprite, playerstate::RoomPos, attack::Attack, - components::{Visible, Blocking, Player, Floor, Item, Inventory, Health, Serialise, RoomExit, Trap}, + components::{Visible, Blocking, Player, Floor, Item, Inventory, Health, Serialise, RoomExit, Trap, Fighter}, parameter::{Parameter, ParameterType} }; @@ -115,7 +115,7 @@ components!( } }; Trap (damage: Int) {Trap{attack: Attack::new(damage)}}; - + Fighter (damage: Int) {Fighter{attack: Attack::new(damage)}}; ); diff --git a/src/controls.rs b/src/controls.rs index 29d45a0..d7471e5 100644 --- a/src/controls.rs +++ b/src/controls.rs @@ -44,7 +44,8 @@ pub enum Control { Move(Direction), Take(Option<usize>), Drop(usize), - Use(usize) + Use(usize), + Attack(Vec<Direction>) } @@ -59,6 +60,13 @@ impl Control { "take" => Some(Control::Take(val.get(1)?.as_u64().map(|idx| idx as usize))), "drop" => Some(Control::Drop(val.get(1)?.as_u64().unwrap_or(0) as usize)), "use" => Some(Control::Use(val.get(1)?.as_u64().unwrap_or(0) as usize)), + "attack" => Some(Control::Attack({ + let mut directions = Vec::new(); + for dir in val.get(1)?.as_array()? { + directions.push(Direction::from_json(dir)?); + } + directions + })), _ => None } } else {None} diff --git a/src/defaultencyclopedia.rs b/src/defaultencyclopedia.rs index ae2e4eb..a9bf5b9 100644 --- a/src/defaultencyclopedia.rs +++ b/src/defaultencyclopedia.rs @@ -131,6 +131,12 @@ pub fn default_encyclopedia() -> Encyclopedia { "components": [["Trap", {"damage": ["int", 8]}]], "sprite": "spikes", "height": 0.8 + }, + "dummy": { + "arguments": [["health", "int", 20]], + "sprite": "dummy", + "height": 1, + "components": [["Health", {"health": ["arg", "health"], "maxhealth": ["int", 20]}]] } })).unwrap() } diff --git a/src/playerstate.rs b/src/playerstate.rs index 6e41623..3339dd1 100644 --- a/src/playerstate.rs +++ b/src/playerstate.rs @@ -6,7 +6,8 @@ use crate::{ componentwrapper::{ComponentWrapper, PreEntity}, PlayerId, RoomId, - components::{Visible, Player, Inventory, Health}, + components::{Visible, Player, Inventory, Health, Fighter}, + attack::Attack, Result, aerr, Sprite, @@ -100,7 +101,7 @@ impl PlayerState { pub fn construct(&self, encyclopedia: &Encyclopedia) -> PreEntity { vec![ - ComponentWrapper::Visible(Visible{sprite: Sprite{name: "player".to_string()}, height: 1.0, name: self.id.name.clone()}), + ComponentWrapper::Visible(Visible{sprite: Sprite{name: "player".to_string()}, height: 1.2, name: self.id.name.clone()}), ComponentWrapper::Player(Player::new(self.id.clone())), ComponentWrapper::Inventory(Inventory{ items: self.inventory.iter().map( |template| { @@ -114,7 +115,8 @@ impl PlayerState { }).collect(), capacity: self.inventory_capacity }), - ComponentWrapper::Health(Health{health: self.health, maxhealth: self.maximum_health}) + ComponentWrapper::Health(Health{health: self.health, maxhealth: self.maximum_health}), + ComponentWrapper::Fighter(Fighter{attack: Attack::new(5)}) ] } } diff --git a/src/room.rs b/src/room.rs index 916d76d..e19d689 100644 --- a/src/room.rs +++ b/src/room.rs @@ -34,7 +34,8 @@ use crate::{ Migrate, Use, Attacking, - Trapping + Trapping, + Fight }, components::{ Position, @@ -83,7 +84,8 @@ impl <'a, 'b>Room<'a, 'b> { .with(Use, "use", &["controlinput"]) .with(Move, "move", &["registernew", "controlinput"]) .with(Trapping, "trapping", &["move"]) - .with(Attacking, "attacking", &["use", "trapping"]) + .with(Fight, "fight", &["move", "controlinput"]) + .with(Attacking, "attacking", &["use", "trapping", "fight"]) .with(View::default(), "view", &["move", "attacking"]) .with(Migrate, "migrate", &["view"]) .with(Create, "create", &["view", "controlinput"]) diff --git a/src/systems/attacking.rs b/src/systems/attacking.rs index 6535a75..1f518cb 100644 --- a/src/systems/attacking.rs +++ b/src/systems/attacking.rs @@ -2,11 +2,12 @@ use specs::{ WriteStorage, System, + Entities, Join }; use crate::{ - components::{Health, Attacked}, + components::{Health, Attacked, Dying, Removed}, util }; @@ -14,15 +15,22 @@ use crate::{ pub struct Attacking; impl <'a> System<'a> for Attacking { type SystemData = ( + Entities<'a>, WriteStorage<'a, Attacked>, - WriteStorage<'a, Health> + WriteStorage<'a, Health>, + WriteStorage<'a, Dying>, + WriteStorage<'a, Removed> ); - fn run(&mut self, (mut victims, mut healths): Self::SystemData) { - for (health, attacked) in (&mut healths, &mut victims).join() { + fn run(&mut self, (entities, mut victims, mut healths, mut deads, mut removals): Self::SystemData) { + for (ent, health, attacked) in (&entities, &mut healths, &mut victims).join() { for attack in attacked.attacks.drain(..) { health.health -= attack.damage; } health.health = util::clamp(health.health, 0, health.maxhealth); + if health.health == 0 { + deads.insert(ent, Dying).unwrap(); + removals.insert(ent, Removed).unwrap(); + } } victims.clear(); } diff --git a/src/systems/fight.rs b/src/systems/fight.rs new file mode 100644 index 0000000..4b3c672 --- /dev/null +++ b/src/systems/fight.rs @@ -0,0 +1,55 @@ + +use std::collections::HashSet; +use specs::{ + Entities, + ReadStorage, + WriteStorage, + System, + Join, + Read +}; + +use crate::components::{ + Controller, + Position, + Attacked, + add_attack, + Fighter, + Health +}; + +use crate::controls::{Control}; +use crate::resources::{Ground}; + + + +pub struct Fight; +impl <'a> System<'a> for Fight { + type SystemData = ( + Entities<'a>, + ReadStorage<'a, Controller>, + WriteStorage<'a, Position>, + Read<'a, Ground>, + WriteStorage<'a, Attacked>, + ReadStorage<'a, Fighter>, + ReadStorage<'a, Health> + ); + + fn run(&mut self, (entities, controllers, positions, ground, mut attacked, fighters, healths): Self::SystemData) { + for (entity, controller, position, fighter) in (&entities, &controllers, &positions, &fighters).join(){ + match &controller.0 { + Control::Attack(directions) => { + for direction in directions { + for ent in ground.cells.get(&(position.pos + direction.to_position())).unwrap_or(&HashSet::new()) { + if healths.contains(*ent) && *ent != entity { + add_attack(&mut attacked, *ent, fighter.attack.clone()); + break; + } + } + } + } + _ => {} + } + } + } +} diff --git a/src/systems/mod.rs b/src/systems/mod.rs index 7864b1c..d73a578 100644 --- a/src/systems/mod.rs +++ b/src/systems/mod.rs @@ -10,6 +10,7 @@ mod migrate; mod useitem; mod attacking; mod trapping; +mod fight; pub use self::{ controlinput::ControlInput, @@ -22,5 +23,6 @@ pub use self::{ migrate::Migrate, useitem::Use, attacking::Attacking, - trapping::Trapping + trapping::Trapping, + fight::Fight }; diff --git a/src/systems/trapping.rs b/src/systems/trapping.rs index 144cd94..5e0921e 100644 --- a/src/systems/trapping.rs +++ b/src/systems/trapping.rs @@ -9,7 +9,7 @@ use specs::{ }; use crate::{ - components::{Health, Attacked, Moved, Entered, Trap, Position}, + components::{Health, Attacked, add_attack, Moved, Entered, Trap, Position}, resources::Ground }; @@ -31,13 +31,7 @@ impl <'a> System<'a> for Trapping { for (entity, _entered, trap, position) in (&entities, &entereds, &traps, &positions).join() { for ent in ground.cells.get(&position.pos).unwrap(){ if ent != &entity && moves.contains(*ent) && healths.contains(*ent) { - victims - .entry(*ent) - .unwrap() - .or_insert_with(Attacked::default) - .attacks - .push(trap.attack.clone()); - + add_attack(&mut victims, *ent, trap.attack.clone()); } } } diff --git a/src/systems/useitem.rs b/src/systems/useitem.rs index 4317162..c9bcfcd 100644 --- a/src/systems/useitem.rs +++ b/src/systems/useitem.rs @@ -14,7 +14,8 @@ use crate::{ Controller, Position, Inventory, - Attacked + Attacked, + add_attack }, resources::{NewEntities}, components::item::ItemAction::{None, Build, Eat}, @@ -45,12 +46,7 @@ impl <'a> System<'a> for Use { inventory.items.remove(*rank); } Eat(health_diff) => { - attacked - .entry(ent) - .unwrap() - .or_insert_with(Attacked::default) - .attacks - .push(Attack::new(-*health_diff)); + add_attack(&mut attacked, ent, Attack::new(-*health_diff)); inventory.items.remove(*rank); } None => {} |
