Page cover

Accessible files

Here you can find all the files which can be edite to make the asset compatible with your server.​

config.lua
----------------------------------------------------------------------------------------------
---------------------------------| Brutal Driving School :) |----------------------------------
----------------------------------------------------------------------------------------------

--[[
Hi, thank you for buying our script, We are very grateful!

For help join our Discord server:     https://discord.gg/85u2u5c8q9
More informations about the script:   https://docs.brutalscripts.com
--]]

Config = {
    Core = 'automatic',  -- All core settings are in the 'core' folder.
    TextUI = 'brutal_textui', -- false / 'brutal_textui' / 'ox_lib' / 'okokTextUI' / 'ESXTextUI' / 'QBDrawText' // Custom can be add in the cl_utils.lua!!!
    Target = 'oxtarget', -- 'oxtarget' / 'qb-target' // if the TextUI is set to false target will step its place. | The Target cannot be false.
    BrutalNotify = true, -- Buy here: (4€+VAT) https://store.brutalscripts.com | Or set up your own notify >> cl_utils.lua   
    BrutalKeys = true, -- Buy here: (15€+VAT) https://store.brutalscripts.com | Or set up your own if you're using a different vehicle key >> client-utils.lua
    
    SteamName = true, -- true = Steam name | false = character name
    LocallyInvisible = true, -- true or false | If your ANTICHEAT ban the player with 'Invisible' reason, set to false!
    Metric = 'kmh', -- 'kmh' / 'mph'

    CirclesSettings = {
        progresstype = 'circular', -- 'linear' or 'circular'

        -- Define the color for each circle element
        progresscolors = {
            -- InfoCircles
            mistakepoint = 'red',
            speedlimit = '#ff9b00',
            checkpoint = 'yellow',
            time = 'green',

            -- WarningCircles
            warning = 'red'
        }
    },

    MaxMistakePoints = 6, -- Maximum number of mistake points a player can accumulate during a driving exam
    ErrorCooldown = {
        use = true, -- If true, a cooldown period will be applied between consecutive errors
        timeout = 10, -- Cooldown time (in seconds) before another error can be registered
    },

    WarningCircles = {
        ExitVehicle = {
            timelimit = 30, -- Time (in seconds) before the test ends if the player does not return to the exam vehicle
        },
        TooFarFromExaminer = {
            timelimit = 60, -- Time (in seconds) before the test ends if the player stays too far from the examiner
        },
        TooFarFromCheckpoint = {
            timelimit = 80, -- Time (in seconds) before the test ends if the player stays too far from the checkpoint
        }
    },

    PracticalTestRetryCooldown = 5, -- Time (in minutes) a player must wait before retaking the specific test type they previously failed
    PracticalTestTimeLimit = 15, -- The maximum time (in minutes) the player has to complete the practical test, applies only if this test type has no speed limit configured

    PassPercentage = 85, -- Minimum percentage required to pass the theory exam
    TheoryExamRemainingTime = 10, -- Time limit for completing the theory exam (in minutes)
    TheoryTestRetryCooldown = 5, -- Time (in minutes) a player must wait before retaking the specific test type they previously failed
    MaxQuestionCount = 20, -- Number of random questions to select from all questions of this exam types

    Blips = {
        school = {use = true, label = 'Driving School', size = 1.0, sprite = 408, color = 0},
        checkpoint = {use = true, label = 'Checkpoint', size = 1.0, sprite = 1, color = 4},
        examiner = {use = true, label = 'Examiner', size = 0.8, sprite = 225, color = 3},
        finalcheckpoint = {use = true, label = 'Final Checkpoint', size = 1.0, sprite = 38, color = 2},
    },

    School = {
        Model = 'ig_drfriedlander',
        Coords = vector4(239.2054, -1381.1808, 33.7417, 143.2578),
        Exams = {
            {
                label = 'A',
                icon = 'fa-solid fa-motorcycle', 
                theory = {name = 'theory_a', price = 250}, 
                practical = {name = 'drive_a', price = 500}
            },
            {
                label = 'B',
                icon = 'fa-solid fa-car',
                theory = {name = 'theory_b', price = 250},
                practical = {name = 'drive_b', price = 500}
            },
            {
                label = 'C',
                icon = 'fa-solid fa-truck',
                theory = {name = 'theory_c', price = 250},
                practical = {name = 'drive_c', price = 500}
            },
            {
                label = 'ICC',
                icon = 'fa-solid fa-ship',
                theory = {name = 'theory_icc', price = 400},
                practical = {name = 'drive_icc', price = 800}
            },
            {
                label = 'PPL-A',
                icon = 'fa-solid fa-plane',
                theory = {name = 'theory_ppl-a', price = 1000},
                practical = {name = 'drive_ppl-a', price = 2000}
            },
            {
                label = 'PPL-H',
                icon = 'fa-solid fa-helicopter',
                theory = {name = 'theory_ppl-h', price = 1000},
                practical = {name = 'drive_ppl-h', price = 2000}
            },
        },
        PracticalTests = {
            ['A'] = {
                VehicleModel = 'bf400',
                VehicleSpawnPoint = vector4(241.3808, -1412.4437, 30.5870, 330.5833),
                ExaminerPed = 'a_m_y_busicas_01',
                ExaminerVehicle = { 
                    use = true, 
                    model = 'dilettante', 
                    spawnpoint = vector4(243.4339, -1416.0374, 30.0601, 326.1994),
                    defaultspeed = 60, -- This comes into effect when the speed limit is not being used.
                    distance = 200 -- The maximum allowed distance between the player's vehicle and the examiner's vehicle before triggering a warning or timer.
                },  
                Markers = {
                    checkpoint = {
                        glowsphere = {use = true, radius = 1.0, rgb = {255, 255, 255}, intensity = 0.5},
                        marker = 21, 
                        scale = {1.0, 1.0, 1.0}, 
                        rgba = {0, 0, 0, 255}, 
                        bobUpAndDown = false, 
                        rotate = false
                    },
                    finalcheckpoint = {
                        glowsphere = {use = true, radius = 1.0, rgb = {255, 255, 255}, intensity = 0.5},
                        marker = 4, 
                        scale = {1.0, 1.0, 1.0}, 
                        rgba = {0, 255, 0, 255}, 
                        bobUpAndDown = false, 
                        rotate = false
                    },
                },
                CheckpointRange = 3.0, -- How close the vehicle must be to a checkpoints.
                MaxCheckpointDistance = {
                    use = true,
                    distance = 500, -- The maximum distance the player can be from the current checkpoint before triggering the out-of-range timer.
                },
                EnableSeparateDimension = false, -- When enabled, the test runs in a private dimension, separating the player from others during their practical exam. 
                OnWaterCheckpoints = false, -- Useful for boat or water-related license tests to prevent checkpoints from being placed underwater.
                CheckPoints = {
                    [1] = {
                        coord = vector3(257.8605, -1397.4191, 30.5314),
                        speedlimit = 60,
                    },
                    [2] = {
                        coord = vector3(248.1144, -1341.2010, 31.8069),
                        speedlimit = 60,
                    },
                    [3] = {
                        coord = vector3(219.7841, -1368.6123, 30.5437),
                        speedlimit = 60,
                    },
                    [4] = {
                        coord = vector3(217.5475, -1410.3495, 29.2921),
                        speedlimit = 60,
                    },
                    [5] = {
                        coord = vector3(182.6509, -1394.0763, 29.2672),
                        speedlimit = 80,
                    },
                    [6] = {
                        coord = vector3(324.1807, -1321.9264, 32.1126),
                        speedlimit = 80,
                    },
                    [7] = {
                        coord = vector3(520.6267, -1438.9844, 29.3452),
                        speedlimit = 80,
                    },
                    [8] = {
                        coord = vector3(766.5687, -1440.0005, 27.5855),
                        speedlimit = 90,
                    },
                    [9] = {
                        coord = vector3(807.8881, -1259.8363, 26.3273),
                        speedlimit = 90,
                    },
                    [10] = {
                        coord = vector3(804.6221, -1222.5441, 45.6145),
                        speedlimit = 120,
                    },
                    [11] = {
                        coord = vector3(1081.5348, -1095.8845, 42.2641),
                        speedlimit = 120,
                    },
                    [12] = {
                        coord = vector3(521.7590, -491.7859, 35.7611),
                        speedlimit = 130,
                    },
                    [13] = {
                        coord = vector3(324.9712, -475.6196, 43.2924),
                        speedlimit = 120,
                    },
                    [14] = {
                        coord = vector3(245.1315, -607.0976, 42.4394),
                        speedlimit = 90,
                    },
                    [15] = {
                        coord = vector3(175.6949, -792.3199, 31.4121),
                        speedlimit = 90,
                    },
                    [16] = {
                        coord = vector3(114.6532, -975.2689, 29.4073),
                        speedlimit = 90,
                    },
                    [17] = {
                        coord = vector3(382.7110, -1060.1171, 29.1948),
                        speedlimit = 90,
                    },
                    [18] = {
                        coord = vector3(395.5611, -1115.5985, 29.3975),
                        speedlimit = 80,
                    },
                    [19] = {
                        coord = vector3(395.5597, -1115.3921, 29.3973),
                        speedlimit = 80,
                    },
                    [20] = {
                        coord = vector3(483.7297, -1134.7544, 29.3909),
                        speedlimit = 80,
                    },
                    [21] = {
                        coord = vector3(496.6960, -1188.1256, 29.1586),
                        speedlimit = 80,
                    },
                    [22] = {
                        coord = vector3(353.7572, -1305.7411, 32.2846),
                        speedlimit = 80,
                    },
                    [23] = {
                        coord = vector3(278.4431, -1375.6649, 31.9351),
                        speedlimit = 80,
                    },
                    [24] = {
                        coord = vector3(224.8872, -1379.1306, 30.4815),
                        speedlimit = 60,
                    },
                }
            },
            ['B'] = {
                VehicleModel = 'dilettante',
                VehicleSpawnPoint = vector4(241.3808, -1412.4437, 30.5870, 330.5833),
                ExaminerPed = 'a_m_y_busicas_01',
                ExaminerVehicle = { 
                    use = false, 
                    model = 'dilettante', 
                    spawnpoint = vector4(253.7149, -1406.0863, 30.5875, 71.4689),
                    defaultspeed = 60, -- This comes into effect when the speed limit is not being used.
                    distance = 200 -- The maximum allowed distance between the player's vehicle and the examiner's vehicle before triggering a warning or timer.
                },
                Markers = {
                    checkpoint = {
                        glowsphere = {use = true, radius = 1.0, rgb = {255, 255, 255}, intensity = 0.5},
                        marker = 21, 
                        scale = {1.0, 1.0, 1.0}, 
                        rgba = {0, 0, 0, 255}, 
                        bobUpAndDown = false, 
                        rotate = false
                    },
                    finalcheckpoint = {
                        glowsphere = {use = true, radius = 1.0, rgb = {255, 255, 255}, intensity = 0.5},
                        marker = 4, 
                        scale = {1.0, 1.0, 1.0}, 
                        rgba = {0, 255, 0, 255}, 
                        bobUpAndDown = false, 
                        rotate = false
                    },
                },
                CheckpointRange = 3.0, -- How close the vehicle must be to a checkpoints.
                MaxCheckpointDistance = {
                    use = true,
                    distance = 500, -- The maximum distance the player can be from the current checkpoint before triggering the out-of-range timer.
                },    
                EnableSeparateDimension = false, -- When enabled, the test runs in a private dimension, separating the player from others during their practical exam.
                OnWaterCheckpoints = false, -- Useful for boat or water-related license tests to prevent checkpoints from being placed underwater.
                CheckPoints = {
                    [1] = {
                        coord = vector3(257.8605, -1397.4191, 30.5314),
                        speedlimit = 60,
                    },
                    [2] = {
                        coord = vector3(248.1144, -1341.2010, 31.8069),
                        speedlimit = 60,
                    },
                    [3] = {
                        coord = vector3(219.7841, -1368.6123, 30.5437),
                        speedlimit = 60,
                    },
                    [4] = {
                        coord = vector3(217.5475, -1410.3495, 29.2921),
                        speedlimit = 60,
                    },
                    [5] = {
                        coord = vector3(182.6509, -1394.0763, 29.2672),
                        speedlimit = 80,
                    },
                    [6] = {
                        coord = vector3(324.1807, -1321.9264, 32.1126),
                        speedlimit = 80,
                    },
                    [7] = {
                        coord = vector3(520.6267, -1438.9844, 29.3452),
                        speedlimit = 80,
                    },
                    [8] = {
                        coord = vector3(766.5687, -1440.0005, 27.5855),
                        speedlimit = 90,
                    },
                    [9] = {
                        coord = vector3(807.8881, -1259.8363, 26.3273),
                        speedlimit = 90,
                    },
                    [10] = {
                        coord = vector3(804.6221, -1222.5441, 45.6145),
                        speedlimit = 120,
                    },
                    [11] = {
                        coord = vector3(1081.5348, -1095.8845, 42.2641),
                        speedlimit = 120,
                    },
                    [12] = {
                        coord = vector3(521.7590, -491.7859, 35.7611),
                        speedlimit = 130,
                    },
                    [13] = {
                        coord = vector3(324.9712, -475.6196, 43.2924),
                        speedlimit = 120,
                    },
                    [14] = {
                        coord = vector3(245.1315, -607.0976, 42.4394),
                        speedlimit = 90,
                    },
                    [15] = {
                        coord = vector3(175.6949, -792.3199, 31.4121),
                        speedlimit = 90,
                    },
                    [16] = {
                        coord = vector3(114.6532, -975.2689, 29.4073),
                        speedlimit = 90,
                    },
                    [17] = {
                        coord = vector3(382.7110, -1060.1171, 29.1948),
                        speedlimit = 90,
                    },
                    [18] = {
                        coord = vector3(395.5611, -1115.5985, 29.3975),
                        speedlimit = 80,
                    },
                    [19] = {
                        coord = vector3(395.5597, -1115.3921, 29.3973),
                        speedlimit = 80,
                    },
                    [20] = {
                        coord = vector3(483.7297, -1134.7544, 29.3909),
                        speedlimit = 80,
                    },
                    [21] = {
                        coord = vector3(496.6960, -1188.1256, 29.1586),
                        speedlimit = 80,
                    },
                    [22] = {
                        coord = vector3(353.7572, -1305.7411, 32.2846),
                        speedlimit = 80,
                    },
                    [23] = {
                        coord = vector3(278.4431, -1375.6649, 31.9351),
                        speedlimit = 80,
                    },
                    [24] = {
                        coord = vector3(224.8872, -1379.1306, 30.4815),
                        speedlimit = 60,
                    },
                }
            },
            ['C'] = {
                VehicleModel = 'mule',
                VehicleSpawnPoint = vector4(241.3808, -1412.4437, 30.5870, 330.5833),
                ExaminerPed = 'a_m_y_busicas_01',
                ExaminerVehicle = { 
                    use = false, 
                    model = 'dilettante', 
                    spawnpoint = vector4(253.7149, -1406.0863, 30.5875, 71.4689),
                    defaultspeed = 60, -- This comes into effect when the speed limit is not being used.
                    distance = 200 -- The maximum allowed distance between the player's vehicle and the examiner's vehicle before triggering a warning or timer.
                },
                Markers = {
                    checkpoint = {
                        glowsphere = {use = true, radius = 1.0, rgb = {255, 255, 255}, intensity = 0.5},
                        marker = 21, 
                        scale = {1.0, 1.0, 1.0}, 
                        rgba = {0, 0, 0, 255}, 
                        bobUpAndDown = false, 
                        rotate = false
                    },
                    finalcheckpoint = {
                        glowsphere = {use = true, radius = 1.0, rgb = {255, 255, 255}, intensity = 0.5},
                        marker = 4, 
                        scale = {1.0, 1.0, 1.0}, 
                        rgba = {0, 255, 0, 255}, 
                        bobUpAndDown = false, 
                        rotate = false
                    },
                },
                CheckpointRange = 3.0, -- How close the vehicle must be to a checkpoints.
                MaxCheckpointDistance = {
                    use = true,
                    distance = 500, -- The maximum distance the player can be from the current checkpoint before triggering the out-of-range timer.
                },
                EnableSeparateDimension = false, -- When enabled, the test runs in a private dimension, separating the player from others during their practical exam.
                OnWaterCheckpoints = false, -- Useful for boat or water-related license tests to prevent checkpoints from being placed underwater.
                CheckPoints = {
                    [1] = {
                        coord = vector3(257.8605, -1397.4191, 30.5314),
                        speedlimit = 60,
                    },
                    [2] = {
                        coord = vector3(248.1144, -1341.2010, 31.8069),
                        speedlimit = 60,
                    },
                    [3] = {
                        coord = vector3(219.7841, -1368.6123, 30.5437),
                        speedlimit = 60,
                    },
                    [4] = {
                        coord = vector3(217.5475, -1410.3495, 29.2921),
                        speedlimit = 60,
                    },
                    [5] = {
                        coord = vector3(182.6509, -1394.0763, 29.2672),
                        speedlimit = 80,
                    },
                    [6] = {
                        coord = vector3(324.1807, -1321.9264, 32.1126),
                        speedlimit = 80,
                    },
                    [7] = {
                        coord = vector3(520.6267, -1438.9844, 29.3452),
                        speedlimit = 80,
                    },
                    [8] = {
                        coord = vector3(766.5687, -1440.0005, 27.5855),
                        speedlimit = 90,
                    },
                    [9] = {
                        coord = vector3(807.8881, -1259.8363, 26.3273),
                        speedlimit = 90,
                    },
                    [10] = {
                        coord = vector3(804.6221, -1222.5441, 45.6145),
                        speedlimit = 120,
                    },
                    [11] = {
                        coord = vector3(1081.5348, -1095.8845, 42.2641),
                        speedlimit = 120,
                    },
                    [12] = {
                        coord = vector3(521.7590, -491.7859, 35.7611),
                        speedlimit = 130,
                    },
                    [13] = {
                        coord = vector3(324.9712, -475.6196, 43.2924),
                        speedlimit = 120,
                    },
                    [14] = {
                        coord = vector3(245.1315, -607.0976, 42.4394),
                        speedlimit = 90,
                    },
                    [15] = {
                        coord = vector3(175.6949, -792.3199, 31.4121),
                        speedlimit = 90,
                    },
                    [16] = {
                        coord = vector3(114.6532, -975.2689, 29.4073),
                        speedlimit = 90,
                    },
                    [17] = {
                        coord = vector3(382.7110, -1060.1171, 29.1948),
                        speedlimit = 90,
                    },
                    [18] = {
                        coord = vector3(395.5611, -1115.5985, 29.3975),
                        speedlimit = 80,
                    },
                    [19] = {
                        coord = vector3(395.5597, -1115.3921, 29.3973),
                        speedlimit = 80,
                    },
                    [20] = {
                        coord = vector3(483.7297, -1134.7544, 29.3909),
                        speedlimit = 80,
                    },
                    [21] = {
                        coord = vector3(496.6960, -1188.1256, 29.1586),
                        speedlimit = 80,
                    },
                    [22] = {
                        coord = vector3(353.7572, -1305.7411, 32.2846),
                        speedlimit = 80,
                    },
                    [23] = {
                        coord = vector3(278.4431, -1375.6649, 31.9351),
                        speedlimit = 80,
                    },
                    [24] = {
                        coord = vector3(224.8872, -1379.1306, 30.4815),
                        speedlimit = 60,
                    },
                }
            },
            ['ICC'] = {
                VehicleModel = 'suntrap',
                VehicleSpawnPoint = vector4(-726.9719, -1326.5741, 0.4409, 229.6710),
                ExaminerPed = 'a_m_y_busicas_01',
                ExaminerVehicle = { 
                    use = false, 
                    model = 'dilettante', 
                    spawnpoint = vector4(253.7149, -1406.0863, 30.5875, 71.4689),
                    defaultspeed = 60, -- This comes into effect when the speed limit is not being used.
                    distance = 200 -- The maximum allowed distance between the player's vehicle and the examiner's vehicle before triggering a warning or timer.
                },
                Markers = {
                    checkpoint = {
                        glowsphere = {use = true, radius = 1.0, rgb = {255, 255, 255}, intensity = 0.5},
                        marker = 21, 
                        scale = {1.0, 1.0, 1.0}, 
                        rgba = {0, 0, 0, 255}, 
                        bobUpAndDown = false, 
                        rotate = false
                    },
                    finalcheckpoint = {
                        glowsphere = {use = true, radius = 1.0, rgb = {255, 255, 255}, intensity = 0.5},
                        marker = 4, 
                        scale = {1.0, 1.0, 1.0}, 
                        rgba = {0, 255, 0, 255}, 
                        bobUpAndDown = false, 
                        rotate = false
                    },
                },
                CheckpointRange = 3.0, -- How close the vehicle must be to a checkpoints.
                MaxCheckpointDistance = {
                    use = false,
                    distance = 500, -- The maximum distance the player can be from the current checkpoint before triggering the out-of-range timer.
                },
                EnableSeparateDimension = true, -- When enabled, the test runs in a private dimension, separating the player from others during their practical exam.
                OnWaterCheckpoints = true, -- Useful for boat or water-related license tests to prevent checkpoints from being placed underwater.
                CheckPoints = {
                    [1] = {
                        coord = vector3(-838.8706, -1528.9634, 0.4104),
                        speedlimit = 120,
                    },
                    [2] = {
                        coord = vector3(-1457.2878, -2000.4242, 0.4365),
                        speedlimit = 120,
                    },
                    [3] = {
                        coord = vector3(-2206.2200, -1551.2163, 0.3466),
                        speedlimit = 120,
                    },
                    [4] = {
                        coord = vector3(-2335.9399, -1205.1528, 0.6234),
                        speedlimit = 120,
                    },
                    [5] = {
                        coord = vector3(-2522.3472, -475.2195, 0.4963),
                        speedlimit = 120,
                    },
                    [6] = {
                        coord = vector3(-3085.4202, -190.0567, 0.8167),
                        speedlimit = 120,
                    },
                    [7] = {
                        coord = vector3(-3480.6682, -1112.7788, 1.6887),
                        speedlimit = 120,
                    },
                    [8] = {
                        coord = vector3(-2097.7268, -2588.0913, -0.0124),
                        speedlimit = 120,
                    },
                    [9] = {
                        coord = vector3(-1469.4004, -2127.8542, 0.8491),
                        speedlimit = 120,
                    },
                    [10] = {
                        coord = vector3(-794.8432, -1502.3141, 0.4229),
                        speedlimit = 120,
                    },
                }
            },
            ['PPL-A'] = {
                VehicleModel = 'nimbus',
                VehicleSpawnPoint = vector4(-1426.4279, -2671.1411, 13.9449, 60.7015),
                ExaminerPed = 's_m_m_pilot_01',
                ExaminerVehicle = { 
                    use = false, 
                    model = 'dilettante', 
                    spawnpoint = vector4(253.7149, -1406.0863, 30.5875, 71.4689),
                    defaultspeed = 60, -- This comes into effect when the speed limit is not being used.
                    distance = 200 -- The maximum allowed distance between the player's vehicle and the examiner's vehicle before triggering a warning or timer.
                },
                Markers = {
                    checkpoint = {
                        glowsphere = {use = true, radius = 3.0, rgb = {255, 255, 255}, intensity = 0.5},
                        marker = 21, 
                        scale = {3.0, 3.0, 3.0}, 
                        rgba = {0, 0, 0, 255}, 
                        bobUpAndDown = false, 
                        rotate = false
                    },
                    finalcheckpoint = {
                        glowsphere = {use = true, radius = 3.0, rgb = {255, 255, 255}, intensity = 0.5},
                        marker = 4, 
                        scale = {3.0, 3.0, 3.0}, 
                        rgba = {0, 255, 0, 255}, 
                        bobUpAndDown = false, 
                        rotate = false
                    },
                },
                CheckpointRange = 5.0, -- How close the vehicle must be to a checkpoints.
                MaxCheckpointDistance = {
                    use = false,
                    distance = 500, -- The maximum distance the player can be from the current checkpoint before triggering the out-of-range timer.
                },
                EnableSeparateDimension = true, -- When enabled, the test runs in a private dimension, separating the player from others during their practical exam.
                OnWaterCheckpoints = false, -- Useful for boat or water-related license tests to prevent checkpoints from being placed underwater.
                CheckPoints = {
                    [1] = {
                        coord = vector3(-1460.8959, -2651.2358, 13.9449),
                    },
                    [2] = {
                        coord = vector3(-1550.5765, -2706.9685, 14.5889),
                    },
                    [3] = {
                        coord = vector3(-1590.6897, -2767.0977, 14.5858),
                    },
                    [4] = {
                        coord = vector3(-1692.5186, -2839.1758, 14.5894),
                    },
                    [5] = {
                        coord = vector3(-1655.0806, -2959.1589, 14.5870),
                    },
                    [6] = {
                        coord = vector3(-234.3214, -3762.4893, 199.5685),
                    },
                    [7] = {
                        coord = vector3(1851.6946, -3145.4822, 378.9897),
                    },
                    [8] = {
                        coord = vector3(2813.6604, 537.1341, 639.9734),
                    },
                    [9] = {
                        coord = vector3(-1219.0930, 1541.1899, 694.3196),
                    },
                    [10] = {
                        coord = vector3(-3837.7881, 755.6537, 559.8992),
                    },
                    [11] = {
                        coord = vector3(-1741.8499, -883.8511, 443.6784),
                    },
                    [12] = {
                        coord = vector3(87.6212, -138.0109, 337.7054),
                    },
                    [13] = {
                        coord = vector3(-1571.3816, -2618.4531, 14.5881),
                    },
                    [14] = {
                        coord = vector3(-1576.3589, -2745.8513, 14.5883),
                    },
                    [15] = {
                        coord = vector3(-1495.0283, -2786.8411, 14.5874),
                    },
                    [16] = {
                        coord = vector3(-1337.3325, -2678.8059, 14.5861),
                    },
                }
            },
            ['PPL-H'] = {
                VehicleModel = 'frogger',
                VehicleSpawnPoint = vector4(-1178.4910, -2845.8889, 13.9458, 150.2578),
                ExaminerPed = 's_m_m_pilot_01',
                ExaminerVehicle = { 
                    use = false, 
                    model = '', 
                    spawnpoint = vector4(253.7149, -1406.0863, 30.5875, 71.4689),
                    defaultspeed = 60, -- This comes into effect when the speed limit is not being used.
                    distance = 200 -- The maximum allowed distance between the player's vehicle and the examiner's vehicle before triggering a warning or timer.
                },
                Markers = {
                    checkpoint = {
                        glowsphere = {use = true, radius = 3.0, rgb = {255, 255, 255}, intensity = 0.5},
                        marker = 21, 
                        scale = {3.0, 3.0, 3.0}, 
                        rgba = {0, 0, 0, 255}, 
                        bobUpAndDown = false, 
                        rotate = false
                    },
                    finalcheckpoint = {
                        glowsphere = {use = true, radius = 3.0, rgb = {255, 255, 255}, intensity = 0.5},
                        marker = 4, 
                        scale = {3.0, 3.0, 3.0}, 
                        rgba = {0, 255, 0, 255}, 
                        bobUpAndDown = false, 
                        rotate = false
                    },
                },
                CheckpointRange = 5.0, -- How close the vehicle must be to a checkpoints.
                MaxCheckpointDistance = {
                    use = false,
                    distance = 500, -- The maximum distance the player can be from the current checkpoint before triggering the out-of-range timer.
                },
                EnableSeparateDimension = true, -- When enabled, the test runs in a private dimension, separating the player from others during their practical exam.
                OnWaterCheckpoints = false, -- Useful for boat or water-related license tests to prevent checkpoints from being placed underwater.
                CheckPoints = {
                    [1] = {
                        coord = vector3(-1229.1206, -2932.0496, 33.9007),
                    },
                    [2] = {
                        coord = vector3(-677.5869, -3218.0696, 144.9007),
                    },
                    [3] = {
                        coord = vector3(264.4388, -2081.6467, 136.1086),
                    },
                    [4] = {
                        coord = vector3(313.3625, -1465.2867, 46.5095),
                    },
                    [5] = {
                        coord = vector3(1.9334, -1076.2899, 162.1407),
                    },
                    [6] = {
                        coord = vector3(-564.1914, -651.4775, 137.7645),
                    },
                    [7] = {
                        coord = vector3(-1220.4926, -872.7462, 87.0920),
                    },
                    [8] = {
                        coord = vector3(-1573.7526, -1414.3477, 70.6686),
                    },
                    [9] = {
                        coord = vector3(-1196.5758, -2320.7588, 78.2605),
                    },
                    [10] = {
                        coord = vector3(-1112.4310, -2883.9526, 13.9460),
                    },
                }
            },
        },
    },

    -----------------------------------------------------------
    -----------------------| TRANSLATE |-----------------------
    -----------------------------------------------------------

    NUILanguage = "en", -- "en", "es", "fr", "de", "pt", "it", "pl", "nl", "ru", "tr", "hu", "ro", "cs", "sv", "ar"

    MoneyForm = '$', -- Money form

    Texts = {
        [1] = {'[E] - Talk to Instructor', 38, 'Talk to Instructor', 'fa-solid fa-user-tie'},
    },
    
    -- Notify function EDITABLE >> cl_utils.lua
    Notify = { 
        [1] = {"Driving School", "You can not do this in a vehicle!", 5000, 'error'},
        [2] = {"Driving School", "Put the gun away!", 5000, 'error'},
        [3] = {"Driving School", "Menu unavailable during the practical test.", 5000, 'error'}, 
        [4] = {"Driving School", "Spawn point blocked!", 5000, 'error'},
        [5] = {"Driving School", "The exam has failed.", 5000, 'error'},
        [6] = {"Driving School", "You have passed the exam.", 5000, 'success'},
    },

    Webhooks = {
        DateFormat = '%d/%m/%Y - %X',

        Locale = {
            ['TestPased'] = '✅ Driving Test Passed',
            ['TestFailed'] = '❌ Driving Test Failed',

            ['HasPassed'] = 'test has been passed!',
            ['HasFailed'] = 'test has been failed!',
            ['HasQuit'] = 'The examinee has disconnected from the server.',

            ['Identifier'] = 'Identifier',
            ['Time'] = 'Time ⏲️'
        },

        -- To change a webhook color you need to set the decimal value of a color, you can use this website to do that - https://www.mathsisfun.com/hexadecimal-decimal-colors.html
        Colors = {
            ['TestPased'] = 3145631, 
            ['TestFailed'] = 16711680
        }
    },
}
client-utils.lua
ESX = Core
QBCore = Core

