rust-rl/src/inventory/equip_system.rs
2023-09-24 23:46:27 +01:00

172 lines
6.7 KiB
Rust

use crate::{
gamelog,
gui::{ item_colour, obfuscate_name },
Beatitude,
EquipmentChanged,
Equippable,
Equipped,
IdentifiedBeatitude,
IdentifiedItem,
InBackpack,
MagicItem,
MasterDungeonMap,
Name,
ObfuscatedName,
WantsToUseItem,
BUC,
};
use specs::prelude::*;
use crate::consts::messages;
use bracket_lib::prelude::*;
pub struct ItemEquipSystem {}
impl<'a> System<'a> for ItemEquipSystem {
#[allow(clippy::type_complexity)]
type SystemData = (
ReadExpect<'a, Entity>,
Entities<'a>,
WriteStorage<'a, WantsToUseItem>,
WriteStorage<'a, IdentifiedItem>,
ReadStorage<'a, Name>,
ReadStorage<'a, Equippable>,
WriteStorage<'a, Equipped>,
WriteStorage<'a, InBackpack>,
WriteStorage<'a, EquipmentChanged>,
ReadStorage<'a, MagicItem>,
ReadStorage<'a, ObfuscatedName>,
ReadStorage<'a, Beatitude>,
WriteStorage<'a, IdentifiedBeatitude>,
ReadExpect<'a, MasterDungeonMap>,
);
#[allow(clippy::cognitive_complexity)]
fn run(&mut self, data: Self::SystemData) {
let (
player_entity,
entities,
mut wants_to_use_item,
mut identified_items,
names,
equippable,
mut equipped,
mut backpack,
mut dirty,
magic_items,
obfuscated_names,
beatitudes,
mut identified_beatitude,
dm,
) = data;
let mut remove: Vec<Entity> = Vec::new();
// For every item with a target, if the item is equippable, find the correct slot.
for (target, wants_to_use_item) in (&entities, &wants_to_use_item).join() {
if let Some(can_equip) = equippable.get(wants_to_use_item.item) {
let target_slot = can_equip.slot;
let mut logger = gamelog::Logger::new();
// Remove any items target has in item's slot
let mut can_equip = true;
let mut to_unequip: Vec<Entity> = Vec::new();
for (item_entity, already_equipped, _name) in (
&entities,
&equipped,
&names,
).join() {
if already_equipped.owner == target && already_equipped.slot == target_slot {
if let Some(beatitude) = beatitudes.get(item_entity) {
if beatitude.buc == BUC::Cursed {
can_equip = false;
logger = logger
.append(messages::YOU_REMOVE_ITEM_CURSED)
.colour(item_colour(item_entity, &beatitudes))
.append_n(
obfuscate_name(
item_entity,
&names,
&magic_items,
&obfuscated_names,
&beatitudes,
&dm,
None
).0
)
.colour(WHITE)
.append("!");
identified_beatitude
.insert(item_entity, IdentifiedBeatitude {})
.expect("Unable to push");
}
}
to_unequip.push(item_entity);
}
}
if !can_equip {
logger.log();
continue;
}
for item in to_unequip.iter() {
equipped.remove(*item);
backpack
.insert(*item, InBackpack { owner: target })
.expect("Unable to insert backpack");
if target == *player_entity {
logger = logger
.append(messages::YOU_REMOVE_ITEM)
.colour(item_colour(*item, &beatitudes))
.append_n(
obfuscate_name(
*item,
&names,
&magic_items,
&obfuscated_names,
&beatitudes,
&dm,
None
).0
)
.colour(WHITE)
.period();
}
}
// Wield the item
equipped
.insert(wants_to_use_item.item, Equipped { owner: target, slot: target_slot })
.expect("Unable to insert equipped component");
backpack.remove(wants_to_use_item.item);
if target == *player_entity {
logger = logger
.append(messages::YOU_EQUIP_ITEM)
.colour(item_colour(wants_to_use_item.item, &beatitudes))
.append_n(
obfuscate_name(
wants_to_use_item.item,
&names,
&magic_items,
&obfuscated_names,
&beatitudes,
&dm,
None
).0
)
.colour(WHITE)
.period();
logger.log();
identified_items
.insert(target, IdentifiedItem {
name: names.get(wants_to_use_item.item).unwrap().name.clone(),
})
.expect("Unable to insert IdentifiedItem");
identified_beatitude
.insert(wants_to_use_item.item, IdentifiedBeatitude {})
.expect("Unable to push");
}
remove.push(target);
}
}
remove.iter().for_each(|e| {
dirty.insert(*e, EquipmentChanged {}).expect("Unabble to insert EquipmentChanged");
wants_to_use_item.remove(*e).expect("Unable to remove *e");
})
}
}