Blogus Maximus

Rubbing people the wrong way since 1970...

  Home  |   Contact  |   Syndication    |   Login
  1366 Posts | 10 Stories | 2226 Comments | 1336 Trackbacks

News


Google My Blog

Catch me at: The List!


My InstallScript Utility Belt My Amazon Wishlist
My Standard Disclaimer

Tag Cloud


Archives

Post Categories

Image Galleries

Blogs

Code Camps

CTown Geeks

Geeky Webcomics

High Geek

Magenic Blogs

Microsoft Blogs

My Articles

My Sites

PodCasts

UG

XNA

Like any good dungeon crawl, part of the fun is finding various items of treasure or equippable items such as armor or weaponry. This is how I do it in HA!

Keeping track of your stuff...
When a new dungeon level is initially generated, items are randomly generated and scattered throughout the level. Each of these items is an individual object with properties that define any special attributes the item may possess. These attributes may include magical bonuses, weight, effect duration, damage, etc.

Once an item is picked up by the player (or a monster, more on that later) it is added to the player's inventory, at which point we check to see if the player already has one of that item. If so, then increment the quantity property of the existing object in inventory and destroy the other object, as it is no longer needed. This assumes they are identical items, such as two non-magical swords or potions of the same type (healing, for example). Special magic items with unique properties get handled differently.

Now that our hero has 2 or 3 swords in his inventory, he may decide to equip one of them. (Some heroic classes, such as a Ranger or Barbarian might even equip more than one, i.e. as a sword in each hand.) When removing an item from inventory, we simply decrement the quantity property of the object in inventory and then create a new object of the specific instance of the item, which get assigned to an equippable body slot.

Dropping an item works much like equipping it. When dropping an item just decrement the quantity and create a new object of the same type on the ground at your feet. In a case where we only have one of an item in inventory, we don't need to alter the quantity, or create a new one. We just assign it to it's new position (if equipped) or map location (if dropped).

Ok, so where does all this stuff actually get stored?
Your backpack is really nothing more complex than an arraylist. (For those of you not familiar with the term, an arraylist is a very cool object in .NET that acts as a container for other objects. It's far superior to an array because all the objects can be of disparate types, and you don't have to predefine how big it is. It grows as you add stuff to it.) Once you have your backpack (arraylist) created, dropping an item into it is as simple as: Backpack.add(sword) or Backpack.add(leatherboots)

For now, just assume these are the names of objects created elsewhere. Note that we aren't using quotation marks around the item name, this isn't a string description but the actual name of the object. It could just as easily be Backpack.add(FlamingSwordofDoom) if that's the name of one of your item objects.