-- Buy here: (4€+VAT) https://store.brutalscripts.com
function notification(title, text, time, type)
    if Config.BrutalNotify then
        exports['brutal_notify']:SendAlert(title, text, time, type)
    else
        -- Put here your own notify and set the Config.BrutalNotify to false
        SetNotificationTextEntry("STRING")
        AddTextComponentString(text)
        DrawNotification(0,1)

        -- Default ESX Notify:
        --TriggerEvent('esx:showNotification', text)

        -- Default QB Notify:
        --TriggerEvent('QBCore:Notify', text, 'info', 5000)

        -- OKOK Notify:
        -- exports['okokNotify']:Alert(title, text, time, type, false)

    end
end

function TextUIFunction(type, text)
    if type == 'open' then
        if Config.TextUI:lower() == 'ox_lib' then
            lib.showTextUI(text)
        elseif Config.TextUI:lower() == 'okoktextui' then
            exports['okokTextUI']:Open(text, 'darkblue', 'right')
        elseif Config.TextUI:lower() == 'esxtextui' then
            ESX.TextUI(text)
        elseif Config.TextUI:lower() == 'qbdrawtext' then
            exports['qb-core']:DrawText(text,'left')
        elseif Config.TextUI:lower() == 'brutal_textui' then
            exports['brutal_textui']:Open(text, "blue")
        end
    elseif type == 'hide' then
        if Config.TextUI:lower() == 'ox_lib' then
            lib.hideTextUI()
        elseif Config.TextUI:lower() == 'okoktextui' then
            exports['okokTextUI']:Close()
        elseif Config.TextUI:lower() == 'esxtextui' then
            ESX.HideUI()
        elseif Config.TextUI:lower() == 'qbdrawtext' then
            exports['qb-core']:HideText()
        elseif Config.TextUI:lower() == 'brutal_textui' then
            exports['brutal_textui']:Close()
        end
    end
