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

Same level for all players?

Asked by
Cuvette 246 Moderation Voter
9 years ago

Hey, this question is about something I've been looking at for weeks which is now causing my project to come to a stop until it is resolved.

I have a script, and I'm sorry but for now I will have to post the whole script due to the possibility of not being able to work out my problem through a segment of it. But anyway this script gives each player their stats and levels etc... But when a player dies at the same time as another player or even after in some cases, the script will give that number of players the same level as everyone else.

For example; I'm level 3 in the game and there are two other players, level 1. When the round ends and all three of us are 'reset' the other two players in the game will be level 3 aswell as me. Or I will be level 1 the same as them.

I hope that is enough of an explanation for you to be able to understand my problem. Thanks for any help given in advance, it is highly appreciated!

local ds = game:GetService("DataStoreService"):GetDataStore("dataone")

function CharacterRemoving(newPlayer)

    p = game.Players:GetPlayers()
    for i = 1, #p do
        s = Instance.new("StringValue", p[i].Character)
        s.Name = "Playing"
    end

    local stats = Instance.new("IntValue")
    stats.Name = "leaderstats"

     coins = Instance.new("IntValue")
    coins.Name = "Coins"

     tokens = Instance.new("IntValue")
    tokens.Name = "Tokens"

     xp = Instance.new("IntValue")
    xp.Name = "XP"

    levels = Instance.new("IntValue")
    levels.Name = "Levels"

    coins.Parent = stats
    tokens.Parent = stats
    xp.Parent = stats
    levels.Parent = stats


    stats.Parent = newPlayer


    if ds:GetAsync("Key" .. newPlayer.Name) then
        coins.Value = ds:GetAsync("Key" .. newPlayer.Name)
    else
        coins.Value = 0
    end

    if ds:GetAsync("Key1" .. newPlayer.Name) then
        tokens.Value = ds:GetAsync("Key1" .. newPlayer.Name)
    else
        tokens.Value = 0
    end

    if ds:GetAsync("Key2" .. newPlayer.Name) then
        xp.Value = ds:GetAsync("Key2" .. newPlayer.Name)
    else
        xp.Value = 0
    end

    if ds:GetAsync("Key3" .. newPlayer.Name) then
        levels.Value = ds:GetAsync("Key3" .. newPlayer.Name)    
    else
        levels.Value = 1
        levels.Changed:connect(function(save)
            ds:SetAsync("Key3" .. newPlayer.Name, save)
        end)
    end

    while true do

    wait(1)
        coins.Changed:connect(function(save)
            ds:SetAsync("Key" .. newPlayer.Name, save)
        end)
        tokens.Changed:connect(function(save)
            ds:SetAsync("Key1" .. newPlayer.Name, save)
        end)
        xp.Changed:connect(function(save)
            ds:SetAsync("Key2" .. newPlayer.Name, save)
        end)

    end
end

game.Players.PlayerAdded:connect(CharacterRemoving)

-- Problem is just under here i'm guessing.
function CharacterRemoving(newPlayer)
    levels.Value = ds:GetAsync("Key3" .. newPlayer.Name)
    wait(1)
    wait(0.1)
    if xp.Value >= 100 then
        levels.Value = levels.Value + 1
        xp.Value = 0
    end
    gui=Instance.new("BillboardGui")
    gui.Parent=newPlayer.Character.Head
    gui.Adornee=newPlayer.Character.Head
    gui.Size=UDim2.new(3,0,2,0)
    gui.StudsOffset=Vector3.new(0,2,0)
    text=Instance.new("TextLabel")
    text.Text = "Level " .. newPlayer.leaderstats.Levels.Value
    text.Size=UDim2.new(1.25,0,0.5,0)
    text.Position=UDim2.new(-0.125,0,-0.25,0)
    text.BackgroundTransparency = 1
    text.Parent=gui
    text.FontSize = ("Size36")
    text.Font = ("ArialBold")
    text.TextColor3 = Color3.new(255, 255, 0)
    text.TextStrokeColor3 = Color3.new(0, 0, 0)
    text.TextStrokeTransparency = 0
    w = game.Lighting.WepsGroup:GetChildren() 
    for i = 1,#w do
        w[i]:Clone().Parent = newPlayer.Backpack
    end
end

function onPlayerEntered(newPlayer) 
    newPlayer.Changed:connect(function (property) 
        if (property == "Character") then 
            CharacterRemoving(newPlayer) 
        end 
    end) 
end 
game.Players.PlayerAdded:connect(onPlayerEntered) 
game.Players.ChildAdded:connect(CharacterRemoving)
game.Players.PlayerAdded:connect(CharacterRemoving)


0
You're connecting hte CharacterRemoving Function 2 times with the same event, remove line 80 completely and test please YellowoTide 1992 — 9y
0
Three times, actually. Lines 121 and 122 are effectively the same as well. adark 5487 — 9y
0
Hey, thanks for the reply. I've tried removing it and i'm guessing it stopped the ' CharacterRemoving' function to stop working because the level now doesn't display above the players head. Cuvette 246 — 9y
0
DataStores coding tends to be buggy in the best of times. I highly suggest using this module: http://wiki.roblox.com/index.php?title=PlayerDataStore_module or making the rest of the code work BEFORE adding DataStore saving. adark 5487 — 9y
View all comments (4 more)
0
The datastore side of it is fine, on the leaderboard everyones levels are as they should be. It's just the billboard GUI that is messing up and its obviously confused by who is who. Cuvette 246 — 9y
0
I'm going to format your code properly and give this another look. Just one moment... adark 5487 — 9y
0
Alright, there is a lot going on here that could be done a LOT better. I'm gonna write an Answer describing all the fixes. adark 5487 — 9y
0
Okay thanks for that. I did think it was quite a mess. Cuvette 246 — 9y

