Diablo 1/2 Inventory system
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 :).
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.
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.
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
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
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).
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 :).
Quote:Original post by Alex131
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).
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.
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 :).
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 :)
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?
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:
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. :)
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. :)
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement