⚙️Editable Files
Config File
Config = {} -- dont touch this!
-- Script use p_bridge as dependency [https://github.com/PiotreeQ/p_bridge]
-- It includes language, framework, inventory and much more!
---@class settings
---@field spawnOffset vec3 [player spawn offset related to vehicle on start practice test]
---@field speedUnit string [KMH | MPH]
---@field speedLimit number | false [false = no speed limit on practice exam]
---@field speedLimitFails number | false [false = no speed limit fails on practice exam, number = how many times player can exceed speed limit before failing]
---@field minVehicleHealth number | false [false = no minimum vehicle health requirement, number = when vehicle reach this health, exam will be failed]
---@field timeLimit number | false [false = no time limit on practice exam, number = time limit in minutes]
---@class examinerPed
---@field spawn boolean [true = spawn ped, false = not spawn ped]
---@field spawnOffset vec3 [spawn offset related to vehicle]
---@field model string [model of ped]
---@field followPlayer boolean [false = will spawn in vehicle, true = will follow player, if player enter vehicle ped also will enter, same for exit]
Config.Tasks = {
settings = {
spawnOffset = vector3(-1.0, 0.0, 0.0),
examinerPed = {
spawn = true,
spawnOffset = vector3(0.5, 0.0, 0.0),
model = 'ig_mp_agent14',
anim = {dict = 'missfam4', clip = 'base', flag = 49},
prop = {model = 'p_amb_clipboard_01', bone = 36029, coords = vec3(0.16, 0.08, 0.1), rot = vec3(-130.0, -50.0, 0.0)},
},
speedUnit = 'MPH', -- SPEED UNIT
speedLimit = 50, -- SPEED LIMIT [IN UNIT ABOVE!]
speedLimitFails = 3,
minVehicleHealth = 600,
timeLimit = 15,
},
variants = {
--@param value: string [unique task name]
--@param label: string [display name in task editor]
--@param disableSetup: boolean [if true, task cannot be set up in editor]
-- THESE ARE DEFAULT TASK VARIANTS, DO NOT REMOVE!
{value = 'park_front', label = 'Park Vehicle Front'},
{value = 'park_back', label = 'Park Vehicle Back'},
{value = 'drive_through', label = 'Drive Through'},
-- ADDITIONAL TASK VARIANTS GO HERE [THEY NEED LOGIC TO WORK!]
{value = 'turn_on_headlights', label = 'Turn on Headlights', disableSetup = true},
{value = 'seat_belt', label = 'Fasten your seat belt', disableSetup = true},
{value = 'look_around', label = 'Look around', disableSetup = true},
},
functionality = {
-- function name must be the same as value in variant!
turn_on_headlights = function(taskData)
local _, lightsOn, beamsOn = GetVehicleLightsState(cache.vehicle)
while not lightsOn and not beamsOn do
Citizen.Wait(500)
_, lightsOn, beamsOn = GetVehicleLightsState(cache.vehicle)
if lightsOn or beamsOn then
break
end
end
-- when task is done, function must return true to execute next task
PlaySoundFrontend(-1, "RACE_PLACED", "HUD_AWARDS")
return true
end,
seat_belt = function(taskData)
-- Logic for fastening seat belt
if GetResourceState('esx_cruisecontrol') ~= 'started' then
lib.print.error('esx_cruisecontrol is missing, change export in config.lua!')
return false
end
local seatBelt = exports['esx_cruisecontrol']:isSeatbeltOn()
while not seatBelt do
Citizen.Wait(200)
seatBelt = exports['esx_cruisecontrol']:isSeatbeltOn()
if seatBelt then
break
end
end
-- when task is done, function must return true to execute next task
PlaySoundFrontend(-1, "RACE_PLACED", "HUD_AWARDS")
return true
end,
look_around = function(taskData)
FreezeEntityPosition(cache.vehicle, true)
Bridge.Notify.showNotify(locale('look_left'), 'inform')
Citizen.Wait(5000)
Bridge.Notify.showNotify(locale('look_right'), 'inform')
Citizen.Wait(5000)
Bridge.Notify.showNotify(locale('you_can_drive'), 'inform')
FreezeEntityPosition(cache.vehicle, false)
return true
end
}
}
---@class Config.Creator
---@field schoolTypes {[type]: {label, theory, practice}}
---@field key string [school type]
---@field label string [display name in creator]
---@field theory string [license name to add after passing theory exam]
---@field practice string [license name to add after passing practice exam]
Config.Creator = {
allowedGroups = {
['owner'] = true,
['admin'] = true,
},
schoolTypes = {
['car'] = {label = 'Car', theory = 'car_theory', practice = 'car_practice'},
['bike'] = {label = 'Bike', theory = 'bike_theory', practice = 'bike_practice'},
['truck'] = {label = 'Truck', theory = 'truck_theory', practice = 'truck_practice'}
}
}
---@class Config.Practice
---@field examFailCooldown number | false [cooldown in seconds to start new exam after failing, false = no cooldown]
Config.Practice = {
examFailCooldown = 300,
}
---@class Config.Theory
---@field examFailCooldown number | false [cooldown in seconds to start new exam after failing, false = no cooldown]
Config.Theory = {
examFailCooldown = 300,
}
Last updated