# Diablo 1/2 Inventory system

This topic is 3326 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello again! :) This time i have a more difficult task beside me. I would like to make an inventory system for my game which is the same that blizzard's diablo 1/2 games use. I tried doing some things like using a panel which will gain a item image if it occupied, if the mouse clicks on it it will gain an image as if it is empty and the mouse cursor will become the item which was in the square panel but this doesn't solve my problem if i use items that require more than 1 square to fill (armors, weapons etc). So i would like to ask if someone has experienced how to make a similar inventory system. Programming language doesn't matter because i only need to get the idea of how to make this system :). Thanks to everyone who read this thread and i hope someone will reply soon with a solution to this problem :).

##### Share on other sites
I've done the exact same thing you're trying to do in Java. I love the Diablo series. The first had such a great atmosphere it made up for the gameplay, and the second had such great gameplay that it made up for the childish atmosphere.

Anyway, how I implemented it was using a system of "States".

At all times the player's current state was being monitored, and if he did something that deemed it necessary, his state could switch. Also, in some instances, multiple states might be required. Anyways, upon the clicking of an item on the ground (or ANY other means of placing the item within the mouse's control) a state was set indicating that the player had control of the item.

Upon any event, such as mouse movement or clicking, the state was checked (this actually provided me with a very quick method of performing any decisions, as each section of the game didn't have to search for conditions upon other parts - it just did a simple check, found if some state was checked, and it was good to go!) and certain actions were taken.

The solution to your problem could be something similar, in which upon the mouse recieving control of an item, one state was set. If the inventory was open, another state was set (Normally this would have already been set, but you understand what I'm getting at). Every mouse movement would check these two states, if they were both set, then our game knows that it needs to be on the lookout for the item being placed over the inventory. If the mouse enters the boxed area, another state. If all three states are set, do whatever additional rendering you need to do (In Diablo II, the boxes would highlight green if the items could fit there, otherwise red - again, maybe another state?). If all four states are set, find the position that the item needs to go, make whatever sounds need to be made, release whatever states need to be release, etc.

States like these provide very fast ways of sizing up certain situations. Instead of checking the mouse position, checking if an item is held, whether the inventory is open, whether the mouse is over the inventory, or whether the spot is good upon every mouse movement, it boils down to some very simple, very fast bitwise ANDs.

##### Share on other sites
one simple solution:

1) you have a list of objects in inventory.
2) You also hase a "struct" that says something like:
struct my_woopie_yuppie_struct{
objtype *obj
int posx, posy
int sizex, sizey
my_woopie_yuppie_struct *next
}

(pseudo code)

3) If users clicks on cell x=4,y=5 its just a matter of using some simple math to find which object was clicked.

This isn't for sure the only, or even the best way of doing what you asked, but it's a start.

Hope it helps,

DC

EDIT: this was only to answer the "problem if i use items that require more than 1 square to fill". THe post above, has a good explanation on the global method

##### Share on other sites
I've got to go to bed, but obviously each item has an item type (Polearm, Ring, etc.) and each type has a certain amount of rows and columns it uses in the inventory. Create an inventory of x rows by x columns. Check the item rows columns. Do some simple grid math (javascript ftw).

##### Share on other sites
Thanks to all who answered in the thread i made and i will give @Brain Me's solution a try. The way I'm going to make it will probably involve using the sprite engine and see if the item's sprite collides with other sprites (the inventory boxes). When i make it (will probably be in a week or so because I'm a student and i have an exam every day till the end of the week) if someone wants it in delphi 6 code using undelphix's sprite engine i could post the source code aswell :).

##### Share on other sites
Quote:
 Original post by Alex131Thanks to all who answered in the thread i made and i will give @Brain Me's solution a try. The way I'm going to make it will probably involve using the sprite engine and see if the item's sprite collides with other sprites (the inventory boxes).

This method (using sprite collision) may cause problems in the future - like when you want the character to pick up an item while the inventory is closed. How will you figure out where to put the item?

I think mystb and Dae were on the right track - you have a model in memory of what the inventory looks like, and a methods for performing tests and drawing that model to the screen.

##### Share on other sites
Well on general thoughts i was planning to get the 0,0 coordinates of every box I'm my inventory where i can put an item. Then i was planning to check if the mouse is occupied with an item and then see if the mouse is over inventory (collision). After that i use the OnMouseMove event for seeing the mouse coordinates (the 0,0 coordinates of the sprite of the mouse which is representing the picked up item). From there on there will be simple calculations about that if the item can be put on the place where the mouse sprite is and whether the squares are occupied or not (maybe a boolean for each square and armor/weapon/ring etc. slot will do the trick though it's will take more time if there is a better way i don't know of ...). And in my opinion this won't cause problems when the inventory is closed simply because there won't be any collision with it and if the mouse clicks where the inventory should be, i would simply code that the item should be released and drawn on the ground next to the character. If i got something wrong someone might want to enlighten me on what i can make better to save time :).

