Hi! So I have made an inventory system where you can equip multiple tools at once. The problem is, when two or more tools are equipped and all the texts say “unequip,” it takes two clicks of the button to finally change the text button’s text to equip. This is a big problem because the tool is still in the player’s inventory even though the button says to “equip.”
Picture of frame:
for i, tool in pairs(ownedTrails) do
local item = script.InvItem:Clone()
item.Image = tool:WaitForChild("Folder").ImageLabel.Image
item.SelectButton.Text = "Equip"
item.Title.Text = tool.Name
item.Visible = true
item.Parent = invFrame.ShopGUI.Tools
item.SelectButton.MouseButton1Click:Connect(function()
local price = tool.Price.Value
local coins = player.leaderstats.Coins.Value
if item == SelectedTrail then
item.SelectButton.Text = "Equip"
SelectedTrail = nil
else
if player.OwnedTools:FindFirstChild(tool.Name) or (price <= coins) then
item.SelectButton.Text = "Unequip"
else
item.SelectButton.Text = "Unequip"
end
SelectedTrail = item
end
TrailSelectedRE:FireServer(tool)
end)
end
end
So to sum this post up in one question, how can I make the button stop requiring to clicks to finally change the text?
Since you have made it so that multiple tools can be equipped at once, the issue at hand is because you have a single variable that holds a reference to the current equipped item… See the issue? How will one variable to one item be able to handle concurrent equipped items?
I’d suggest changing SelectedTrail to a table, because with that you can insert multiple things and delete multiple things without having to change any already existing ones.
Im confused on how to change that variable into a table. When the button is clicked, it needs to send over that tools information. If I send it over in a table, won’t there be multiple options?
So when the button is clicked, it triggers a remote event. Its connected through this script.
ToolSelectedRE.OnServerEvent:Connect(function(plr, tool)
if not tool or typeof(tool) ~= "Instance" then return end -- we still want this here just in case
local ownedTool = plr.OwnedTools:FindFirstChild(tool.Name)
if not ownedTool then
print(plr.Name," is buying the ",tool.Name," tool.")
local price = tool.Price.Value
local coins = plr.leaderstats.Coins
if price <= coins.Value then
coins.Value -= price
local newTool = tool:Clone() do
newTool.Parent = plr.OwnedTools
end
end
elseif ownedTool then
if plr.Backpack:FindFirstChild(tool.Name) == nil then
print(plr.Name," equipped ",tool.Name," tool.")
local new = tool:Clone()
new.Parent = plr.Backpack
elseif plr.Backpack:FindFirstChild(tool.Name) then
print("triggered")
local deleted = plr.Backpack:WaitForChild(tool.Name)
deleted:Destroy()
end
end
end)
ToolSelectedRE.OnServerEvent:Connect(function(plr, tools) -- tools is the table you're going to send
if not tool or typeof(tool) ~= "Instance" then return end -- we still want this here just in case
for _, tool in pairs(tools) do
local ownedTool = plr.OwnedTools:FindFirstChild(tool.Name)
if not ownedTool then
print(plr.Name," is buying the ",tool.Name," tool.")
local price = tool.Price.Value
local coins = plr.leaderstats.Coins
if price <= coins.Value then
coins.Value -= price
local newTool = tool:Clone() do
newTool.Parent = plr.OwnedTools
end
end
elseif ownedTool then
if plr.Backpack:FindFirstChild(tool.Name) == nil then
print(plr.Name," equipped ",tool.Name," tool.")
local new = tool:Clone()
new.Parent = plr.Backpack
elseif plr.Backpack:FindFirstChild(tool.Name) then
print("triggered")
local deleted = plr.Backpack:WaitForChild(tool.Name)
deleted:Destroy()
end
end
end
end)
So, its acting even weirder now (i’ll try to explain the best I can). So instead of last time where when all 2 of the buttons said “unequip” and you would have to click each of them 2 times to work, you can now click one button just once to change back to “equip” but the other one will take two clicks. This has nothing to do with the frame, its whatever button says “unequip” last will take two clicks. Does that make sense?
function updateInventory()
for i, child in pairs(invFrame.ShopGUI.Tools:GetChildren()) do
if child:IsA("ImageLabel") then child:Destroy() end
end
local ownedTrails = ownedTrailsFolder:GetChildren()
print(ownedTrails)
table.sort(ownedTrails, function(a, b)
return trailsFolder[a.Name].Price.Value < trailsFolder[b.Name].Price.Value or trailsFolder[a.Name].Price.Value == trailsFolder[b.Name].Price.Value and a.Name < b.Name
end)
for i, tool in pairs(ownedTrails) do
local item = script.InvItem:Clone()
item.Image = tool:WaitForChild("Folder").ImageLabel.Image
item.SelectButton.Text = "Equip"
item.Title.Text = tool.Name
item.Visible = true
item.Parent = invFrame.ShopGUI.Tools
item.SelectButton.MouseButton1Click:Connect(function()
local price = tool.Price.Value
local coins = player.leaderstats.Coins.Value
if item == SelectedTrail then
item.SelectButton.Text = "Equip"
SelectedTrail = nil
else
if player.OwnedTools:FindFirstChild(tool.Name) or (price <= coins) then
item.SelectButton.Text = "Unequip"
else
item.SelectButton.Text = "Unequip"
end
SelectedTrail = item
end
TrailSelectedRE:FireServer(tool)
end)
end
end
I realize now I was missing some parts which could have made some variables confusing.
Before I give you the full script, I need to tell you about another problem.
You see the function where you click SelectButton? When updateInventory runs again, those functions are still there.
If we use a dictionary, we would be able to remove and disconnect this function.
also I changed everything to a table
local buttonDictionary = {}
local clonedToItem = {}
function updateInventory()
for i, child in pairs(invFrame.ShopGUI.Tools:GetChildren()) do
if child:IsA("ImageLabel") then
child:Destroy()
buttonDictionary[child.SelectButton]:Disconnect() -- removing it
buttonDictionary[child.SelectButton] = nil
end
end
for i, v in pairs(clonedToItem) do
clonedToItem[i] = nil
end
local ownedTrails = ownedTrailsFolder:GetChildren()
print(ownedTrails)
table.sort(ownedTrails, function(a, b)
return trailsFolder[a.Name].Price.Value < trailsFolder[b.Name].Price.Value or trailsFolder[a.Name].Price.Value == trailsFolder[b.Name].Price.Value and a.Name < b.Name
end)
for i, tool in pairs(ownedTrails) do
local item = script.InvItem:Clone()
item.Image = tool:WaitForChild("Folder").ImageLabel.Image
item.SelectButton.Text = "Equip"
item.Title.Text = tool.Name
item.Visible = true
clonedToItem[item] = tool
item.Parent = invFrame.ShopGUI.Tools
buttonDictionary[item.SelectButton] = item.SelectButton.MouseButton1Click:Connect(function() -- adding it
local price = tool.Price.Value
local coins = player.leaderstats.Coins.Value
if item == SelectedTrail then
item.SelectButton.Text = "Equip"
table.remove(SelectedTrail, table.find(SelectedTrail, item))
else
if player.OwnedTools:FindFirstChild(tool.Name) or (price <= coins) then
item.SelectButton.Text = "Unequip"
else
item.SelectButton.Text = "Unequip"
end
table.insert(SelectedTrail, item)
end
local finalTable = {}
for i, v in pairs(SelectedTrail) do
table.insert(finalTable, clonedToItem[v])
end
TrailSelectedRE:FireServer(finalTable)
end)
end
end
There is still a red line under “SelectedTrail.” Also, could you elaborate on the future issue and what this could cause?
Edit: I see what you mean about the problem, nevermind.