diff --git a/src/components.rs b/src/components.rs index 10ec230..8d6b22d 100644 --- a/src/components.rs +++ b/src/components.rs @@ -1,4 +1,4 @@ -use rltk::{RGB}; +use rltk::RGB; use specs::prelude::*; use specs_derive::*; @@ -13,7 +13,7 @@ pub struct Renderable { pub glyph: rltk::FontCharType, pub fg: RGB, pub bg: RGB, - pub render_order : i32, + pub render_order: i32, } #[derive(Component, Debug)] @@ -41,7 +41,7 @@ pub enum RunState { PlayerTurn, MonsterTurn, ShowInventory, - ShowDropItem + ShowDropItem, } #[derive(Component, Debug)] @@ -82,7 +82,7 @@ impl SufferDamage { pub struct Item {} #[derive(Component, Debug)] -pub struct Potion { +pub struct ProvidesHealing { pub heal_amount: i32, } @@ -98,13 +98,13 @@ pub struct WantsToPickupItem { } #[derive(Component, Debug)] -pub struct WantsToDrinkPotion { - pub potion: Entity, +pub struct WantsToUseItem { + pub item: Entity, } #[derive(Component, Debug, Clone)] pub struct WantsToDropItem { - pub item : Entity + pub item: Entity, } #[derive(Component, Debug)] -pub struct Consumable {} \ No newline at end of file +pub struct Consumable {} diff --git a/src/inventory_system.rs b/src/inventory_system.rs index 2ada99f..2100618 100644 --- a/src/inventory_system.rs +++ b/src/inventory_system.rs @@ -1,11 +1,10 @@ use specs::prelude::*; use super::{ - gamelog::GameLog, CombatStats, InBackpack, Name, Position, Potion, WantsToDrinkPotion, - WantsToPickupItem,WantsToDropItem + gamelog::GameLog, CombatStats, Consumable, InBackpack, Name, Position, ProvidesHealing, + WantsToDropItem, WantsToPickupItem, WantsToUseItem, }; - pub struct ItemCollectionSystem {} impl<'a> System<'a> for ItemCollectionSystem { @@ -45,17 +44,18 @@ impl<'a> System<'a> for ItemCollectionSystem { } } -pub struct PotionUseSystem {} +pub struct ItemUseSystem {} -impl<'a> System<'a> for PotionUseSystem { +impl<'a> System<'a> for ItemUseSystem { #[allow(clippy::type_complexity)] type SystemData = ( ReadExpect<'a, Entity>, WriteExpect<'a, GameLog>, Entities<'a>, - WriteStorage<'a, WantsToDrinkPotion>, + WriteStorage<'a, WantsToUseItem>, ReadStorage<'a, Name>, - ReadStorage<'a, Potion>, + ReadStorage<'a, Consumable>, + ReadStorage<'a, ProvidesHealing>, WriteStorage<'a, CombatStats>, ); @@ -64,65 +64,85 @@ impl<'a> System<'a> for PotionUseSystem { player_entity, mut gamelog, entities, - mut wants_drink, + mut wants_use, names, - potions, + consumables, + healing, mut combat_stats, ) = data; - for (entity, drink, stats) in (&entities, &wants_drink, &mut combat_stats).join() { - let potion = potions.get(drink.potion); - - match potion { + for (entity, useitem) in (&entities, &wants_use).join() { + let item_heals = healing.get(useitem.item); + match item_heals { None => {} - Some(potion) => { - stats.hp = i32::min(stats.max_hp, stats.hp + potion.heal_amount); - gamelog.entries.push(format!("{}", stats.hp)); - if entity == *player_entity { - gamelog.entries.push(format!( - "You drink the {}, healing {} hp.", - names.get(drink.potion).unwrap().name, - potion.heal_amount - )); - entities.delete(drink.potion).expect("Delete failed") - } + Some(healer) => { + let stats = combat_stats.get_mut(*player_entity); + stats.hp = i32::min(stats.max_hp, stats.hp + healer.heal_amount); + } + } + let consumable = consumables.get(useitem.item); + + match consumable { + None => {} + Some(_) => { + entities.delete(useitem.item).expect("Delete failed"); } } } - wants_drink.clear(); + wants_use.clear(); } } pub struct ItemDropSystem {} impl<'a> System<'a> for ItemDropSystem { #[allow(clippy::type_complexity)] - type SystemData = ( ReadExpect<'a, Entity>, - WriteExpect<'a, GameLog>, - Entities<'a>, - WriteStorage<'a, WantsToDropItem>, - ReadStorage<'a, Name>, - WriteStorage<'a, Position>, - WriteStorage<'a, InBackpack> - ); + type SystemData = ( + ReadExpect<'a, Entity>, + WriteExpect<'a, GameLog>, + Entities<'a>, + WriteStorage<'a, WantsToDropItem>, + ReadStorage<'a, Name>, + WriteStorage<'a, Position>, + WriteStorage<'a, InBackpack>, + ); - fn run(&mut self, data : Self::SystemData) { - let (player_entity, mut gamelog, entities, mut wants_drop, names, mut positions, mut backpack) = data; + fn run(&mut self, data: Self::SystemData) { + let ( + player_entity, + mut gamelog, + entities, + mut wants_drop, + names, + mut positions, + mut backpack, + ) = data; for (entity, to_drop) in (&entities, &wants_drop).join() { - let mut dropper_pos : Position = Position{x:0, y:0}; + 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("Unable to insert position"); + positions + .insert( + to_drop.item, + Position { + x: dropper_pos.x, + y: dropper_pos.y, + }, + ) + .expect("Unable to insert position"); backpack.remove(to_drop.item); if entity == *player_entity { - gamelog.entries.push(format!("You drop the {}", names.get(to_drop.item).unwrap().name)); + gamelog.entries.push(format!( + "You drop the {}", + names.get(to_drop.item).unwrap().name + )); } } - + wants_drop.clear(); } } diff --git a/src/main.rs b/src/main.rs index 5e6a2d4..97f19fd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -58,9 +58,9 @@ impl State { damage_system.run_now(&self.ecs); let mut pickup = ItemCollectionSystem {}; pickup.run_now(&self.ecs); - let mut drop_items = ItemDropSystem{}; + let mut drop_items = ItemDropSystem {}; drop_items.run_now(&self.ecs); - let mut potions = PotionUseSystem {}; + let mut potions = ItemUseSystem {}; potions.run_now(&self.ecs); self.ecs.maintain(); } @@ -77,11 +77,13 @@ impl GameState for State { let map = self.ecs.fetch::(); let mut data = (&positions, &renderables).join().collect::>(); - data.sort_by(|&a, &b| b.1.render_order.cmp(&a.1.render_order) ); + data.sort_by(|&a, &b| b.1.render_order.cmp(&a.1.render_order)); for (pos, render) in data.iter() { let idx = map.xy_idx(pos.x, pos.y); - if map.visible_tiles[idx] { ctx.set(pos.x, pos.y, render.fg, render.bg, render.glyph) } + if map.visible_tiles[idx] { + ctx.set(pos.x, pos.y, render.fg, render.bg, render.glyph) + } } // for (pos, render) in (&positions, &renderables).join() { // let idx = map.xy_idx(pos.x, pos.y); @@ -142,11 +144,16 @@ impl GameState for State { let result = gui::drop_item_menu(self, ctx); match result.0 { gui::ItemMenuResult::Cancel => newrunstate = RunState::AwaitingInput, - gui::ItemMenuResult::NoResponse => {}, + gui::ItemMenuResult::NoResponse => {} gui::ItemMenuResult::Selected => { let item_entity = result.1.unwrap(); let mut intent = self.ecs.write_storage::(); - intent.insert(*self.ecs.fetch::(), WantsToDropItem { item: item_entity }).expect("Unable to insert intent"); + intent + .insert( + *self.ecs.fetch::(), + WantsToDropItem { item: item_entity }, + ) + .expect("Unable to insert intent"); newrunstate = RunState::PlayerTurn; } } @@ -155,11 +162,16 @@ impl GameState for State { let result = gui::drop_item_menu(self, ctx); match result.0 { gui::ItemMenuResult::Cancel => newrunstate = RunState::AwaitingInput, - gui::ItemMenuResult::NoResponse => {}, + gui::ItemMenuResult::NoResponse => {} gui::ItemMenuResult::Selected => { let item_entity = result.1.unwrap(); let mut intent = self.ecs.write_storage::(); - intent.insert(*self.ecs.fetch::(), WantsToDropItem { item: item_entity }).expect("Unable to insert intent"); + intent + .insert( + *self.ecs.fetch::(), + WantsToDropItem { item: item_entity }, + ) + .expect("Unable to insert intent"); newrunstate = RunState::PlayerTurn; } } @@ -193,7 +205,7 @@ fn main() -> rltk::BError { gs.ecs.register::(); gs.ecs.register::(); gs.ecs.register::(); - gs.ecs.register::(); + gs.ecs.register::(); gs.ecs.register::(); gs.ecs.register::(); gs.ecs.register::(); diff --git a/src/spawner.rs b/src/spawner.rs index c94092a..055f437 100644 --- a/src/spawner.rs +++ b/src/spawner.rs @@ -1,8 +1,8 @@ use crate::MAPWIDTH; use super::{ - BlocksTile, CombatStats, Item, Monster, Name, Player, Position, Potion, Rect, Renderable, - Viewshed, + BlocksTile, CombatStats, Item, Monster, Name, Player, Position, ProvidesHealing, Rect, + Renderable, Viewshed, }; use rltk::{RandomNumberGenerator, RGB}; use specs::prelude::*; @@ -21,7 +21,7 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity { glyph: rltk::to_cp437('@'), fg: RGB::named(rltk::YELLOW), bg: RGB::named(rltk::BLACK), - render_order: 0 + render_order: 0, }) .with(Player {}) .with(Viewshed { @@ -67,7 +67,7 @@ fn monster(ecs: &mut World, x: i32, y: i32, glyph: rltk::FontCharTy glyph: glyph, fg: RGB::named(rltk::RED), bg: RGB::named(rltk::BLACK), - render_order: 1 + render_order: 1, }) .with(Viewshed { visible_tiles: Vec::new(), @@ -144,12 +144,12 @@ fn health_potion(ecs: &mut World, x: i32, y: i32) { glyph: rltk::to_cp437(';'), fg: RGB::named(rltk::MAGENTA), bg: RGB::named(rltk::BLACK), - render_order: 2 + render_order: 2, }) .with(Name { name: "Health Potion".to_string(), }) .with(Item {}) - .with(Potion { heal_amount: 8 }) + .with(ProvidesHealing { heal_amount: 8 }) .build(); }