Sign in to follow this  
Noobis

RPG Inventory c++

Recommended Posts

Ok, heres my problem: I need an inventory for a texted based RPG. I thought I could make classes of each item and store the items in a vector. But I can't create a vector for Super class :ITEM which sucks. So I have no idea of any other way to store multiple types of variables in one object, and then store each object in a list... So anyone have any example code I can look at that deals with this, or any ideas? I tried to think about how to do this and I just don't know how. I can't figure out how to store pointers to the object that hasn't be made yet lol. PS: Anyone know how to program a tv remote to access a motorola cable box. Specifically: Sanyo DS27930 TV > FXWK Remote ; I have the manual but the codes don't work.

Share this post


Link to post
Share on other sites
I think this is how you mean.

You can use a pointer to the base class and store them in an vector, some code from the top off my head...


//The base class
class Item
{
// Virtual functions and so on
}

class Axe : public Item
{
// Axe specific code
}

class Sword : public Item
{
// Axe specific code
}






Then you do:


int main()
{
std::vector<Item*> backpack;
backpack.push_back(new Axe);
backpack.push_back(new Sword);

// Rest of code here

for (int i = 0; i < backpack.size(); i++)
{
delete backpack.at(i);
}
}





The deletion should perhaps be done with iterators and such, but this is the quick dirty way :)

Hope this helps!

Share this post


Link to post
Share on other sites
Hm, although I don't know enough to give you an answer, I hope somebody who has the knowledge will provide a thorough answer for this as it will definitely help me in my current game.

Share this post


Link to post
Share on other sites
For the items I would use inheritance with plenty of virtual functions to ensure a consistent interface with unique item data and functionality.

For an inventory you'd want fast insertion and deletion times and I don't think that random access is that critical. I would recommend using a linked list instead of a vector. I also would recommend using a boost pointer container as it will take care of handling memory for you and help prevent memory leaks.

Share this post


Link to post
Share on other sites
Well, as the posters above pointed out, if you want different classes of item, virtual functions are probably a big part of the answer. Using them you should be able to specify the functions that you expect an inventory object to use in teh base class, but only implement them in the child classes.

The form is something like this:

class Base
{
virtual void use(); //Note that the function is only declared in the Base class
};

class Child1: public Base
{
void use()
{
//actual code here. Note that it may well be better to put this in a separate
// .cpp file, rather than here in what is presumed to be the header, but that
// is largely irrelevant to the discussion.
};
};

class Child2: public Base
{
void use()
{
//As in the previous case.
};
};




You could then do something like this:


vector<Base> v;

Child1 c1;
Child2 c1;

v.push_back(c1);
v.push_back(c2);
v[0].use();
v[1].use();



The correct child version of the virtual function should be executed in each case.

If you want to know what type of object was called, include a virtual function that returns the type of object that it represents, such as:


class Base
{
virtual string myType();
};

class Axe: public Base
{
string myType() {return "Axe";};
};

class Sword: public Base
{
string myType() {return "Sword";};
};




However, there is another question that I would like to ask: Are you sure that you want to create separate classes for different types of inventory item? I daresay that it can be very useful (I can see it being used for such items as Ultima VIII's keyring item, for instance, which acted in a different way to other inventory items), but is it really called for in your case?

What about storing the object's information, and perhaps scripts for its interactions with the world, in a single object. Include a name variable with which to identify the object, for example, and perhaps which actions it can be used with.

A very simple version might have something like this:


class InventoryItem
{
string name;
string description;
vector<int> scripts;
vector<int> valid_actions;
}

//Elsewhere...

InventoryItem an_item;
an_item.name = "Blue potion";
an_item.description = "This is a mysterious blue potion";
scripts.push_back(DECREASE_PLAYER_HEALTH);
scripts.push_back(DECREASE_PLAYER_STAMINA);
scripts.push_back(DECREASE_PLAYER_LEVEL);
valid_actions.push_back(QUAFF);




In this case, I presume that you would somewhere have enumerations that specify the actions and scripts that are allowed. When the player attempts to do something with the item (such as hitting someone with it), simply check the requested action against those specified in the valid_actions vector and, if it is there, perform it with that item, and otherwise tell the player that they are a silly player and that, for instance, they are not allowed to hit people with bottles of expensive magical elixirs.

This system could of course also be extended to allow parameters for the scripts, to, for example, specify how much health to deduct from the player.

Note that in the cases of such things as axes and swords, you might want to make the actual wielded weapons different to inventory weapons, or have their script simply set the "current weapon" statistics appropriately, depending on how you are handling such things, instead of creating separate classes to allow for different abilities.

Share this post


Link to post
Share on other sites
Quote:
Original post by Thaumaturge
Well, as the posters above pointed out, if you want different classes of item, virtual functions are probably a big part of the answer. Using them you should be able to specify the functions that you expect an inventory object to use in teh base class, but only implement them in the child classes.

The form is something like this:

*** Source Snippet Removed ***


You could then do something like this:

*** Source Snippet Removed ***

The correct child version of the virtual function should be executed in each case.

If you want to know what type of object was called, include a virtual function that returns the type of object that it represents, such as:

*** Source Snippet Removed ***

However, there is another question that I would like to ask: Are you sure that you want to create separate classes for different types of inventory item? I daresay that it can be very useful (I can see it being used for such items as Ultima VIII's keyring item, for instance, which acted in a different way to other inventory items), but is it really called for in your case?

What about storing the object's information, and perhaps scripts for its interactions with the world, in a single object. Include a name variable with which to identify the object, for example, and perhaps which actions it can be used with.

A very simple version might have something like this:

*** Source Snippet Removed ***

In this case, I presume that you would somewhere have enumerations that specify the actions and scripts that are allowed. When the player attempts to do something with the item (such as hitting someone with it), simply check the requested action against those specified in the valid_actions vector and, if it is there, perform it with that item, and otherwise tell the player that they are a silly player and that, for instance, they are not allowed to hit people with bottles of expensive magical elixirs.

This system could of course also be extended to allow parameters for the scripts, to, for example, specify how much health to deduct from the player.

Note that in the cases of such things as axes and swords, you might want to make the actual wielded weapons different to inventory weapons, or have their script simply set the "current weapon" statistics appropriately, depending on how you are handling such things, instead of creating separate classes to allow for different abilities.


Hmmm...very interesting. So I can completely understand a derived class for each type of weapon from a base Weapon class, which would allow for weapon-specific modifiers to take place within each derived class and allow for various weapons to be created with different damages and speeds. Makes perfect sense to me, sounds like the right way to do it.

But, I really like your suggestion, though I'm unsure on the benefits of using a system such as yours. It seems like you would be doing a lot of typing when creating an object of InventoryItem and it would be a bit confusing later on of what you're dealing with. So if you could please explains this method a bit more that'd be sweet hah, thank you

Share this post


Link to post
Share on other sites
I kinda have no idea what your talking about lol, im trying to follow along the best i can. I don't exactly understand how using enumerators will work.

I created my weapons through base class ITEM- so that I could use them and class them as Items, but I thought I could make a VECTOR within my character class.

vector<Item> inventory;

but I can't.

I want the player to be able to see a list of items within the inventory, and then be able to choose from a menu -> Look, Use, Toss;

I also want my monsters to have their OWN inventory which will be used to calculate from random, what drops for loot. Also, I want my monsters to be able to carry Weapons and Items to use on their own.

I want each individual item to have its own specs. Such as "Damage, Hit Rating, Magical Attributes;"

I don't want to the game to be scripted like a movie, I want random encounters, random drops, and the ability to choose what loot the player wants to pick up.

So what I am trying to figure out is how to make this. I don't know enough about all the functions available to make lists and things. I just know I guess the basics, what I learned from a few books.

Im not working with graphics, It all completely texted based.

The hardest thing I am having to deal with right now is the inventory.

This whole project is a "Learn as I go" Type of thing.

I don't want to have to write a new inventory for each instance of monster or player, I want to expand this to net play and graphics later as well. But right now, im working on a working, single player, texted based RPG.



PS: How do you make the rand() function, more.... Random. Without seeding a new number every second from time.

Share this post


Link to post
Share on other sites
Quote:
Originally posted by Shakedown
But, I really like your suggestion, though I'm unsure on the benefits of using a system such as yours. It seems like you would be doing a lot of typing when creating an object of InventoryItem and it would be a bit confusing later on of what you're dealing with. So if you could please explains this method a bit more that'd be sweet hah, thank you


Well, yes, it probably would incur more typing, but it has the advantage that, as long as you can implement your desired object with the script commands that you have defined as being available, you can specify new items in external files without having to recompile your code, which can speed things up and increase convenience of development.

Just change your script, re-run your program, and your new behaviour should be present in your game, without recompilation. As well as this, as long as your scripting system doesn't have loopholes, your scripts shouldn't bring down your program, let alone produce compilation errors to chase down (since you shouldn't have to recompile) on top of any corrections that you might want to make to the behaviour that you just created.

Other than that, is there any particular part of the system that you'd like explained further?

Wikipedia has a general article on scripting languages; what I'm describing here is probably what they describe as "application-specific languages", although they have only a brief section on it, I'm afraid.

Quote:
Originally posted by Noobis
I created my weapons through base class ITEM- so that I could use them and class them as Items, but I thought I could make a VECTOR within my character class.

vector<Item> inventory;

but I can't.


Ah, you're right, of course - I made a mistake in my original post, I think, for which I apologise. Instead of creating a vector of Items, create a vector of pointers to Items, like so:

vector<Item*> v



Then create pointers to your individual subclasses, and store those, like so:

Axe *a = new Axe();
v.push_back(a);

v[0]->someVirtualFunction();



As to scripts, a game script needn't be as set in stone as a movie script - they're related, but a game script can include choices.

Essentially in this case the scripts would each be relatively small, unconnected sets of commands, such as the command to decrease the player's health, rather than a single monolithic and unchanging description of each moment in the game, as with a movie script. The commands, please note, may include randomness, and may be selected from randomly or assigned randomly. Furthermore, they may be "written" as the game progresses.

In the metaphor of a movie, instead of a single document by which the actors are controlled, think of lots of little documents that describe how a given actor should act under certain circumstances, and which may only be written as the movie is being filmed, and, should the movie be re-filmed, which may change drastically as they are re-written.

Thus, let's say that you want to create an Item which is an axe that the player can wield. Let us further say that you want the axe to do a random amount of damage between 1.0 and 5.0, and, with a certain low probability, may have a randomly selected magical ability. I will presume for now that you have a function that returns a random value between 0.0 and 1.0 called getRandom().

If we use scripts, we could use a script vector to store the scripts to execute, and a parameters vector to provide them with information that they might want, such as amount of damage to inflict, amount of health to restore, number of monsters to summon, etc. How you relate those is up to you - you could even keep them all in one vector if you wanted to.

Thus we might have something like this:


Item *axe = new Item();
axe->damage = getRandom()*4.0 + 1.0; //a random value between 1.0 and 5.0
float percentage = getRandom(); //generate a random number with which to select
// a magical power, if any.
if(percentage < 0.1)
{
//there's a chance of getting this (really nasty) magical ability...
axe->scripts.push_back(SET_PLAYER_HEALTH);
axe->parameters.push_back(0.0); //(Set the player's health to 0)
}
else if(percentage < 0.25)
{
//You might also get the power to do some ice damage
axe->scripts.push_back(DO_ICE_DAMAGE);
axe->parameters.push_back(getRandom()*2.0+1.0); //a randomised amount of damage.
}
//add more abilities if desired.



Note that these are extremely simple, one-command scripts. A more complex one could include multiple commands.

Share this post


Link to post
Share on other sites
Just a note on virtual function usage: don't forget to make the destructor of the base class virtual as well. Otherwise, when you call delete on a base class pointer that points to an instance of a derived class, only the base class destructor is called, leaving you with a half-destructed object somewhere in memory.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this