From 4e9869b09f0973518236db6a16e181a682f15520 Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Thu, 4 Nov 2021 15:06:04 -0400 Subject: [PATCH] Refactor potion, and its associated components to be more generic --- src/components.rs | 9 ++++++--- src/inventory_system.rs | 45 +++++++++++++++++++++++++---------------- src/main.rs | 27 +++++++++++++++---------- src/spawner.rs | 7 ++++--- 4 files changed, 54 insertions(+), 34 deletions(-) diff --git a/src/components.rs b/src/components.rs index aac8516..cfd0a2a 100644 --- a/src/components.rs +++ b/src/components.rs @@ -72,7 +72,7 @@ impl SufferDamage { pub struct Item {} #[derive(Component, Debug)] -pub struct Potion { +pub struct ProvidesHealing { pub heal_amount: i32, } @@ -88,11 +88,14 @@ 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, } + +#[derive(Component, Debug)] +pub struct Consumable {} diff --git a/src/inventory_system.rs b/src/inventory_system.rs index ca76327..6967b8d 100644 --- a/src/inventory_system.rs +++ b/src/inventory_system.rs @@ -1,6 +1,6 @@ use crate::{ - game_log::GameLog, CombatStats, InBackpack, Name, Position, Potion, WantsToDrinkPotion, - WantsToDropItem, WantsToPickupItem, + game_log::GameLog, CombatStats, Consumable, InBackpack, Map, Name, Position, ProvidesHealing, + WantsToDropItem, WantsToPickupItem, WantsToUseItem, }; use specs::prelude::*; @@ -44,17 +44,19 @@ 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>, + ReadExpect<'a, Map>, Entities<'a>, - WriteStorage<'a, WantsToDrinkPotion>, + WriteStorage<'a, WantsToUseItem>, ReadStorage<'a, Name>, - ReadStorage<'a, Potion>, + ReadStorage<'a, Consumable>, + ReadStorage<'a, ProvidesHealing>, WriteStorage<'a, CombatStats>, ); @@ -62,33 +64,42 @@ impl<'a> System<'a> for PotionUseSystem { let ( player_entity, mut gamelog, + map, 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() { - match potions.get(drink.potion) { + for (entity, useitem, stats) in (&entities, &wants_use, &mut combat_stats).join() { + match healing.get(useitem.item) { None => {} - Some(potion) => { - stats.hp = i32::min(stats.max_hp, stats.hp + potion.heal_amount); + Some(healer) => { + stats.hp = i32::min(stats.max_hp, stats.hp + healer.heal_amount); if entity == *player_entity { gamelog.entries.push(format!( "You drink the {}, healing {} hp.", - names.get(drink.potion).unwrap().name, - potion.heal_amount + names.get(useitem.item).unwrap().name, + healer.heal_amount )); } + } + } + + let consumable = consumables.get(useitem.item); + match consumable { + None => {} + Some(_) => { entities - .delete(drink.potion) - .expect("Failed to delete potion"); + .delete(useitem.item) + .expect("Failed to consume item"); } } } - wants_drink.clear(); + wants_use.clear(); } } diff --git a/src/main.rs b/src/main.rs index 48c94dd..7e4437f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,7 @@ mod visibility_system; pub use components::*; use damage_system::DamageSystem; pub use game_log::GameLog; -use inventory_system::{ItemCollectionSystem, ItemDropSystem, PotionUseSystem}; +use inventory_system::{ItemCollectionSystem, ItemDropSystem, ItemUseSystem}; pub use map::*; use map_indexing_system::MapIndexingSystem; use melee_combat_system::MeleeCombatSystem; @@ -55,6 +55,10 @@ pub struct State { } impl State { + fn new() -> Self { + State { ecs: World::new() } + } + fn run_systems(&mut self) { let mut vis = VisibilitySystem {}; vis.run_now(&self.ecs); @@ -74,8 +78,8 @@ impl State { let mut pickup = ItemCollectionSystem {}; pickup.run_now(&self.ecs); - let mut potions = PotionUseSystem {}; - potions.run_now(&self.ecs); + let mut items = ItemUseSystem {}; + items.run_now(&self.ecs); let mut drop_items = ItemDropSystem {}; drop_items.run_now(&self.ecs); @@ -140,15 +144,15 @@ impl GameState for State { gui::ItemMenuResult::NoResponse => {} gui::ItemMenuResult::Selected => { let item_entity = result.1.unwrap(); - let mut intent = self.ecs.write_storage::(); + let mut intent = self.ecs.write_storage::(); intent .insert( *self.ecs.fetch::(), - WantsToDrinkPotion { - potion: item_entity, + WantsToUseItem { + item: item_entity, }, ) - .expect("failed to add intent to drink potion"); + .expect("failed to add intent to use item"); newrunstate = RunState::PlayerTurn; } @@ -192,7 +196,7 @@ fn main() -> rltk::BError { .with_title("Roguelike Tutorial") .build()?; - let mut gs = State { ecs: World::new() }; + let mut gs = State::new(); register!( gs <- @@ -207,14 +211,15 @@ fn main() -> rltk::BError { WantsToMelee, SufferDamage, Item, - Potion, + ProvidesHealing, InBackpack, WantsToPickupItem, - WantsToDrinkPotion, + WantsToUseItem, WantsToDropItem, + Consumable, ); - let map: Map = Map::new_map_rooms_and_corridors(); + let map = Map::new_map_rooms_and_corridors(); let (player_x, player_y) = map.rooms[0].center(); let player_entity = spawner::player(&mut gs.ecs, player_x, player_y); diff --git a/src/spawner.rs b/src/spawner.rs index b8d5fd3..5383dad 100644 --- a/src/spawner.rs +++ b/src/spawner.rs @@ -1,6 +1,6 @@ use crate::{ - BlocksTile, CombatStats, Item, Monster, Name, Player, Position, Potion, Rect, Renderable, - Viewshed, MAP_WIDTH, + BlocksTile, CombatStats, Consumable, Item, Monster, Name, Player, Position, ProvidesHealing, + Rect, Renderable, Viewshed, MAP_WIDTH, }; use rltk::{RandomNumberGenerator, RGB}; use specs::prelude::*; @@ -160,6 +160,7 @@ fn health_potion(ecs: &mut World, x: i32, y: i32) { name: "Health Potion".to_string(), }) .with(Item {}) - .with(Potion { heal_amount: 8 }) + .with(Consumable {}) + .with(ProvidesHealing { heal_amount: 8 }) .build(); }