Lesson 12.5: Creating the first consumable GameItem

Now, we’ll create our first consumable item – a healthy granola bar that will heal the player for 2 hit points.




Lesson Steps

Step 1: Modify Engine\Models\GameItem.cs

We’re eventually going to display all consumable items in a combombo on the UI, with a button to eat/use the item. So, we need a way to know which GameItem objects can be consumed.

For now, we’ll do that by adding the value ” Consumable” to the ItemCategory enum (line 11). Be sure to add the comma at the end of line 10.





Step 2: Create the new class Engine\Actions\Heal.cs

Before we create the granola bar GameItem, we need to make the action class it will use. This will be the Heal class.

There is a lot of code in Heal that is similar to the code in AttackWithWeapon. We’re going to do some refactoring soon, to combine the duplicate code.





Step 3: Modify Engine\Factories\ItemFactory.cs

Now, we can create the granola bar GameItem object.


I added a helper function BuildHealingItem (lines 51-56) to create the default healing item object and populate its Action property with a Heal action object.


We create the standard granola bar object on line 21.





Step 4: Modify Engine\Models\LivingEntity.cs

Since we’re going to display the player’s consumable inventory items in the UI, and let them eat/use one of them, we need to add a list of the consumable items (to bind to the combobox) and a property to hold the currently-selected consumable.


Line 18 has the backing variable “_currentConsumable” for the currently-selected consumable in the combobox.


The setter and getter for the CurrentConsumable are on lines 91-110. It subscribes to, and unsubscribes from, the item’s Action’s OnActionPerformed and handles it with the existing RaiseActionPerformedEvent function (to report the item’s message back to the UI).


There’s a new Consumables property (lines 119-120) to bind to the UI’s combobox, and a new HasConsumable property (line 122) to hide or show the combobox.


On lines 149-153, I added a small helper function we’ll call from GameSession, when the player uses their currently-selected consumable.

Currently, the actor and target are both the player (the “this” parameter values). In the future, we might add the ability to use a consumable on someone else – for example, using a healing potion on a pet that travels with you. But, we’ll worry about that in the future.

This function also removes the item from the player’s inventory after they use it.


The new Consumables list property does not automatically notify the UI of changes (because it’s a derived list), we need to manually notify the UI when we add or remove items that might be in the Consumables property.

We do this by calling the OnPropertyChanged function for the Consumables and HasConsumable properties on lines 215-216 and 240-241.





Step 5: Modify Engine\ViewModels\GameSession.cs

Add the UseCurrentConsumable function on lines 272-275.


While we’re in this class, let’s give the Player a granola bar when they start the game (line 132).





Step 6: Modify WPFUI\MainWindow.xaml and MainWindow.xaml.cs

Replace the “Combat Controls” grid (lines 216-241, in the original code) with the code listed below.

This is the new combobox and “Use” button for consumable items.

There are also some changes for hiding and showing the controls. Originally, the complete grid was only shown if there is a monster at the current location. Now, the weapon combobox and button use the “HasMonster” property, while the consumable controls use “CurrentPlayer.HasConsumable” – so the player can use a consumable item at any location.


NOTE: I also removed the SelectedValuePath=”ID” attribute from the CurrentWeapon combobox. We don’t use it, and it actually should have been “ItemTypeID”.


MainWindow.xaml.cs has a new function OnClick_UseCurrentConsumable (lines 49-52) for when the player clicks the “Use” button for a consumable item.


MainWindow.xaml (lines 216-252)






Step 7: Run the unit tests and test the game


Return to main page

Leave a Reply

Your email address will not be published. Required fields are marked *