Hello everyone.
I have finally created an inventory for my RPG game, right now It can do:
-> Show the items I have in a 20 slot inventory.
-> Show the icon of the item
-> Show the description (3 lines max)
Here is how it looks now:
{"name":"at18.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/e\/0\/e0ca6a4ca3e8a6cbf411a05ef11c1ee6.png","w":636,"h":476,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/e\/0\/e0ca6a4ca3e8a6cbf411a05ef11c1ee6"}
But, as you can see I have many potions on my inventory, what I want to do is to use only 1 slot for them, I mean have a "stack" of items, a number will show the quantity of items I have. Like that:
{"name":"3vg5.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/e\/ce647b46fa8d611541f39a0f30dd237a.png","w":636,"h":476,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/e\/ce647b46fa8d611541f39a0f30dd237a"}
I have tried to do that, but no success, here is my code for the Scene_Inventory class:
The last function is the one I am talking about, this is how it should work:
1- Check if the player has the item (itemname.have)
2- If the player doesn't has the item, then we add a new element to the vector with the item name provided. Then increment the quantity by 1, then set "have" to true.
3- If the player has the item, then just increment it's quantity by 1.
Please help me, I really don't know how to do that, the function doesn't work...
Thank you very much
Well, unless I'm missing something(how do you call addItem?), the function can't work, because you aren't checking if an Item of the same type already exiss within the inventory. Allow me to explan, your method does the following:
1. Check if the itemname.have is 1 or 0. This is a bad idea and (in this case) meaningless. More about that later.
2. if itemname.have is zero, the Item gets put in the vector
3. if itemname.have is one, you incremet the quantity of the Item and then you actually don't do anything with it.
Example:
You want to add two SnackBars to the inventory. You have two options.
Option 1:
You create two Item objects, lets say snack1 and snack2, and pass them both to addItem()
Outcome:
-snack1 get added to the vector
-snack1.have is set to one
-snack1.cur_quantity is incremented
-snack2.cur_quantity is incremented, never to be used again
Option 2:
You create one Item object, lets say snacks, and pass it two times to addItem()
Outcome:
-snacks get added to the vector
-snacks.have is set to one
-snacks.cur_quantity is incremented
-snacks.cur_quantity is incremented again
Option two would do the job, actually. If that's what you're going for, that is. Assuming vector<Item> Inventory takes pointers isnstead of the actual objects. (Sorry, my C++ skills get a bit rusty... :/ )
Well... no. Just did some testing and it seems vectors store a copy of the object.
Either way, you should implement a function that checks if the type of item is in the inventory by scanning the vector instead of relying on a variable and incrementing the cur_quantity of the object that is already in the vector. That would be cleaner and more understandable, anyway.
Thanks for the reply.
Well, I call the function like that:
The vector takes the actual item... Maybe there is something that I'm not doing correct.
Maybe I'm not passing correctly the item to the function..
I'm really stuck with this :S
Ah, ya beat me to it, was just editing my post...
Here is a cleaner and more understandable approach
Thanks for the example.
But I can't use Inventory.size() because at the start the vector is empty, so I'm getting an "out of range" error...
I tried to switch Inventory.size() to 20, in line 3 of your code and anyway get the error...
std::map<string , int> inv; void AddItem(String item) { if (inv.find(item) != inv.end()) { inv[item]++; else inv[item] = 1; } AddItem("Health Potion");
Oh, right. Sorry, my bad.
make that
int Scene_Inventory::containsItem(Item &itemname) { if(!Inventory.empty()) { for(int i=0; i<Inventory.size(); i++) { if(Inventory.at(i).name==itemname.name)// i.e. "potion" or "gold ring" (use string class for name) return i;//return position of Item of same type as itemname } } return -1; }
EDIT:
Or do what Edgar said
Thanks everyone, I think I got it to work finally.The only thing is that now I have changed the Item name from char to string, the name is not displaying in the inventory...
Here is how I'm drawing my item's name:
al_draw_textf(font, al_map_rgba(100,100,100, 0.5), 80, 76 + (i * (slot_h + 2)), 0, "%s", Inventory.at(i).name);
fixed now
Thanks
If name is now a std::string, use name.c_str() to convert it into a const char * array.
Thanks everyone, I think I got it to work finally.
You're welcome. Though Edgar Reynaldo brought up a valid point.
Unless your Item objects have other important properties that a name you could use a map as well. Would save up some RAM.
You could register classes of items with a registry. And if you wanted stackable inventory, you could use a multimap which allows you to have multiple copies of the key (item) and since you store an int then that is the count of the item in that 'pile'.