What does the code do and what are you not satisfied with?
Currently, I have my shop and inventory system work in separate Guis. The shop Gui updates an item information frame with the information of the item button you clicked. When the buy button is clicked, it invokes a remote function to the server to handle purchases. The inventory Gui listens for an event to be fired, which will then create a new button in the player’s inventory of their purchased item. Clicking a item button inside the inventory Gui will open an information frame like the shop, and has an equip button that will change the player’s EquippedItem value.
How (specifically) do you want to improve the code?
I would like to make it less exploitable, or to change my current system to make it more efficient.
Handles shop items and invokes the purchase remotefunction
for _, frameItem in pairs(itemFrame:GetChildren()) do
if frameItem:IsA("TextButton") then
frameItem.MouseButton1Click:Connect(function()
local itemName = frameItem:WaitForChild("ItemName")
local displayResult = displayInformation:InvokeServer(itemName.Value)
if displayResult == "Buy" then
buyButton.Text = "Buy"
else
buyButton.Text = "Already Owned"
end
nameLabel.Text = itemName.Value
informationFrame.Visible = true
end)
end
end
buyButton.MouseButton1Click:Connect(function()
local successfulPurchase = buyItem:InvokeServer(nameLabel.Text)
if successfulPurchase == true then
buyButton.Text = "Already Owned"
elseif successfulPurchase == false then
buyButton.Text = "Insufficient Kills"
wait(1)
buyButton.Text = "Buy"
else
print("Already owned")
end
end)
Makes a table of prices for the items and handles the purchase button invoke
local itemPrices = {}
for _, item in pairs(items:GetChildren()) do
itemPrices[item.Name] = item:FindFirstChild("Price").Value
end
displayInformation.OnServerInvoke = function(player, itemName)
if not items:FindFirstChild(itemName) then
return
end
local playerInventory = serverStorage.PlayerData[player.Name].Inventory
if not playerInventory:FindFirstChild(itemName) then
return "Buy"
else
return
end
end
buyItem.OnServerInvoke = function(player, itemName)
if not items:FindFirstChild(itemName) then
return
end
local playerInventory = serverStorage.PlayerData[player.Name].Inventory
if not playerInventory:FindFirstChild(itemName) then
local itemCost = itemPrices[itemName]
local kills = player.leaderstats.Kills
if kills.Value >= itemCost then
local purchasedItem = Instance.new("StringValue")
purchasedItem.Name = itemName
purchasedItem.Parent = playerInventory
kills.Value -= itemCost
purchaseComplete:FireClient(player, itemName)
return true
else
return false
end
else
return
end
end
Handles inventory and updates when a new button is cloned inside
local function clickedFunction(frameItem)
if not frameItem:IsA("TextButton") then
return
end
frameItem.MouseButton1Click:Connect(function()
local itemName = frameItem.ItemName.Value
local textUpdate = updateEquipButton:InvokeServer(itemName)
if textUpdate == "Equip" then
equipButton.Text = "Equip"
else
equipButton.Text = "Unequip"
end
nameLabel.Text = itemName
informationFrame.Visible = true
end)
end
for _, frameItem in pairs(inventoryFrame:GetChildren()) do
clickedFunction(frameItem)
end
inventoryFrame.ChildAdded:Connect(function(frameItem)
clickedFunction(frameItem)
end)
equipButton.MouseButton1Click:Connect(function()
local result = equipToggle:InvokeServer(nameLabel.Text)
if result == "Equip" then
equipButton.Text = "Unequip"
else
equipButton.Text = "Equip"
end
end)
purchaseComplete.OnClientEvent:Connect(function(itemName)
local addedItem = inventoryItem:Clone()
addedItem.Text = itemName
addedItem.ItemName.Value = itemName
addedItem.Parent = inventoryFrame
end)
Handles the equip button invoke
updateEquipButton.OnServerInvoke = function(player, itemName)
if not items:FindFirstChild(itemName) then
return
end
local equippedItem = serverStorage.PlayerData[player.Name].EquippedItem
if equippedItem.Value ~= itemName then
return "Equip"
else
return
end
end
equipToggle.OnServerInvoke = function(player, itemName)
if not items:FindFirstChild(itemName) then
return
end
local playerData = serverStorage.PlayerData[player.Name]
local equippedItem = playerData.EquippedItem
if playerData.Inventory:FindFirstChild(itemName) then
if equippedItem.Value ~= itemName then
equippedItem.Value = itemName
return "Equip"
else
equippedItem.Value = "Default"
return
end
end
end