Welcome back, screenshot voyeurs! A lot of work has been done on the ‘Ho! since I last checked in; multiple screens, UI goodness, and major chunks of functionality have been added… so let’s see some screenage!
This is Dungeon Ho!: Unity as it currently looks. Note the fancy new message console, which updates as commands are processed and automagically scrolls along with the messages. It’s groovy. We’ll look at how it was implemented in a future blog post. Also, check this;
Mmm, programmer art! Takes me back to the good ol’ days. Anyway, you’re looking at the inventory screen, and there are three major components of this bad boy. There’s the scrolling list of items on the left, then the information panel on the right, and of course the (cut off) context menu on the right-right. Both the item list and the context menu are fully interactive, and clicking on them will do interesting things like update the aforementioned information panel and execute the listed commands (although at the moment it’s only possible to equip, unequip, and drop the selected items).
That’s pretty hefty, I hear you cry. How did you do that? That’s why I come here, to read how you do things! Well, settle down there, Beavis; before we tackle any of that we need to talk about Items. How they’re defined, how they exist in the world, and how to interact with them. Once we get all of that nonsense out of the way, and are actually capable of picking up an item and placing it in our inventory (…and implement the inventory), we can start digging into the fancy-shmancy UI magic. Sound good? Are you psyched? Next to the combat process and effects system, this is pretty much the core of the entire game here, so let’s make sure we do it all real thorough-like.
First, what is an item? Well, in DHo! terms an Item is anything that is not a Mob, but is an Entity. Items inherit from the Entity class, and here is the first deviation from the original code design that we’re going to address; the issue of corpses.
Mobs leave behind corpses when they die. Is a corpse an Item, or simply a Mob with no health left? In the original game, Mobs spawned an actual corpse Item that contained a FLAG_CORPSE identifier when killed, and the actual Mob was removed from the Dungeon’s mob list. (Don’t worry, we’ll go over object flags in a later post.) This was fine, but it wasn’t optimal. What would I do if I wanted to add Raise/Animate Dead spells? I eventually decided for the rewrite to simply flag a dead mob as a corpse and handle the occasional deviation in logic in the relevant inventory subroutines.
But enough about that. We’ll go over it when we talk about combat. Here’s the Item class definition.
As you can see, there’s not much to it… but the Entity class has definitely expanded since we saw it last, so we’ll look at it next. An Item defines a slot variable that defaults to Inventory.SLOT_WEAPON_HAND, a constant that you can probably guess the purpose of without too much trouble… but if not, don’t worry; we’ll come back to it when we discuss the Inventory.
Items are actually GameObjects, so that they can be inserted into the world the same as the Player and Mobs. They exist on their own sprite render layer which is one step up from the TileMap, but one step down from the Mob/Entity layer. This allows Mob sprites to be rendered on top of any items in their current space. The Dungeon object has a List of Items in it (as well as a List for Mobs as well as a master List of both combined). Whenever we spawn either a Mob or Item into the level (including the Player), we invoke a method on the Dungeon that adds the object to the relevant list, as well as parenting its GameObject to the Dungeon’s.
So, what magic have we wrought upon the Entity class? Here you go;
The Entity item contains a number of interesting member variables, as well as getters and setters for all of them. Unfortunately, here’s where I’ve deviated from Unity/C# best practices and did not use the built-in C# getter/setter syntax. I did this because, well, I’m lazy and forgot about it until after I’d already defined all of the member variables, and didn’t feel like going back and duplicating them all and add underscores to the originals. The original Java codebase used standard getters and setters, so I basically just ported that because it’s what I’m more comfortable with. What can I say, I’m old. You kids and your new-fangled technology.
Anyway let’s talk about these variables. Most of what I’m about to say is basically regurgitating the code comments, so feel free to skip it if those made sense.
type – Every Entity has a type. For example, remember when we defined TYPE_HUMAN in order to spawn a Human Mob in the ObjectSpawner? That value gets stored here. That way, if we need a quick-and-dirty way to tell if an Item is a sword, or a Mob is a Kobold, we can look at this index. It’ll also come in handy when we eventually start writing these values out to a save file of some kind, so that we can use a generic table for every Item but call the relevant spawner method, of which there will be many.
id – A unique integer that identifies the Entity. Useful for “tagging” stuff, again, in the save file so that we know which items/effects belong to which mobs when storing inventories, for example.
flags – a single integer that can store a whole mess of information by way of boolean operations. We’ll look at Entity flags and how they work in a future blog.
weight – how much the Entity weighs, in pounds. (I’m American, what can I say?)
hp, maxHp, mana, maxMana – the current and maximum values of the relevant statistics. Yes, Items can have mana and health; it’s so we can allow things like wands to have “charges” or a set number of uses, and to model item damage and repair.
value – how much gold the player can get for selling the item to a vendor. Will also be used to calculate the player’s final haul (IE, score) if they survive the dungeon and complete the quest.
baseDamageType – a constant defining one of the eleven damage types in the game. Mainly used to determine the type of damage a Mob does with an unarmed attack; a human would deal TYPE_PHYSICAL damage while a ghost would deal TYPE_SPIRITUAL. Most weapons would have an attached DamageEffect and not use this value, but since it defaults to TYPE_PHYSICAL it can provide a quick-and-dirty way to use a generic, non-weapon item as a weapon. If that makes sense.
solid – if this boolean is set to true, then the Entity obstructs other Entities trying to move into its space. Primary used for Mobs, but also leaves open the option for things like conjurable Walls and such.
Inventory – this is the Entity’s inventory (duh). The reason it’s defined at the Entity level and not at the Mob level is because certain Items (such as containers – chests, bags, etc.) can have inventories.
Effects – any effects attached to the Entity. Effects are a huge, core component of the game and will be dealt with in a later blog.
Whew. That’s enough for today, I think. Tune in next time when I’ll show you how to spawn an item, then pick it up (via the PickUpCommand). Once it’s in our inventory, that’s where the real fun begins.