Jump to content

[HELP] Slot inventory with different sized items


Dzsozi (h03)

Recommended Posts

Hello MTA community!

I would like to make an inventory system, which has different sized items (1*1, 2*1, 1*3, etc.), so the inventory space would matter based only on your space management. Here are some example photos of what I mean:

maxresdefault.jpg

_gquAra4uuBgrPOZ7V1oPlNlcgWBxUMWT7SREbBB

1es77vtmibu01.jpg

I haven’t started coding yet, that is the reason I created this topic. First of all I am trying to put together a structure and I would like to hear your opinions and suggestions on how to make this type of inventory.

I have some main questions but please let me know anything you think I might have to know regarding this topic.

My main questions are:

- How should I do the calculations for item positioning? (I would like players to be able to move the items within an inventory, that’s for sure)

- Do I calculate a freshly added items’ position inside the dx drawing function? Or should I specify the new items’ position at the point when I give it to the player?

- I would like to make it as simple, as efficient and as “automatic” as possible, so if it is an option, when I give an item to an element inventory I would like to only specify the element, item and item value variable.

- Where or how should I store the items’ position or how can I return the position and other data of an item when clicking on a slot? Do I make a variable for each slot representing it’s space (true if free/false if taken)? Do I save the currently visible inventory’s content with item data inside a table on client side?

- I would like to make inventories for vehicles peds and objects as well with a function, something like createInventory(element, slotNumber) for example. Should I make a new element for that using createElement or is there any other way to do that?

As I mentioned above, right now I am putting together a plan about how I would like to start working on this inventory resource, so please let me know anything useful!

Edited by Dzsozi (h03)
Link to comment
  • Moderators
On 01/02/2020 at 07:02, Dzsozi (h03) said:

- How should I do the calculations for item positioning? (I would like players to be able to move the items within an inventory, that’s for sure)

I have done this before, but think I would go for 2 grids.

 

  • Every item has a startX, startY, width and height.
  • Grid 1: contains only the start position of the added items. (Which is saved)
  • Grid 2: A computed version of grid 1, where it is for each cell know which item is placed on it. This makes it easier to see if there is space. (unsaved)
local grid1 = {
	{ -- column / X1
		{ -- cell / Y1
			width = 2,
			height = 3,
			type = "drink",
			name = "bottle",
			id = 1
		},
		nil, -- cell / Y2
		nil, -- cell / Y3
		nil, -- cell / Y4
		{ -- cell / Y5
			width = 4,
			height = 3,
			type = "ammo",
			name = "bullets ...",
			id = 2
		}
	},
	nil,  -- column / X2
	{  -- column / X3
		{ -- cell / Y1
			width = 1,
			height = 1,
			type = "matches",
			name = "matches",
			id = 3
		}
	}
}

 

Don't program it like this, this is how the computed version would looks like. (With only the bottle)

local grid2 = {
	{ -- column
		grid1[1][1], grid1[1][1], grid1[1][1]
	},
	{ -- column
		grid1[1][1], grid1[1][1], grid1[1][1]
	}
}

 

So if you want to place an item at: X2, Y3

print(grid2[2][3])

You would find the the bottle table. Therefore there is no space.

 

Demo: https://www.Lua.org/cgi-bin/demo

Spoiler

local grid1 = {
	{ -- column / X1
		{ -- cell / Y1
			width = 2,
			height = 3,
			type = "drink",
			name = "bottle",
			id = 1
		},
		nil, -- cell / Y2
		nil, -- cell / Y3
		nil, -- cell / Y4
		{ -- cell / Y5
			width = 4,
			height = 3,
			type = "ammo",
			name = "bullets ...",
			id = 2
		}
	},
	nil,  -- column / X2
	{  -- column / X3
		{ -- cell / Y1
			width = 1,
			height = 1,
			type = "matches",
			name = "matches",
			id = 3
		}
	}
}


local grid2 = {
	{ -- column
		grid1[1][1], grid1[1][1], grid1[1][1]
	},
	{ -- column
		grid1[1][1], grid1[1][1], grid1[1][1]
	}
}

