Complete roguelike tutorial using C++ and libtcod - part 8: items and inventory

From RogueBasin
Jump to navigation Jump to search
Complete roguelike tutorial using C++ and libtcod
-originally written by Jice
Text in this tutorial was released under the Creative Commons Attribution-ShareAlike 3.0 Unported and the GNU Free Documentation License (unversioned, with no invariant sections, front-cover texts, or back-cover texts) on 2015-09-21.


In this article, we will start to add items to the dungeon, in the form of health potions. This will make it possible to kill every monster in the dungeon for the first time, even if the engine won't yet detect the end of game.

libtcod functions used in this article :

TCODConsole::printFrame

TCODSystem::waitForEvent

Actors that can be healed

For the health potion to work, we first need to be able to heal a Destructible. Let's add this. Destructible.hpp :

float heal(float amount);

Destructible.cpp :

float Destructible::heal(float amount) {
   hp += amount;
   if ( hp > maxHp ) {
       amount -= hp-maxHp;
       hp=maxHp;
   }
   return amount;
}

The function returns the amount of health point actually restored.

Pickable actors and containers

Now, we can start to make items that we can pick. Roguelikes often make a strong separation between creatures and items. Creatures have inventory and items can be picked. This can lead to unnecessary complications. For example, a chest is an item, has an inventory and cannot be picked.

Here we will break this separation and simply create actors that can be picked (and used) and actors that can contain other actors (a chest or a creature with an inventory). Let's add those two new features to our almighty Actor class :

Ai *ai; // something self-updating
Pickable *pickable; // something that can be picked and used
Container *container; // something that can contain actors

Include the headers (yet to be written) in main.hpp :

#include "Ai.hpp"
#include "Pickable.hpp"
#include "Container.hpp"
#include "Actor.hpp"

And initialize the features in the Actor constructor :

Actor::Actor(int x, int y, int ch, const char *name,
   const TCODColor &col) :
   x(x),y(y),ch(ch),col(col), name(name),
   blocks(true),attacker(NULL),destructible(NULL),ai(NULL),
   pickable(NULL),container(NULL) {
}   

Ok. So far we didn't bother with what happens when an actor is destroyed (because it never happens in the game since even a dead creature is an Actor). But when we're going to drink a health potion, we expect it to disappear from our inventory, so we're actually doing to delete the Actor object. Let's add a destructor that cleans the features :

Actor.hpp:

Actor(int x, int y, int ch, const char *name, const TCODColor &col);
~Actor();
void update();

Actor.cpp :

Actor::~Actor() {
   if ( attacker ) delete attacker;
   if ( destructible ) delete destructible;
   if ( ai ) delete ai;
   if ( pickable ) delete pickable;
   if ( container ) delete container;
}