1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
use std::cmp; use specs::{prelude::*, System}; use crate::{ actions::Action, engine::components::{UnitComponent, UnitType}, Player, Warrior, }; pub struct PlayerSystem { pub player: Box<dyn Player + Send + Sync>, } impl PlayerSystem { pub fn new(player: impl Player + Send + Sync + 'static) -> PlayerSystem { PlayerSystem { player: Box::new(player), } } } impl<'a> System<'a> for PlayerSystem { type SystemData = (Entities<'a>, WriteStorage<'a, UnitComponent>); fn run(&mut self, (entities, mut units): Self::SystemData) { let mut all_units = (&entities, &mut units).join(); let warrior_unit = all_units .find(|(_, comp)| comp.unit_type == UnitType::Warrior) .unwrap(); let (_, mut warrior_comp) = warrior_unit; let sludge = all_units .by_ref() .find(|(_, comp)| comp.unit_type == UnitType::Sludge); let path_clear = { match &sludge { Some((_, sludge_comp)) => { let (wx, _) = warrior_comp.position; let (sx, _) = sludge_comp.position; (wx - sx).abs() > 1 } None => true, } }; let mut warrior = Warrior::new(path_clear); self.player.play_turn(&mut warrior); if let Some(action) = warrior.action { match action { Action::Walk => { if path_clear { println!("Warrior walks forward"); let (x, y) = warrior_comp.position; warrior_comp.position = (x + 1, y); } else { println!("Warrior bumps into Sludge"); } } Action::Attack => { if path_clear { println!("Warrior attacks and hits nothing"); } else { match sludge { Some((sludge_entity, sludge_comp)) => { println!("Warrior attacks Sludge"); let (current, max) = sludge_comp.hp; let remaining = cmp::max(current - warrior_comp.atk, 0); println!( "Sludge takes {} damage, {} HP left", warrior_comp.atk, remaining ); sludge_comp.hp = (remaining, max); if remaining == 0 { println!("Sludge is dead!"); entities.delete(sludge_entity).unwrap(); } } None => { println!("Warrior attacks but there is nothing there"); } } } } } } } }