diff --git a/src/inventory/collection_system.rs b/src/inventory/collection_system.rs new file mode 100644 index 0000000..3c54c35 --- /dev/null +++ b/src/inventory/collection_system.rs @@ -0,0 +1,60 @@ +use super::{ + gamelog, EquipmentChanged, InBackpack, MagicItem, MasterDungeonMap, Name, ObfuscatedName, Position, Wand, + WantsToPickupItem, +}; +use crate::gui::obfuscate_name; +use specs::prelude::*; + +pub struct ItemCollectionSystem {} + +impl<'a> System<'a> for ItemCollectionSystem { + #[allow(clippy::type_complexity)] + type SystemData = ( + ReadExpect<'a, Entity>, + WriteStorage<'a, WantsToPickupItem>, + WriteStorage<'a, Position>, + ReadStorage<'a, Name>, + WriteStorage<'a, InBackpack>, + WriteStorage<'a, EquipmentChanged>, + ReadStorage<'a, MagicItem>, + ReadStorage<'a, ObfuscatedName>, + ReadExpect<'a, MasterDungeonMap>, + ReadStorage<'a, Wand>, + ); + + fn run(&mut self, data: Self::SystemData) { + let ( + player_entity, + mut wants_pickup, + mut positions, + names, + mut backpack, + mut equipment_changed, + magic_items, + obfuscated_names, + dm, + wands, + ) = data; + + for pickup in wants_pickup.join() { + positions.remove(pickup.item); + backpack.insert(pickup.item, InBackpack { owner: pickup.collected_by }).expect("Unable to pickup item."); + equipment_changed + .insert(pickup.collected_by, EquipmentChanged {}) + .expect("Unable to insert EquipmentChanged."); + + if pickup.collected_by == *player_entity { + gamelog::Logger::new() + .append("You pick up the") + .item_name_n(format!( + "{}", + obfuscate_name(pickup.item, &names, &magic_items, &obfuscated_names, &dm, Some(&wands)).0 + )) + .period() + .log(); + } + } + + wants_pickup.clear(); + } +} diff --git a/src/inventory/drop_system.rs b/src/inventory/drop_system.rs new file mode 100644 index 0000000..1f23442 --- /dev/null +++ b/src/inventory/drop_system.rs @@ -0,0 +1,68 @@ +use super::{ + gamelog, EquipmentChanged, InBackpack, MagicItem, MasterDungeonMap, Name, ObfuscatedName, Position, Wand, + WantsToDropItem, +}; +use crate::gui::obfuscate_name; +use specs::prelude::*; + +pub struct ItemDropSystem {} + +impl<'a> System<'a> for ItemDropSystem { + #[allow(clippy::type_complexity)] + type SystemData = ( + ReadExpect<'a, Entity>, + Entities<'a>, + WriteStorage<'a, WantsToDropItem>, + ReadStorage<'a, Name>, + WriteStorage<'a, Position>, + WriteStorage<'a, InBackpack>, + WriteStorage<'a, EquipmentChanged>, + ReadStorage<'a, MagicItem>, + ReadStorage<'a, ObfuscatedName>, + ReadExpect<'a, MasterDungeonMap>, + ReadStorage<'a, Wand>, + ); + + fn run(&mut self, data: Self::SystemData) { + let ( + player_entity, + entities, + mut wants_drop, + names, + mut positions, + mut backpack, + mut equipment_changed, + magic_items, + obfuscated_names, + dm, + wands, + ) = data; + + for (entity, to_drop) in (&entities, &wants_drop).join() { + equipment_changed.insert(entity, EquipmentChanged {}).expect("Unable to insert EquipmentChanged."); + let mut dropper_pos: Position = Position { x: 0, y: 0 }; + { + let dropped_pos = positions.get(entity).unwrap(); + dropper_pos.x = dropped_pos.x; + dropper_pos.y = dropped_pos.y; + } + positions + .insert(to_drop.item, Position { x: dropper_pos.x, y: dropper_pos.y }) + .expect("Failed to insert position."); + backpack.remove(to_drop.item); + + if entity == *player_entity { + gamelog::Logger::new() + .append("You drop the") + .item_name_n(format!( + "{}", + obfuscate_name(to_drop.item, &names, &magic_items, &obfuscated_names, &dm, Some(&wands)).0 + )) + .period() + .log(); + } + } + + wants_drop.clear(); + } +} diff --git a/src/inventory/identification_system.rs b/src/inventory/identification_system.rs new file mode 100644 index 0000000..4e34123 --- /dev/null +++ b/src/inventory/identification_system.rs @@ -0,0 +1,37 @@ +use super::{IdentifiedItem, MasterDungeonMap, Name, ObfuscatedName}; +use crate::{Item, Player}; +use specs::prelude::*; + +pub struct ItemIdentificationSystem {} + +impl<'a> System<'a> for ItemIdentificationSystem { + #[allow(clippy::type_complexity)] + type SystemData = ( + ReadStorage<'a, Player>, + WriteStorage<'a, IdentifiedItem>, + WriteExpect<'a, MasterDungeonMap>, + ReadStorage<'a, Item>, + ReadStorage<'a, Name>, + WriteStorage<'a, ObfuscatedName>, + Entities<'a>, + ); + + fn run(&mut self, data: Self::SystemData) { + let (player, mut identified, mut dm, items, names, mut obfuscated_names, entities) = data; + for (_p, id) in (&player, &identified).join() { + rltk::console::log(id.name.clone()); + let tag = crate::raws::get_id_from_name(id.name.clone()); + if !dm.identified_items.contains(&id.name) && crate::raws::is_tag_magic(&tag) { + dm.identified_items.insert(id.name.clone()); + + for (entity, _item, name) in (&entities, &items, &names).join() { + if name.name == id.name { + obfuscated_names.remove(entity); + } + } + } + } + // Clean up + identified.clear(); + } +} diff --git a/src/inventory/mod.rs b/src/inventory/mod.rs new file mode 100644 index 0000000..5fa5336 --- /dev/null +++ b/src/inventory/mod.rs @@ -0,0 +1,18 @@ +use super::{ + gamelog, Confusion, Consumable, Cursed, Destructible, Digger, EquipmentChanged, Equippable, Equipped, HungerClock, + HungerState, IdentifiedItem, InBackpack, InflictsDamage, MagicItem, MagicMapper, Map, MasterDungeonMap, Name, + ObfuscatedName, ParticleBuilder, Point, Pools, Position, ProvidesHealing, ProvidesNutrition, RandomNumberGenerator, + RunState, SufferDamage, TileType, Viewshed, Wand, WantsToDropItem, WantsToPickupItem, WantsToRemoveItem, + WantsToUseItem, AOE, DEFAULT_PARTICLE_LIFETIME, LONG_PARTICLE_LIFETIME, +}; + +mod collection_system; +mod drop_system; +mod identification_system; +mod remove_system; +mod use_system; + +pub use { + collection_system::ItemCollectionSystem, drop_system::ItemDropSystem, + identification_system::ItemIdentificationSystem, remove_system::ItemRemoveSystem, use_system::ItemUseSystem, +}; diff --git a/src/inventory/remove_system.rs b/src/inventory/remove_system.rs new file mode 100644 index 0000000..1b33f50 --- /dev/null +++ b/src/inventory/remove_system.rs @@ -0,0 +1,32 @@ +use super::{gamelog, Equipped, InBackpack, Name, WantsToRemoveItem}; +use specs::prelude::*; + +pub struct ItemRemoveSystem {} + +impl<'a> System<'a> for ItemRemoveSystem { + #[allow(clippy::type_complexity)] + type SystemData = ( + Entities<'a>, + ReadExpect<'a, Entity>, + ReadStorage<'a, Name>, + WriteStorage<'a, WantsToRemoveItem>, + WriteStorage<'a, Equipped>, + WriteStorage<'a, InBackpack>, + ); + + fn run(&mut self, data: Self::SystemData) { + let (entities, player_entity, names, mut wants_remove, mut equipped, mut backpack) = data; + + for (entity, to_remove) in (&entities, &wants_remove).join() { + equipped.remove(to_remove.item); + if let Some(name) = names.get(to_remove.item) { + if entity == *player_entity { + gamelog::Logger::new().append("You unequip the").item_name_n(&name.name).period().log(); + } + } + backpack.insert(to_remove.item, InBackpack { owner: entity }).expect("Unable to insert backpack"); + } + + wants_remove.clear(); + } +} diff --git a/src/inventory_system.rs b/src/inventory/use_system.rs similarity index 70% rename from src/inventory_system.rs rename to src/inventory/use_system.rs index 235dc12..0b1bc32 100644 --- a/src/inventory_system.rs +++ b/src/inventory/use_system.rs @@ -1,66 +1,11 @@ use super::{ - gamelog, gui::obfuscate_name, Confusion, Consumable, Cursed, Destructible, Digger, EquipmentChanged, Equippable, - Equipped, HungerClock, HungerState, IdentifiedItem, InBackpack, InflictsDamage, MagicItem, MagicMapper, Map, - MasterDungeonMap, Name, ObfuscatedName, ParticleBuilder, Point, Pools, Position, ProvidesHealing, - ProvidesNutrition, RandomNumberGenerator, RunState, SufferDamage, TileType, Viewshed, Wand, WantsToDropItem, - WantsToPickupItem, WantsToRemoveItem, WantsToUseItem, AOE, DEFAULT_PARTICLE_LIFETIME, LONG_PARTICLE_LIFETIME, + gamelog, Confusion, Consumable, Cursed, Destructible, Digger, EquipmentChanged, Equippable, Equipped, HungerClock, + HungerState, IdentifiedItem, InBackpack, InflictsDamage, MagicMapper, Map, Name, ParticleBuilder, Point, Pools, + Position, ProvidesHealing, ProvidesNutrition, RandomNumberGenerator, RunState, SufferDamage, TileType, Viewshed, + Wand, WantsToUseItem, AOE, DEFAULT_PARTICLE_LIFETIME, LONG_PARTICLE_LIFETIME, }; use specs::prelude::*; -pub struct ItemCollectionSystem {} - -impl<'a> System<'a> for ItemCollectionSystem { - #[allow(clippy::type_complexity)] - type SystemData = ( - ReadExpect<'a, Entity>, - WriteStorage<'a, WantsToPickupItem>, - WriteStorage<'a, Position>, - ReadStorage<'a, Name>, - WriteStorage<'a, InBackpack>, - WriteStorage<'a, EquipmentChanged>, - ReadStorage<'a, MagicItem>, - ReadStorage<'a, ObfuscatedName>, - ReadExpect<'a, MasterDungeonMap>, - ReadStorage<'a, Wand>, - ); - - fn run(&mut self, data: Self::SystemData) { - let ( - player_entity, - mut wants_pickup, - mut positions, - names, - mut backpack, - mut equipment_changed, - magic_items, - obfuscated_names, - dm, - wands, - ) = data; - - for pickup in wants_pickup.join() { - positions.remove(pickup.item); - backpack.insert(pickup.item, InBackpack { owner: pickup.collected_by }).expect("Unable to pickup item."); - equipment_changed - .insert(pickup.collected_by, EquipmentChanged {}) - .expect("Unable to insert EquipmentChanged."); - - if pickup.collected_by == *player_entity { - gamelog::Logger::new() - .append("You pick up the") - .item_name_n(format!( - "{}", - obfuscate_name(pickup.item, &names, &magic_items, &obfuscated_names, &dm, Some(&wands)).0 - )) - .period() - .log(); - } - } - - wants_pickup.clear(); - } -} - // Grouping together components because of type complexity issues - SystemData was too large. // This is a temporary solution that'll be fixed once inventory use is refactored into separate // systems. @@ -428,129 +373,3 @@ impl<'a> System<'a> for ItemUseSystem { wants_to_use.clear(); } } - -pub struct ItemIdentificationSystem {} - -impl<'a> System<'a> for ItemIdentificationSystem { - #[allow(clippy::type_complexity)] - type SystemData = ( - ReadStorage<'a, crate::components::Player>, - WriteStorage<'a, IdentifiedItem>, - WriteExpect<'a, crate::map::MasterDungeonMap>, - ReadStorage<'a, crate::Item>, - ReadStorage<'a, Name>, - WriteStorage<'a, crate::ObfuscatedName>, - Entities<'a>, - ); - - fn run(&mut self, data: Self::SystemData) { - let (player, mut identified, mut dm, items, names, mut obfuscated_names, entities) = data; - for (_p, id) in (&player, &identified).join() { - rltk::console::log(id.name.clone()); - let tag = crate::raws::get_id_from_name(id.name.clone()); - if !dm.identified_items.contains(&id.name) && crate::raws::is_tag_magic(&tag) { - dm.identified_items.insert(id.name.clone()); - - for (entity, _item, name) in (&entities, &items, &names).join() { - if name.name == id.name { - obfuscated_names.remove(entity); - } - } - } - } - // Clean up - identified.clear(); - } -} - -pub struct ItemDropSystem {} - -impl<'a> System<'a> for ItemDropSystem { - #[allow(clippy::type_complexity)] - type SystemData = ( - ReadExpect<'a, Entity>, - Entities<'a>, - WriteStorage<'a, WantsToDropItem>, - ReadStorage<'a, Name>, - WriteStorage<'a, Position>, - WriteStorage<'a, InBackpack>, - WriteStorage<'a, EquipmentChanged>, - ReadStorage<'a, MagicItem>, - ReadStorage<'a, ObfuscatedName>, - ReadExpect<'a, MasterDungeonMap>, - ReadStorage<'a, Wand>, - ); - - fn run(&mut self, data: Self::SystemData) { - let ( - player_entity, - entities, - mut wants_drop, - names, - mut positions, - mut backpack, - mut equipment_changed, - magic_items, - obfuscated_names, - dm, - wands, - ) = data; - - for (entity, to_drop) in (&entities, &wants_drop).join() { - equipment_changed.insert(entity, EquipmentChanged {}).expect("Unable to insert EquipmentChanged."); - let mut dropper_pos: Position = Position { x: 0, y: 0 }; - { - let dropped_pos = positions.get(entity).unwrap(); - dropper_pos.x = dropped_pos.x; - dropper_pos.y = dropped_pos.y; - } - positions - .insert(to_drop.item, Position { x: dropper_pos.x, y: dropper_pos.y }) - .expect("Failed to insert position."); - backpack.remove(to_drop.item); - - if entity == *player_entity { - gamelog::Logger::new() - .append("You drop the") - .item_name_n(format!( - "{}", - obfuscate_name(to_drop.item, &names, &magic_items, &obfuscated_names, &dm, Some(&wands)).0 - )) - .period() - .log(); - } - } - - wants_drop.clear(); - } -} - -pub struct ItemRemoveSystem {} - -impl<'a> System<'a> for ItemRemoveSystem { - #[allow(clippy::type_complexity)] - type SystemData = ( - Entities<'a>, - ReadExpect<'a, Entity>, - ReadStorage<'a, Name>, - WriteStorage<'a, WantsToRemoveItem>, - WriteStorage<'a, Equipped>, - WriteStorage<'a, InBackpack>, - ); - - fn run(&mut self, data: Self::SystemData) { - let (entities, player_entity, names, mut wants_remove, mut equipped, mut backpack) = data; - - for (entity, to_remove) in (&entities, &wants_remove).join() { - equipped.remove(to_remove.item); - if let Some(name) = names.get(to_remove.item) { - if entity == *player_entity { - gamelog::Logger::new().append("You unequip the").item_name_n(&name.name).period().log(); - } - } - backpack.insert(to_remove.item, InBackpack { owner: entity }).expect("Unable to insert backpack"); - } - - wants_remove.clear(); - } -} diff --git a/src/main.rs b/src/main.rs index 1631a67..76aaa12 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,8 +28,7 @@ mod hunger_system; mod melee_combat_system; mod trigger_system; use melee_combat_system::MeleeCombatSystem; -mod inventory_system; -use inventory_system::*; +mod inventory; mod particle_system; use particle_system::{ParticleBuilder, DEFAULT_PARTICLE_LIFETIME, LONG_PARTICLE_LIFETIME}; mod ai; @@ -100,11 +99,11 @@ impl State { let mut trigger_system = trigger_system::TriggerSystem {}; let mut melee_system = MeleeCombatSystem {}; let mut damage_system = DamageSystem {}; - let mut inventory_system = ItemCollectionSystem {}; - let mut item_use_system = ItemUseSystem {}; - let mut item_drop_system = ItemDropSystem {}; - let mut item_remove_system = ItemRemoveSystem {}; - let mut item_id_system = ItemIdentificationSystem {}; + let mut inventory_system = inventory::ItemCollectionSystem {}; + let mut item_use_system = inventory::ItemUseSystem {}; + let mut item_drop_system = inventory::ItemDropSystem {}; + let mut item_remove_system = inventory::ItemRemoveSystem {}; + let mut item_id_system = inventory::ItemIdentificationSystem {}; let mut hunger_clock = hunger_system::HungerSystem {}; let mut particle_system = particle_system::ParticleSpawnSystem {};