Search code examples
luarobloxluau

What could be causing my robbing bank script to increment faster than a second each time I rob. (Roblox LuaU)


It's like cashpersecond function isnt actually per second though im not really sure what could be causing this.

Also each time I rob the increment increased by like a second which is so weird.

Script below:

local maxCash = 3000
local cashPerSecond = 500
local timeToRob = 300
local robbing = false
local cooldown = 30
local closed = false
local defaultVaultPosition = script.Parent.VaultDoor.Position

local playersRobbing = {}
local alreadyRobbed = {}
local guis = {}


function endRobbery()

    closed = true
    robbing = false

    wait(1)

    script.Parent.Door.CanCollide = true
    script.Parent.VaultDoor.Position = defaultVaultPosition


    for i, gui in pairs(guis) do
        gui:Destroy()
    end

    for p, x in pairs(playersRobbing) do
        p.Character.HumanoidRootPart.CFrame = script.Parent.FailedToRob.CFrame
    end


    playersRobbing = {}
    alreadyRobbed = {}

    script.Alarm:Stop()

    wait(cooldown)
    closed = false

    script.Parent.Door.CanCollide = false
end


function beginRobbery()

    for i = 1, timeToRob do

        wait(1)

        local region3 = Region3.new(script.Parent.VaultArea.Position - script.Parent.VaultArea.Size/2, script.Parent.VaultArea.Position + script.Parent.VaultArea.Size/2)
        local parts = workspace:FindPartsInRegion3(region3, script.Parent, math.huge)

        local playersGivenCashTo = {}

        for x, part in pairs(parts) do

            if playersRobbing[game.Players:GetPlayerFromCharacter(part.Parent)] and playersRobbing[game.Players:GetPlayerFromCharacter(part.Parent)] < maxCash and not playersGivenCashTo[game.Players:GetPlayerFromCharacter(part.Parent)] then

                playersGivenCashTo[game.Players:GetPlayerFromCharacter(part.Parent)] = true
                
                playersRobbing[game.Players:GetPlayerFromCharacter(part.Parent)] += cashPerSecond

                if not game.Players:GetPlayerFromCharacter(part.Parent).PlayerGui:FindFirstChild("RobberyGui") then
                    script.RobberyGui:Clone().Parent = game.Players:GetPlayerFromCharacter(part.Parent).PlayerGui
                    game.Players:GetPlayerFromCharacter(part.Parent).PlayerGui.RobberyGui.StatsHUD.CashBagHUD.Cash.Amount.Text = "$0"
                    table.insert(guis, game.Players:GetPlayerFromCharacter(part.Parent).PlayerGui.RobberyGui)
                    game.Players:GetPlayerFromCharacter(part.Parent).PlayerGui.RobberyGui.StatsHUD.CashBagHUD.Cash.Visible = true
                    game.Players:GetPlayerFromCharacter(part.Parent).PlayerGui.RobberyGui.StatsHUD.CashBagHUD.CashIcon.Visible = true
                end

                game.Players:GetPlayerFromCharacter(part.Parent).PlayerGui.RobberyGui.StatsHUD.CashBagHUD.Cash.Amount.Text= "$" .. playersRobbing[game.Players:GetPlayerFromCharacter(part.Parent)]
            end
        end
    end

    endRobbery()
end


local touchedCooldown = {}

script.Parent.Door.Touched:Connect(function(hit)
    if not closed and game.Players:GetPlayerFromCharacter(hit.Parent) and not touchedCooldown[game.Players:GetPlayerFromCharacter(hit.Parent)] and not playersRobbing[game.Players:GetPlayerFromCharacter(hit.Parent)] and not alreadyRobbed[game.Players:GetPlayerFromCharacter(hit.Parent)] then
        script.Alarm:Resume()
        touchedCooldown[game.Players:GetPlayerFromCharacter(hit.Parent)] = true
        playersRobbing[game.Players:GetPlayerFromCharacter(hit.Parent)] = 0
        spawn(function()
            wait(2)
            touchedCooldown[game.Players:GetPlayerFromCharacter(hit.Parent)] = nil
        end)
        if not robbing then
            beginRobbery()
        end
        robbing = true

    elseif not closed and game.Players:GetPlayerFromCharacter(hit.Parent) and not touchedCooldown[game.Players:GetPlayerFromCharacter(hit.Parent)] and playersRobbing[game.Players:GetPlayerFromCharacter(hit.Parent)] then
        -- Remove this section

    end
end)

-- Connect to the Trigger part instead of the Door part
game.Workspace.Doors.DoubleKeyDoorCriminal.Trigger.Touched:Connect(function(hit)
    
    if not closed and game.Players:GetPlayerFromCharacter(hit.Parent) and not touchedCooldown[game.Players:GetPlayerFromCharacter(hit.Parent)] and playersRobbing[game.Players:GetPlayerFromCharacter(hit.Parent)] then
        -- on hit collect money
        game.Players:GetPlayerFromCharacter(hit.Parent).leaderstats.Cash.Value += playersRobbing[game.Players:GetPlayerFromCharacter(hit.Parent)]
        playersRobbing[game.Players:GetPlayerFromCharacter(hit.Parent)] = nil
        alreadyRobbed[game.Players:GetPlayerFromCharacter(hit.Parent)] = true

        local stillRobbing = false
        for _, x in pairs(playersRobbing) do
            if x then stillRobbing = true end
        end

        if not stillRobbing then
            endRobbery()
        end
    end
end)



script.Parent.OpenVault.Touched:Connect(function(hit)

    if game.Players:GetPlayerFromCharacter(hit.Parent) then

        wait(3)

        game:GetService("TweenService"):Create(script.Parent.VaultDoor, TweenInfo.new(5), {Position = defaultVaultPosition + Vector3.new(0, script.Parent.Door.Size.Y, 0)}):Play()
    end
end)

I've tried playersRobbing[game.Players:GetPlayerFromCharacter(part.Parent)] += cashPerSecond + wait(1) which sort of worked but it made the increment into weird decimal amounts while also passing the maximum amount. would be great if someone could explain this script more


Solution

  • Aside from your lack of using variables, the solution is rather simple: Every instruction takes a certain amount of time to be executed. Functions that interact with the WorldRoot are the major part of instructions that take up the most time.

    Because you have a lot of :GetPlayerFromCharacter functions, there are chances where the time may deviate from your target 1 second.

    The wait() function is deprecated, the smallest amount can be 0.30 seconds, so we can conclude from this that it'll wait in partitions of 0.30 seconds. The new function from the task scheduler, task.wait() has the smallest amount of 0.016 seconds, which makes it more accurate to waiting for one second than the wait() function.

    To ensure the player will receive increments of money every second, you want to make use of coroutines. As of this date, you can use the task.spawn() function to make it run on a different thread, bypassing the waiting time required to execute the other instructions:

    ...
    task.spawn(function()
        task.wait(1)
        playersRobbing[player] += cashPerSecond
    end)
    -- rest of the code
    ...