The first type of entity that we will make is the Item class, which will be used for anything the player can pick up and collect in their adventure through the dungeon. We will also be using it as a base class for Weapons and Armor, which as well as being collectible will also have more useful properties such as damage done or damage reduced. The Item class will define just the attributes they share, specifically a name and a description.

Item of course inherits from the Entity base class, and so shares the load function as well as taking an id variable in its constructor arguments. The second constructor takes the same arguments as load and is required by the EntityManager as we discussed previously. We won’t be using the first constructor because all Items will be defined in JSON files, but its useful if you want to hardcode an Item into the game so I’ve included it.

Note that like in entity.hpp we’ve forward declared the EntityManager class, because we need to know of its existence. Whilst Item isn’t used directly by EntityManager, it is used in a template instantiation so one of the files has to forward declare instead of #include.

The definitions of these functions are all rather simple, and are contained in the item.cpp file.

The first constructor simply sets the name and description of the item according to the given arguments, and also calls the Entity constructor with the given id. The second calls the Entity constructor before calling the load() function in order to load the Item from the given JSON value. This will be a common pattern shared by all our derived entities. You might wonder why we’re bothering to create a load function at all if its only ever called by one constructor, which does nothing else! Well we want to ensure that each derived entity has a way to load from JSON files, and C++ unfortunately doesn’t let us create (pure) virtual constructors so we have to force it some other way. Sadly this means that we can still create derived classes which don’t have a constructor compatible with the EntityManager, but the compilation error that occurs is pretty easy to understand so it isn’t much of an issue.

Note that the JsonBox::Value will not be an entire JSON file, but instead just the value corresponding to a single key extracted by the EntityManager. By converting the value into a JsonBox::Object we can access that value like an std::map and extract all the information we want, namely the item name and description. We then convert the returned values into strings (because o["name"] returns a JsonBox::Value), which are assigned to the Item.

Note that here we are simply assuming the passed JsonBox::Value has a certain structure, which in general use is not guaranteed to be the case. To reduce complexity I haven’t included any error handling, but really you should check here for correct input, as JsonBox doesn’t do that for you.

There’s no use being able to load Items if you haven’t made any though! You’ll need to create at least one JSON file containing the items and then load them using the EntityManager. I used a single items.json file.

Now that the Item class is complete, we an implement two more entities; Weapon and Armor. These are pretty much identical to Item but each have an additional member variable corresponding to either the amount of damage they deal or the amount of incoming damage they reduce. The follow the same pattern as Item, but instead of calling the Entity constructor they call Items.

Additionally instead of using the getString function on the JsonBox::Value we’ve used getInteger, because defense is an int and not a string. JsonBox also provides getFloat, getDouble, getBoolean, and getArray, the last of which we will use later.

Weapon is pretty much identical but with defense replaced with damage, so I won’t waste space putting it here. For their JSON files I used separate weapon.json and armor.json files. (The last weapon is not for use by the player, but by a rat enemy that we will be creating later.)

It’s time now to start main.cpp I think, where we’ll just create an instance of EntityManager and load the items. Before you do, make sure you add those explicit function template instantiations!

We’ve also seeded the random number generator, which we’ll be using later. Usually the rand function returns the same set of random numbers every time the program is run (doesn’t sound very random does it?), by giving it a different seed each time we can guarantee that the random numbers will be different. C++ now has its own more powerful random number generator which we could use instead of C’s rand function, but its needlessly complicated when we don’t actually care how random our random numbers are.