print(grid2[2] and grid2[2][3] and grid2[2][3].name)

 

 

 

 

Link to comment

So based on this logic I assume that I should make utility functions like isSlotFree(x, y) and then check the indexes inside the table, then if an index is same as the given variable it should return false, am I correct?

Then use this function to check movent of an item by player to a hovered slot.

But when beginning the calculation and adding a new item, how do I set it’s first position if there are already items in the inventory, but lets say there is just enough space at the bottom of the inventory? What should be the criteria or logic behind checking for free positions anywhere inside an opened inventory?

Link to comment
  • Moderators
8 hours ago, Dzsozi (h03) said:

What should be the criteria or logic behind checking for free positions anywhere inside an opened inventory?

I do not know the best algorithm.

But what you can do for now:

- First get all open spaces.

 

- Get the size of the item you want to place.

Example: 3x2

 

- Go through each open space

 

- Make a checking box, starting from the left-top corner.

Left-top corner:

XOOOOOO

OOOOOOO

OOOOOOO

Checking box:

XXXOOOO

XXXOOOO

OOOOOOO

 

Next item:

3x3

XXXXOOO

XXXOOOO

OOOOOOO

---

XXXXXXO

XXXXXXO

OOOXXXO

 

 

This is just a way. I am sure you can optimise it in a way.

For example items that start at a position that is going to be out of the box because of the width and height.

3X3 Is never going to fit here: (start point)

OOOOOOO

OOOOOOO

OOOOOOO

 

 

Edited by IIYAMA
Link to comment

I came to the conclusion that I can basically use one table for the item list which holds the currently opened inventory’s items and the indexes of this table represent the items’ position, like this

itemTable = {
   {name = "item1", size = {1, 1}}, -- 1
   {name = "item2", size = {1, 3}}, -- 2
}

------------------

-- this should be the temporary item table which I don't save, because it is for drawing the items of an opened inventory(?)

inventoryItems = {
   -- [x position/column] = {[y position/row] = {itemData}},
   [2] = {
      [3] = {itemID = 1, value = 100},
   },
}

So in my mind I could use this for checking positions and use an utility function like isSlotFree(x, y, w, h) which would be similar to isMouseInPosition, that checks if the given variables match the item positions from the inventoryItems table, then if they are matching just return false.

But then this raises another question for me, how can I change the index of a specified item, especially if there are 2 items of the same id, or what would be a way to identify items seperately?

Sorry I got a little bit confused with this ”checking box” thing. Also these things are only in my head right now, but today when I get home I will start working on it based on the things and ideas in this topic and will see if this all is a good approach, but correct me please if there is something wrong with my “theories”.

Link to comment
  • Moderators
51 minutes ago, Dzsozi (h03) said:

especially if there are 2 items of the same id, or what would be a way to identify items seperately?

Double id's are not allowed. Your database will never generate the same ID, if the column is correct set-up.

If you move the item on top of the same item, it should consider those cells as empty.

isSlotFree(x, y, w, h [[, ignoreID int ]]) 

 

The checking box is the computed version of the grid, where each cell has data applied. (Unlike just the start position)

 

Edited by IIYAMA
Link to comment

So no matter what, I will have to use at least 2 tables for the item positions? Btw sorry for the lots of questions, I’ve never created or worked with inventory systems by myself.

Also, what should be the value of the ignoreID variable in this case?

Edited by Dzsozi (h03)
Link to comment
  • Moderators
5 hours ago, Dzsozi (h03) said:

I will have to use at least 2 tables for the item positions?

Nope, there are other methods, like checking if rectangles are colliding.

But if you use 2, it doesn't mean it is more difficult. Infact it is a lot easier to create a computed version of your grid. It tells you exactly which cells are being used and you can throw it away when you do not need it any more.

 

5 hours ago, Dzsozi (h03) said:

Also, what should be the value of the ignoreID variable in this case?

An item ID, which is the one of the item you want to move. This value is an integer, the first column located in your db table.

 

 

 

 

Link to comment

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...