##### Share on other sites
Quote:
 Original post by Alex131 if someone wants it in delphi 6 code using undelphix's sprite engine i could post the source code aswell :).

don't post code. Its a terrible source of lazziness for brains. Post "ideas, solutions, methods". NOT source code :)

##### Share on other sites
If i finish the inventory system will it be suitable to upload the executive so that people can comment if i have made something wrong?

##### Share on other sites
I'm sorry for the double posting but i got quite a big problem. I don't know how big my inventory will be and i don't want to make every square of it by copying, editing and pasting 20 lines of code per square. I would like to ask for some sort of algorithm for making the inventory by a procedure where you type how much columns and rows it needs and therefore do all the math calculations for their position and name the box IB"Column"x"Row" but the problem is truly that i can't seem to name the box and when i say what is the type of the box (TInvBox = class (TImageSprite)) it says that this is an undeclared identifier and therefore i cannot make the inventory in some easy way. To enlighten people what I'm trying to do I'll post some (a little bit pseudo) delphi 6 code of what i would like to do:
Procedure InvetoryCreate (Width, Height, Columns, Rows: Integer)begin  create and name inventory boxes "IB Columns x Rows";  InvBox.X := Columns*Width;  InvBox.Y := Rows*Height;  InvBox.Image := assing image to box ....end;

The problem i get is only with naming the boxes and this undeclared identifier (maybe because the procedures are before the custom made classes and the program doesn't actually know that i will declare it after the procedure.....). I hope someone could help me solve this problem because writing about 10*30*20 = 6000 lines of code to just make your inventory boxes seems just stupid for me. :)

##### Share on other sites

Hi again. I don't know the language syntaxe/semantics, but let's think a little in pseudo code:

 - Create a inventoryfunction InventoryCreate (width, height)   Invbox.width=width   Invbox.height=height   Invbox.objects=NULL   Invbox.nrobjects=0    return Invboxend - Create a Objfunction ObjectCreate(some_vars_about_the_object, inv_width, inv_height, inv_image)   Obj.vars= some_vars_about_the_object   ...   ...   Obj.inv_width=inv_width   Obj.inv_height=inv_height   Obj.inv_image=inv_image   return Objend -- Add a object to a inventory on position X,Yprocedure InventoryAddObject(inv, obj, x, y)   -- check to see if it fits   if inv.width < x+ obj.inv_width return "does not fit"   if inv.height <y+ obj.inv_height return "does not fit"   for every object already in inventory       if inv_obj.x <  x+ obj.inv_width and          inv_obj.x+ inv_obj.width >= x return "does not fit"        .....        same for Y   end   inv.objects[inv.nrobjects].x=x   inv.objects[inv.nrobjects].y=y   inv.objects[inv.nrobjects].obj=obj   inv.nrobjects++end-- Now using itinv=InventoryCreate(10,5)obj=ObjectCreate("Sword", "blablabla", 1,3, "cool_sword.jpg")-- get mouse position, find that user wants to "drop a sword in the inventory", transform the X,Y screen coordinates to a inventory X,YInventoryAddObject(inv, obj, x,y)

this is was just typed without too much thinking. But it would help you sort some ideas, I hope :)

About the other question: you can post the executable, or the source code, it isn't forbiden in here. Its just a personal oppinion about posting full functional source code: users just grab it, use it, without knowing what it does or how it does it.

##### Share on other sites
Thanks for the fast answer, but i do managed to use almost the same things as you mentioned in you code but i still haven't seen my problem solved as it is that i get undeclared identifier when i try to use my custom made TImageSprite because the procedures are before the custom classes in delphi 6. Also i need to know how can i include integers in component names as i need to name the component InventoryBox1x1 where 1x1 means that this component is on the 1st row and 1st column of the inventory. Though i think that this is impossible, maybe someone could point a more effective way for me knowing that some component belongs to some row and column by setting something in its component parameters or maybe someone could tell me how i can include 2 custom parameters to my component - InventoryBox.Column and InventoryBox.Row because this way i think i could easily manage the code by using these parameters. Though i still do not know how could i make a function to name and declare the components like InventoryBox1,InventoryBox2,InventoryBox3 and etc so that i wouldn't need to declare and create them all.

##### Share on other sites
I got the idea how to make my custom component and now i can do all the calculations i need very smoothly :). The only problem i have now is to make a function/procedure which can declare and name my components, something like i said in my previous post InventoryBox1,InventoryBox2,InventoryBox3 and etc. I hope someone will come with an idea how to make this in delphi 6 :).

Edit 1: I'm so stupid, i forgot that i can make an array not only of numbers but of custom components as well :). I think i will be able to show some executable soon :).

[Edited by - Alex131 on January 17, 2009 12:33:55 AM]