![]() |
|
Items stack in a RPG Inventory system |
NickyP
Member #15,390
November 2013
|
Hello everyone. -> Show the items I have in a 20 slot inventory. 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: 1#pragma once
2#include <allegro5\allegro.h>
3#include <allegro5\allegro_primitives.h>
4#include <allegro5\allegro_image.h>
5#include <allegro5\allegro_font.h>
6#include <allegro5\allegro_ttf.h>
7#include <algorithm>
8#include "item.h"
9#include <vector>
10using std::vector;
11
12///////
13int potions = 0;
14
15vector<Item> Inventory;
16vector<Item>::iterator it;
17
18int slot_w = 275;
19int slot_h = 30;
20
21int slot = -1;
22
23int selection = 0;
24int total_slots = 20;
25
26int cur_items = 0;
27
28int player_coins = 102034; //Just for testing
29
30Item itemname;
31
32class Scene_Inventory : public Item
33{
34public:
35 Scene_Inventory();
36 ALLEGRO_BITMAP *inv;
37 ALLEGRO_FONT *font;
38 ALLEGRO_FONT *font2;
39 void Init();
40 void Draw();
41 void addItem(Item &itemname);
42};
43
44Scene_Inventory::Scene_Inventory()
45{
46 cur_items = Inventory.size();
47}
48
49void Scene_Inventory::Init()
50{
51 inv = al_load_bitmap("inventory.png");
52 font = al_load_font("arial.ttf", 16, 0);
53 font2 = al_load_font("arial.ttf", 14, 0);
54}
55
56void Scene_Inventory::Draw()
57{
58 al_draw_bitmap(inv, 0, 0, 0);
59 for(unsigned int i = 0; i < Inventory.size(); i++)
60 {
61 if(i <= 9)
62 {
63 al_draw_bitmap(Inventory.at(i).icon, 50, 75 + (i * (slot_h + 2)), 0);
64 al_draw_textf(font, al_map_rgba(100,100,100, 0.5), 80, 76 + (i * (slot_h + 2)), 0, "%s", Inventory.at(i).getName());
65 al_draw_textf(font2, al_map_rgba(100,100,100, 0.5), 45, 82 + (i * (slot_h + 2)), 0, "%i", Inventory.at(i).cur_quantity);
66
67 }
68 else if(i >= 10 && i < total_slots)
69 {
70 al_draw_bitmap(Inventory.at(i).icon, 334, 75 + ((i-10) * (slot_h + 2)), 0);
71 al_draw_textf(font, al_map_rgba(100,100,100, 0.5), 364, 76 + ((i-10) * (slot_h + 2)), 0, "%s", Inventory.at(i).getName());
72 }
73 }
74
75 if(selection <= 9)
76 {
77 al_draw_rectangle(40,70 + (selection * (slot_h + 2)),315,100 + (selection * (slot_h + 2)),al_map_rgba(100,100,100, 0.5),1);
78 }
79 else if(selection >= 10 && selection < 20)
80 {
81 al_draw_rectangle(323,70 + ((selection-10) * (slot_h + 2)),600,100 + ((selection-10) * (slot_h + 2)),al_map_rgba(100,100,100, 0.5),1);
82 }
83
84 //DRAWING DESCRIPTION
85 if(selection < Inventory.size())
86 {
87 al_draw_textf(font, al_map_rgb(255,255,255), 40, 405, 0, "%s", Inventory.at(selection).getDescription(1));
88 al_draw_textf(font2, al_map_rgb(255,255,255), 40, 425, 0, "%s", Inventory.at(selection).getDescription(2));
89 al_draw_textf(font2, al_map_rgb(255,255,255), 40, 440, 0, "%s", Inventory.at(selection).getDescription(3));
90 }
91
92 //Drawing coins
93 al_draw_textf(font2, al_map_rgb(255,255,255),622, 15, ALLEGRO_ALIGN_RIGHT, "Coins: %i", player_coins);
94
95 //Size test
96 al_draw_textf(font, al_map_rgb(255,255,255), 20, 20, 0, "%i", Inventory.size());
97
98}
99
100void Scene_Inventory::addItem(Item &itemname)
101{
102 switch(itemname.have)
103 {
104 case 0:
105 Inventory.push_back(itemname);
106 itemname.cur_quantity++;
107 itemname.have = true;
108 break;
109
110 case 1:
111 itemname.cur_quantity++;
112 break;
113 }
114}
The last function is the one I am talking about, this is how it should work: Please help me, I really don't know how to do that, the function doesn't work... Thank you very much |
Lupuss.Umbrae
Member #8,387
March 2007
![]() |
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: Example: Option 1: Option 2:
-------------------------------------------------- |
NickyP
Member #15,390
November 2013
|
Thanks for the reply. Well, I call the function like that: 1Scene_Inventory.addItem(potion);
The vector takes the actual item... Maybe there is something that I'm not doing correct. I'm really stuck with this :S |
Lupuss.Umbrae
Member #8,387
March 2007
![]() |
Ah, ya beat me to it, was just editing my post... Here is a cleaner and more understandable approach 1int Scene_Inventory::containsItem(Item &itemname)
2{
3 for(int i=0; i<Inventory.size(); i++)
4 {
5 if(Inventory.at(i).name==itemname.name)// i.e. "potion" or "gold ring" (use string class for name)
6 return i;//return position of Item of same type as itemname
7 }
8 return -1;
9}
10
11void Scene_Inventory::addItem(Item &itemname)
12{
13 int itemPos=containsItem(itemname);
14 if(itemPos) // itemPos>=0 means the item is already there, increment quanity
15 {
16 Inventory.at(itemPos).cur_quantity++;
17 }
18 else //itemPos==-1 means this item is not yet listed in the inventory, add it
19 {
20 Inventoy.push_back(itemname);
21 }
22}
-------------------------------------------------- |
NickyP
Member #15,390
November 2013
|
Thanks for the example. I tried to switch Inventory.size() to 20, in line 3 of your code and anyway get the error... |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
std::map<string , int> inv; void AddItem(String item) { if (inv.find(item) != inv.end()) { inv[item]++; else inv[item] = 1; } AddItem("Health Potion"); My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Lupuss.Umbrae
Member #8,387
March 2007
![]() |
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: -------------------------------------------------- |
NickyP
Member #15,390
November 2013
|
Thanks everyone, I think I got it to work finally.
Thanks |
OnlineCop
Member #7,919
October 2006
![]() |
If name is now a std::string, use name.c_str() to convert it into a const char * array.
|
Lupuss.Umbrae
Member #8,387
March 2007
![]() |
NickyP said: Thanks everyone, I think I got it to work finally.
You're welcome. Though Edgar Reynaldo brought up a valid point. -------------------------------------------------- |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
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'. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|