859 lines
		
	
	
	
		
			38 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			859 lines
		
	
	
	
		
			38 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
local QBCore = exports['qb-core']:GetCoreObject()
 | 
						|
local Countdown = 10
 | 
						|
local ToFarCountdown = 10
 | 
						|
local FinishedUITimeout = false
 | 
						|
 | 
						|
local RaceData = {
 | 
						|
    InCreator = false,
 | 
						|
    InRace = false,
 | 
						|
    ClosestCheckpoint = 0,
 | 
						|
}
 | 
						|
 | 
						|
local CreatorData = {
 | 
						|
    RaceName = nil,
 | 
						|
    Checkpoints = {},
 | 
						|
    TireDistance = 3.0,
 | 
						|
    ConfirmDelete = false,
 | 
						|
}
 | 
						|
 | 
						|
local CurrentRaceData = {
 | 
						|
    RaceId = nil,
 | 
						|
    RaceName = nil,
 | 
						|
    Checkpoints = {},
 | 
						|
    Started = false,
 | 
						|
    CurrentCheckpoint = nil,
 | 
						|
    TotalLaps = 0,
 | 
						|
    Lap = 0,
 | 
						|
}
 | 
						|
 | 
						|
-- Handlers
 | 
						|
 | 
						|
AddEventHandler('onResourceStop', function(resource)
 | 
						|
    if resource == GetCurrentResourceName() then
 | 
						|
        for k, _ in pairs(CreatorData.Checkpoints) do
 | 
						|
            if CreatorData.Checkpoints[k].pileleft ~= nil then
 | 
						|
                local coords = CreatorData.Checkpoints[k].offset.right
 | 
						|
                local Obj = GetClosestObjectOfType(coords.x, coords.y, coords.z, 5.0, `prop_offroad_tyres02`, 0, 0, 0)
 | 
						|
                DeleteObject(Obj)
 | 
						|
                ClearAreaOfObjects(coords.x, coords.y, coords.z, 50.0, 0)
 | 
						|
                CreatorData.Checkpoints[k].pileright = nil
 | 
						|
            end
 | 
						|
            if CreatorData.Checkpoints[k].pileright ~= nil then
 | 
						|
                local coords = CreatorData.Checkpoints[k].offset.right
 | 
						|
                local Obj = GetClosestObjectOfType(coords.x, coords.y, coords.z, 5.0, `prop_offroad_tyres02`, 0, 0, 0)
 | 
						|
                DeleteObject(Obj)
 | 
						|
                ClearAreaOfObjects(coords.x, coords.y, coords.z, 50.0, 0)
 | 
						|
                CreatorData.Checkpoints[k].pileright = nil
 | 
						|
            end
 | 
						|
        end
 | 
						|
 | 
						|
        for k, _ in pairs(CurrentRaceData.Checkpoints) do
 | 
						|
            if CurrentRaceData.Checkpoints[k] ~= nil then
 | 
						|
                if CurrentRaceData.Checkpoints[k].pileleft ~= nil then
 | 
						|
                    local coords = CurrentRaceData.Checkpoints[k].offset.right
 | 
						|
                    local Obj = GetClosestObjectOfType(coords.x, coords.y, coords.z, 5.0, `prop_offroad_tyres02`, 0, 0, 0)
 | 
						|
                    DeleteObject(Obj)
 | 
						|
                    ClearAreaOfObjects(coords.x, coords.y, coords.z, 50.0, 0)
 | 
						|
                    CurrentRaceData.Checkpoints[k].pileright = nil
 | 
						|
                end
 | 
						|
                if CurrentRaceData.Checkpoints[k].pileright ~= nil then
 | 
						|
                    local coords = CurrentRaceData.Checkpoints[k].offset.right
 | 
						|
                    local Obj = GetClosestObjectOfType(coords.x, coords.y, coords.z, 5.0, `prop_offroad_tyres02`, 0, 0, 0)
 | 
						|
                    DeleteObject(Obj)
 | 
						|
                    ClearAreaOfObjects(coords.x, coords.y, coords.z, 50.0, 0)
 | 
						|
                    CurrentRaceData.Checkpoints[k].pileright = nil
 | 
						|
                end
 | 
						|
            end
 | 
						|
        end
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
-- Functions
 | 
						|
 | 
						|
local function DrawText3Ds(x, y, z, text)
 | 
						|
	SetTextScale(0.35, 0.35)
 | 
						|
    SetTextFont(4)
 | 
						|
    SetTextProportional(1)
 | 
						|
    SetTextColour(255, 255, 255, 215)
 | 
						|
    BeginTextCommandDisplayText("STRING")
 | 
						|
    SetTextCentre(true)
 | 
						|
    AddTextComponentSubstringPlayerName(text)
 | 
						|
    SetDrawOrigin(x,y,z, 0)
 | 
						|
    EndTextCommandDisplayText(0.0, 0.0)
 | 
						|
    local factor = (string.len(text)) / 370
 | 
						|
    DrawRect(0.0, 0.0+0.0125, 0.017+ factor, 0.03, 0, 0, 0, 75)
 | 
						|
    ClearDrawOrigin()
 | 
						|
end
 | 
						|
 | 
						|
local function GetClosestCheckpoint()
 | 
						|
    local pos = GetEntityCoords(PlayerPedId(), true)
 | 
						|
    local current = nil
 | 
						|
    local dist = nil
 | 
						|
    for id, _ in pairs(CreatorData.Checkpoints) do
 | 
						|
        if current ~= nil then
 | 
						|
            if #(pos - vector3(CreatorData.Checkpoints[id].coords.x, CreatorData.Checkpoints[id].coords.y, CreatorData.Checkpoints[id].coords.z)) < dist then
 | 
						|
                current = id
 | 
						|
                dist = #(pos - vector3(CreatorData.Checkpoints[id].coords.x, CreatorData.Checkpoints[id].coords.y, CreatorData.Checkpoints[id].coords.z))
 | 
						|
            end
 | 
						|
        else
 | 
						|
            dist = #(pos - vector3(CreatorData.Checkpoints[id].coords.x, CreatorData.Checkpoints[id].coords.y, CreatorData.Checkpoints[id].coords.z))
 | 
						|
            current = id
 | 
						|
        end
 | 
						|
    end
 | 
						|
    RaceData.ClosestCheckpoint = current
 | 
						|
end
 | 
						|
 | 
						|
local function CreatorUI()
 | 
						|
    CreateThread(function()
 | 
						|
        while true do
 | 
						|
            if RaceData.InCreator then
 | 
						|
                SendNUIMessage({
 | 
						|
                    action = "Update",
 | 
						|
                    type = "creator",
 | 
						|
                    data = CreatorData,
 | 
						|
                    racedata = RaceData,
 | 
						|
                    active = true,
 | 
						|
                })
 | 
						|
            else
 | 
						|
                SendNUIMessage({
 | 
						|
                    action = "Update",
 | 
						|
                    type = "creator",
 | 
						|
                    data = CreatorData,
 | 
						|
                    racedata = RaceData,
 | 
						|
                    active = false,
 | 
						|
                })
 | 
						|
                break
 | 
						|
            end
 | 
						|
            Wait(200)
 | 
						|
        end
 | 
						|
    end)
 | 
						|
end
 | 
						|
 | 
						|
local function DeleteCheckpoint()
 | 
						|
    local NewCheckpoints = {}
 | 
						|
    if RaceData.ClosestCheckpoint ~= 0 then
 | 
						|
        if CreatorData.Checkpoints[RaceData.ClosestCheckpoint] ~= nil then
 | 
						|
            if CreatorData.Checkpoints[RaceData.ClosestCheckpoint].blip ~= nil then
 | 
						|
                RemoveBlip(CreatorData.Checkpoints[RaceData.ClosestCheckpoint].blip)
 | 
						|
                CreatorData.Checkpoints[RaceData.ClosestCheckpoint].blip = nil
 | 
						|
            end
 | 
						|
            if CreatorData.Checkpoints[RaceData.ClosestCheckpoint].pileleft ~= nil then
 | 
						|
                local coords = CreatorData.Checkpoints[RaceData.ClosestCheckpoint].offset.left
 | 
						|
                local Obj = GetClosestObjectOfType(coords.x, coords.y, coords.z, 5.0, `prop_offroad_tyres02`, 0, 0, 0)
 | 
						|
                DeleteObject(Obj)
 | 
						|
                ClearAreaOfObjects(coords.x, coords.y, coords.z, 50.0, 0)
 | 
						|
                CreatorData.Checkpoints[RaceData.ClosestCheckpoint].pileleft = nil
 | 
						|
            end
 | 
						|
            if CreatorData.Checkpoints[RaceData.ClosestCheckpoint].pileright ~= nil then
 | 
						|
                local coords = CreatorData.Checkpoints[RaceData.ClosestCheckpoint].offset.right
 | 
						|
                local Obj = GetClosestObjectOfType(coords.x, coords.y, coords.z, 5.0, `prop_offroad_tyres02`, 0, 0, 0)
 | 
						|
                DeleteObject(Obj)
 | 
						|
                ClearAreaOfObjects(coords.x, coords.y, coords.z, 50.0, 0)
 | 
						|
                CreatorData.Checkpoints[RaceData.ClosestCheckpoint].pileright = nil
 | 
						|
            end
 | 
						|
 | 
						|
            for id, data in pairs(CreatorData.Checkpoints) do
 | 
						|
                if id ~= RaceData.ClosestCheckpoint then
 | 
						|
                    NewCheckpoints[#NewCheckpoints+1] = data
 | 
						|
                end
 | 
						|
            end
 | 
						|
            CreatorData.Checkpoints = NewCheckpoints
 | 
						|
        else
 | 
						|
            QBCore.Functions.Notify('You cant go to fast', 'error')
 | 
						|
        end
 | 
						|
    else
 | 
						|
        QBCore.Functions.Notify('You cant go too fast', 'error')
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
local function SaveRace()
 | 
						|
    local RaceDistance = 0
 | 
						|
 | 
						|
    for k, v in pairs(CreatorData.Checkpoints) do
 | 
						|
        if k + 1 <= #CreatorData.Checkpoints then
 | 
						|
            local checkpointdistance = #(vector3(v.coords.x, v.coords.y, v.coords.z) - vector3(CreatorData.Checkpoints[k + 1].coords.x, CreatorData.Checkpoints[k + 1].coords.y, CreatorData.Checkpoints[k + 1].coords.z))
 | 
						|
            RaceDistance = RaceDistance + checkpointdistance
 | 
						|
        end
 | 
						|
    end
 | 
						|
 | 
						|
    CreatorData.RaceDistance = RaceDistance
 | 
						|
 | 
						|
    TriggerServerEvent('qb-lapraces:server:SaveRace', CreatorData)
 | 
						|
 | 
						|
    QBCore.Functions.Notify('Race: '..CreatorData.RaceName..' is saved!', 'success')
 | 
						|
 | 
						|
    for id,_ in pairs(CreatorData.Checkpoints) do
 | 
						|
        if CreatorData.Checkpoints[id].blip ~= nil then
 | 
						|
            RemoveBlip(CreatorData.Checkpoints[id].blip)
 | 
						|
            CreatorData.Checkpoints[id].blip = nil
 | 
						|
        end
 | 
						|
        if CreatorData.Checkpoints[id] ~= nil then
 | 
						|
            if CreatorData.Checkpoints[id].pileleft ~= nil then
 | 
						|
                local coords = CreatorData.Checkpoints[id].offset.left
 | 
						|
                local Obj = GetClosestObjectOfType(coords.x, coords.y, coords.z, 5.0, `prop_offroad_tyres02`, 0, 0, 0)
 | 
						|
                DeleteObject(Obj)
 | 
						|
                ClearAreaOfObjects(coords.x, coords.y, coords.z, 50.0, 0)
 | 
						|
                CreatorData.Checkpoints[id].pileleft = nil
 | 
						|
            end
 | 
						|
            if CreatorData.Checkpoints[id].pileright ~= nil then
 | 
						|
                local coords = CreatorData.Checkpoints[id].offset.right
 | 
						|
                local Obj = GetClosestObjectOfType(coords.x, coords.y, coords.z, 5.0, `prop_offroad_tyres02`, 0, 0, 0)
 | 
						|
                DeleteObject(Obj)
 | 
						|
                ClearAreaOfObjects(coords.x, coords.y, coords.z, 50.0, 0)
 | 
						|
                CreatorData.Checkpoints[id].pileright = nil
 | 
						|
            end
 | 
						|
        end
 | 
						|
    end
 | 
						|
 | 
						|
    RaceData.InCreator = false
 | 
						|
    CreatorData.RaceName = nil
 | 
						|
    CreatorData.Checkpoints = {}
 | 
						|
end
 | 
						|
 | 
						|
local function AddCheckpoint()
 | 
						|
    local PlayerPed = PlayerPedId()
 | 
						|
    local PlayerPos = GetEntityCoords(PlayerPed)
 | 
						|
    local PlayerVeh = GetVehiclePedIsIn(PlayerPed)
 | 
						|
    local Offset = {
 | 
						|
        left = {
 | 
						|
            x = (GetOffsetFromEntityInWorldCoords(PlayerVeh, -CreatorData.TireDistance, 0.0, 0.0)).x,
 | 
						|
            y = (GetOffsetFromEntityInWorldCoords(PlayerVeh, -CreatorData.TireDistance, 0.0, 0.0)).y,
 | 
						|
            z = (GetOffsetFromEntityInWorldCoords(PlayerVeh, -CreatorData.TireDistance, 0.0, 0.0)).z,
 | 
						|
        },
 | 
						|
        right = {
 | 
						|
            x = (GetOffsetFromEntityInWorldCoords(PlayerVeh, CreatorData.TireDistance, 0.0, 0.0)).x,
 | 
						|
            y = (GetOffsetFromEntityInWorldCoords(PlayerVeh, CreatorData.TireDistance, 0.0, 0.0)).y,
 | 
						|
            z = (GetOffsetFromEntityInWorldCoords(PlayerVeh, CreatorData.TireDistance, 0.0, 0.0)).z,
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    CreatorData.Checkpoints[#CreatorData.Checkpoints+1] = {
 | 
						|
        coords = {
 | 
						|
            x = PlayerPos.x,
 | 
						|
            y = PlayerPos.y,
 | 
						|
            z = PlayerPos.z,
 | 
						|
        },
 | 
						|
        offset = Offset,
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    for id, CheckpointData in pairs(CreatorData.Checkpoints) do
 | 
						|
        if CheckpointData.blip ~= nil then
 | 
						|
            RemoveBlip(CheckpointData.blip)
 | 
						|
        end
 | 
						|
 | 
						|
        CheckpointData.blip = AddBlipForCoord(CheckpointData.coords.x, CheckpointData.coords.y, CheckpointData.coords.z)
 | 
						|
 | 
						|
        SetBlipSprite(CheckpointData.blip, 1)
 | 
						|
        SetBlipDisplay(CheckpointData.blip, 4)
 | 
						|
        SetBlipScale(CheckpointData.blip, 0.8)
 | 
						|
        SetBlipAsShortRange(CheckpointData.blip, true)
 | 
						|
        SetBlipColour(CheckpointData.blip, 26)
 | 
						|
        ShowNumberOnBlip(CheckpointData.blip, id)
 | 
						|
        SetBlipShowCone(CheckpointData.blip, false)
 | 
						|
        BeginTextCommandSetBlipName("STRING")
 | 
						|
        AddTextComponentSubstringPlayerName("Checkpoint: "..id)
 | 
						|
        EndTextCommandSetBlipName(CheckpointData.blip)
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
local function CreatorLoop()
 | 
						|
    CreateThread(function()
 | 
						|
        while RaceData.InCreator do
 | 
						|
            local PlayerPed = PlayerPedId()
 | 
						|
            local PlayerVeh = GetVehiclePedIsIn(PlayerPed)
 | 
						|
 | 
						|
            if PlayerVeh ~= 0 then
 | 
						|
                if IsControlJustPressed(0, 161) or IsDisabledControlJustPressed(0, 161) then
 | 
						|
                    AddCheckpoint()
 | 
						|
                end
 | 
						|
 | 
						|
                if IsControlJustPressed(0, 162) or IsDisabledControlJustPressed(0, 162) then
 | 
						|
                    if CreatorData.Checkpoints ~= nil and next(CreatorData.Checkpoints) ~= nil then
 | 
						|
                        DeleteCheckpoint()
 | 
						|
                    else
 | 
						|
                        QBCore.Functions.Notify('You have not placed any checkpoints yet..', 'error')
 | 
						|
                    end
 | 
						|
                end
 | 
						|
 | 
						|
                if IsControlJustPressed(0, 311) or IsDisabledControlJustPressed(0, 311) then
 | 
						|
                    if CreatorData.Checkpoints ~= nil and #CreatorData.Checkpoints >= 2 then
 | 
						|
                        SaveRace()
 | 
						|
                    else
 | 
						|
                        QBCore.Functions.Notify('You must have at least 10 checkpoints', 'error')
 | 
						|
                    end
 | 
						|
                end
 | 
						|
 | 
						|
                if IsControlJustPressed(0, 40) or IsDisabledControlJustPressed(0, 40) then
 | 
						|
                    if CreatorData.TireDistance + 1.0 ~= 16.0 then
 | 
						|
                        CreatorData.TireDistance = CreatorData.TireDistance + 1.0
 | 
						|
                    else
 | 
						|
                        QBCore.Functions.Notify('You can not go higher than 15')
 | 
						|
                    end
 | 
						|
                end
 | 
						|
 | 
						|
                if IsControlJustPressed(0, 39) or IsDisabledControlJustPressed(0, 39) then
 | 
						|
                    if CreatorData.TireDistance - 1.0 ~= 1.0 then
 | 
						|
                        CreatorData.TireDistance = CreatorData.TireDistance - 1.0
 | 
						|
                    else
 | 
						|
                        QBCore.Functions.Notify('You cannot go lower than 2')
 | 
						|
                    end
 | 
						|
                end
 | 
						|
            else
 | 
						|
                local coords = GetEntityCoords(PlayerPedId())
 | 
						|
                DrawText3Ds(coords.x, coords.y, coords.z, 'You must be in a vehicle')
 | 
						|
            end
 | 
						|
 | 
						|
            if IsControlJustPressed(0, 163) or IsDisabledControlJustPressed(0, 163) then
 | 
						|
                if not CreatorData.ConfirmDelete then
 | 
						|
                    CreatorData.ConfirmDelete = true
 | 
						|
                    QBCore.Functions.Notify('Press [9] again to confirm', 'error', 5000)
 | 
						|
                else
 | 
						|
                    for _, CheckpointData in pairs(CreatorData.Checkpoints) do
 | 
						|
                        if CheckpointData.blip ~= nil then
 | 
						|
                            RemoveBlip(CheckpointData.blip)
 | 
						|
                        end
 | 
						|
                    end
 | 
						|
 | 
						|
                    for id,_ in pairs(CreatorData.Checkpoints) do
 | 
						|
                        if CreatorData.Checkpoints[id].pileleft ~= nil then
 | 
						|
                            local coords = CreatorData.Checkpoints[id].offset.left
 | 
						|
                            local Obj = GetClosestObjectOfType(coords.x, coords.y, coords.z, 8.0, `prop_offroad_tyres02`, 0, 0, 0)
 | 
						|
                            DeleteObject(Obj)
 | 
						|
                            ClearAreaOfObjects(coords.x, coords.y, coords.z, 50.0, 0)
 | 
						|
                            CreatorData.Checkpoints[id].pileleft = nil
 | 
						|
                        end
 | 
						|
 | 
						|
                        if CreatorData.Checkpoints[id].pileright ~= nil then
 | 
						|
                            local coords = CreatorData.Checkpoints[id].offset.right
 | 
						|
                            local Obj = GetClosestObjectOfType(coords.x, coords.y, coords.z, 8.0, `prop_offroad_tyres02`, 0, 0, 0)
 | 
						|
                            DeleteObject(Obj)
 | 
						|
                            ClearAreaOfObjects(coords.x, coords.y, coords.z, 50.0, 0)
 | 
						|
                            CreatorData.Checkpoints[id].pileright = nil
 | 
						|
                        end
 | 
						|
                    end
 | 
						|
 | 
						|
                    RaceData.InCreator = false
 | 
						|
                    CreatorData.RaceName = nil
 | 
						|
                    CreatorData.Checkpoints = {}
 | 
						|
                    QBCore.Functions.Notify('Race-editor canceled!', 'error')
 | 
						|
                    CreatorData.ConfirmDelete = false
 | 
						|
                end
 | 
						|
            end
 | 
						|
            Wait(3)
 | 
						|
        end
 | 
						|
    end)
 | 
						|
end
 | 
						|
 | 
						|
local function RaceUI()
 | 
						|
    CreateThread(function()
 | 
						|
        while true do
 | 
						|
            if CurrentRaceData.Checkpoints ~= nil and next(CurrentRaceData.Checkpoints) ~= nil then
 | 
						|
                if CurrentRaceData.Started then
 | 
						|
                    CurrentRaceData.RaceTime = CurrentRaceData.RaceTime + 1
 | 
						|
                    CurrentRaceData.TotalTime = CurrentRaceData.TotalTime + 1
 | 
						|
                end
 | 
						|
                SendNUIMessage({
 | 
						|
                    action = "Update",
 | 
						|
                    type = "race",
 | 
						|
                    data = {
 | 
						|
                        CurrentCheckpoint = CurrentRaceData.CurrentCheckpoint,
 | 
						|
                        TotalCheckpoints = #CurrentRaceData.Checkpoints,
 | 
						|
                        TotalLaps = CurrentRaceData.TotalLaps,
 | 
						|
                        CurrentLap = CurrentRaceData.Lap,
 | 
						|
                        RaceStarted = CurrentRaceData.Started,
 | 
						|
                        RaceName = CurrentRaceData.RaceName,
 | 
						|
                        Time = CurrentRaceData.RaceTime,
 | 
						|
                        TotalTime = CurrentRaceData.TotalTime,
 | 
						|
                        BestLap = CurrentRaceData.BestLap,
 | 
						|
                    },
 | 
						|
                    racedata = RaceData,
 | 
						|
                    active = true,
 | 
						|
                })
 | 
						|
            else
 | 
						|
                if not FinishedUITimeout then
 | 
						|
                    FinishedUITimeout = true
 | 
						|
                    SetTimeout(10000, function()
 | 
						|
                        FinishedUITimeout = false
 | 
						|
                        SendNUIMessage({
 | 
						|
                            action = "Update",
 | 
						|
                            type = "race",
 | 
						|
                            data = {},
 | 
						|
                            racedata = RaceData,
 | 
						|
                            active = false,
 | 
						|
                        })
 | 
						|
                    end)
 | 
						|
                end
 | 
						|
                break
 | 
						|
            end
 | 
						|
            Wait(12)
 | 
						|
        end
 | 
						|
    end)
 | 
						|
end
 | 
						|
 | 
						|
local function SetupRace(sRaceData, Laps)
 | 
						|
    RaceData.RaceId = sRaceData.RaceId
 | 
						|
    CurrentRaceData = {
 | 
						|
        RaceId = sRaceData.RaceId,
 | 
						|
        Creator = sRaceData.Creator,
 | 
						|
        RaceName = sRaceData.RaceName,
 | 
						|
        Checkpoints = sRaceData.Checkpoints,
 | 
						|
        Started = false,
 | 
						|
        CurrentCheckpoint = 1,
 | 
						|
        TotalLaps = Laps,
 | 
						|
        Lap = 1,
 | 
						|
        RaceTime = 0,
 | 
						|
        TotalTime = 0,
 | 
						|
        BestLap = 0,
 | 
						|
        Racers = {}
 | 
						|
    }
 | 
						|
 | 
						|
    for k, v in pairs(CurrentRaceData.Checkpoints) do
 | 
						|
        ClearAreaOfObjects(v.offset.left.x, v.offset.left.y, v.offset.left.z, 50.0, 0)
 | 
						|
        CurrentRaceData.Checkpoints[k].pileleft = CreateObject(`prop_offroad_tyres02`, v.offset.left.x, v.offset.left.y, v.offset.left.z, 0, 0, 0)
 | 
						|
        PlaceObjectOnGroundProperly(CurrentRaceData.Checkpoints[k].pileleft)
 | 
						|
        FreezeEntityPosition(CurrentRaceData.Checkpoints[k].pileleft, 1)
 | 
						|
        SetEntityAsMissionEntity(CurrentRaceData.Checkpoints[k].pileleft, 1, 1)
 | 
						|
 | 
						|
        ClearAreaOfObjects(v.offset.right.x, v.offset.right.y, v.offset.right.z, 50.0, 0)
 | 
						|
        CurrentRaceData.Checkpoints[k].pileright = CreateObject(`prop_offroad_tyres02`, v.offset.right.x, v.offset.right.y, v.offset.right.z, 0, 0, 0)
 | 
						|
        PlaceObjectOnGroundProperly(CurrentRaceData.Checkpoints[k].pileright)
 | 
						|
        FreezeEntityPosition(CurrentRaceData.Checkpoints[k].pileright, 1)
 | 
						|
        SetEntityAsMissionEntity(CurrentRaceData.Checkpoints[k].pileright, 1, 1)
 | 
						|
 | 
						|
        CurrentRaceData.Checkpoints[k].blip = AddBlipForCoord(v.coords.x, v.coords.y, v.coords.z)
 | 
						|
        SetBlipSprite(CurrentRaceData.Checkpoints[k].blip, 1)
 | 
						|
        SetBlipDisplay(CurrentRaceData.Checkpoints[k].blip, 4)
 | 
						|
        SetBlipScale(CurrentRaceData.Checkpoints[k].blip, 0.6)
 | 
						|
        SetBlipAsShortRange(CurrentRaceData.Checkpoints[k].blip, true)
 | 
						|
        SetBlipColour(CurrentRaceData.Checkpoints[k].blip, 26)
 | 
						|
        ShowNumberOnBlip(CurrentRaceData.Checkpoints[k].blip, k)
 | 
						|
        BeginTextCommandSetBlipName("STRING")
 | 
						|
        AddTextComponentSubstringPlayerName("Checkpoint: "..k)
 | 
						|
        EndTextCommandSetBlipName(CurrentRaceData.Checkpoints[k].blip)
 | 
						|
    end
 | 
						|
 | 
						|
    RaceUI()
 | 
						|
end
 | 
						|
 | 
						|
local function showNonLoopParticle(dict, particleName, coords, scale)
 | 
						|
    RequestNamedPtfxAsset(dict)
 | 
						|
    while not HasNamedPtfxAssetLoaded(dict) do
 | 
						|
        Wait(0)
 | 
						|
    end
 | 
						|
    UseParticleFxAssetNextCall(dict)
 | 
						|
    local particleHandle = StartParticleFxLoopedAtCoord(particleName, coords.x, coords.y, coords.z, 0.0, 0.0, 0.0, scale, false, false, false)
 | 
						|
    SetParticleFxLoopedColour(particleHandle, 0, 255, 0 ,0)
 | 
						|
    return particleHandle
 | 
						|
end
 | 
						|
 | 
						|
local function DoPilePfx()
 | 
						|
    if CurrentRaceData.Checkpoints[CurrentRaceData.CurrentCheckpoint] ~= nil then
 | 
						|
        local Timeout = 500
 | 
						|
        local Size = 2.0
 | 
						|
        local left = showNonLoopParticle('core', 'ent_sht_flame', CurrentRaceData.Checkpoints[CurrentRaceData.CurrentCheckpoint].offset.left, Size)
 | 
						|
        local right = showNonLoopParticle('core', 'ent_sht_flame', CurrentRaceData.Checkpoints[CurrentRaceData.CurrentCheckpoint].offset.right, Size)
 | 
						|
 | 
						|
        SetTimeout(Timeout, function()
 | 
						|
            StopParticleFxLooped(left, false)
 | 
						|
            StopParticleFxLooped(right, false)
 | 
						|
        end)
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
local function SetupPiles()
 | 
						|
    for k, v in pairs(CreatorData.Checkpoints) do
 | 
						|
        if CreatorData.Checkpoints[k].pileleft == nil then
 | 
						|
            ClearAreaOfObjects(v.offset.left.x, v.offset.left.y, v.offset.left.z, 50.0, 0)
 | 
						|
            CreatorData.Checkpoints[k].pileleft = CreateObject(`prop_offroad_tyres02`, v.offset.left.x, v.offset.left.y, v.offset.left.z, 0, 0, 0)
 | 
						|
            PlaceObjectOnGroundProperly(CreatorData.Checkpoints[k].pileleft)
 | 
						|
            FreezeEntityPosition(CreatorData.Checkpoints[k].pileleft, 1)
 | 
						|
            SetEntityAsMissionEntity(CreatorData.Checkpoints[k].pileleft, 1, 1)
 | 
						|
        end
 | 
						|
 | 
						|
        if CreatorData.Checkpoints[k].pileright == nil then
 | 
						|
            ClearAreaOfObjects(v.offset.right.x, v.offset.right.y, v.offset.right.z, 50.0, 0)
 | 
						|
            CreatorData.Checkpoints[k].pileright = CreateObject(`prop_offroad_tyres02`, v.offset.right.x, v.offset.right.y, v.offset.right.z, 0, 0, 0)
 | 
						|
            PlaceObjectOnGroundProperly(CreatorData.Checkpoints[k].pileright)
 | 
						|
            FreezeEntityPosition(CreatorData.Checkpoints[k].pileleft, 1)
 | 
						|
            SetEntityAsMissionEntity(CreatorData.Checkpoints[k].pileleft, 1, 1)
 | 
						|
        end
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
local function GetMaxDistance(OffsetCoords)
 | 
						|
    local Distance = #(vector3(OffsetCoords.left.x, OffsetCoords.left.y, OffsetCoords.left.z) - vector3(OffsetCoords.right.x, OffsetCoords.right.y, OffsetCoords.right.z))
 | 
						|
    local Retval = 7.5
 | 
						|
    if Distance > 20.0 then
 | 
						|
        Retval = 12.5
 | 
						|
    end
 | 
						|
    return Retval
 | 
						|
end
 | 
						|
 | 
						|
local function SecondsToClock(seconds)
 | 
						|
    seconds = tonumber(seconds)
 | 
						|
    local retval
 | 
						|
    if seconds <= 0 then
 | 
						|
        retval = "00:00:00";
 | 
						|
    else
 | 
						|
        local hours = string.format("%02.f", math.floor(seconds/3600));
 | 
						|
        local mins = string.format("%02.f", math.floor(seconds/60 - (hours*60)));
 | 
						|
        local secs = string.format("%02.f", math.floor(seconds - hours*3600 - mins *60));
 | 
						|
        retval = hours..":"..mins..":"..secs
 | 
						|
    end
 | 
						|
    return retval
 | 
						|
end
 | 
						|
 | 
						|
local function FinishRace()
 | 
						|
    TriggerServerEvent('qb-lapraces:server:FinishPlayer', CurrentRaceData, CurrentRaceData.TotalTime, CurrentRaceData.TotalLaps, CurrentRaceData.BestLap)
 | 
						|
    if CurrentRaceData.BestLap ~= 0 then
 | 
						|
        QBCore.Functions.Notify('Race finished in '..SecondsToClock(CurrentRaceData.TotalTime)..', with the best lap: '..SecondsToClock(CurrentRaceData.BestLap))
 | 
						|
    else
 | 
						|
        QBCore.Functions.Notify('Race finished in '..SecondsToClock(CurrentRaceData.TotalTime))
 | 
						|
    end
 | 
						|
    for k, _ in pairs(CurrentRaceData.Checkpoints) do
 | 
						|
        if CurrentRaceData.Checkpoints[k].blip ~= nil then
 | 
						|
            RemoveBlip(CurrentRaceData.Checkpoints[k].blip)
 | 
						|
            CurrentRaceData.Checkpoints[k].blip = nil
 | 
						|
        end
 | 
						|
        if CurrentRaceData.Checkpoints[k].pileleft ~= nil then
 | 
						|
            local coords = CurrentRaceData.Checkpoints[k].offset.left
 | 
						|
            local Obj = GetClosestObjectOfType(coords.x, coords.y, coords.z, 5.0, `prop_offroad_tyres02`, 0, 0, 0)
 | 
						|
            DeleteObject(Obj)
 | 
						|
            ClearAreaOfObjects(coords.x, coords.y, coords.z, 50.0, 0)
 | 
						|
            CurrentRaceData.Checkpoints[k].pileleft = nil
 | 
						|
        end
 | 
						|
        if CurrentRaceData.Checkpoints[k].pileright ~= nil then
 | 
						|
            local coords = CurrentRaceData.Checkpoints[k].offset.right
 | 
						|
            local Obj = GetClosestObjectOfType(coords.x, coords.y, coords.z, 5.0, `prop_offroad_tyres02`, 0, 0, 0)
 | 
						|
            DeleteObject(Obj)
 | 
						|
            ClearAreaOfObjects(coords.x, coords.y, coords.z, 50.0, 0)
 | 
						|
            CurrentRaceData.Checkpoints[k].pileright = nil
 | 
						|
        end
 | 
						|
    end
 | 
						|
    CurrentRaceData.RaceName = nil
 | 
						|
    CurrentRaceData.Checkpoints = {}
 | 
						|
    CurrentRaceData.Started = false
 | 
						|
    CurrentRaceData.CurrentCheckpoint = 0
 | 
						|
    CurrentRaceData.TotalLaps = 0
 | 
						|
    CurrentRaceData.Lap = 0
 | 
						|
    CurrentRaceData.RaceTime = 0
 | 
						|
    CurrentRaceData.TotalTime = 0
 | 
						|
    CurrentRaceData.BestLap = 0
 | 
						|
    CurrentRaceData.RaceId = nil
 | 
						|
    RaceData.InRace = false
 | 
						|
end
 | 
						|
 | 
						|
local function Info()
 | 
						|
    local PlayerPed = PlayerPedId()
 | 
						|
    local plyVeh = GetVehiclePedIsIn(PlayerPed, false)
 | 
						|
    local IsDriver = GetPedInVehicleSeat(plyVeh, -1) == PlayerPed
 | 
						|
    local returnValue = plyVeh ~= 0 and plyVeh ~= nil and IsDriver
 | 
						|
    return returnValue, plyVeh
 | 
						|
end
 | 
						|
 | 
						|
local function IsInRace()
 | 
						|
    local retval = false
 | 
						|
    if RaceData.InRace then
 | 
						|
        retval = true
 | 
						|
    end
 | 
						|
    return retval
 | 
						|
end
 | 
						|
 | 
						|
local function IsInEditor()
 | 
						|
    local retval = false
 | 
						|
    if RaceData.InCreator then
 | 
						|
        retval = true
 | 
						|
    end
 | 
						|
    return retval
 | 
						|
end
 | 
						|
 | 
						|
exports('IsInEditor', IsInEditor)
 | 
						|
exports('IsInRace', IsInRace)
 | 
						|
 | 
						|
-- Events
 | 
						|
 | 
						|
RegisterNetEvent('qb-lapraces:client:StartRaceEditor', function(RaceName)
 | 
						|
    if not RaceData.InCreator then
 | 
						|
        CreatorData.RaceName = RaceName
 | 
						|
        RaceData.InCreator = true
 | 
						|
        CreatorUI()
 | 
						|
        CreatorLoop()
 | 
						|
    else
 | 
						|
        QBCore.Functions.Notify('You are already making a race.', 'error')
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('qb-lapraces:client:UpdateRaceRacerData', function(RaceId, aRaceData)
 | 
						|
    if (CurrentRaceData.RaceId ~= nil) and CurrentRaceData.RaceId == RaceId then
 | 
						|
        CurrentRaceData.Racers = aRaceData.Racers
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('qb-lapraces:client:JoinRace', function(Data, Laps)
 | 
						|
    if not RaceData.InRace then
 | 
						|
        RaceData.InRace = true
 | 
						|
        SetupRace(Data, Laps)
 | 
						|
        TriggerServerEvent('qb-lapraces:server:UpdateRaceState', CurrentRaceData.RaceId, false, true)
 | 
						|
    else
 | 
						|
        QBCore.Functions.Notify('Youre already in a race..', 'error')
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('qb-lapraces:client:LeaveRace', function(_)
 | 
						|
    QBCore.Functions.Notify('You have completed the race!')
 | 
						|
    for k, _ in pairs(CurrentRaceData.Checkpoints) do
 | 
						|
        if CurrentRaceData.Checkpoints[k].blip ~= nil then
 | 
						|
            RemoveBlip(CurrentRaceData.Checkpoints[k].blip)
 | 
						|
            CurrentRaceData.Checkpoints[k].blip = nil
 | 
						|
        end
 | 
						|
        if CurrentRaceData.Checkpoints[k].pileleft ~= nil then
 | 
						|
            local coords = CurrentRaceData.Checkpoints[k].offset.left
 | 
						|
            local Obj = GetClosestObjectOfType(coords.x, coords.y, coords.z, 5.0, `prop_offroad_tyres02`, 0, 0, 0)
 | 
						|
            DeleteObject(Obj)
 | 
						|
            ClearAreaOfObjects(coords.x, coords.y, coords.z, 50.0, 0)
 | 
						|
            CurrentRaceData.Checkpoints[k].pileleft = nil
 | 
						|
        end
 | 
						|
        if CurrentRaceData.Checkpoints[k].pileright ~= nil then
 | 
						|
            local coords = CurrentRaceData.Checkpoints[k].offset.right
 | 
						|
            local Obj = GetClosestObjectOfType(coords.x, coords.y, coords.z, 5.0, `prop_offroad_tyres02`, 0, 0, 0)
 | 
						|
            DeleteObject(Obj)
 | 
						|
            ClearAreaOfObjects(coords.x, coords.y, coords.z, 50.0, 0)
 | 
						|
            CurrentRaceData.Checkpoints[k].pileright = nil
 | 
						|
        end
 | 
						|
    end
 | 
						|
    CurrentRaceData.RaceName = nil
 | 
						|
    CurrentRaceData.Checkpoints = {}
 | 
						|
    CurrentRaceData.Started = false
 | 
						|
    CurrentRaceData.CurrentCheckpoint = 0
 | 
						|
    CurrentRaceData.TotalLaps = 0
 | 
						|
    CurrentRaceData.Lap = 0
 | 
						|
    CurrentRaceData.RaceTime = 0
 | 
						|
    CurrentRaceData.TotalTime = 0
 | 
						|
    CurrentRaceData.BestLap = 0
 | 
						|
    CurrentRaceData.RaceId = nil
 | 
						|
    RaceData.InRace = false
 | 
						|
    FreezeEntityPosition(GetVehiclePedIsIn(PlayerPedId(), false), false)
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('qb-lapraces:client:RaceCountdown', function()
 | 
						|
    TriggerServerEvent('qb-lapraces:server:UpdateRaceState', CurrentRaceData.RaceId, true, false)
 | 
						|
    if CurrentRaceData.RaceId ~= nil then
 | 
						|
        while Countdown ~= 0 do
 | 
						|
            if CurrentRaceData.RaceName ~= nil then
 | 
						|
                if Countdown == 10 then
 | 
						|
                    QBCore.Functions.Notify('The race will start in 10 seconds', 'error', 2500)
 | 
						|
                    PlaySound(-1, "slow", "SHORT_PLAYER_SWITCH_SOUND_SET", 0, 0, 1)
 | 
						|
                elseif Countdown <= 5 then
 | 
						|
                    QBCore.Functions.Notify(Countdown, 'error', 500)
 | 
						|
                    PlaySound(-1, "slow", "SHORT_PLAYER_SWITCH_SOUND_SET", 0, 0, 1)
 | 
						|
                end
 | 
						|
                Countdown = Countdown - 1
 | 
						|
                FreezeEntityPosition(GetVehiclePedIsIn(PlayerPedId(), true), true)
 | 
						|
            else
 | 
						|
                break
 | 
						|
            end
 | 
						|
            Wait(1000)
 | 
						|
        end
 | 
						|
        if CurrentRaceData.RaceName ~= nil then
 | 
						|
            SetNewWaypoint(CurrentRaceData.Checkpoints[CurrentRaceData.CurrentCheckpoint + 1].coords.x, CurrentRaceData.Checkpoints[CurrentRaceData.CurrentCheckpoint + 1].coords.y)
 | 
						|
            QBCore.Functions.Notify('GO!', 'success', 1000)
 | 
						|
            SetBlipScale(CurrentRaceData.Checkpoints[CurrentRaceData.CurrentCheckpoint + 1].blip, 1.0)
 | 
						|
            FreezeEntityPosition(GetVehiclePedIsIn(PlayerPedId(), true), false)
 | 
						|
            DoPilePfx()
 | 
						|
            CurrentRaceData.Started = true
 | 
						|
            Countdown = 10
 | 
						|
        else
 | 
						|
            FreezeEntityPosition(GetVehiclePedIsIn(PlayerPedId(), true), false)
 | 
						|
            Countdown = 10
 | 
						|
        end
 | 
						|
    else
 | 
						|
        QBCore.Functions.Notify('You are not currently in a race..', 'error')
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('qb-lapraces:client:PlayerFinishs', function(RaceId, Place, FinisherData)
 | 
						|
    if CurrentRaceData.RaceId ~= nil then
 | 
						|
        if CurrentRaceData.RaceId == RaceId then
 | 
						|
            QBCore.Functions.Notify(FinisherData.PlayerData.charinfo.firstname..' is finished on spot: '..Place, 'error', 3500)
 | 
						|
        end
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('qb-lapraces:client:WaitingDistanceCheck', function()
 | 
						|
    Wait(1000)
 | 
						|
    CreateThread(function()
 | 
						|
        while true do
 | 
						|
            if not CurrentRaceData.Started then
 | 
						|
                local ped = PlayerPedId()
 | 
						|
                local pos = GetEntityCoords(ped)
 | 
						|
                if CurrentRaceData.Checkpoints[1] ~= nil then
 | 
						|
                    local cpcoords = CurrentRaceData.Checkpoints[1].coords
 | 
						|
                    local dist = #(pos - vector3(cpcoords.x, cpcoords.y, cpcoords.z))
 | 
						|
                    if dist > 115.0 then
 | 
						|
                        if ToFarCountdown ~= 0 then
 | 
						|
                            ToFarCountdown = ToFarCountdown - 1
 | 
						|
                            QBCore.Functions.Notify('Go back to the start or you will be kicked from the race: '..ToFarCountdown..'s', 'error', 500)
 | 
						|
                        else
 | 
						|
                            TriggerServerEvent('qb-lapraces:server:LeaveRace', CurrentRaceData)
 | 
						|
                            ToFarCountdown = 10
 | 
						|
                            break
 | 
						|
                        end
 | 
						|
                        Wait(1000)
 | 
						|
                    else
 | 
						|
                        if ToFarCountdown ~= 10 then
 | 
						|
                            ToFarCountdown = 10
 | 
						|
                        end
 | 
						|
                    end
 | 
						|
                end
 | 
						|
            else
 | 
						|
                break
 | 
						|
            end
 | 
						|
            Wait(3)
 | 
						|
        end
 | 
						|
    end)
 | 
						|
end)
 | 
						|
 | 
						|
-- Threads
 | 
						|
 | 
						|
CreateThread(function()
 | 
						|
    while true do
 | 
						|
        if RaceData.InCreator then
 | 
						|
            local PlayerPed = PlayerPedId()
 | 
						|
            local PlayerVeh = GetVehiclePedIsIn(PlayerPed)
 | 
						|
 | 
						|
            if PlayerVeh ~= 0 then
 | 
						|
                local Offset = {
 | 
						|
                    left = {
 | 
						|
                        x = (GetOffsetFromEntityInWorldCoords(PlayerVeh, -CreatorData.TireDistance, 0.0, 0.0)).x,
 | 
						|
                        y = (GetOffsetFromEntityInWorldCoords(PlayerVeh, -CreatorData.TireDistance, 0.0, 0.0)).y,
 | 
						|
                        z = (GetOffsetFromEntityInWorldCoords(PlayerVeh, -CreatorData.TireDistance, 0.0, 0.0)).z,
 | 
						|
                    },
 | 
						|
                    right = {
 | 
						|
                        x = (GetOffsetFromEntityInWorldCoords(PlayerVeh, CreatorData.TireDistance, 0.0, 0.0)).x,
 | 
						|
                        y = (GetOffsetFromEntityInWorldCoords(PlayerVeh, CreatorData.TireDistance, 0.0, 0.0)).y,
 | 
						|
                        z = (GetOffsetFromEntityInWorldCoords(PlayerVeh, CreatorData.TireDistance, 0.0, 0.0)).z,
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                DrawText3Ds(Offset.left.x, Offset.left.y, Offset.left.z, 'Checkpoint L')
 | 
						|
                DrawText3Ds(Offset.right.x, Offset.right.y, Offset.right.z, 'Checkpoint R')
 | 
						|
            end
 | 
						|
        end
 | 
						|
        Wait(3)
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
CreateThread(function()
 | 
						|
    while true do
 | 
						|
 | 
						|
        local ped = PlayerPedId()
 | 
						|
        local pos = GetEntityCoords(ped)
 | 
						|
 | 
						|
        if CurrentRaceData.RaceName ~= nil then
 | 
						|
            if CurrentRaceData.Started then
 | 
						|
                local cp
 | 
						|
                if CurrentRaceData.CurrentCheckpoint + 1 > #CurrentRaceData.Checkpoints then
 | 
						|
                    cp = 1
 | 
						|
                else
 | 
						|
                    cp = CurrentRaceData.CurrentCheckpoint + 1
 | 
						|
                end
 | 
						|
                local data = CurrentRaceData.Checkpoints[cp]
 | 
						|
                local CheckpointDistance = #(pos - vector3(data.coords.x, data.coords.y, data.coords.z))
 | 
						|
                local MaxDistance = GetMaxDistance(CurrentRaceData.Checkpoints[cp].offset)
 | 
						|
 | 
						|
                if CheckpointDistance < MaxDistance then
 | 
						|
                    if CurrentRaceData.TotalLaps == 0 then
 | 
						|
                        if CurrentRaceData.CurrentCheckpoint + 1 < #CurrentRaceData.Checkpoints then
 | 
						|
                            CurrentRaceData.CurrentCheckpoint = CurrentRaceData.CurrentCheckpoint + 1
 | 
						|
                            SetNewWaypoint(CurrentRaceData.Checkpoints[CurrentRaceData.CurrentCheckpoint + 1].coords.x, CurrentRaceData.Checkpoints[CurrentRaceData.CurrentCheckpoint + 1].coords.y)
 | 
						|
                            TriggerServerEvent('qb-lapraces:server:UpdateRacerData', CurrentRaceData.RaceId, CurrentRaceData.CurrentCheckpoint, CurrentRaceData.Lap, false)
 | 
						|
                            DoPilePfx()
 | 
						|
                            PlaySound(-1, "SELECT", "HUD_FRONTEND_DEFAULT_SOUNDSET", 0, 0, 1)
 | 
						|
                            SetBlipScale(CurrentRaceData.Checkpoints[CurrentRaceData.CurrentCheckpoint].blip, 0.6)
 | 
						|
                            SetBlipScale(CurrentRaceData.Checkpoints[CurrentRaceData.CurrentCheckpoint + 1].blip, 1.0)
 | 
						|
                        else
 | 
						|
                            DoPilePfx()
 | 
						|
                            PlaySound(-1, "SELECT", "HUD_FRONTEND_DEFAULT_SOUNDSET", 0, 0, 1)
 | 
						|
                            CurrentRaceData.CurrentCheckpoint = CurrentRaceData.CurrentCheckpoint + 1
 | 
						|
                            TriggerServerEvent('qb-lapraces:server:UpdateRacerData', CurrentRaceData.RaceId, CurrentRaceData.CurrentCheckpoint, CurrentRaceData.Lap, true)
 | 
						|
                            FinishRace()
 | 
						|
                        end
 | 
						|
                    else
 | 
						|
                        if CurrentRaceData.CurrentCheckpoint + 1 > #CurrentRaceData.Checkpoints then
 | 
						|
                            if CurrentRaceData.Lap + 1 > CurrentRaceData.TotalLaps then
 | 
						|
                                DoPilePfx()
 | 
						|
                                PlaySound(-1, "SELECT", "HUD_FRONTEND_DEFAULT_SOUNDSET", 0, 0, 1)
 | 
						|
                                CurrentRaceData.CurrentCheckpoint = CurrentRaceData.CurrentCheckpoint + 1
 | 
						|
                                TriggerServerEvent('qb-lapraces:server:UpdateRacerData', CurrentRaceData.RaceId, CurrentRaceData.CurrentCheckpoint, CurrentRaceData.Lap, true)
 | 
						|
                                FinishRace()
 | 
						|
                            else
 | 
						|
                                DoPilePfx()
 | 
						|
                                PlaySound(-1, "SELECT", "HUD_FRONTEND_DEFAULT_SOUNDSET", 0, 0, 1)
 | 
						|
                                if CurrentRaceData.RaceTime < CurrentRaceData.BestLap then
 | 
						|
                                    CurrentRaceData.BestLap = CurrentRaceData.RaceTime
 | 
						|
                                elseif CurrentRaceData.BestLap == 0 then
 | 
						|
                                    CurrentRaceData.BestLap = CurrentRaceData.RaceTime
 | 
						|
                                end
 | 
						|
                                CurrentRaceData.RaceTime = 0
 | 
						|
                                CurrentRaceData.Lap = CurrentRaceData.Lap + 1
 | 
						|
                                CurrentRaceData.CurrentCheckpoint = 1
 | 
						|
                                SetNewWaypoint(CurrentRaceData.Checkpoints[CurrentRaceData.CurrentCheckpoint + 1].coords.x, CurrentRaceData.Checkpoints[CurrentRaceData.CurrentCheckpoint + 1].coords.y)
 | 
						|
                                TriggerServerEvent('qb-lapraces:server:UpdateRacerData', CurrentRaceData.RaceId, CurrentRaceData.CurrentCheckpoint, CurrentRaceData.Lap, false)
 | 
						|
                            end
 | 
						|
                        else
 | 
						|
                            CurrentRaceData.CurrentCheckpoint = CurrentRaceData.CurrentCheckpoint + 1
 | 
						|
                            if CurrentRaceData.CurrentCheckpoint ~= #CurrentRaceData.Checkpoints then
 | 
						|
                                SetNewWaypoint(CurrentRaceData.Checkpoints[CurrentRaceData.CurrentCheckpoint + 1].coords.x, CurrentRaceData.Checkpoints[CurrentRaceData.CurrentCheckpoint + 1].coords.y)
 | 
						|
                                TriggerServerEvent('qb-lapraces:server:UpdateRacerData', CurrentRaceData.RaceId, CurrentRaceData.CurrentCheckpoint, CurrentRaceData.Lap, false)
 | 
						|
                                SetBlipScale(CurrentRaceData.Checkpoints[CurrentRaceData.CurrentCheckpoint].blip, 0.6)
 | 
						|
                                SetBlipScale(CurrentRaceData.Checkpoints[CurrentRaceData.CurrentCheckpoint + 1].blip, 1.0)
 | 
						|
                            else
 | 
						|
                                SetNewWaypoint(CurrentRaceData.Checkpoints[1].coords.x, CurrentRaceData.Checkpoints[1].coords.y)
 | 
						|
                                TriggerServerEvent('qb-lapraces:server:UpdateRacerData', CurrentRaceData.RaceId, CurrentRaceData.CurrentCheckpoint, CurrentRaceData.Lap, false)
 | 
						|
                                SetBlipScale(CurrentRaceData.Checkpoints[#CurrentRaceData.Checkpoints].blip, 0.6)
 | 
						|
                                SetBlipScale(CurrentRaceData.Checkpoints[1].blip, 1.0)
 | 
						|
                            end
 | 
						|
                            DoPilePfx()
 | 
						|
                            PlaySound(-1, "SELECT", "HUD_FRONTEND_DEFAULT_SOUNDSET", 0, 0, 1)
 | 
						|
                        end
 | 
						|
                    end
 | 
						|
                end
 | 
						|
            else
 | 
						|
                local data = CurrentRaceData.Checkpoints[CurrentRaceData.CurrentCheckpoint]
 | 
						|
                -- DrawText3Ds(data.coords.x, data.coords.y, data.coords.z, 'Ga hier staan')
 | 
						|
                DrawMarker(4, data.coords.x, data.coords.y, data.coords.z + 1.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.9, 1.5, 1.5, 255, 255, 255, 255, 0, 1, 0, 0, 0, 0, 0)
 | 
						|
            end
 | 
						|
        else
 | 
						|
            Wait(1000)
 | 
						|
        end
 | 
						|
 | 
						|
        Wait(3)
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
CreateThread(function()
 | 
						|
    while true do
 | 
						|
        if RaceData.InCreator then
 | 
						|
            GetClosestCheckpoint()
 | 
						|
            SetupPiles()
 | 
						|
        end
 | 
						|
        Wait(1000)
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
CreateThread(function()
 | 
						|
    while true do
 | 
						|
        local Driver, plyVeh = Info()
 | 
						|
        if Driver then
 | 
						|
            if GetVehicleCurrentGear(plyVeh) < 3 and GetVehicleCurrentRpm(plyVeh) == 1.0 and math.ceil(GetEntitySpeed(plyVeh) * 2.236936) > 50 then
 | 
						|
              while GetVehicleCurrentRpm(plyVeh) > 0.6 do
 | 
						|
                  SetVehicleCurrentRpm(plyVeh, 0.3)
 | 
						|
                  Wait(1)
 | 
						|
              end
 | 
						|
              Wait(800)
 | 
						|
            end
 | 
						|
        end
 | 
						|
        Wait(500)
 | 
						|
    end
 | 
						|
end)
 |