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

Scripting a coin that can only be collected once?

Asked by 4 years ago

so im working on a game, yes

ive been trying to script this coin collecting thing. say there's one coin in the game, yes? player 1 collects it, but player 1 won't be able to collect it anymore afterwards cause he has already collected it. player 2 comes along, but is also able to collect it and bla bla (same concept applies)

thing is i know how to make the simple coin script of collecting, but it's only executed simply in a local script:

local StarOrb = game.Workspace.StarOrbs.StarOrb1
local db = true

---

StarOrb.Touched:Connect(function(hit)
    if hit.Parent:FindFirstChild("Humanoid") ~= nil then
        if db == true then
            db = false
            local player = game.Players:GetPlayerFromCharacter(hit.Parent)
            player.leaderstats.StarOrbs.Value = player.leaderstats.StarOrbs.Value + 1
            wait(0.1)
            script.Sound:Play()
            wait(1)
            db = true
            StarOrb:Destroy()
        end
    end
end)

can someone help me improve this code and modify it? and can someone TEACH (not do it for me) how to use datastore to make it so if the player rejoins, the player STILL cant collect the coin (i already have a datastore that saves the accumulated value)

any help is appreciated and if i was confusing, please let me know. thank you!

0
Well, if you don't want it to happen again, don't set db back to true. killerbrenden 1537 — 4y
0
It's also not working because LocalScripts are ClientSided, not ServerSided. So, any player will be able to collect it. killerbrenden 1537 — 4y
0
Please provide an attempt at solving this.  User#5423 17 — 4y

3 answers

Log in to vote
0
Answered by 4 years ago
Edited 4 years ago

So, to do this you would want to put a ServerScript inside of the Orb and write this code. I'll explain how it works below the code.

Setup

ServerScript inside of the part

local incremental = 1 --// Changeable

script.Parent.Touched:Connect(function(hit)
    if hit.Parent:FindFirstChild("Humanoid") then
        script.Sound.PlayOnRemove = true
        local player = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
        local starOrbs = player:WaitForChild("leaderstats"):FindFirstChild("StarOrbs")
        starOrbs.Value = starOrbs.Value + incremental
        wait()
        script.Parent:Destroy()
    end
end)

So, the first line is how much their StarOrbs value will increase by. Line 4 will make sure to play the sound when the part is destroyed. Everything else is pretty much the same except you don't need a debounce variable for this since the part will be removed when it is touched.


If you wanted to do a DataStore, there's 2 ways. ROBLOX DataStore or DataStore2. Either way works.

Depends on how you want to do it, DataStore is better for Tables, and DataStore2 is better for variables.

I would put a folder inside of the player when they join and put a bool value for every coin there is, like this. I would assume there is a folder in ReplicatedStorage to hold all the coins.

game.Players.PlayerAdded:Connect(function(player)
    local coinsFolder = Instance.new("Folder",player)
    coinsFolder.Name = "Coins"

    for _,pCoin in pairs(game:GetService("ReplicatedStorage"):WaitForChild("CoinModels"):GetChildren()) do
        local coinBool = Instance.new("BoolValue",coinsFolder)
        coinBool.Name = pCoin.Name
    end
end)

I then would create a dictionary for the names and values, like so.

local coinsDictionary =
    {
    ["Coin1"] = true,
    ["Coin2"] = false
    }

After that, you can save that and load that with DataStore, using GetAsync and SetAsync.

GetAsync is to get the saved values. SetAsync is to set the new values. You can also change the values in the Dictionary by doing this.

local coinsDictionary =
    {
    ["Coin1"] = true,
    ["Coin2"] = false
    }

game.Players.PlayerAdded:Connect(function(player)
    coinsDictionary.Coin1 = player:WaitForChild("Coins"):FindFirstChild("Coin1").Value
    coinsDictionary.Coin2 = player:WaitForChild("Coins"):FindFirstChild("Coin2").Value
end)

Then you would use :GetAsync() to get the table and set the values & :SetAsync() to set the new values when the player leaves.

DataStore Wiki

Dev Forum Table

Dev Forum Dictionary

Hope this helped! If this is what you're looking for, let me know by selecting this as an answer!

Ad
Log in to vote
0
Answered by
Alphexus 498 Moderation Voter
4 years ago

I would put all your coins in a folder. Name them differently(I would name them numbers from 1 to how ever many coins there are).

In order to do this, we need to create a DataStore and add the name of the coin when it gets touched in the DataStore. Before we add it to the DataStore, we make sure its not already in the DataStore.

Here is a rough example of what I mean(assuming you named each coin a different number).

local CoinData = game:GetService("DataStoreService"):GetDataStore("CoinData") -- // The data store
local CoinsFolder = workspace.CoinsFolder -- // A folder where all the coins are 

for _,coin in pairs(CoinsFolder:GetChildren()) do
    coin.Touched:Connect(function(hit)
        if hit.Parent:FindFirstChild("Humanoid") then
            local Player = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
            local Success, playerData = pcall(function()
                return CoinData:GetAsync(Player.UserId) -- // Get data
            end)

            if Success then
                if not playerData then playerData = {} end -- If we can't find old data, we will create a new table for the player
                if table.find(playerData, coin.Name, 1) == nil then -- If the coin isn't in the data 
                    table.insert(playerData, coin.Name)
                    Player.leaderstats.StarOrbs.Value = Player.leaderstats.StarOrbs.Value + 1
                    coin:Destroy()
                    pcall(function()
                        coinData:SetAsync(Player.UserId, playerData) -- Save the data
                    end)
                end
            end
        end
    end)
end

0
I don't have time to test this as I am in class rn, but if there are any issues, feel free to ask. Alphexus 498 — 4y
Log in to vote
0
Answered by 4 years ago
Edited 4 years ago

datastore basically lets you store data in roblox servers... this is done through what we call methods, methods are basically functions of an object.. for instance, RobloxObject:FindFirstChild(), FindFirstChild is a method, it's a function you can call on an object.. keep in mind that roblox objects are not the only example of objects

you can create your own objects, for instance, the following is an object;

local MyObject = {};
MyObject.SayHi = function(who)
    print("Hello "..who,"How are you?")
end

SayHI is a method of MyObject..

so datastore service has methods that let you access Datastore of your game, and methods that let you access specific data, for instance coins for a player.

some methods include GetAsync(datastore_key), SetAsync(datastore_key, value, UpdateAsync(datastore_key, f)...

i don't have time to explain thoroughly, but once i get time i will edit my answer to explain how to properly use Datastore and will show you how to use it for your purpose. meanwhile, you can research and tune in to other answers to see if they help you..

Answer this question