How to implement RPG Inventory
by Colin McEachern · in Torque Game Engine · 09/29/2004 (6:57 am) · 6 replies
I've recently begun work on a large-scale project using and learning Torque along the way. To begin, I need some form of inventory that is pretty much completely different from what is currently available in Torque. I'm used to Java/C++ programming, and the script language with datablocks is still new to me. However, I'd like to have a system which has an array/linked list of the actual Items (in my mind, Crossbow or HealthPack would be a subclass of Item) and then use their properties which all items would have to determine if the user has reached the maximum number of those items or not. However, Tim Newell's tutorial simply doesn't work right, and I still don't entirely understand if what I'd like to do is possible.
I simply want to make an inventory system which uses the actual item objects. How might I go about implementing this? I feel like I should be modifying the Item class in the engine to do this but I'm not sure how I would go about doing that.
I simply want to make an inventory system which uses the actual item objects. How might I go about implementing this? I feel like I should be modifying the Item class in the engine to do this but I'm not sure how I would go about doing that.
#2
However, the tutorial by Tim Newell doesn't work. It crashes the torque engine on mac, and on PC, everything simply goes crazy. It is, after all, two years old, and while I updated the console methods to use ConsoleMethod instead of Con::addCommand, it still doesn't work. I couldn't find any information on getting it to work perfectly on here.
09/30/2004 (4:46 am)
Now that I've learned more about the torque engine, I've figured out that I don't actually need to hold the objects, just their type and number and such, which is great. So, I'd like to implement Tim's system.However, the tutorial by Tim Newell doesn't work. It crashes the torque engine on mac, and on PC, everything simply goes crazy. It is, after all, two years old, and while I updated the console methods to use ConsoleMethod instead of Con::addCommand, it still doesn't work. I couldn't find any information on getting it to work perfectly on here.
#3
The only real impact it had on the game was that I had no arrows on game startup. But inventory management seemed to work fine, which was the point. Didn't try any of the GUI stuff.
For your reference, you can pick up a copy of the files that I changed at www.e-goh.com/Inventory.rar I'll keep it there for a few days. Compare it with what you have and see if you missed anything out. Don't forget to recompile after you update the .cc and .h files.
09/30/2004 (5:20 pm)
I ran through the tutorial on TGE 1.3, Win 2000 SP4, VC6 SP5 without any major problems. Only deviations I made were using ConsoleMethod, and the inclusion of dummy function setInventory to supress an error message (not strictly necessary). And of course, that there is no rifle object anymore.The only real impact it had on the game was that I had no arrows on game startup. But inventory management seemed to work fine, which was the point. Didn't try any of the GUI stuff.
For your reference, you can pick up a copy of the files that I changed at www.e-goh.com/Inventory.rar I'll keep it there for a few days. Compare it with what you have and see if you missed anything out. Don't forget to recompile after you update the .cc and .h files.
#4
09/30/2004 (7:16 pm)
Hmm, I'm developing this on a Mac, and using those files still crashes the game when I click on "Launch Mission". I believe I've gotten it to work on a windows machine once, though.
#5
10/01/2004 (4:59 am)
Afraid I'm not a Mac person, so not much help there. Might want to try downloading a fresh build, and seeing if anything got missed/messed. Other than that, I'm out of ideas. :-(
#6
As I remember it has a bug and crash sometimes when you have no items in inventory.
To get you started with, here are a few corrections :
1) you need to add the CurrentItemInList check in NextLink() and LastLink().
2) Second big bug is the GetItem function, it crash if the inventory is empty also it was a bit repetitive so I changed the way it was written (carefull, the information I store is different from Tim, so you have to adapt) :
These corrections should get you out of trouble.
Otherwise don't hesitate to contact me.
If you still have trouble after that, turn the trace on (insert "trace(true);" in the main.cs) and send me the console.log. (see my profile for e-mail address)
10/01/2004 (12:51 pm)
I implemented a full inventory system for a mmorpg using Tim inventory as stater example so I am pretty used to the code. As I remember it has a bug and crash sometimes when you have no items in inventory.
To get you started with, here are a few corrections :
1) you need to add the CurrentItemInList check in NextLink() and LastLink().
bool Inventory::NextLink() {
if(!CurrentItemInList)
return false ;
if (CurrentItemInList->nextLink != NULL) {
CurrentItemInList = CurrentItemInList->nextLink;
return true;
}
return false;
}
bool Inventory::LastLink() {
if(!CurrentItemInList)
return false ;
if (CurrentItemInList->lastLink != NULL) {
CurrentItemInList = CurrentItemInList->lastLink;
return true;
}
return false;
} 2) Second big bug is the GetItem function, it crash if the inventory is empty also it was a bit repetitive so I changed the way it was written (carefull, the information I store is different from Tim, so you have to adapt) :
void InventoryClient::GetItem(char* type, char* rettype, char* retvalue, S32 retSize)
{
InvLink *foundItem = NULL ;
// First found the item
if (dStricmp(type, "first") == 0) //first Item in list
{
foundItem = FirstItemInList ;
}
else if (dStricmp(type, "current") == 0) //current item in list
{
foundItem = CurrentItemInList ;
}
else
{
foundItem = GetLink(dAtoi(type));
}
if(foundItem)
{
// now check for rettype ONCE
if (dStricmp(rettype, "id") == 0)
{
dSprintf(retvalue, retSize, "%d", foundItem->ItemData.instanceId);
}
else if (dStricmp(rettype, "name") == 0)
{
dStrcpy(retvalue, foundItem->ItemData.name);
}
else if (dStricmp(rettype, "amount") == 0)
{
dSprintf(retvalue, retSize, "%d", foundItem->ItemData.amount);
}
else if (dStricmp(rettype, "type") == 0)
{
dStrcpy(retvalue, foundItem->ItemData.type);
}
else if (dStricmp(rettype, "description") == 0)
{
dStrcpy(retvalue, foundItem->ItemData.description);
}
else if (dStricmp(rettype, "icon") == 0)
{
dStrcpy(retvalue, foundItem->ItemData.icon);
}
else if (dStricmp(rettype, "shape") == 0)
{
dStrcpy(retvalue, foundItem->ItemData.shape);
}
else if (dStricmp(rettype, "container") == 0)
{
dSprintf(retvalue, retSize, "%d",foundItem->ItemData.containerId);
}
else
{ //return all separated by \t
//dStrcatl seems not to work properly.
dSprintf(retvalue, retSize, "%d\t%s\t%d\t%s\t%s\t%s\t%s\t%d",
foundItem->ItemData.instanceId,
foundItem->ItemData.name,
foundItem->ItemData.amount,
foundItem->ItemData.type,
foundItem->ItemData.description,
foundItem->ItemData.icon,
foundItem->ItemData.shape,
foundItem->ItemData.containerId) ;
}
}
else
{
dStrcpy(retvalue, ""); // something wrong here
}
}These corrections should get you out of trouble.
Otherwise don't hesitate to contact me.
If you still have trouble after that, turn the trace on (insert "trace(true);" in the main.cs) and send me the console.log. (see my profile for e-mail address)
Torque Owner Eugene Goh
If I read correctly, you want an inventory system that:
1) Stores the actual objects somewhere instead of the merely the type and quantity of object.
2) Has a limit to the number of items that can be stored, either by pure number, or a function of their properties, e.g weight
I wouldn't recommend doing (1) as you'll be storing a lot of redundant stuff, since the object no longer needs to be rendered. You might want to isolate the key properties you really really need, and put them as additional arguments to addItem() and getItem() (plus a few other internal functions). If you have a lot of these, store them in an array and use that.
If you're hellbent on doing this, I suppose you could always create some sort of makeshift underground bunker to store all these objects, perhaps with appropriately barcoded shelves.....
(2) is much easier. Change addItem() and removeItem() to keep a running total of the specific property(s) your measuring. When it hits a predefined limit, return a failure flag (change them from void to int functions) and fail to add the item.