end

function PlayerDied()
    if GetResourceState("brutal_ambulancejob") == "started" then
        return exports.brutal_ambulancejob:IsDead()
    elseif GetResourceState("wasabi_ambulance") == "started" then
        return exports.wasabi_ambulance:isPlayerDead()
    else
        if IsEntityDead(PlayerPedId()) then
            return true
        else
            return false
        end
    end
end

function NoCarryWeapon()
    if GetSelectedPedWeapon(PlayerPedId()) == GetHashKey('WEAPON_UNARMED') then
        return true
    else
        SendNotify(2)
        return false
    end
end

function OpenMenuUtil()
    -- Here you can add a trigger to hide your HUD system
    
    InMenu = true
    SetNuiFocus(true, true)

    Citizen.CreateThread(function()
        while InMenu do
            N_0xf4f2c0d4ee209e20() -- it's disable the AFK camera zoom
            Citizen.Wait(15000)
        end 
    end)

    DisplayRadar(false)
end

function CloseMenuUtil()
    -- Here you can add a trigger to enable your HUD system

    InMenu = false
    SetNuiFocus(false,false)

    DisplayRadar(true)
end

RegisterNetEvent('brutal_driving_school:client:utils:CreateVehicle')
AddEventHandler('brutal_driving_school:client:utils:CreateVehicle', function(Vehicle)
    local plate = GetVehicleNumberPlateText(Vehicle)

    SetVehicleFuelLevel(Vehicle, 100.0)
    DecorSetFloat(Vehicle, "_FUEL_LEVEL", GetVehicleFuelLevel(Vehicle))

    if Config.BrutalKeys and GetResourceState("brutal_keys") == "started" then 
        exports.brutal_keys:addVehicleKey(plate, plate) 
    end

    if Config['Core']:upper() == 'QBCORE' then
        TriggerEvent("vehiclekeys:client:SetOwner", QBCore.Functions.GetPlate(Vehicle))
    end
end)