1 answer

Log in to vote
0
Answered by
adark 5487 Badge of Merit Moderation Voter Community Moderator
9 years ago

There are a lot of problems with your code. I'm going to go through it line by line and refactor it. This may not fix anything, but it will run a lot better.

local ds = game:GetService("DataStoreService"):GetDataStore("dataone")

function PlayerAdded(newPlayer) --This function is called when a Player gets added. Why is it called 'CharacterRemoving'?

--I'm not really sure what to do with this block of code. It definitely doesn't go inside the PlayerAdded function. What are you trying to do with this?
--[[    p = game.Players:GetPlayers()
    for i = 1, #p do
        s = Instance.new("StringValue", p[i].Character)
        s.Name = "Playing"
    end]]

    local stats = Instance.new("IntValue", newPlayer) --We can use this second argument to set the Parent on the same line.
    stats.Name = "leaderstats"

     local coins = Instance.new("IntValue", stats) --ALL of these properties are now local! If they aren't, they will overwrite each other and we don't want that.
    coins.Name = "Coins"

    local tokens = Instance.new("IntValue", stats)
    tokens.Name = "Tokens"

    local xp = Instance.new("IntValue", stats)
    xp.Name = "XP"

    local levels = Instance.new("IntValue", stats)
    levels.Name = "Levels"

    local coinKey = ds:GetAsync("Key" .. newPlayer.Name) --GetAsync called more than once is wasteful. You have a limit to the number of times you can call this per minute!
    if coinKey then
        coins.Value = coinKey
    else
        coins.Value = 0
    end

    local tokensKey = ds:GetAsync("Key1" .. newPlayer.Name)
    if  tokensKey then
        tokens.Value = tokensKey
    else
        tokens.Value = 0
    end
    local xpKey = ds:GetAsync("Key2" .. newPlayer.Name)
    if xpKey then
        xp.Value =xpKey
    else
        xp.Value = 0
    end
    local levelsKey = ds:GetAsync("Key3" .. newPlayer.Name)
    if  then
        levels.Value = ds:GetAsync("Key3" .. newPlayer.Name)    
    else
        levels.Value = 1
    end

    --This while loop was repeatedly creating these function connections once a second. Changed events will fire every single time they are fired!
        coins.Changed:connect(function(save)
            ds:SetAsync("Key" .. newPlayer.Name, save)
        end)
        tokens.Changed:connect(function(save)
            ds:SetAsync("Key1" .. newPlayer.Name, save)
        end)

    local xpDeb = false
        xp.Changed:connect(function() --I made this function control saving of both levels and xp, based on your formula below.
        if xpDeb then return end
        xpDeb = true
        while xp.Value >= 100 do
            xp.Value = xp.Value - 100
            levels.Value = levels.Value + 1
        end
            ds:SetAsync("Key2" .. newPlayer.Name, xp.Value)
        ds:SetAsync("Key3" .. newPlayer.Name, levels.Value)
        xpDeb = false
        end)

    local function CharacterAdded(newCharacter) --NEVER use the same global function name twice. This can cause unforeseeable bugs and errors!
        --This function had to be moved inside here so that trying to access the various ValueObjects that are now local don't cause any errors.
        --We already loaded this above! No need to do it again.
        --levels.Value = ds:GetAsync("Key3" .. newPlayer.Name)
        wait(1.1) --No need for two wait statements

        local gui = Instance.new("BillboardGui") --This could have been your error! When this function was called more than once, the global `gui` variable got overwritten. Setting it to be a local variable makes sure that your code works as intended: only editing THIS BillboardGui.
        gui.Parent = newPlayer.Character.Head
        gui.Adornee = newPlayer.Character.Head
        gui.Size = UDim2.new(3,0,2,0)
        gui.StudsOffset = Vector3.new(0,2,0)

        local text = Instance.new("TextLabel")
        text.Text = "Level " .. newPlayer.leaderstats.Levels.Value
        text.Size = UDim2.new(1.25,0,0.5,0)
        text.Position = UDim2.new(-0.125,0,-0.25,0)
        text.BackgroundTransparency = 1
        text.Parent = gui
        text.FontSize = ("Size36")
        text.Font = ("ArialBold")
        text.TextColor3 = Color3.new(255, 255, 0)
        text.TextStrokeColor3 = Color3.new(0, 0, 0)
        text.TextStrokeTransparency = 0

        for _, wep in ipairs(game.Lighting.WepsGroup:GetChildren()) do --A generic `for` is better here than a numeric.
            wep:Clone().Parent = newPlayer.Backpack
        end
    end
    newPlayer.CharacterAdded:connect(CharacterAdded)
end
game.Players.PlayerAdded:connect(PlayerAdded)

--All the lines after this are completely unnecessary.

If this still errors, please let me know where.

0
Oh wow thank you, i'm glad someone has explained it to me because it makes a lot more sense now. I hate to be persevering but the Billboard Gui no longer displays above the players head. And from reading your script I cannot see what is wrong? Cuvette 246 — 9y
0
Don't worry its fine. Anyway thank you for everything! I'm pleased I can get back on track with my game. You deserve more +1's! Cuvette 246 — 9y
Ad

Answer this question