|
@@ -1,7 +1,8 @@
|
|
|
extern crate specs;
|
|
|
use specs::prelude::*;
|
|
|
-use super::{WantsToPickupItem, Name, InBackpack, Position, gamelog::GameLog, WantsToDrinkPotion,
|
|
|
- Potion, CombatStats, WantsToDropItem};
|
|
|
+use super::{WantsToPickupItem, Name, InBackpack, Position, gamelog::GameLog, WantsToUseItem,
|
|
|
+ Consumable, ProvidesHealing, CombatStats, WantsToDropItem, InflictsDamage, Map, SufferDamage,
|
|
|
+ AreaOfEffect};
|
|
|
|
|
|
pub struct ItemCollectionSystem {}
|
|
|
|
|
@@ -31,37 +32,110 @@ impl<'a> System<'a> for ItemCollectionSystem {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-pub struct PotionUseSystem {}
|
|
|
+pub struct ItemUseSystem {}
|
|
|
|
|
|
-impl<'a> System<'a> for PotionUseSystem {
|
|
|
+impl<'a> System<'a> for ItemUseSystem {
|
|
|
#[allow(clippy::type_complexity)]
|
|
|
type SystemData = ( ReadExpect<'a, Entity>,
|
|
|
WriteExpect<'a, GameLog>,
|
|
|
+ ReadExpect<'a, Map>,
|
|
|
Entities<'a>,
|
|
|
- WriteStorage<'a, WantsToDrinkPotion>,
|
|
|
+ WriteStorage<'a, WantsToUseItem>,
|
|
|
ReadStorage<'a, Name>,
|
|
|
- ReadStorage<'a, Potion>,
|
|
|
- WriteStorage<'a, CombatStats>
|
|
|
+ ReadStorage<'a, Consumable>,
|
|
|
+ ReadStorage<'a, ProvidesHealing>,
|
|
|
+ ReadStorage<'a, InflictsDamage>,
|
|
|
+ WriteStorage<'a, CombatStats>,
|
|
|
+ WriteStorage<'a, SufferDamage>,
|
|
|
+ ReadStorage<'a, AreaOfEffect>
|
|
|
);
|
|
|
|
|
|
fn run(&mut self, data : Self::SystemData) {
|
|
|
- let (player_entity, mut gamelog, entities, mut wants_drink, names, potions, mut combat_stats) = data;
|
|
|
+ let (player_entity, mut gamelog, map, entities, mut wants_use, names,
|
|
|
+ consumables, healing, inflict_damage, mut combat_stats, mut suffer_damage, aoe) = data;
|
|
|
+
|
|
|
+ for (entity, useitem) in (&entities, &wants_use).join() {
|
|
|
+ let mut used_item = true;
|
|
|
+
|
|
|
+ // Targeting
|
|
|
+ let mut targets : Vec<Entity> = Vec::new();
|
|
|
+ match useitem.target {
|
|
|
+ None => { targets.push( *player_entity ); }
|
|
|
+ Some(target) => {
|
|
|
+ let area_effect = aoe.get(useitem.item);
|
|
|
+ match area_effect {
|
|
|
+ None => {
|
|
|
+ // Single target in tile
|
|
|
+ let idx = map.xy_idx(target.x, target.y);
|
|
|
+ for mob in map.tile_content[idx].iter() {
|
|
|
+ targets.push(*mob);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Some(area_effect) => {
|
|
|
+ // AoE
|
|
|
+ let blast_tiles = rltk::field_of_view(target, area_effect.radius, &*map);
|
|
|
+ for tile_idx in blast_tiles.iter() {
|
|
|
+ let idx = map.xy_idx(tile_idx.x, tile_idx.y);
|
|
|
+ for mob in map.tile_content[idx].iter() {
|
|
|
+ targets.push(*mob);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // If it heals, apply the healing
|
|
|
+ let item_heals = healing.get(useitem.item);
|
|
|
+ match item_heals {
|
|
|
+ None => {}
|
|
|
+ Some(healer) => {
|
|
|
+ used_item = false;
|
|
|
+ for target in targets.iter() {
|
|
|
+ let stats = combat_stats.get_mut(*target);
|
|
|
+ if let Some(stats) = stats {
|
|
|
+ stats.hp = i32::max(stats.max_hp, stats.hp + healer.heal_amount);
|
|
|
+ if entity == *player_entity {
|
|
|
+ gamelog.entries.insert(0, format!("You use the {}, healing {} hp.", names.get(useitem.item).unwrap().name, healer.heal_amount));
|
|
|
+ }
|
|
|
+ used_item = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- for (entity, drink, stats) in (&entities, &wants_drink, &mut combat_stats).join() {
|
|
|
- let potion = potions.get(drink.potion);
|
|
|
- match potion {
|
|
|
+ // If it inflicts damage, apply it to the target cell
|
|
|
+ let item_damages = inflict_damage.get(useitem.item);
|
|
|
+ match item_damages {
|
|
|
None => {}
|
|
|
- Some(potion) => {
|
|
|
- stats.hp = i32::max(stats.max_hp, stats.hp + potion.heal_amount);
|
|
|
- if entity == *player_entity {
|
|
|
- gamelog.entries.insert(0, format!("You drink the {}, healing {} hp.", names.get(drink.potion).unwrap().name, potion.heal_amount));
|
|
|
+ Some(damage) => {
|
|
|
+ used_item = false;
|
|
|
+ for mob in targets.iter() {
|
|
|
+ suffer_damage.insert(*mob, SufferDamage{ amount : damage.damage }).expect("Unable to insert");
|
|
|
+ if entity == *player_entity {
|
|
|
+ let mob_name = names.get(*mob).unwrap();
|
|
|
+ let item_name = names.get(useitem.item).unwrap();
|
|
|
+ gamelog.entries.insert(0, format!("You use {} on {}, inflicting {} hp.", item_name.name, mob_name.name, damage.damage));
|
|
|
+ }
|
|
|
+
|
|
|
+ used_item = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // If its a consumable, we delete it on use
|
|
|
+ if used_item {
|
|
|
+ let consumable = consumables.get(useitem.item);
|
|
|
+ match consumable {
|
|
|
+ None => {}
|
|
|
+ Some(_) => {
|
|
|
+ entities.delete(useitem.item).expect("Delete failed");
|
|
|
}
|
|
|
- entities.delete(drink.potion).expect("Delete failed");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- wants_drink.clear();
|
|
|
+ wants_use.clear();
|
|
|
}
|
|
|
}
|
|
|
|