What is wrong with my script/function?

  1. What do you want to achieve?
    Within this function, I want it to check to see whether all of items within the slots each have a certain level AND are a specific type. It doesn’t matter the order of how the player puts them into the slots, just that each item has a specific level. For example, one item has a Level.Value = 1, one item has a Level.Value = 2, one item has a Level.Value = 3, and one item has a Level.Value = 4. If this condition is met, then when they press the UpgradeButton, the slots will be cleared and the items that they inserted into the slots will be removed from their inventory. If the condition is not met, then nothing will happen.

  2. What is the issue?
    When I press the UpgradeButton, the items aren’t being removed from the player’s inventory AND it’s printing this (see photo below) which means that it’s false… but it’s actually NOT false because the items DO meet the Level requirements :upside_down_face: Additionally, it puts the items back into the Items frame/grid, even though they’re also still being displayed in the slots.

  1. What solutions have you tried so far?
    I’ve literally spent hours trying to fix my code and it still is not working… nothing online helps either ):

--Variables--
local DataFolder = game.Players.LocalPlayer:WaitForChild('Data_Folder')
local SettingsFolder = script.Parent.Parent.Parent.Parent:WaitForChild('GameInventory').Frame.Inventory.Settings
local ForgeFrame = script.Parent.ForgeFrame
local UpgradeButton = script.Parent.ForgeFrame.UpgradeButton
local OpenEvent = game.ReplicatedStorage.UpgradeEvents.OpenTradeUI -- create RE
local UpgradeCard = game.ReplicatedStorage.UpgradeEvents.SubmitArtifacts -- create RE
local ItemGrid = script.Parent.Items.Grid
local InvGrid = script.Parent.Parent.Parent.Parent.GameInventory.Frame.Inventory.Items.Grid
local Events = game.ReplicatedStorage.InvEvents
local Available = ForgeFrame.Slots.Available --// Holds the value of the first available slot

...

local function upgradeCard()
	print("UpgradeCard funct")
	local levels = {} -- Empty table to track levels

	-- Check for cards with the required levels in the slots
	for level = 1, 4 do
		local cardFound = false -- Flag to track if a card with the required level is found

		-- Iterate over the Slots and check for cards with the required level
		for _, slot in ipairs(Slots) do
			local item = slot.ViewportFrame.Model:FindFirstChildWhichIsA('Model')
			if item and item:FindFirstChild("Level") and item.Level.Value == level then
				cardFound = true
				break
			end
		end

		table.insert(levels, cardFound) -- Store whether a card with the required level was found
	end

	-- Check if all required levels are filled
	local allLevelsFilled = true
	for _, filled in ipairs(levels) do
		if not filled then
			allLevelsFilled = false
			break
		end
	end

	print("Levels:", table.unpack(levels))
	print("allLevelsFilled:", allLevelsFilled)

	if allLevelsFilled then
		-- Remove items from the player's inventory and update SettingsFolder
		for _, slot in ipairs(Slots) do
			local item = slot.ViewportFrame.Model:FindFirstChildWhichIsA('Model')
			if item then
				print("Removing", item.Name, "with Level", item.Level.Value)
				removeCard(slot)
				Events.RemoveFromInv:FireServer(item)
				script.UpgradeSound:Play()
			end
		end

		SettingsFolder.CurrentArtStorage.Value = SettingsFolder.CurrentArtStorage.Value - 4 -- Decrease the value by 4

		Available.Value = 1

		print("Items removed from the player's inventory.")
		print("SettingsFolder.CurrentArtStorage.Value decreased by 4.")

		for _, slot in ipairs(Slots) do
			local viewportFrame = slot.ViewportFrame
			slot.Occupied.Value = ''
			local model = viewportFrame.Model:FindFirstChildWhichIsA('Model')
			if model then model:Destroy() end
		end
	else
		print("Please fill all slots with the required levels.")
	end
end

...
...

--Events--

OpenEvent.OnClientEvent:Connect(function(itemType)
	script.Parent.Parent.Visible = true
	selectedType = itemType
	updateList()
end)

for _, slot in ipairs(Slots) do
	slot.Activated:Connect(function()
		if slot.Occupied.Value ~= '' and slot.Occupied.Value ~= nil then
			if slot.ViewportFrame.Model:FindFirstChildOfClass('Model') then
				removeCard(Slots[Available.Value - 1])
			end
		end
	end)



	slot.Text = slot.Occupied.Value
	slot.Occupied.Changed:Connect(function(value)
		slot.Text = value
	end)
end

Available.Changed:Connect(function(value)
	if value == 1 then
		for _, tab in ipairs(ItemGrid:GetChildren()) do
			if tab:IsA('Frame') then
				tab.Visible = true
			end
		end
	end
end)

UpgradeButton.Activated:Connect(function()
	upgradeCard(Slots[1].Occupied.Value)
	task.wait(0.1)
	updateList()
end)

