1
0
Fork 0
roguelike-game/src/inventory_system/equip_use.rs

120 lines
4.2 KiB
Rust

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");
})
}
}