RegisterNetEvent('brutal_driving_school:client:utils:DeleteVehicle')
AddEventHandler('brutal_driving_school:client:utils:DeleteVehicle', function(Vehicle)
    local plate = GetVehicleNumberPlateText(Vehicle)

    if Config.BrutalKeys and GetResourceState("brutal_keys") == "started" then 
		exports.brutal_keys:removeKey(plate, true) 
	end	

    DeleteVehicle(Vehicle)
end)

RegisterNetEvent('brutal_driving_school:client:utils:RepairExaminerVehicle')
AddEventHandler('brutal_driving_school:client:utils:RepairExaminerVehicle', function(Vehicle)

end)
server-utils.lua
local YourWebhook = 'YOUR-WEBHOOK'  -- help: https://docs.brutalscripts.com/site/others/discord-webhook

function GetWebhook()
    return YourWebhook
end    

function CheckLicense(src, licenseName)
    if GetResourceState("es_extended") == "started" then

        local p = promise.new()
        TriggerEvent('esx_license:checkLicense', src, licenseName, function(hasLicense)
            p:resolve(hasLicense)
        end)
        return Citizen.Await(p)

    elseif GetResourceState("qb-core") == "started" or GetResourceState("qbx_core") == "started" then

        return GetPlayerLicenceMetaData(src, licenseName)
    end
