RPG Item class

Started by
16 comments, last by BUnzaga 15 years, 10 months ago
I am recoding my RPG (for the third time) that I have been making on and off for 8 years now (I started before I knew c++). This time I decided instead of starting with getting a map displayed, then character, then moving around I would start with the battle system as it is something I haven never got around to doing and might give me some more insight on a better engine structure for my game. Currently it goes like this: BattleEngine class handles whos turn it is, asking them for an action and doing that action, then doling out exp/items at the end of the battle. There is the Beastiary & Party classes that handle the Character class, they both basically load a character (savegame or monster) from xml and is used to be scalable (so I can have more than one character on each side of the fight). What I am implementing now is an item system so the characters can equip something. My question is how have people gone about this.... I want my game to be very item-oriented ala Diablo II but for now I'll leave random item generation alone and stick to helm with 5 fire resistance etc. My Character class has private members like health, dhealth (delta health, i.e. how much health skills/items add onto or decrease your base health), strength, dStrength, fire_resistance, dFire_resistance, etc, etc. and I was thinking of having the Character class load in the items and parse their modifiers, adding them to the 'd' members of Character to be used in damage calculations, but then I realised if I did this I wouldn't really need an item class so much as a function to open the itemstats.xml, grab the item's modifiers and return them to the Character class... to me this doesn't sound right, I want to have the items loaded so you can view them in your inventory without having to relaod an xml everytime. The other way was to have the item class and load each item into its repspective Character memeber (Head, Torso, Ring1, Ring2, etc.) and then parse the modifiers everytime you need to claculate damage, but that seems inefficient to me, haivng to loop through all the items every round (Even item in the inventory can effect the player ala Diablo II charms). I was just looking for some advice on someone who has done this before on which way to go or wether there is a different approach I can't see. Thanks for reading this long as(probably illegible) post, first time posting here, but long time reader.
Advertisement
I think you're right that it's not good to run through the xml doc every time you use an item. I suggest loading items to memory (when needed, or if there aren't many, all at once) and keeping it somewhere it'll stay until no longer needed or until the game shuts down (whichever you feel is best for your game). But, I don't just mean in battle scope, I mean, what's in your inventory (in-game, in-battle) on the field, or in battle.

I also don't really like your delta-statistic system, but I never really thought about it. What I don't like about it is how it adds more variables to the equation (twice as many, in fact). Especially since how much fire-damage an attack should cause shouldn't need to be recalculated every time you attack. Maybe stat, dstat, and tstat (t for total). You might even have only dstat and tstat with the t being implicit.

Ever thought of having an object deal with how much damage an attack does? The result could be recalculated and you'd only ever need to recalculate when you change equipment, and it could keep track of the modifiers so when you attack using that object, it could figure the deductions based on defenses on its own.
They are there mainly so when temporary stat buffs/debuffs wear off it comes out of the delta and means things that use the base stat to calculate percentages (i.e. helm gives +15% strength should only work on base strength, not the extra strength from the +10% torso you have on), I evolved the delta stat idea into having a stat class where you overload operators so you would have a Statistics member in Character and when you load an item it would return a Statistic you could '+' onto the Character member. Oh, and yes, the total was implicit (return health + dHealth; )

I think I'll have the items instantiate at Character creation and have it cache the damage values/resistance values in the Character class, and if I need the original character's values I could reload from xml, right?
"if I need the original character's values I could reload from xml, right?"

sure.

I guess what I'm curious about now is: How do you calculate the delta stat? How often?

But back to the items: I don't really know that there's a best solution. If you have to look into the xml file every frame and the frame rate doesn't dip, you're code is redundant, but you can get away with it. If you load every item, all at once, you only have to look into the xml file once, but you've offended your RAM; not that that matters if you're not already using a bunch of RAM. The rout of loading at character initialization seems like the middle-ground to me.

So, what I'm trying to say is, I don't know that what you're doing, or what you're going to do, is bad because I don't know where your game is or is going. Never having had a problem with RAM, myself, I'd just load all the items, but you might've had a different experience.
No RAM probelms for me, and this is game is more a personal project than 'Hey world! Heres my awesome game!' so I can get away with being a RAM whore (If it ends up that way).

At the moment all it is is a commandline turn-by-turn fight (Press 1 for attack, 2 for items, 3 for skills, 4 for character screen, 5 for run away kinda thing). ofc in the end it'll get a gui and be integrated into RPG, but for now I like the autonomy (means I'm not influenced by previous game's structure).

The delta stats are calculated at Character intialisation and item equipping, so not very often... this will be later extended to being called when a spell wears off/battle is over as well.

e.g.:
You start off with dStrength = 0; (nothing calculated yet) Strength = 50; (from xml file).
You load up the helm, it has +15% strength (50 * 0.15 = 7.5 = 7) so dStrength = 7.
You load up the Armour it has + 4 strength, so dStrength is now 11.
Load the Gloves and they have +50% strength, so dStrength = 36 (25 + 11).
Boots have -10 strength, so dStrength is now 26.
if you call getStrength() it'll: return 50 + 26;

Make sense and answer your curiosities?
Do your calculations when you add or remove an item. That is the only time that it is going to change. Other then that just store them as a modifier on the character.

theTroll
But I don;t like the idea of opening the xml everytime they view the inventory, so I'll load them into a class, too, its just they won't be used much. Inelegant, but it'll work.
I am also working on a rpg game right now.

The way I am doing it is the way Splinter of Chaos suggested. At the start I load an 'item catalog' file which is basically a text file which stores everything about the items. As an example, here is one item:

Goblin Cleaver
right
An old cleaver which still has an edge.
C:\Documents and Settings\BUnzaga\My Documents\DX Dungeon\Items\cleaver.png
C:\Documents and Settings\BUnzaga\My Documents\DX Dungeon\Items\goblinCleaver.dxmesh
2.0
250
5
0.00
C:\Documents and Settings\BUnzaga\My Documents\DX Dungeon\Item Scripts\testClick.is

At runtime I parse all that into an array of GameObject.

GameObject(name, position, description, bmpLoc, meshLoc, weight, range, damage, sellPrice, script)
{
//assign the signature info to the objects fields
}

The next thing I did was create an Item Controller. This handles the methods for loading the items giving them unique names, etc.

So as an example, as part of my map loading script, I have it load items and position them in the map:

0
1
new Vector(10,0,10)
-1

0 is the item position in the catalogue (ie: itemList[0]). 1 is the number of itmes (for coins and arrows and such this will be larger than 1). Place it on the map at the Vector, and the -1 means it belongs to the 'map'.

The Item Controller also handles things such as monsters dropping loot, or the player picking up items, dropping items, etc.

Once the player picks up the item though, the item is now handled by the Character Inventory Controller.

From the item data you can see above, the second line is the string 'right'. This means this object can be used in the right hand.

The line third from the bottom is the integer '5' this means this object adds +5 to the players damage.

So you can see the item itself is responsable for damage checks, etc.
As far as when to check the users stats, just do it when an effect is applied, or removed, or when initializing the character like The Troll said.

Here is some psuedo code to get you on your way.

onInit()
baseStr = character.getStat(strength)
itemStr = equippedGear.getStat(strength)
currentStr = baseStr+itemStr

character.getStat(statType)
return stat[statType]

equippedGear.getStat(statType)
var amount = 0
for(var i1=0;i1<equippedGear.length;i1++)
{
amount+=equippedGear[i1].statBonus[statType]
}
return amount;



When you add or remove an item, the equippedGear needs to be recalculated. If you level up or something your base stats need to be adjusted.

Perhaps you might even want a third calculation for spell effects...

currentStr = baseStr+itemStr+effectStr

Then when you use your stats for combat, you just reference currentStr.
Ok, so I finished it a few days ago (Thanks for the input anyway). Here is what my items go through:

I have items.xml
<items>
<item id"1">
<name>Short Sword</name>
<type>WEAPON1H</type>
<base_dmg min="10" max="20"/>
<mod id="1">70</mod> //these ids are defined in mods.h
</item></items>

I load the character from hero.xml
...
<equipped>
<head>0</head>
<weapon1>1</weapon1>
....

So the character init() calls Item::create(1) which loads the data into an Item and sends back a Statistics which has all the deltas from the item.

The deltas include from spells etc and are recalculated when a base stat is changed or items are equipped/unequipped. spell duration running out tells the delta how much to increase/decrease to stop spell effect.

And thats what I'm currently doing; designing spells so I can get a feel of what they do/how to code them in.

This topic is closed to new replies.

Advertisement