Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Why won't this shop gui subtract the price and clone the weapon into the players inventory?

Asked by
bailley5 114
3 years ago
Edited 3 years ago

I made a simple shop script (I am new and I want to learn without tutorials) I want the script to check how much coins the player has, if the player has 50 or more it will subtract the price and clone a gun into the players backpack if the player clicked.

I have no errors in the output other then "Infinite yield possible on 'Players.GrannyCooksBaldGuys.leaderstats:WaitForChild("score")'"

This is a local script as well.

local player = game.Players.LocalPlayer

local leaderstats = player:WaitForChild("leaderstats")

local coins = leaderstats:WaitForChild("score")

local playerbackpack = player.Backpack

local success = "Gave player Ak-47!"

local notenough = "Player doesn't have enough!"

script.Parent.MouseButton1Click:Connect(function()
    if coins.Value >= 50 then
        local gunCopy = game.ReplicatedStorage["Ak-47"]:Clone()
        gunCopy.Parent =  playerbackpack
        coins.Value -= 50
        print(success)
    else
        print(notenough)
    end
end)

leaderstats:

function onPlayerEntered(newPlayer)
    wait(.5)
    local stats = Instance.new("IntValue")
    stats.Name = "leaderstats"

    local score = Instance.new("IntValue")

    score.Name = "Coins"
    score.Value = 150

    score.Parent = stats    
    stats.Parent = newPlayer
end

game.Players.ChildAdded:connect(onPlayerEntered)

0
Try using "FindFirstChild("leaderstats")" and tell me if it works, if it doesn't, are there any errors? ZIRFAL3 17 — 3y
0
I got an error it says Players.GrannyCooksBaldGuys.PlayerGui.ScreenGui.Frame.BuySword.LocalScript:14: attempt to index nil with 'Value' bailley5 114 — 3y
0
can you check if score and stats are really there when you test it? ZIRFAL3 17 — 3y
0
Do game.Players.PlayerAdded:Connect(onPlayerEntered) because if you were to add a instance which is not a PlayerObject it will insert a leaderstats folder into the instance. MarkedTomato 810 — 3y

2 answers

Log in to vote
1
Answered by 3 years ago
Edited 3 years ago

This can be exploited very badly. An exploiter can make their cash to a high number and the LocalScript will see that, but on the server, exploiters can't mess with the server.

Also, your leaderstats should be a Folder instead of an IntValue.

So to set this up, you'd just need to insert a RemoteEvent into ReplicatedStorage. It's best to insert it into ReplicatedStorage because the client and the server can see the RemoteEvent.

Before we start I highly recommend you to understand RemoteEvents.

LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local player = Players.LocalPlayer

local leaderstats = player:WaitForChild("leaderstats")
local coins = leaderstats:WaitForChild("score")

local Backpack = player.Backpack

local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")


script.Parent.MouseButton1Click:Connect(function()
   remoteEvent:FireServer("Ak-47")
end)

I'd put the LocalScript into StarterPlayerScripts. DataModel > StarterPlayer > StarterPlayerScripts

LOCAL SCRIPT EXPLANATION

It's best to use :GetService on services in the explorer if for some reason you changed the name.

So, the first two lines are retrieving the services ReplicatedStorage and Players.

line 4 is getting the player.

line 6 is getting the leaderstats folder.

line 7 is getting the score IntValue.

line 9 is getting the player's Backpack

line 11 is getting the RemoteEvent.

Finally, the function will fire the RemoteEvent to the server using :FireServer with an argument which is the tool's name.

Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")

local remoteEvent = ReplicatedStorage.RemoteEvent

remoteEvent.OnServerEvent:Connect(function(playerObj, tool)
   local coins = playerObj.leaderstats.score

   if coins.Value >= 50 then
         coins.Value = coins.Value - 50
         ServerStorage[tool]:Clone().Parent = playerObj.Backpack
         print("Enough")
      else
         print("Not enough")
   end
end)

I'd put the Script into ServerScriptService. DataModel > ServerScriptService

SCRIPT EXPLANATION

So, the first two lines are retrieving the services ReplicatedStorage and ServerStorage. It's best to have the AK-47 in ServerStorage because the client can't see the contents of ServerStorage.

line 4 is the RemoteEvent. You don't need to use :WaitForChild on the server because everything loads at the same time.

line 6 OnServerEvent will listen out for :FireServer then will trigger the function connected to the event.

line 7 will get the score IntValue. After that, using a relational operator to compare the player's cash and if true then it'll run the code after the if statement otherwise it will run the code after the else.

line 11 you should use square brackets because tool is an argument passed from the LocalScript.

Hopefully, this works because I just wrote it in here and didn't write the code in Roblox studio.

If you have any problems or you were confused, you can reply to me.

Edit1: Added links and tried to fix some grammar mistakes.

0
Nice script! qes 0 — 3y
Ad
Log in to vote
0
Answered by 3 years ago

This is a common problem I had when I started scripting, The only thing you need to do is that when you are subtracting the money you have to do it server sided meaning you can't use a local script to change the money value, If you need a local script I recommend you check out this: https://developer.roblox.com/en-us/articles/Remote-Functions-and-Events

If you want you could add me on discord (A_XxJOxX#1337) and I can show you in studio

Answer this question