end

RegisterNetEvent('brutal_driving_school:server:AddLicense')
AddEventHandler('brutal_driving_school:server:AddLicense', function(type)
	local src = source

    if GetResourceState("es_extended") == "started" then 
        TriggerEvent('esx_license:addLicense', src, type, function() end)
    elseif GetResourceState("qb-core") == "started" or GetResourceState("qbx_core") == "started" then
        SetPlayerLicenceMetaData(src, type)
    end    
end)
client-core.lua
Core = nil

if GetResourceState("es_extended") == "started" then
    local _esx_ = 'new' -- 'new' / 'old'

    if _esx_ then
        Core = exports['es_extended']:getSharedObject()
    else
        while Core == nil do
            TriggerEvent('esx:getSharedObject', function(obj) Core = obj end)
            Citizen.Wait(0)
        end
    end

    LoadedEvent = 'esx:playerLoaded'
    ReviveEvent = 'esx_ambulancejob:revive'
    TSCB = Core.TriggerServerCallback

    function GetPlayerJobDatas()
        return Core.GetPlayerData().job
    end

    function GetPlayersFunction()
        return Core.Game.GetPlayers()
    end

    function GetVehiclePropertiesFunction(vehicle)
        return Core.Game.GetVehicleProperties(vehicle)
    end

    function SetVehiclePropertiesFunction(vehicle, properties)
        return Core.Game.SetVehicleProperties(vehicle, properties)
    end

    function GetClosestVehicleFunction(coords, modelFilter)
        return Core.Game.GetClosestVehicle(coords, modelFilter)
    end

