Adding Power After Receiving Inventory
Learn how to manage power after receiving a dungeon map and healing potion.
Sending an item-activation message
In Sending Messages of Intent, we adopted a pattern in which systems indicate their intent to perform an action and the actual action is handled in its own system. Using an item is no different. Decoupling intent and activation in this way allows our code to remain flexible. If we decide that a tough monster should be able to use magical items, we only need to send the message of intent without duplicating the effect code.
Add a new component named ActivateItem
in components.rs
:
#[derive(Clone, Copy, Debug, PartialEq)]pub struct ActivateItem {pub used_by : Entity,pub item : Entity}
The player needs to be able to send an ActivateItem
message by pressing a number key that matches the numbers displayed next to items in the HUD.
For this, we’ll add a new function at the end of the player_input.rs
file:
fn use_item(n: usize, ecs: &mut SubWorld, commands: &mut CommandBuffer)-> Point {let player_entity = <(Entity, &Player)>::query().iter(ecs).find_map(|(entity, _player)| Some(*entity)).unwrap();let item_entity = <(Entity, &Item, &Carried)>::query().iter(ecs).filter(|(_, _, carried)| carried.0 == player_entity).enumerate().filter(|(item_count, (_, _, _))| *item_count == n).find_map(|(_, (item_entity, _, _))| Some(*item_entity));if let Some(item_entity) = item_entity {commands.push(((), ActivateItem{used_by: player_entity,item: item_entity}));}Point::zero()}
-
Line 1: The
use_item()
function needs access to theSubWorld
andCommandBuffer
from the parent system. Borrowing these variables allows us to pass the variables from the system and use them in a function. -
Line 6: This uses a query to find the
Player
entity, exactly as we did before. -
Line 8: This uses a similar query to the HUD item finder. We iterate through carried items and filter out those not held by the player.
-
Line 11: The
enumerate
function adds a number starting from zero to each result. It’s a little confusing because we wind up with two tuples. The first contains(counter, other_tuple)
. The previous tuple is contained within the second tuple. The final structure is(counter, (Entity, Item, Carried))
. The nested brackets de-structure this into useful variable names. -
Line 12: This filters out items whose enumerator doesn’t match the
n
variable passed into the function. For example, if the user ...