When leaving stuff on the ground (either at level creation or as the result of dropping something from inventory, we use a slightly different structure. The level map is essentially a giant array of type gridcell. Gridcell is a custom structure that contains info about each square of the map. (Remember roguelike games are essentially top-down, tile-based games...) Gridcell contains information such as tiletype {rock, wall, floor, door, etc} and items which is another arraylist, just like Backpack. This lets us add as many items as we want to any given square in the dungeon (provided it's not a forbidden type like rock, wall or closed door). The most recently added item is the one we actually display on the map, since it's "on top" of the pile. We could easily add code to limit the number of items added to a tile, causing the overflow to randomly spill over to another adjacent tile.

The code:

    Public Structure BodyLocations
        Dim Helmet As Object
        Dim Neck As Object
        Dim Cloak As Object
        Dim Girdle As Object
        Dim Armor As Object
        Dim LeftHand As Object
        Dim RightHand As Object
        Dim LeftRing As Object
        Dim RightRing As Object
        Dim Gloves As Object
        Dim Bracers As Object
        Dim Boots As Object
        Dim MissleWeapon As Object
        Dim Missles As Object
        Dim Tool As Object

        Dim BackPack As ArrayList
    End Structure


    ' This gets called when creating our Hero
    Public Equipment As BodyLocations
    Equipment.BackPack = New ArrayList

So then, to add an item to inventory... (.walkover is a string containing a description of what the Hero sees, items(0) assumes only 1 item exists in the square, there is other code for handling a pile of items, lastly m_arrLevel is the array containing the map info)

    Dim item As Object, AlreadyInBackpack As Boolean = False
    For Each item In m_Hero.Equipment.BackPack
       ' a match here means at least one of the item is already in our pack
       If item.walkover = m_arrLevel(intX, intY, intZ).items(0).walkover Then
          item.quantity += 1
          AlreadyInBackpack = True
       End If
    Next

    ' if the item we're picking up is NOT already in our pack, then add it
    If Not AlreadyInBackpack Then
       m_Hero.Equipment.BackPack.Add(m_arrLevel(intX, intY, intZ).items(0))
    End If

    m_arrLevel(intX, intY, intZ).items.RemoveAt(0)
    m_arrLevel(intX, intY, intZ).itemcount -= 1
    If m_arrLevel(intX, intY, intZ).itemcount = 0 Then m_arrLevel(intX, intY, intZ).itemcount = Nothing

In HA!, the equipped itms screen has a letter attached to each slot (A is for Head, B is for Neck, down through your cloak, armor, left and right hand, boots, etc...) If we want to move an item from inventory to the equippable neck slot, the code would look like this:

    ' show us ONLY the items in our backpack that can be equipped to this slot
    m_Hero.Equipment.Neck = ShowBackpack("", ItemType.Neck)

    
    ' inside the ShowBackpack function...
            Case ItemType.Neck
                Dim thing As Object
                WriteAt(0, yPos, "Amulets & Talismans:", ConsoleColor.DarkYellow)
                yPos += 1
                WriteAt(0, yPos, "--------------------", ConsoleColor.DarkYellow)
                yPos += 1

                WriteAt(1, yPos, "No items of this type.")
                For Each thing In m_Hero.Equipment.BackPack
                    If thing.type = ItemType.Neck Then
                        intQty = thing.quantity
                        Dim strItem As New StringBuilder

                        strItem.Append(startLetter & "] " & thing.Name)
                        If intQty > 1 Then strItem.Append(" (Qty: " & thing.quantity & ")")
                        strItem.Append("               ")
                        WriteAt(1, yPos, strItem.ToString)

                        yPos += 1
                        startLetter = Chr(Asc(startLetter) + 1)
                        itemArray.Add(thing)
                    End If
                Next
                yPos += 2

The above code will display all matches for the neck slot, with a different letter next to each item so you can press 'a' for the first one, 'b' for the second one, etc... then we pass the selected item (object) back to the proper slot in the code below:

     ShowBackpack = itemArray(intItemIndex)

So in the example above, m_Hero.Equipment.Neck = ShowBackpack("", ItemType.Neck), ShowBackpack returns the object of the item we selected, thereby assigning it to the equippable slot. All that is left is to destroy the item in inventory (or decrement the quantity if there's more than one)

    If itemArray(intItemIndex).quantity = 1 Then
         m_Hero.Equipment.BackPack.Remove(itemArray(intItemIndex))
         itemArray.RemoveAt(intItemIndex)

    ElseIf itemArray(intItemIndex).quantity > 1 Then
         m_Hero.Equipment.BackPack.Remove(itemArray(intItemIndex))
         itemArray(intItemIndex).quantity -= 1
         m_Hero.Equipment.BackPack.Add(itemArray(intItemIndex))
    End If

So that's pretty much it for inventory management. Certain cases require special coding, such as picking up items from piles and that sort of thing. Feel free to ask any questions.

Chris

posted on Saturday, May 28, 2005 2:16 PM

Feedback

# Heroic Adventure: Really cool RPG written in Visual Basic! 6/7/2005 6:51 PM briankel's WebLog
Chris Williams wrote an article talking about how he manages character inventory for his Visual...

# re: Object Oriented Inventory & Item Management in Heroic Adventure! 6/8/2005 8:05 AM Chris Williams
Hey thanks for stopping by. I'm at Tech*Ed so feel free to swing by the INETA booth and chat for a bit!

# re: Object Oriented Inventory & Item Management in Heroic Adventure! 6/9/2005 7:19 PM Matt
1. What is the point of creating a structure with all reference types in it?

2. Why not create your own base class for BodyLocations instead of using object. That way you can tell by the type that it is a body part.

3. Why are you having the programmer initialize the BackPack arraylist outside of the BodyLocations structure? That should be taken care of within the structure (which should be a class, given structures cannot have empty constructs)

4. Why wouldn't you use the Contains function for checking to see if an item is in the Backpack?



# re: Object Oriented Inventory & Item Management in Heroic Adventure! 6/11/2005 3:17 PM BlogusMaximus
Thanks for the feedback, when I decompress from Tech*Ed (just got back) I'll take a closer look and provide a better response.

# Trekking with Nomdas 8/10/2005 7:44 AM Jordan Beauty Tours
When thinking of Jordan, many of us associate it mainly with desert sands and the rose-red city of Petra. However Jordan has a lot more to offer. It abounds in natural beauty. There are a lot of places in Jordan where you can still merge with nature and have a true wilderness experience. You might wander about for days without meeting a soul, something you won’t even dream of anymore in the crowded and busy western world.

This 13-day hiking tour offers you the undiscovered Jordan. It’s an excellent opportunity to ‘walk slowly in this life’ and be one with nature. Allow yourself to explore the country on foot, and you will enjoy the beautiful natural environment with ‘every move you make, every step you take’.

The trail will offer an endless variety of landscapes, ranging from the green mountains of Dana to the natural fountains and white sands of Wadi Araba. From the black basalt rocks near Ras Namalah to the prehistoric site of Little Petra. Nowadays many of the sites you will visit are sparsely inhabited by the local Bedouin tribes. But in the early days many of them were flourishing. The tour will show you some of the highlights of these cultures ancient and gone. And of course we will also show you some of the highlights of the Jordanian history.
www.jordanbeauty.com

# re: Object Oriented Inventory & Item Management in Heroic Adventure! 1/28/2011 6:08 AM Swords
Do you really mean to say there's such intricate code behind a simple thing as items in an adventure game? I wasn't expecting that. I tried to keep up with the code and see what each bit does but object oriented programming isn't really my cup of tea. Thank you though for sharing this. It left me some thoughts on a few things and not many posts about games can do that.

Post A Comment
Title:
Name:
Email:
Comment:
Verification: