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?
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.
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.
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)
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.
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 (so change that aswell)
Don’t use ipairs, use regular pairs. ipairs is for numbered indexes, which you have none of.
Yeah that was my bad, I forgot it was a dictionary not an array
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
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
I understand, i’ll learn about this. Thanks.
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?
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
It’s my first time going in-depth into creating a proper inventory system, and the dev forums helped me so much!
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.