Table only counts last thing that added

Just printing X supposedly fires the same tables, which looks like its just creating a new item with the same id.

I’ll move that function out, but where should it be?

I am inserting the same item into my inventory, but the ID should be randomized.

It should be above that function, also that’s exactly your issue like @Darkmist101 said, you’re not creating a new table each time you add the item to the inventory so you’re basically modifying the same table each time you add the same item.

To explain :
When you require a module script it caches the result for all the scripts so when you require twice you’re getting the same table and when you edit the result you get you’re basically editing it globally.

So, in order to fix your issue, all you have to do is create a new table for every new item.

You could just do this :

local newItemData = {}
for i,v in ipairs(itemData) do
   newItemData[i] = v
end

then you change the newItemData UniqueID and insert that to the inventory table.

You have to make a new table. Tables are passed by reference, not by value; which is saying you are passing a pointer to a table in memory, not creating a new one (which has to be done explicitly).

When printing a table, it defaults to table: [Memory address]; as you can see in your output, that memory address is identical.

2 Likes

Where should I do this though? Where should I put this newItemData, and how can I insert it into my player inventory I am a bit conflicted. :grimacing:

Actually I am starting to realize, hold up!

So it seems like newItemData is a table that I am adding to my inv table every time, and it just takes all the information and puts it there. (I cannot explain it that well)

1 Like

In your current AddItem it’ll be like this :


		local function checkItemExistence(name) -- itemsData is a module that includes all the items in my game
			for _,v in pairs(itemsData) do
				if v.Name == name then
					return true
				end
			end
		end

function inventoryHandler:AddItem(Player, itemData)
	if not inventories[Player] then
		inventories[Player] = {}
	end
	local inventory = inventories[Player]
	if itemData then
		if #inventories[Player]["Items"] < 40 then
			if checkItemExistence(itemData.Name) then
                                local newItemData = {} 
                                for i,v in ipairs(itemData) do
                                      newItemData[i] = v
                                end
				local unique = httpService:GenerateGUID(false)
				newItemData.UniqueId = unique
				newItemData.Equipped = false
				table.insert(inventories[Player]["Items"],newItemData)
				for _,x in pairs(inventories[Player]["Items"]) do
					print(x.UniqueId)
				end
				reps.Events.InventoryInfo:FireClient(Player,inventories[Player])
			end
		end
	end
	return true
end

Sorry for the indenting issues, I’m just using the message box to edit the script.

2 Likes

Alright, so this does create a new item every time which is perfect!
https://gyazo.com/437fc87d29240ed8d62d0694f4bbaa1c.png

But now inside my client script (which is supposed to replicate the new items added) I get this error, and I don’t get it for print(v.UniqueId) but for v.Name

https://gyazo.com/833e729b29733be3ad2b2b0764001b5e.jp

function newInv(inv)
	invtable = {}
	for d,x in pairs(slotsFrame:GetChildren()) do
		if x:FindFirstChild("Selection") then
			x:Destroy()
		end
	end
	invtable = inv
	buttons = {}
	for i,v in pairs(inv["Items"]) do
		print(v.UniqueId)
		local itemFrame = script.ItemPreview:Clone()
		itemFrame.ItemName.Text = v.Name -- IT ERRORS HERE.
		itemFrame.Parent = slotsFrame
		itemFrame.ID.Value = v.UniqueId
		local buttonTable = {
			[1] = itemFrame,
			[2] = v,
		}
		table.insert(buttons,buttonTable)
	end
	updateInventory()
end

In this specfic code in your AddItem function can you add print(i,v) and show me the output?
Also meant to use pairs not ipairs :laughing: (so change that aswell)

1 Like

Don’t use ipairs, use regular pairs. ipairs is for numbered indexes, which you have none of.

2 Likes

Yeah that was my bad, I forgot it was a dictionary not an array :pensive:

1 Like

ipairs, that was it! Thank you both for helping each other and me! If I have any other questions then I hope you will be embraced to answer them as well :innocent:

1 Like

Already got to a question.
In my equipitem event I fire the ID once the player clicks the ‘equip’ button on their gui, then I want to do a check on the server to loop through their inventory and check if the id they sent matches any of the id’s they have in their inventory.

I have the itemdata in this order:

	{
		Name = "Firecracker";
		Type = "MagicWeapon";
		Description = "This magical stick casts a fireball that explodes upon contact! 20 Magic Damage.";
		UII = "rbxassetid://4851526783";
		Rarity = "Unique";
		UniqueId = nil;
		Equipped = false;
	},

When we added all the data to the new item, it doesn’t add it in the same order?

				for i,v in pairs(itemData) do
					newItemData[i] = v
				end

This is how I am attempting to check:

	local inv = invmod:GetInventory(plr)
	for _,v in pairs(inv["Items"]) do
		for i,x in pairs(v) do
			print(i,x)
			if x.UniqueId == id then -- line 47

What bugs me other than this error is that it’s not in the correct order.
https://gyazo.com/d65045a847bdea0b51dc3f08f2381b36.png

Well, when you do pairs() it does not give the same order instead it’ll order it in an arbitrary order, I don’t really know anything to change it since it’s a dictionary not an array.

Why do you need it to be in the same order though? It shouldn’t matter since again it’s a dictionary not an array so when you index the key you don’t need it to be in the same order.

Also again since the keys are not numbered indexes you could just do :

for _,v in pairs(inv.Items) do
   if v.UniqueId == id then
       -- gottem
   end
end

You can read more about it here :
https://www.lua.org/pil/7.3.html

1 Like

I understand, i’ll learn about this. Thanks.

1 Like

Hey BasedFX, I ran into another issue.
From the things we did yesterday, right now I wrote this in attempt to remove the items from my inventory.

But it looks like that if I “spam” drop my items, it will output this error:

And I won’t be able to drop/equip any items until I refresh the inventory again.

This is my remove item code:

function inventoryHandler:RemoveItem(Player, itemID)
	local inventory = inventories[Player]
	if itemID then
		for i,v in pairs(inventory.Items) do
			if v.UniqueId == itemID then
				if v.Equipped == false then
					inventory.Items[i] = nil
				end
			end
		end
		reps.Events.InventoryInfo:FireClient(Player,inventory) -- line 75
	end
	return true
end

I surely am doing something wrong here.

I don’t know if that’s it, but changing inventory.Items[i] = nil to table.remove(inventory.Items,i) fixes it? I am not sure how I encounter it in the first time honestly, what do you say?

1 Like

I’m assuming inventory.Items is an array even though you’re using pairs instead of ipairs.
If Items table is an array (numeric indices) then they have to be in order from 1 to x in order to be able to pass it to the client and go across the server-client boundary, so instead of doing inventory.Items[i] = nil try doing table.remove(inventory.Items,i)

Just read your reply and yeah that’s the issue, here’s a post about it "Invalid table key type used" When Firing RemoteFunction - #3 by EncodedLua

2 Likes

It’s my first time going in-depth into creating a proper inventory system, and the dev forums helped me so much! :smiling_face_with_three_hearts:

2 Likes

If you would like direct help through discord I can do that aswell rather than flooding/posting on the same thread or waiting for me to open devforum!

Sure, I didn’t see this response from 5 days ago, i’ll just DM my discord to you or if you got a general chatting server.