use ::bracket_lib::prelude::*; use ::specs::prelude::*; use crate::components::{AreaOfEffect, EntityMoved, EntryTrigger, Name, Position}; use crate::effects::{add_effect, aoe_tiles, EffectType, Targets}; use crate::{colors, gamelog, spatial, Map}; pub struct TriggerSystem {} impl<'a> System<'a> for TriggerSystem { #[allow(clippy::type_complexity)] type SystemData = ( ReadExpect<'a, Map>, WriteStorage<'a, EntityMoved>, ReadStorage<'a, Position>, ReadStorage<'a, EntryTrigger>, ReadStorage<'a, Name>, Entities<'a>, ReadStorage<'a, AreaOfEffect>, ); fn run(&mut self, data: Self::SystemData) { let (map, mut entity_moved, position, entry_trigger, names, entities, area_of_effect) = data; // Iterate the entities that moved and their final position for (entity, mut _entity_moved, pos) in (&entities, &mut entity_moved, &position).join() { let idx = map.xy_idx(pos.x, pos.y); spatial::for_each_tile_content(idx, |entity_id| { // Do not bother to check yourself for being a trap! if entity != entity_id { match entry_trigger.get(entity_id) { None => {} Some(_trigger) => { // We triggered it if let Some(name) = names.get(entity_id) { gamelog::color_line(colors::RED, &name.name) .append("triggers!") .log(); } // Call the effects system add_effect( Some(entity), EffectType::TriggerFire { trigger: entity_id }, if let Some(aoe) = area_of_effect.get(entity_id) { Targets::Tiles { tiles: aoe_tiles(&*map, Point::from(*pos), aoe.radius), } } else { Targets::Tile { tile_idx: idx as i32, } }, ) } } } }); } // Remove all entity movement markers entity_moved.clear(); } }