What's wrong with my script?

  1. What do you want to achieve?

The script is checking if the player has at least three items with the same name in their inventory. If they do, the script destroys those items and gives the player a new, upgraded item depending on the 3 cards/items. It also subtracts 2 from the current_card value & destroys the 3 cards/items in the inventory that are being used to upgrade the card. If the player does not have at least three items with the same name, the script displays a message saying that the player does not have enough cards to upgrade.

  1. What is the issue?

So far, the only issue I’ve been able to notice is that It’s not inserting all the objects within “Grid” that are Frames, only 1 object is being inserted which is UIGridLayout.

  1. What solutions have you tried so far?

Searched the DevForum, Watched youtube videos about Tables/ table.insert, rewrote the code multiple times, asked people on discord, etc.


script.Parent.Triggered:Connect(function(player)
	local current_card = player:FindFirstChild("Data_Folder").CurrentCardStorage
	local grid = player.PlayerGui:WaitForChild("GameInventory").Frame.Inventory.Items.Grid-- replace 'Grid' with the actual name of your object
	local frames = grid:GetChildren()
	
	local frameNames = {}

	while #frames == 0 do
		wait()
		frames = grid:GetChildren()
	end

	for _, v in ipairs(grid:GetChildren()) do
		if v:IsA("Frame") and v.Name ~= "" then
			table.insert(frameNames, v.Name)
		end
	end

	print("Number of frames: " .. #frameNames)

	for _, name in ipairs(frameNames) do
		print(name)
	-- check if there are at least three frame names in the table
	if #frameNames < 3 then
		player.PlayerGui.GameInventory.DeleteOneMsg.Visible = true
		player.PlayerGui.GameInventory.DeleteOneMsg.Msg.Text = "You don't have enough cards to upgrade."

		wait(2)
		player.PlayerGui.GameInventory.DeleteOneMsg.Visible = false
		else
		if #frameNames == 3 or #frameNames >= 3 then
				print("yes")
		local nameCount = {}
		for _, name in ipairs(frameNames) do
			if nameCount[name] == nil then
				nameCount[name] = 1
			else
				nameCount[name] = nameCount[name] + 1
			end
		end
		-- check if there are three frames with the same name
		local foundMatch = false
		local itemName = nil
		for name, count in pairs(nameCount) do
			if count >= 3 then
				foundMatch = true
				itemName = name
				break
			end
		end

		-- give item to player depending on the name of the frames
				if foundMatch then
					current_card.Value -= 2
			local player = game.Players.LocalPlayer -- replace with actual player object
				if itemName == "Soul Seeker I" then	
					local destroyCount = 0
					for _, frame in ipairs(grid:GetChildren()) do
						if frame:IsA("Frame") and frame.Name == "Soul Seeker I" then
							frame:Destroy()
							destroyCount += 1
							if destroyCount == 3 then
							local event = game.ReplicatedStorage.InvEvents.PickUp
							local item = game.ReplicatedStorage.Cards["Soul Seeker II"]
							--local firstChild = itemModel
							local itemdescription = item:FindFirstChild("Desc").Value
							event:FireServer(item, itemdescription)
								break
							end
						end
					end
			--player.Backpack:FindFirstChild("Item1"):Clone().Parent = player.Character
					elseif itemName == "Soul Seeker II" then
		local destroyCount = 0
					for _, frame in ipairs(grid:GetChildren()) do
						if frame:IsA("Frame") and frame.Name == "Soul Seeker II" then
							frame:Destroy()
							destroyCount += 1
							if destroyCount == 3 then
							local event = game.ReplicatedStorage.InvEvents.PickUp
							local item = game.ReplicatedStorage.Cards["Soul Seeker III"]
							--local firstChild = itemModel
							local itemdescription = item:FindFirstChild("Desc").Value
							event:FireServer(item, itemdescription)
								break
							end
						end
					end
					elseif itemName == "Stealth I" then
					local destroyCount = 0
					for _, frame in ipairs(grid:GetChildren()) do
						if frame:IsA("Frame") and frame.Name == "Stealth I" then
							frame:Destroy()
							destroyCount += 1
							if destroyCount == 3 then
								local event = game.ReplicatedStorage.InvEvents.PickUp
								local item = game.ReplicatedStorage.Cards["Stealth II"]
								--local firstChild = itemModel
								local itemdescription = item:FindFirstChild("Desc").Value
								event:FireServer(item, itemdescription)
								break
							end
						end
					end
					--player.Backpack:FindFirstChild("Item3"):Clone().Parent = player.Character
					elseif itemName == "Stealth II" then
					local destroyCount = 0
					for _, frame in ipairs(grid:GetChildren()) do
						if frame:IsA("Frame") and frame.Name == "Stealth II" then
							frame:Destroy()
							destroyCount += 1
							if destroyCount == 3 then
								local event = game.ReplicatedStorage.InvEvents.PickUp
								local item = game.ReplicatedStorage.Cards["Stealth III"]
								--local firstChild = itemModel
								local itemdescription = item:FindFirstChild("Desc").Value
								event:FireServer(item, itemdescription)
								break
							end
						end
					end
					elseif itemName == "Beast Sense I" then
					local destroyCount = 0
					for _, frame in ipairs(grid:GetChildren()) do
						if frame:IsA("Frame") and frame.Name == "Beast Sense I" then
							frame:Destroy()
							destroyCount += 1
							if destroyCount == 3 then
								local event = game.ReplicatedStorage.InvEvents.PickUp
								local item = game.ReplicatedStorage.Cards["Beast Sense II"]
								--local firstChild = itemModel
								local itemdescription = item:FindFirstChild("Desc").Value
								event:FireServer(item, itemdescription)
								break
							end
						end
					end
					elseif itemName == "Beast Sense II" then
					local destroyCount = 0
					for _, frame in ipairs(grid:GetChildren()) do
						if frame:IsA("Frame") and frame.Name == "Beast Sense II" then
							frame:Destroy()
							destroyCount += 1
							if destroyCount == 3 then
								local event = game.ReplicatedStorage.InvEvents.PickUp
								local item = game.ReplicatedStorage.Cards["Beast Sense III"]
								--local firstChild = itemModel
								local itemdescription = item:FindFirstChild("Desc").Value
								event:FireServer(item, itemdescription)
								break
							end
						end
					end
					elseif itemName == "Loot Finder I" then
					local destroyCount = 0
					for _, frame in ipairs(grid:GetChildren()) do
						if frame:IsA("Frame") and frame.Name == "Loot Finder I" then
							frame:Destroy()
							destroyCount += 1
							if destroyCount == 3 then
								local event = game.ReplicatedStorage.InvEvents.PickUp
								local item = game.ReplicatedStorage.Cards["Loot Finder I"]
								--local firstChild = itemModel
								local itemdescription = item:FindFirstChild("Desc").Value
								event:FireServer(item, itemdescription)
								break
							end
						end
					end
					elseif itemName == "Loot Finder II" then
					local destroyCount = 0
					for _, frame in ipairs(grid:GetChildren()) do
						if frame:IsA("Frame") and frame.Name == "Loot Finder II" then
							frame:Destroy()
							destroyCount += 1
							if destroyCount == 3 then
								local event = game.ReplicatedStorage.InvEvents.PickUp
								local item = game.ReplicatedStorage.Cards["Loot Finder III"]
								--local firstChild = itemModel
								local itemdescription = item:FindFirstChild("Desc").Value
								event:FireServer(item, itemdescription)
								break
							end
						end
					end
					elseif itemName == "Resistance I" then
					local destroyCount = 0
					for _, frame in ipairs(grid:GetChildren()) do
						if frame:IsA("Frame") and frame.Name == "Resistance I" then
							frame:Destroy()
							destroyCount += 1
							if destroyCount == 3 then
								local event = game.ReplicatedStorage.InvEvents.PickUp
								local item = game.ReplicatedStorage.Cards["Resistance II"]
								--local firstChild = itemModel
								local itemdescription = item:FindFirstChild("Desc").Value
								event:FireServer(item, itemdescription)
								break
							end
						end
					end
					elseif itemName == "Resistance II" then
					local destroyCount = 0
					for _, frame in ipairs(grid:GetChildren()) do
						if frame:IsA("Frame") and frame.Name == "Resistance II" then
							frame:Destroy()
							destroyCount += 1
							if destroyCount == 3 then
								local event = game.ReplicatedStorage.InvEvents.PickUp
								local item = game.ReplicatedStorage.Cards["Resistance II"]
								--local firstChild = itemModel
								local itemdescription = item:FindFirstChild("Desc").Value
								event:FireServer(item, itemdescription)
								break
							end
						end
					end
			end
		end
			--end
	end
end
end)

I set up your code as you have described, however, was unable to replicate that specific problem.
The only thing I can think of is that the function is being triggered prior to the elements loading into the PlayerGui. I notice the output line in the InventoryMain script Found Player Inventory: ServerStorage (Attempting Save), does this attempt to use the DataStoreService before adding the Frames to the PlayerGui?

I have no idea exactly what the code is trying to do. It’s far too bloated and repetitive for such a simple sounding task.

I have changed the code a little (making it more readable and less repeatable). I’m not saying this will work for you, or even run since I can’t test it without much more work on my behalf. I may have missed some nuances in the massive logic tree structures, but you will get the essence of how to write this code more efficiently and readable, and manageable for the future.

local function makeFrame(frame,destroyCount)
	
	if frame:IsA("Frame") then
		frame:Destroy()
		destroyCount += 1;
		if destroyCount == 3 then
			local event = game.ReplicatedStorage.InvEvents.PickUp;
			local item = game.ReplicatedStorage.Cards[frame.Name];
			local itemdescription = item:FindFirstChild("Desc").Value;
			event:FireServer(item,itemdescription);
			return true;
		end
	end
	return false;
end

local function getFrameNames(player)
	
	local grid = player.PlayerGui:WaitForChild("GameInventory").Frame.Inventory.Items.Grid;
	local frames = grid:GetChildren();
	local frameNames = {};

	while #frames == 0 do -- dunno what this is for
		wait();
		frames = grid:GetChildren();
	end
	-- why the frames variable above if you go ahead and GetChildren() again, frames is the children??
	for _, v in ipairs(grid:GetChildren()) do
		if v:IsA("Frame") and v.Name ~= "" then
			table.insert(frameNames, v.Name)
		end
	end

	print("Number of frames: " .. #frameNames);
	return frameNames;
	
end

script.Parent.Triggered:Connect(function(player)
	
	local frameNames = getFrameNames(player);
	local current_card = player:FindFirstChild("Data_Folder").CurrentCardStorage;
	
	for _, name in ipairs(frameNames) do
		print(name)
		-- check if there are at least three frame names in the table
		if #frameNames < 3 then
			player.PlayerGui.GameInventory.DeleteOneMsg.Visible = true;
			player.PlayerGui.GameInventory.DeleteOneMsg.Msg.Text = "You don't have enough cards to upgrade.";
			wait(2);
			player.PlayerGui.GameInventory.DeleteOneMsg.Visible = false;
		else
			if #frameNames >= 3 then -- why check if it's equal twice, besides this is redundant, you already checked if it was less than 3 so it must be greater than or equal to here?
				print("yes");
				local nameCount = {};
				for _, name in ipairs(frameNames) do
					if nameCount[name] == nil then
						nameCount[name] = 1
					else
						nameCount[name] = nameCount[name] + 1
					end
				end
				
				-- check if there are three frames with the same name
				local foundMatch = false;
				local itemName = nil;
				for name, count in pairs(nameCount) do
					if count >= 3 then
						foundMatch = true;
						itemName = name;
						break
					end
				end

				-- give item to player depending on the name of the frames
				if foundMatch then
					current_card.Value -= 2;
					local destroyCount = 0;
					local player = game.Players.LocalPlayer; -- ??????
					for _, frame in ipairs(grid:GetChildren()) do
						if frame.Name == itemName then
							local stop = makeFrame(frame,destroyCount); 
							if stop == true then
								break;
							end
						end
					end
				end	
			end	
		end
	end
end)
1 Like