From d246537a28a7a71dfb2487d31d6fac3ccab5053d Mon Sep 17 00:00:00 2001 From: troido Date: Mon, 2 Mar 2020 00:45:21 +0100 Subject: implemented autofight --- src/components/mod.rs | 10 +++++++++- src/componentwrapper.rs | 4 +++- src/controls.rs | 4 +++- src/playerstate.rs | 15 +++++++++++++-- src/systems/controlinput.rs | 25 ++++++++++++++++++++----- src/systems/fight.rs | 20 +++++++++++++++----- 6 files changed, 63 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/components/mod.rs b/src/components/mod.rs index 3925d85..f7e483b 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -14,7 +14,8 @@ use specs::{ HashMapStorage, FlaggedStorage, NullStorage, - Component + Component, + Entity }; use crate::{ @@ -172,3 +173,10 @@ pub struct ControlCooldown { } +#[derive(Component, Debug, Clone, Default)] +#[storage(HashMapStorage)] +pub struct Autofight { + pub target: Option +} + + diff --git a/src/componentwrapper.rs b/src/componentwrapper.rs index 08164e4..54c0daa 100644 --- a/src/componentwrapper.rs +++ b/src/componentwrapper.rs @@ -22,7 +22,8 @@ use crate::{ Fighter, Healing, Volatile, - AttackMessage + AttackMessage, + Autofight }, parameter::{Parameter, ParameterType} }; @@ -134,6 +135,7 @@ components!( Fighter (damage: Int, cooldown: Int) {Fighter{attack: AttackMessage::new(damage), cooldown}}; Healing (delay: Int, health: Int) {Healing{delay, health, next_heal: None}}; Volatile (delay: Int) {Volatile{delay, end_time: None}}; + Autofight () {Autofight::default()}; ); diff --git a/src/controls.rs b/src/controls.rs index d7471e5..d317317 100644 --- a/src/controls.rs +++ b/src/controls.rs @@ -1,6 +1,7 @@ use serde_json::Value; +use specs::Entity; use crate::{PlayerId, Pos}; #[derive(Debug, Clone)] @@ -45,7 +46,8 @@ pub enum Control { Take(Option), Drop(usize), Use(usize), - Attack(Vec) + Attack(Vec), + AttackTarget(Entity) } diff --git a/src/playerstate.rs b/src/playerstate.rs index 79c7b31..baabacd 100644 --- a/src/playerstate.rs +++ b/src/playerstate.rs @@ -6,7 +6,17 @@ use crate::{ componentwrapper::{ComponentWrapper, PreEntity}, PlayerId, RoomId, - components::{Visible, Player, Inventory, Health, Fighter, Healing, Movable, AttackMessage}, + components::{ + Visible, + Player, + Inventory, + Health, + Fighter, + Healing, + Movable, + AttackMessage, + Autofight + }, Result, aerr, Sprite, @@ -117,7 +127,8 @@ impl PlayerState { ComponentWrapper::Health(Health{health: self.health, maxhealth: self.maximum_health}), ComponentWrapper::Fighter(Fighter{attack: AttackMessage::new(5), cooldown: 8}), ComponentWrapper::Healing(Healing{delay: 50, health: 1, next_heal: None}), - ComponentWrapper::Movable(Movable{cooldown: 2}) + ComponentWrapper::Movable(Movable{cooldown: 2}), + ComponentWrapper::Autofight(Autofight::default()) ] } } diff --git a/src/systems/controlinput.rs b/src/systems/controlinput.rs index 17bc40f..6d5b4ea 100644 --- a/src/systems/controlinput.rs +++ b/src/systems/controlinput.rs @@ -8,8 +8,11 @@ use specs::{ Join }; -use crate::components::{Controller, Player, ControlCooldown}; -use crate::resources::{Input}; +use crate::{ + components::{Controller, Player, ControlCooldown, Autofight}, + resources::{Input}, + controls::Control +}; pub struct ControlInput; @@ -19,14 +22,26 @@ impl <'a> System<'a> for ControlInput { Write<'a, Input>, WriteStorage<'a, Controller>, ReadStorage<'a, Player>, - ReadStorage<'a, ControlCooldown> + ReadStorage<'a, ControlCooldown>, + WriteStorage<'a, Autofight> ); - fn run(&mut self, (entities, mut input, mut controllers, players, cooldowns): Self::SystemData) { + fn run(&mut self, (entities, mut input, mut controllers, players, cooldowns, mut autofighters): Self::SystemData) { controllers.clear(); for (player, entity, ()) in (&players, &entities, !&cooldowns).join() { if let Some(control) = input.actions.remove(&player.id){ - let _ = controllers.insert(entity, Controller{control: control}); + controllers.insert(entity, Controller{control: control}).unwrap(); + if let Some(autofighter) = autofighters.get_mut(entity) { + autofighter.target = None; + } + } else if let Some(autofighter) = autofighters.get_mut(entity) { + if let Some(target) = autofighter.target { + if !entities.is_alive(target) { + autofighter.target = None; + } else { + controllers.insert(entity, Controller{control: Control::AttackTarget(target)}).unwrap(); + } + } } } } diff --git a/src/systems/fight.rs b/src/systems/fight.rs index 2a663e3..182dba6 100644 --- a/src/systems/fight.rs +++ b/src/systems/fight.rs @@ -15,7 +15,8 @@ use crate::components::{ AttackInbox, Fighter, Health, - ControlCooldown + ControlCooldown, + Autofight }; use crate::controls::{Control}; @@ -33,25 +34,34 @@ impl <'a> System<'a> for Fight { WriteStorage<'a, AttackInbox>, ReadStorage<'a, Fighter>, ReadStorage<'a, Health>, - WriteStorage<'a, ControlCooldown> + WriteStorage<'a, ControlCooldown>, + WriteStorage<'a, Autofight> ); - fn run(&mut self, (entities, controllers, positions, ground, mut attacked, fighters, healths, mut cooldowns): Self::SystemData) { + fn run(&mut self, (entities, controllers, positions, ground, mut attacked, fighters, healths, mut cooldowns, mut autofighters): Self::SystemData) { for (entity, controller, position, fighter) in (&entities, &controllers, &positions, &fighters).join(){ + let mut target = None; match &controller.control { Control::Attack(directions) => { 'targets: 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 { - AttackInbox::add_message(&mut attacked, *ent, fighter.attack.clone()); - cooldowns.insert(entity, ControlCooldown{amount: fighter.cooldown}).unwrap(); + target = Some(*ent); break 'targets; } } } } + Control::AttackTarget(t) => {target = Some(*t);} _ => {} } + if let Some(ent) = target { + AttackInbox::add_message(&mut attacked, ent, fighter.attack.clone()); + cooldowns.insert(entity, ControlCooldown{amount: fighter.cooldown}).unwrap(); + if let Some(autofighter) = autofighters.get_mut(entity){ + autofighter.target = Some(ent); + } + } } } } -- cgit