elseif GetResourceState("qb-core") == "started" or GetResourceState("qbx_core") == "started" then
    Core = exports['qb-core']:GetCoreObject()

    LoadedEvent = 'QBCore:Client:OnPlayerLoaded'
    ReviveEvent = 'hospital:client:Revive'
    TSCB = Core.Functions.TriggerCallback

    function GetPlayerJobDatas()
        return Core.Functions.GetPlayerData().job
    end

    function GetPlayersFunction()
        return Core.Functions.GetPlayers()
    end

    function GetVehiclePropertiesFunction(vehicle)
        return Core.Functions.GetVehicleProperties(vehicle)
    end

    function SetVehiclePropertiesFunction(vehicle, properties)
        return Core.Functions.SetVehicleProperties(vehicle, properties)
    end

    function GetClosestVehicleFunction(coords, modelFilter)
        return Core.Functions.GetClosestVehicle(coords, modelFilter)
    end

end
server-core.lua
Core = nil

if GetResourceState("es_extended") == "started" then
    local _esx_ = 'new' -- 'new' / 'old'
    
    if _esx_ == 'new' then
        Core = exports['es_extended']:getSharedObject()
    else
        Core = nil
        TriggerEvent('esx:getSharedObject', function(obj) Core = obj end)
        while Core == nil do
            Citizen.Wait(0)
        end
    end

    RESCB = Core.RegisterServerCallback
    GETPFI = Core.GetPlayerFromId
    RUI = Core.RegisterUsableItem

    function GetIdentifier(source)
        local xPlayer = GETPFI(source)
        while xPlayer == nil do
            Citizen.Wait(1000)
            xPlayer = GETPFI(source) 
        end
        return xPlayer.identifier
    end

    function GetPlayerByIdentifier(identifier)
        return Core.GetPlayerFromIdentifier(identifier)
    end

    function GetAccountMoney(source,account)
        local xPlayer = GETPFI(source)
        if account == 'bank' then
            return xPlayer.getAccount(account).money
        elseif account == 'money' then
            return xPlayer.getMoney()
        end
    end

    function AddMoneyFunction(source, account, amount)
        local xPlayer = GETPFI(source)
        if account == 'bank' then
            xPlayer.addAccountMoney('bank', amount)
        elseif account == 'money' then
            xPlayer.addMoney(amount)
        end
    end

    function RemoveAccountMoney(source, account, amount)
        local xPlayer = GETPFI(source)
        if account == 'bank' then
            xPlayer.removeAccountMoney('bank', amount)
        elseif account == 'money' then
            xPlayer.removeMoney(amount)
        end
    end

    function GetItemCount(source, item)
        local xPlayer = GETPFI(source)

        if _esx_ == 'new' then
            if xPlayer.getInventoryItem(item) == nil then
                print("^1PROBLEM!^7 The ^3" ..item.. "^7 item is not created.")
                return 0
            end

            return xPlayer.getInventoryItem(item).count
        else
            if string.sub(item, 0, 6):lower() == 'weapon' then
                local loadoutNum, weapon = xPlayer.getWeapon(item:upper())

                if weapon then
                    return true
                else
                    return false
                end
            else
                return xPlayer.getInventoryItem(item).count
            end
        end
    end
    
    function RemoveItem(source, item, amount)
        local xPlayer = GETPFI(source)
        if _esx_ == 'new' then
            xPlayer.removeInventoryItem(item, amount)
        else
            if string.sub(item, 0, 6):lower() == 'weapon' then
                xPlayer.removeWeapon(item)
            else
                xPlayer.removeInventoryItem(item, amount)
            end
        end
    end

    function AddItem(source, item, count, info)
        local xPlayer = GETPFI(source)
        if _esx_ == 'new' then
            xPlayer.addInventoryItem(item, count, info)
        else
            if string.sub(item, 0, 6):lower() == 'weapon' then
                xPlayer.addWeapon(item, 90)
            else
                xPlayer.addInventoryItem(item, count)
            end
        end
    end

    function GetPlayerNameFunction(source)
        local name
        if Config.SteamName then
            name = GetPlayerName(source) or 'No Data'
        else
            local xPlayer = GETPFI(source)
            name = xPlayer.getName() or 'No Data'
        end
        return name
    end

    function GetPlayerJob(source)
        local xPlayer = GETPFI(source)
        if xPlayer ~= nil then
            PlayerJob = xPlayer.job.name
        else
            PlayerJob = ''
        end
        return PlayerJob
    end

    function GetPlayersFunction()
        return Core.GetPlayers()
    end