game.ReplicatedStorage.UpgradeEvents.OpenTradeUI.OnClientEvent:Connect(function(itemType)
	if DataFolder.CurrentArtStorage.Value ~= (#ItemGrid:GetChildren() - 1) then
		selectedType = itemType
		updateList()
	end
end)

task.wait(3)
updateList()

PLEASE let me know if you’d like to include any more additional information!!!

3 Likes

Are you sure that this bit of code is being run? Pop a print statement inside and just make sure. Also verify the contents of “Slots” variable.

1 Like

Thank you for your reply!! Your help really means a lot to me :slight_smile:

It seems like that bit of code is not being run… here’s what I wrote:

for _, slot in ipairs(Slots) do
			local item = slot.ViewportFrame.Model:FindFirstChildWhichIsA('Model')
			if item and item:FindFirstChild("Level") and item.Level.Value == level then
				print("PRINT CHECK!!!")
				cardFound = true
				break
			end
		end

“PRINT CHECK!!!” is not being printed.

I fixed it for the most part… but now it items aren’t being removed from the inventory:

local function upgradeCard()
	print("UpgradeCard funct")
	local levels = {} -- Empty table to track levels

	-- Check for cards with the required levels in the slots
	for level = 1, 4 do
		local cardFound = false -- Flag to track if a card with the required level is found

		-- Iterate over the Slots and check for cards with the required level
		for _, slot in ipairs(Slots) do
			local item = slot.ViewportFrame.Model:FindFirstChildWhichIsA('Model')
			if item then
				local itemLevel = item:FindFirstChild("Level")
				if itemLevel and itemLevel:IsA("StringValue") and itemLevel.Value == tostring(level) then
					print("PRINT CHECK!!!")
					cardFound = true
					break
				end
			end
		end
		
		table.insert(levels, cardFound) -- Store whether a card with the required level was found
	end

	-- Check if all required levels are filled
	local allLevelsFilled = true
	for _, filled in ipairs(levels) do
		if not filled then
			allLevelsFilled = false
			break
		end
	end

	print("Levels:", table.unpack(levels))
	print("allLevelsFilled:", allLevelsFilled)

	if allLevelsFilled then
		-- Remove items from the player's inventory and update SettingsFolder
		local itemsToRemove = {}

		-- Gather all the items from the slots
		for _, slot in ipairs(Slots) do
			local item = slot.ViewportFrame.Model:FindFirstChildWhichIsA('Model')
			if item then
				removeCard(slot) -- Remove the card from the slot
				print("Removing", item)
				Events.RemoveFromInv:FireServer(item.Name) -- Fire the event for each item
				item:Destroy()
			--	update(InvGrid:FindFirstChild(item), 'remove')
			end
		end

		script.UpgradeSound:Play()

		SettingsFolder.CurentArtStorage.Value = SettingsFolder.CurentArtStorage.Value - 4 -- Decrease the value by 4

		Available.Value = 1

		print("Items removed from the player's inventory.")
		print("SettingsFolder.CurrentArtStorage.Value decreased by 4.")

		for _, slot in ipairs(Slots) do
			local viewportFrame = slot.ViewportFrame
			slot.Occupied.Value = ''
			local model = viewportFrame.Model:FindFirstChildWhichIsA('Model')
			if model then model:Destroy() 
			
			end
		end
	else
		print("Please fill all slots with the required levels.")
	end
	end

Available.Value is set to 1 as default, and you only seem to hinge any logic on it being 1. So the code above could well be indexing 0 and supplying it as an input parameter to removeCard(). Which for me and everyone else, remains an undefined function in the code you posted.

2 Likes
local function removeCard(slot)
	print("removeCard funct")
	local item = slot.ViewportFrame.Model:FindFirstChildWhichIsA('Model')
	if item then
		item:Destroy()
		slot.Occupied.Value = ''
		Available.Value -= 1

		for _, itemSlab in ipairs(ItemGrid:GetChildren()) do
			if itemSlab:IsA('Frame') and itemSlab.Name == item.Name then
				if itemSlab.Visible == false then
					itemSlab.Visible = true
					break
				end
			end
		end
	end
end

Ahhh now this could be problematic, after this subtraction it may be prudent to check whether the value has become 0. So you can either do:

if Available.Value >=1 then Available.Value -= 1 end

Or:

Available.Value -= 1
if Available.Value < 1 then Available.Value = 1 end

And where possible, you should try to alter global variables in the same function or code body. So try to subtract from this value and add to it in the same function, code body, or if there are many variables to change, create an UpdateVariables() function. This will make it easier to spot any logic errors if the code continues to grow.

Also, this call below is finding a Model within a Model, I assume this is a Folder name Model with a Model inside it. Is this how your work tree is setup?

if slot.ViewportFrame.Model:FindFirstChildOfClass('Model') then
1 Like

I was wondering if you’d be willing to have me share the game with you via Team Create so that you could get a better idea or picture of what the setup is? If not, that’s okay!

Also, that call you’ve mentioned — it’s an actual Model (not a folder) and then within/inside that model, there is the item (which is also a model but it is not named “Model”).

Yes absolutely, always happy to help a fellow Robloxian.

I will try to help anyway I can.