use ::specs::prelude::*; use crate::components::{ CursedItem, EquipmentChanged, Equippable, Equipped, IdentifiedItem, InBackpack, Name, WantsToUseItem, }; use crate::gamelog; pub struct ItemEquipOnUse {} impl<'a> System<'a> for ItemEquipOnUse { #[allow(clippy::type_complexity)] type SystemData = ( ReadExpect<'a, Entity>, Entities<'a>, WriteStorage<'a, WantsToUseItem>, ReadStorage<'a, Name>, ReadStorage<'a, Equippable>, WriteStorage<'a, Equipped>, WriteStorage<'a, InBackpack>, WriteStorage<'a, EquipmentChanged>, WriteStorage<'a, IdentifiedItem>, ReadStorage<'a, CursedItem>, ); fn run(&mut self, data: Self::SystemData) { let ( player_entity, entities, mut wants_use, names, equippable, mut equipped, mut backpack, mut dirty, mut identified_item, cursed, ) = data; let mut remove_use = Vec::new(); for (target, useitem) in (&entities, &wants_use).join() { // If it is equippable, then we want to equip it -- // and un-equip whatever else was in that slot if let Some(can_equip) = equippable.get(useitem.item) { let target_slot = can_equip.slot; // Remove any items the target has in the item's slot let mut can_equip = true; let mut to_unequip = Vec::new(); for (item_entity, already_equipped, name) in (&entities, &equipped, &names).join() { if already_equipped.owner == target && already_equipped.slot == target_slot { if cursed.get(item_entity).is_some() { gamelog::line("You cannot un-equip") .item_name(&name.name) .append("- it is cursed!") .log(); can_equip = false; } else { to_unequip.push(item_entity); if target == *player_entity { gamelog::line("You un-equip").item_name(&name.name).log(); } } } } if can_equip { // Identify the item if target == *player_entity { identified_item .insert( target, IdentifiedItem { name: names.get(useitem.item).unwrap().name.clone(), }, ) .expect("Unable to identify item."); } for item in to_unequip.iter() { equipped.remove(*item); backpack .insert(*item, InBackpack { owner: target }) .expect("Unable to move equipped item to backpack."); } // Wield the item equipped .insert( useitem.item, Equipped { owner: target, slot: target_slot, }, ) .expect("Unable to equip item"); backpack.remove(useitem.item); if target == *player_entity { gamelog::line("You equip") .item_name(&names.get(useitem.item).unwrap().name) .log(); } } // Done with item remove_use.push(target); } } remove_use.iter().for_each(|e| { dirty .insert(*e, EquipmentChanged {}) .expect("Unable to insert EquipmentChanged tag"); wants_use .remove(*e) .expect("Failed to remove WantsToUseItem tag"); }) } }