elseif GetResourceState("qb-core") == "started" or GetResourceState("qbx_core") == "started" then

    Core = exports['qb-core']:GetCoreObject()
    
    RESCB = Core.Functions.CreateCallback
    GETPFI = Core.Functions.GetPlayer
    RUI = Core.Functions.CreateUseableItem

    function GetIdentifier(source)
        local xPlayer = GETPFI(source)
        while xPlayer == nil do
            Citizen.Wait(1000)
            xPlayer = GETPFI(source) 
        end
        return xPlayer.PlayerData.citizenid
    end

    function GetPlayerByIdentifier(identifier)
        return Core.Functions.GetPlayerByCitizenId(identifier)
    end

    function GetAccountMoney(source, account)
        local xPlayer = GETPFI(source)
        if account == 'bank' then
            return xPlayer.PlayerData.money.bank
        elseif account == 'money' then
            return xPlayer.PlayerData.money.cash
        end
    end

    function AddMoneyFunction(source, account, amount)
        local xPlayer = GETPFI(source)
        if account == 'bank' then
            xPlayer.Functions.AddMoney('bank', amount)
        elseif account == 'money' then
            xPlayer.Functions.AddMoney('cash', amount)
        end
    end

    function RemoveAccountMoney(source, account, amount)
        local xPlayer = GETPFI(source)
        if account == 'bank' then
            xPlayer.Functions.RemoveMoney('bank', amount)
        elseif account == 'money' then
            xPlayer.Functions.RemoveMoney('cash', amount)
        end
    end

    function GetItemCount(source, item)
        local xPlayer = GETPFI(source)
        local items = xPlayer.Functions.GetItemByName(item)
        local item_count = 0
        if items ~= nil then
            item_count = items.amount
        else
            item_count = 0
        end
        return item_count
    end

    function RemoveItem(source, item, amount)
        local xPlayer = GETPFI(source)
        xPlayer.Functions.RemoveItem(item, amount)
    end

    function AddItem(source, item, count, info)
        local xPlayer = GETPFI(source)
        xPlayer.Functions.AddItem(item, count, nil, info)
    end

    function GetPlayerNameFunction(source)
        local name
        if Config.SteamName then
            name = GetPlayerName(source)
        else
            local xPlayer = GETPFI(source)
            name = xPlayer.PlayerData.charinfo.firstname..' '..xPlayer.PlayerData.charinfo.lastname
        end
        return name
    end

    function GetPlayerJob(source)
        local xPlayer = GETPFI(source)
        return xPlayer.PlayerData.gang.name
    end

    function GetPlayersFunction()
        return Core.Functions.GetPlayers()
    end

    function GetPlayerLicenceMetaData(source, type)
        local xPlayer = GETPFI(source)
        local licence = xPlayer.PlayerData.metadata['licences'][type] 

        if licence then
            return true
        else
            return false    
        end
    end

    function SetPlayerLicenceMetaData(source, type)
        local xPlayer = GETPFI(source)
        local licence = xPlayer.PlayerData.metadata['licences']
        licence[type] = true

        xPlayer.Functions.SetMetaData('licences', licence)
    end    
end

Last updated

Was this helpful?