diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..41c2aaf2
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,9 @@
+root = true
+
+[*]
+indent_size = 2
+indent_style = space
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
\ No newline at end of file
diff --git a/__resource.lua b/__resource.lua
index 6a917dbe..06cb9fea 100644
--- a/__resource.lua
+++ b/__resource.lua
@@ -2,26 +2,33 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937'
description 'ESX DMV School'
-version '1.0.1'
+version '1.0.2'
server_scripts {
- 'server/main.lua'
+ '@es_extended/locale.lua',
+ 'locales/fr.lua',
+ 'locales/en.lua',
+ 'config.lua',
+ 'server/main.lua'
}
client_scripts {
- 'config.lua',
- 'client/main.lua'
+ '@es_extended/locale.lua',
+ 'locales/fr.lua',
+ 'locales/en.lua',
+ 'config.lua',
+ 'client/main.lua'
}
ui_page 'html/ui.html'
files {
- 'html/ui.html',
- 'html/logo.png',
- 'html/dmv.png',
- 'html/cursor.png',
- 'html/styles.css',
- 'html/questions.js',
- 'html/scripts.js',
- 'html/debounce.min.js'
-}
\ No newline at end of file
+ 'html/ui.html',
+ 'html/logo.png',
+ 'html/dmv.png',
+ 'html/cursor.png',
+ 'html/styles.css',
+ 'html/questions.js',
+ 'html/scripts.js',
+ 'html/debounce.min.js'
+}
diff --git a/client/main.lua b/client/main.lua
index 96b9eee0..e2ee0cf9 100644
--- a/client/main.lua
+++ b/client/main.lua
@@ -1,13 +1,13 @@
local Keys = {
- ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57,
- ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177,
- ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18,
- ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182,
- ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81,
- ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70,
- ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178,
- ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173,
- ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118
+ ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57,
+ ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177,
+ ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18,
+ ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182,
+ ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81,
+ ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70,
+ ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178,
+ ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173,
+ ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118
}
ESX = nil
@@ -27,29 +27,29 @@ local IsAboveSpeedLimit = false
local LastVehicleHealth = nil
Citizen.CreateThread(function()
- while ESX == nil do
- TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
- Citizen.Wait(0)
- end
+ while ESX == nil do
+ TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
+ Citizen.Wait(0)
+ end
end)
function DrawMissionText(msg, time)
ClearPrints()
- SetTextEntry_2('STRING')
- AddTextComponentString(msg)
- DrawSubtitleTimed(time, 1)
+ SetTextEntry_2('STRING')
+ AddTextComponentString(msg)
+ DrawSubtitleTimed(time, 1)
end
function StartTheoryTest()
- CurrentTest = 'theory'
+ CurrentTest = 'theory'
SendNUIMessage({
- openQuestion = true
+ openQuestion = true
})
ESX.SetTimeout(200, function()
- SetNuiFocus(true, true)
+ SetNuiFocus(true, true)
end)
TriggerServerEvent('esx_dmvschool:pay', Config.Prices['dmv'])
@@ -57,20 +57,20 @@ function StartTheoryTest()
end
function StopTheoryTest(success)
-
- CurrentTest = nil
+
+ CurrentTest = nil
SendNUIMessage({
- openQuestion = false
+ openQuestion = false
})
SetNuiFocus(false)
if success then
- TriggerServerEvent('esx_dmvschool:addLicense', 'dmv')
- ESX.ShowNotification('Vous avez ~g~réussi~s~ le test')
+ TriggerServerEvent('esx_dmvschool:addLicense', 'dmv')
+ ESX.ShowNotification(_U('passed_test'))
else
- ESX.ShowNotification('Vous avez ~r~raté~s~ le test')
+ ESX.ShowNotification(_U('failed_test'))
end
end
@@ -78,33 +78,31 @@ end
function StartDriveTest(type)
- ESX.Game.SpawnVehicle(Config.VehicleModels[type], Config.Zones.VehicleSpawnPoint.Pos, 317.0, function(vehicle)
-
- CurrentTest = 'drive'
- CurrentTestType = type
- CurrentCheckPoint = 0
+ ESX.Game.SpawnVehicle(Config.VehicleModels[type], Config.Zones.VehicleSpawnPoint.Pos, 317.0, function(vehicle)
+ CurrentTest = 'drive'
+ CurrentTestType = type
+ CurrentCheckPoint = 0
LastCheckPoint = -1
- CurrentZoneType = 'residence'
- DriveErrors = 0
- IsAboveSpeedLimit = false
- CurrentVehicle = vehicle
- LastVehicleHealth = GetEntityHealth(vehicle)
- local playerPed = GetPlayerPed(-1)
-
- TaskWarpPedIntoVehicle(playerPed, vehicle, -1)
- end)
+ CurrentZoneType = 'residence'
+ DriveErrors = 0
+ IsAboveSpeedLimit = false
+ CurrentVehicle = vehicle
+ LastVehicleHealth = GetEntityHealth(vehicle)
+ local playerPed = GetPlayerPed(-1)
+ TaskWarpPedIntoVehicle(playerPed, vehicle, -1)
+ end)
- TriggerServerEvent('esx_dmvschool:pay', Config.Prices[type])
+ TriggerServerEvent('esx_dmvschool:pay', Config.Prices[type])
end
function StopDriveTest(success)
if success then
- TriggerServerEvent('esx_dmvschool:addLicense', CurrentTestType)
- ESX.ShowNotification('Vous avez ~g~réussi~s~ le test')
+ TriggerServerEvent('esx_dmvschool:addLicense', CurrentTestType)
+ ESX.ShowNotification(_U('passed_test'))
else
- ESX.ShowNotification('Vous avez ~r~raté~s~ le test')
+ ESX.ShowNotification(_U('failed_test'))
end
CurrentTest = nil
@@ -113,77 +111,77 @@ function StopDriveTest(success)
end
function SetCurrentZoneType(type)
- CurrentZoneType = type
+ CurrentZoneType = type
end
function OpenDMVSchoolMenu()
- local ownedLicenses = {}
+ local ownedLicenses = {}
- for i=1, #Licenses, 1 do
- ownedLicenses[Licenses[i].type] = true
- end
+ for i=1, #Licenses, 1 do
+ ownedLicenses[Licenses[i].type] = true
+ end
- local elements = {}
+ local elements = {}
- if not ownedLicenses['dmv'] then
- table.insert(elements, {label = 'Examen du code $' .. Config.Prices['dmv'], value = 'theory_test'})
- end
+ if not ownedLicenses['dmv'] then
+ table.insert(elements, {label = _U('theory_test') .. Config.Prices['dmv'], value = 'theory_test'})
+ end
- if ownedLicenses['dmv'] then
+ if ownedLicenses['dmv'] then
- if not ownedLicenses['drive'] then
- table.insert(elements, {label = 'Examen de conduite [voiture] $' .. Config.Prices['drive'], value = 'drive_test', type = 'drive'})
- end
+ if not ownedLicenses['drive'] then
+ table.insert(elements, {label = _U('road_test_car') .. Config.Prices['drive'], value = 'drive_test', type = 'drive'})
+ end
- if not ownedLicenses['drive_bike'] then
- table.insert(elements, {label = 'Examen de conduite [moto] $' .. Config.Prices['drive_bike'], value = 'drive_test', type = 'drive_bike'})
- end
+ if not ownedLicenses['drive_bike'] then
+ table.insert(elements, {label = _U('road_test_bike') .. Config.Prices['drive_bike'], value = 'drive_test', type = 'drive_bike'})
+ end
- if not ownedLicenses['drive_truck'] then
- table.insert(elements, {label = 'Examen de conduite [camion] $' .. Config.Prices['drive_truck'], value = 'drive_test', type = 'drive_truck'})
- end
+ if not ownedLicenses['drive_truck'] then
+ table.insert(elements, {label = _U('road_test_truck') .. Config.Prices['drive_truck'], value = 'drive_test', type = 'drive_truck'})
+ end
- end
+ end
- ESX.UI.Menu.CloseAll()
+ ESX.UI.Menu.CloseAll()
- ESX.UI.Menu.Open(
- 'default', GetCurrentResourceName(), 'dmvschool_actions',
- {
- title = 'Ecole de conduite',
- elements = elements
- },
- function(data, menu)
+ ESX.UI.Menu.Open(
+ 'default', GetCurrentResourceName(), 'dmvschool_actions',
+ {
+ title = _U('driving_school'),
+ elements = elements
+ },
+ function(data, menu)
- if data.current.value == 'theory_test' then
- menu.close()
- StartTheoryTest()
- end
+ if data.current.value == 'theory_test' then
+ menu.close()
+ StartTheoryTest()
+ end
- if data.current.value == 'drive_test' then
- menu.close()
- StartDriveTest(data.current.type)
- end
+ if data.current.value == 'drive_test' then
+ menu.close()
+ StartDriveTest(data.current.type)
+ end
- end,
- function(data, menu)
+ end,
+ function(data, menu)
- menu.close()
+ menu.close()
- CurrentAction = 'dmvschool_menu'
- CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour ouvrir le menu'
- CurrentActionData = {}
+ CurrentAction = 'dmvschool_menu'
+ CurrentActionMsg = _U('press_open_menu')
+ CurrentActionData = {}
- end
- )
+ end
+ )
end
RegisterNUICallback('question', function(data, cb)
-
+
SendNUIMessage({
- openSection = 'question'
+ openSection = 'question'
})
cb('OK')
@@ -201,88 +199,88 @@ end)
AddEventHandler('esx_dmvschool:hasEnteredMarker', function(zone)
- if zone == 'DMVSchool' then
+ if zone == 'DMVSchool' then
- CurrentAction = 'dmvschool_menu'
- CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour ouvrir le menu'
- CurrentActionData = {}
+ CurrentAction = 'dmvschool_menu'
+ CurrentActionMsg = _U('press_open_menu')
+ CurrentActionData = {}
- end
+ end
end)
AddEventHandler('esx_dmvschool:hasExitedMarker', function(zone)
- CurrentAction = nil
- ESX.UI.Menu.CloseAll()
+ CurrentAction = nil
+ ESX.UI.Menu.CloseAll()
end)
RegisterNetEvent('esx_dmvschool:loadLicenses')
AddEventHandler('esx_dmvschool:loadLicenses', function(licenses)
- Licenses = licenses
+ Licenses = licenses
end)
-- Create Blips
Citizen.CreateThread(function()
- local blip = AddBlipForCoord(Config.Zones.DMVSchool.Pos.x, Config.Zones.DMVSchool.Pos.y, Config.Zones.DMVSchool.Pos.z)
+ local blip = AddBlipForCoord(Config.Zones.DMVSchool.Pos.x, Config.Zones.DMVSchool.Pos.y, Config.Zones.DMVSchool.Pos.z)
- SetBlipSprite (blip, 408)
- SetBlipDisplay(blip, 4)
- SetBlipScale (blip, 1.2)
- SetBlipAsShortRange(blip, true)
+ SetBlipSprite (blip, 408)
+ SetBlipDisplay(blip, 4)
+ SetBlipScale (blip, 1.2)
+ SetBlipAsShortRange(blip, true)
- BeginTextCommandSetBlipName("STRING")
- AddTextComponentString("Auto-école")
- EndTextCommandSetBlipName(blip)
+ BeginTextCommandSetBlipName("STRING")
+ AddTextComponentString(_U('driving_school_blip'))
+ EndTextCommandSetBlipName(blip)
end)
-- Display markers
Citizen.CreateThread(function()
- while true do
+ while true do
- Citizen.Wait(0)
+ Citizen.Wait(0)
- local coords = GetEntityCoords(GetPlayerPed(-1))
+ local coords = GetEntityCoords(GetPlayerPed(-1))
- for k,v in pairs(Config.Zones) do
- if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then
- DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false)
- end
- end
+ for k,v in pairs(Config.Zones) do
+ if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then
+ DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false)
+ end
+ end
- end
+ end
end)
-- Enter / Exit marker events
Citizen.CreateThread(function()
- while true do
+ while true do
- Citizen.Wait(0)
+ Citizen.Wait(0)
- local coords = GetEntityCoords(GetPlayerPed(-1))
- local isInMarker = false
- local currentZone = nil
+ local coords = GetEntityCoords(GetPlayerPed(-1))
+ local isInMarker = false
+ local currentZone = nil
- for k,v in pairs(Config.Zones) do
- if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then
- isInMarker = true
- currentZone = k
- end
- end
+ for k,v in pairs(Config.Zones) do
+ if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then
+ isInMarker = true
+ currentZone = k
+ end
+ end
- if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then
- HasAlreadyEnteredMarker = true
- LastZone = currentZone
- TriggerEvent('esx_dmvschool:hasEnteredMarker', currentZone)
- end
+ if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then
+ HasAlreadyEnteredMarker = true
+ LastZone = currentZone
+ TriggerEvent('esx_dmvschool:hasEnteredMarker', currentZone)
+ end
- if not isInMarker and HasAlreadyEnteredMarker then
- HasAlreadyEnteredMarker = false
- TriggerEvent('esx_dmvschool:hasExitedMarker', LastZone)
- end
+ if not isInMarker and HasAlreadyEnteredMarker then
+ HasAlreadyEnteredMarker = false
+ TriggerEvent('esx_dmvschool:hasExitedMarker', LastZone)
+ end
- end
+ end
end)
-- Block UI
@@ -300,7 +298,7 @@ Citizen.CreateThread(function()
DisablePlayerFiring(playerPed, true) -- Disable weapon firing
DisableControlAction(0, 142, true) -- MeleeAttackAlternate
DisableControlAction(0, 106, true) -- VehicleMouseControlOverride
-
+
end
end
@@ -308,147 +306,144 @@ end)
-- Key Controls
Citizen.CreateThread(function()
- while true do
+ while true do
- Citizen.Wait(0)
+ Citizen.Wait(0)
- if CurrentAction ~= nil then
+ if CurrentAction ~= nil then
- SetTextComponentFormat('STRING')
- AddTextComponentString(CurrentActionMsg)
- DisplayHelpTextFromStringLabel(0, 0, 1, -1)
+ SetTextComponentFormat('STRING')
+ AddTextComponentString(CurrentActionMsg)
+ DisplayHelpTextFromStringLabel(0, 0, 1, -1)
- if IsControlJustReleased(0, Keys['E']) then
+ if IsControlJustReleased(0, Keys['E']) then
- if CurrentAction == 'dmvschool_menu' then
- OpenDMVSchoolMenu()
- end
+ if CurrentAction == 'dmvschool_menu' then
+ OpenDMVSchoolMenu()
+ end
- CurrentAction = nil
+ CurrentAction = nil
- end
+ end
- end
+ end
- end
+ end
end)
-- Drive test
Citizen.CreateThread(function()
- while true do
+ while true do
- Citizen.Wait(0)
+ Citizen.Wait(0)
- if CurrentTest == 'drive' then
+ if CurrentTest == 'drive' then
- local playerPed = GetPlayerPed(-1)
- local coords = GetEntityCoords(playerPed)
- local nextCheckPoint = CurrentCheckPoint + 1
+ local playerPed = GetPlayerPed(-1)
+ local coords = GetEntityCoords(playerPed)
+ local nextCheckPoint = CurrentCheckPoint + 1
- if Config.CheckPoints[nextCheckPoint] == nil then
-
- if DoesBlipExist(CurrentBlip) then
- RemoveBlip(CurrentBlip)
- end
+ if Config.CheckPoints[nextCheckPoint] == nil then
+ if DoesBlipExist(CurrentBlip) then
+ RemoveBlip(CurrentBlip)
+ end
- CurrentTest = nil
+ CurrentTest = nil
- ESX.ShowNotification('Test de conduite terminé')
+ ESX.ShowNotification(_U('driving_test_complete'))
- if DriveErrors < Config.MaxErrors then
- StopDriveTest(true)
- else
- StopDriveTest(false)
- end
-
- else
+ if DriveErrors < Config.MaxErrors then
+ StopDriveTest(true)
+ else
+ StopDriveTest(false)
+ end
+ else
- if CurrentCheckPoint ~= LastCheckPoint then
+ if CurrentCheckPoint ~= LastCheckPoint then
- if DoesBlipExist(CurrentBlip) then
- RemoveBlip(CurrentBlip)
- end
+ if DoesBlipExist(CurrentBlip) then
+ RemoveBlip(CurrentBlip)
+ end
- CurrentBlip = AddBlipForCoord(Config.CheckPoints[nextCheckPoint].Pos.x, Config.CheckPoints[nextCheckPoint].Pos.y, Config.CheckPoints[nextCheckPoint].Pos.z)
- SetBlipRoute(CurrentBlip, 1)
+ CurrentBlip = AddBlipForCoord(Config.CheckPoints[nextCheckPoint].Pos.x, Config.CheckPoints[nextCheckPoint].Pos.y, Config.CheckPoints[nextCheckPoint].Pos.z)
+ SetBlipRoute(CurrentBlip, 1)
- LastCheckPoint = CurrentCheckPoint
+ LastCheckPoint = CurrentCheckPoint
- end
+ end
- local distance = GetDistanceBetweenCoords(coords, Config.CheckPoints[nextCheckPoint].Pos.x, Config.CheckPoints[nextCheckPoint].Pos.y, Config.CheckPoints[nextCheckPoint].Pos.z, true)
+ local distance = GetDistanceBetweenCoords(coords, Config.CheckPoints[nextCheckPoint].Pos.x, Config.CheckPoints[nextCheckPoint].Pos.y, Config.CheckPoints[nextCheckPoint].Pos.z, true)
- if distance <= 100.0 then
- DrawMarker(1, Config.CheckPoints[nextCheckPoint].Pos.x, Config.CheckPoints[nextCheckPoint].Pos.y, Config.CheckPoints[nextCheckPoint].Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 1.5, 1.5, 1.5, 102, 204, 102, 100, false, true, 2, false, false, false, false)
- end
+ if distance <= 100.0 then
+ DrawMarker(1, Config.CheckPoints[nextCheckPoint].Pos.x, Config.CheckPoints[nextCheckPoint].Pos.y, Config.CheckPoints[nextCheckPoint].Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 1.5, 1.5, 1.5, 102, 204, 102, 100, false, true, 2, false, false, false, false)
+ end
- if distance <= 3.0 then
- Config.CheckPoints[nextCheckPoint].Action(playerPed, CurrentVehicle, SetCurrentZoneType)
- CurrentCheckPoint = CurrentCheckPoint + 1
- end
+ if distance <= 3.0 then
+ Config.CheckPoints[nextCheckPoint].Action(playerPed, CurrentVehicle, SetCurrentZoneType)
+ CurrentCheckPoint = CurrentCheckPoint + 1
+ end
- end
+ end
- end
+ end
- end
+ end
end)
-- Speed / Damage control
Citizen.CreateThread(function()
- while true do
+ while true do
- Citizen.Wait(0)
+ Citizen.Wait(0)
- if CurrentTest == 'drive' then
+ if CurrentTest == 'drive' then
- local playerPed = GetPlayerPed(-1)
+ local playerPed = GetPlayerPed(-1)
- if IsPedInAnyVehicle(playerPed, false) then
+ if IsPedInAnyVehicle(playerPed, false) then
- local vehicle = GetVehiclePedIsIn(playerPed, false)
- local speed = GetEntitySpeed(vehicle) * Config.SpeedMultiplier
- local tooMuchSpeed = false
+ local vehicle = GetVehiclePedIsIn(playerPed, false)
+ local speed = GetEntitySpeed(vehicle) * Config.SpeedMultiplier
+ local tooMuchSpeed = false
- for k,v in pairs(Config.SpeedLimits) do
- if CurrentZoneType == k and speed > v then
+ for k,v in pairs(Config.SpeedLimits) do
+ if CurrentZoneType == k and speed > v then
- tooMuchSpeed = true
+ tooMuchSpeed = true
- if not IsAboveSpeedLimit then
+ if not IsAboveSpeedLimit then
- DriveErrors = DriveErrors + 1
- IsAboveSpeedLimit = true
+ DriveErrors = DriveErrors + 1
+ IsAboveSpeedLimit = true
- ESX.ShowNotification('Vous roulez trop vite, vitesse limite : ~y~' .. v .. 'km/h')
- ESX.ShowNotification('Erreurs : ~r~' .. DriveErrors .. '~s~/' .. Config.MaxErrors)
+ ESX.ShowNotification(_U('driving_too_fast') .. v .. 'km/h')
+ ESX.ShowNotification(_U('errors') .. DriveErrors .. '~s~/' .. Config.MaxErrors)
- end
+ end
- end
- end
+ end
+ end
- if not tooMuchSpeed then
- IsAboveSpeedLimit = false
- end
+ if not tooMuchSpeed then
+ IsAboveSpeedLimit = false
+ end
- local health = GetEntityHealth(vehicle)
+ local health = GetEntityHealth(vehicle)
- if health < LastVehicleHealth then
+ if health < LastVehicleHealth then
- DriveErrors = DriveErrors + 1
+ DriveErrors = DriveErrors + 1
- ESX.ShowNotification('Vous avez endommagé votre véhicule')
- ESX.ShowNotification('Erreurs : ~r~' .. DriveErrors .. '~s~/' .. Config.MaxErrors)
-
- LastVehicleHealth = health
+ ESX.ShowNotification(_U('you_damaged_veh'))
+ ESX.ShowNotification(_U('errors') .. DriveErrors .. '~s~/' .. Config.MaxErrors)
+ LastVehicleHealth = health
- end
+ end
- end
+ end
- end
+ end
- end
+ end
-end)
\ No newline at end of file
+end)
diff --git a/config.lua b/config.lua
index 7e864ca6..aa8eed1a 100644
--- a/config.lua
+++ b/config.lua
@@ -2,186 +2,187 @@ Config = {}
Config.DrawDistance = 100.0
Config.MaxErrors = 5
Config.SpeedMultiplier = 3.6
+Config.Locale = 'fr'
Config.Prices = {
- dmv = 200,
- drive = 500,
- drive_bike = 500,
- drive_truck = 500
+ dmv = 200,
+ drive = 500,
+ drive_bike = 500,
+ drive_truck = 500
}
Config.VehicleModels = {
- drive = 'blista',
- drive_bike = 'sanchez',
- drive_truck = 'mule3'
+ drive = 'blista',
+ drive_bike = 'sanchez',
+ drive_truck = 'mule3'
}
Config.SpeedLimits = {
- residence = 50,
- town = 80,
- freeway = 120
+ residence = 50,
+ town = 80,
+ freeway = 120
}
Config.Zones = {
- DMVSchool = {
- Pos = {x = 239.471, y = -1380.960, z = 32.741},
- Size = {x = 1.5, y = 1.5, z = 1.0},
- Color = {r = 204, g = 204, b = 0},
- Type = 1
- },
+ DMVSchool = {
+ Pos = {x = 239.471, y = -1380.960, z = 32.741},
+ Size = {x = 1.5, y = 1.5, z = 1.0},
+ Color = {r = 204, g = 204, b = 0},
+ Type = 1
+ },
- VehicleSpawnPoint = {
- Pos = {x = 249.409, y = -1407.230, z = 30.4094},
- Size = {x = 1.5, y = 1.5, z = 1.0},
- Color = {r = 204, g = 204, b = 0},
- Type = -1
- },
+ VehicleSpawnPoint = {
+ Pos = {x = 249.409, y = -1407.230, z = 30.4094},
+ Size = {x = 1.5, y = 1.5, z = 1.0},
+ Color = {r = 204, g = 204, b = 0},
+ Type = -1
+ },
}
Config.CheckPoints = {
- {
- Pos = {x = 255.139, y = -1400.731, z = 29.537},
- Action = function(playerPed, vehicle, setCurrentZoneType)
- DrawMissionText('Allez vers le prochain passage ! Vitesse limite : ~y~' .. Config.SpeedLimits['residence'] .. 'km/h', 5000)
- end
- },
-
- {
- Pos = {x = 271.874, y = -1370.574, z = 30.932},
- Action = function(playerPed, vehicle, setCurrentZoneType)
- DrawMissionText('Allez vers le prochain passage !', 5000)
- end
- },
+ {
+ Pos = {x = 255.139, y = -1400.731, z = 29.537},
+ Action = function(playerPed, vehicle, setCurrentZoneType)
+ DrawMissionText(_U('next_point_speed') .. Config.SpeedLimits['residence'] .. 'km/h', 5000)
+ end
+ },
{
- Pos = {x = 234.907, y = -1345.385, z = 29.542},
- Action = function(playerPed, vehicle, setCurrentZoneType)
- Citizen.CreateThread(function()
- DrawMissionText('Faite rapidement un ~r~stop~s~ pour le piéton qui ~y~traverse', 5000)
- PlaySound(-1, 'RACE_PLACED', 'HUD_AWARDS', 0, 0, 1)
- FreezeEntityPosition(vehicle, true)
- Citizen.Wait(4000)
- FreezeEntityPosition(vehicle, false)
- DrawMissionText('~g~Bien!~s~ continuons!', 5000)
-
- end)
- end
- },
+ Pos = {x = 271.874, y = -1370.574, z = 30.932},
+ Action = function(playerPed, vehicle, setCurrentZoneType)
+ DrawMissionText(_U('go_next_point'), 5000)
+ end
+ },
{
- Pos = {x = 217.821, y = -1410.520, z = 28.292},
- Action = function(playerPed, vehicle, setCurrentZoneType)
+ Pos = {x = 234.907, y = -1345.385, z = 29.542},
+ Action = function(playerPed, vehicle, setCurrentZoneType)
+ Citizen.CreateThread(function()
+ DrawMissionText(_U('stop_for_ped'), 5000)
+ PlaySound(-1, 'RACE_PLACED', 'HUD_AWARDS', 0, 0, 1)
+ FreezeEntityPosition(vehicle, true)
+ Citizen.Wait(4000)
+ FreezeEntityPosition(vehicle, false)
+ DrawMissionText(_U('good_lets_cont'), 5000)
- setCurrentZoneType('town')
-
- Citizen.CreateThread(function()
- DrawMissionText('Marquer rapidement un ~r~stop~s~ et regardez à votre ~y~gauche~s~. Vitesse limite : ~y~' .. Config.SpeedLimits['town'] .. 'km/h', 5000)
- PlaySound(-1, 'RACE_PLACED', 'HUD_AWARDS', 0, 0, 1)
- FreezeEntityPosition(vehicle, true)
- Citizen.Wait(6000)
- FreezeEntityPosition(vehicle, false)
- DrawMissionText('~g~bien!~s~ prenez à ~y~droite~s~ et suivez votre file', 5000)
- end)
- end
- },
+ end)
+ end
+ },
{
- Pos = {x = 178.550, y = -1401.755, z = 27.725},
- Action = function(playerPed, vehicle, setCurrentZoneType)
- DrawMissionText('Observez le traffic ~y~allumez vos feux~s~ !', 5000)
- end
- },
+ Pos = {x = 217.821, y = -1410.520, z = 28.292},
+ Action = function(playerPed, vehicle, setCurrentZoneType)
+
+ setCurrentZoneType('town')
+
+ Citizen.CreateThread(function()
+ DrawMissionText(_U('stop_look_left') .. Config.SpeedLimits['town'] .. 'km/h', 5000)
+ PlaySound(-1, 'RACE_PLACED', 'HUD_AWARDS', 0, 0, 1)
+ FreezeEntityPosition(vehicle, true)
+ Citizen.Wait(6000)
+ FreezeEntityPosition(vehicle, false)
+ DrawMissionText(_U('good_turn_right'), 5000)
+ end)
+ end
+ },
{
- Pos = {x = 113.160, y = -1365.276, z = 27.725},
- Action = function(playerPed, vehicle, setCurrentZoneType)
- DrawMissionText('Allez vers le prochain passage !', 5000)
- end
- },
+ Pos = {x = 178.550, y = -1401.755, z = 27.725},
+ Action = function(playerPed, vehicle, setCurrentZoneType)
+ DrawMissionText(_U('watch_traffic_lightson'), 5000)
+ end
+ },
{
- Pos = {x = -73.542, y = -1364.335, z = 27.789},
- Action = function(playerPed, vehicle, setCurrentZoneType)
- DrawMissionText('Marquez le stop pour laisser passer les véhicules !', 5000)
- PlaySound(-1, 'RACE_PLACED', 'HUD_AWARDS', 0, 0, 1)
- FreezeEntityPosition(vehicle, true)
- Citizen.Wait(6000)
- FreezeEntityPosition(vehicle, false)
- end
- },
+ Pos = {x = 113.160, y = -1365.276, z = 27.725},
+ Action = function(playerPed, vehicle, setCurrentZoneType)
+ DrawMissionText(_U('go_next_point'), 5000)
+ end
+ },
{
- Pos = {x = -355.143, y = -1420.282, z = 27.868},
- Action = function(playerPed, vehicle, setCurrentZoneType)
- DrawMissionText('Allez vers le prochain passage !', 5000)
- end
- },
+ Pos = {x = -73.542, y = -1364.335, z = 27.789},
+ Action = function(playerPed, vehicle, setCurrentZoneType)
+ DrawMissionText(_U('stop_for_passing'), 5000)
+ PlaySound(-1, 'RACE_PLACED', 'HUD_AWARDS', 0, 0, 1)
+ FreezeEntityPosition(vehicle, true)
+ Citizen.Wait(6000)
+ FreezeEntityPosition(vehicle, false)
+ end
+ },
{
- Pos = {x = -439.148, y = -1417.100, z = 27.704},
- Action = function(playerPed, vehicle, setCurrentZoneType)
- DrawMissionText('Allez vers le prochain passage !', 5000)
- end
- },
+ Pos = {x = -355.143, y = -1420.282, z = 27.868},
+ Action = function(playerPed, vehicle, setCurrentZoneType)
+ DrawMissionText(_U('go_next_point'), 5000)
+ end
+ },
{
- Pos = {x = -453.790, y = -1444.726, z = 27.665},
- Action = function(playerPed, vehicle, setCurrentZoneType)
-
- setCurrentZoneType('freeway')
-
- DrawMissionText('Il est temps d\'aller sur la rocade ! Vitesse limite : ~y~' .. Config.SpeedLimits['freeway'] .. 'km/h', 5000)
- PlaySound(-1, 'RACE_PLACED', 'HUD_AWARDS', 0, 0, 1)
- end
- },
+ Pos = {x = -439.148, y = -1417.100, z = 27.704},
+ Action = function(playerPed, vehicle, setCurrentZoneType)
+ DrawMissionText(_U('go_next_point'), 5000)
+ end
+ },
{
- Pos = {x = -463.237, y = -1592.178, z = 37.519},
- Action = function(playerPed, vehicle, setCurrentZoneType)
- DrawMissionText('Allez vers le prochain passage !', 5000)
- end
- },
+ Pos = {x = -453.790, y = -1444.726, z = 27.665},
+ Action = function(playerPed, vehicle, setCurrentZoneType)
+
+ setCurrentZoneType('freeway')
+
+ DrawMissionText(_U('hway_time') .. Config.SpeedLimits['freeway'] .. 'km/h', 5000)
+ PlaySound(-1, 'RACE_PLACED', 'HUD_AWARDS', 0, 0, 1)
+ end
+ },
{
- Pos = {x = -900.647, y = -1986.28, z = 26.109},
- Action = function(playerPed, vehicle, setCurrentZoneType)
- DrawMissionText('Allez vers le prochain passage !', 5000)
- end
- },
+ Pos = {x = -463.237, y = -1592.178, z = 37.519},
+ Action = function(playerPed, vehicle, setCurrentZoneType)
+ DrawMissionText(_U('go_next_point'), 5000)
+ end
+ },
{
- Pos = {x = 1225.759, y = -1948.792, z = 38.718},
- Action = function(playerPed, vehicle, setCurrentZoneType)
- DrawMissionText('Allez vers le prochain passage !', 5000)
- end
- },
+ Pos = {x = -900.647, y = -1986.28, z = 26.109},
+ Action = function(playerPed, vehicle, setCurrentZoneType)
+ DrawMissionText(_U('go_next_point'), 5000)
+ end
+ },
{
- Pos = {x = 1225.759, y = -1948.792, z = 38.718},
- Action = function(playerPed, vehicle, setCurrentZoneType)
-
- setCurrentZoneType('town')
-
- DrawMissionText('Entrée en ville, attention à votre vitesse ! Vitesse limite : ~y~' .. Config.SpeedLimits['town'] .. 'km/h', 5000)
- end
- },
+ Pos = {x = 1225.759, y = -1948.792, z = 38.718},
+ Action = function(playerPed, vehicle, setCurrentZoneType)
+ DrawMissionText(_U('go_next_point'), 5000)
+ end
+ },
{
- Pos = {x = 1163.603, y = -1841.771, z = 35.679},
- Action = function(playerPed, vehicle, setCurrentZoneType)
- DrawMissionText('Bravo, restez vigilant!', 5000)
- PlaySound(-1, 'RACE_PLACED', 'HUD_AWARDS', 0, 0, 1)
- end
- },
+ Pos = {x = 1225.759, y = -1948.792, z = 38.718},
+ Action = function(playerPed, vehicle, setCurrentZoneType)
+
+ setCurrentZoneType('town')
+
+ DrawMissionText(_U('in_town_speed') .. Config.SpeedLimits['town'] .. 'km/h', 5000)
+ end
+ },
{
- Pos = {x = 235.283, y = -1398.329, z = 28.921},
- Action = function(playerPed, vehicle, setCurrentZoneType)
- ESX.Game.DeleteVehicle(vehicle)
- end
- },
-
-}
\ No newline at end of file
+ Pos = {x = 1163.603, y = -1841.771, z = 35.679},
+ Action = function(playerPed, vehicle, setCurrentZoneType)
+ DrawMissionText(_U('gratz_stay_alert'), 5000)
+ PlaySound(-1, 'RACE_PLACED', 'HUD_AWARDS', 0, 0, 1)
+ end
+ },
+
+ {
+ Pos = {x = 235.283, y = -1398.329, z = 28.921},
+ Action = function(playerPed, vehicle, setCurrentZoneType)
+ ESX.Game.DeleteVehicle(vehicle)
+ end
+ },
+
+}
diff --git a/html/questions_en.js b/html/questions_en.js
new file mode 100644
index 00000000..01e95a07
--- /dev/null
+++ b/html/questions_en.js
@@ -0,0 +1,71 @@
+var tableauQuestion = [
+ { question : "If you're going 65 mph, and you're approaching a residential area you must:",
+ propositionA : "You accelerate",
+ propositionB : "You keep your speed, if you do not pass other vehicles",
+ propositionC : "You slow down",
+ propositionD : "You keep your speed",
+ reponse : "C"},
+
+ { question : "If you're turning right at a traffic light, but see a pedestrian crossing what do you do:",
+ propositionA : "You pass the pedestrian",
+ propositionB : "You check that there is no other vehicles around",
+ propositionC : "You wait until the pedestrian has crossed",
+ propositionD : "You shoot the pedestrian and continue to drive",
+ reponse : "C"},
+
+ { question : "Without any prior indication, the speed in a residential area is: __ mph",
+ propositionA : "30",
+ propositionB : "35",
+ propositionC : "40",
+ propositionD : "45",
+ reponse : "A"},
+
+ { question : "Before every lane change you must:",
+ propositionA : "Check your mirrors",
+ propositionB : "Check your blind spots",
+ propositionC : "Signal your intentions",
+ propositionD : "All of the above",
+ reponse : "D"},
+
+ { question : "What blood alcohol level is classified as driving while intoxicated?",
+ propositionA : "0.05%",
+ propositionB : "0.18%",
+ propositionC : "0.08%",
+ propositionD : "0.06%",
+ reponse : "C"},
+
+ { question : "When can you continue to drive at a traffic light?",
+ propositionA : "When it is green",
+ propositionB : "When there is nobody in the intersection",
+ propositionC : "You are in a school zone",
+ propositionD : "When it is green and / or red and you're turning right",
+ reponse : "D"},
+
+ { question : "A pedestrian has a do not cross signal, what do you do?",
+ propositionA : "You let them pass",
+ propositionB : "You observe before continuing",
+ propositionC : "You wave to tell them to cross",
+ propositionD : "You continue because your traffic light is green",
+ reponse : "D"},
+
+ { question : "What is allowed when passing another vehicle",
+ propositionA : "You follow it closely to pass it faster",
+ propositionB : "You pass it without leaving the roadway",
+ propositionC : "You drive on the opposite side of the road to pass",
+ propositionD : "You exceed the speed limit to pass them",
+ reponse : "C"},
+
+ { question : "You are driving on a highway which indicates a maximum speed of 70 mph. Most traffic drives at 75 mph, so you should not drive faster than:",
+ propositionA : "50 mph",
+ propositionB : "25 mph",
+ propositionC : "30 mph",
+ propositionD : "70 mph",
+ reponse : "D"},
+
+ { question : "When you are overtaken by another vehicle it is important NOT to:",
+ propositionA : "Slow Down",
+ propositionB : "Check your mirrors",
+ propositionC : "Watch other drivers",
+ propositionD : "Increase your speed",
+ reponse : "D"},
+]
diff --git a/html/scripts.js b/html/scripts.js
index 6494266f..234a2a4a 100644
--- a/html/scripts.js
+++ b/html/scripts.js
@@ -52,7 +52,7 @@ function closeAll() {
function openQuestionnaire() {
$(".questionnaire-container").css("display", "block");
var randomQuestion = getRandomQuestion();
- $("#questionNumero").html("Question : " + questionNumber);
+ $("#questionNumero").html("Question: " + questionNumber);
$("#question").html(tableauQuestion[randomQuestion].question);
$(".answerA").html(tableauQuestion[randomQuestion].propositionA);
$(".answerB").html(tableauQuestion[randomQuestion].propositionB);
diff --git a/html/ui_en.html b/html/ui_en.html
new file mode 100644
index 00000000..e0844ab4
--- /dev/null
+++ b/html/ui_en.html
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
Driving School
+
+
+
+
+
+
Welcome to Driving School
+
All citizens of Los Santos must pass their exam before they can drive. Take your time, answer with common sense, and do not answer randomly.
+ Theory Test
+ - The Theory Test costs $200, this is not refunded if you fail the test.
+ - Don't be afraid, the driving school accepts credit, but be careful not to get into debt.
+ - If you fail your test the first time, you can't retake it immediately, you'll have to take it at a later date.
+ Driving Test
+ - The Driving Test costs $500, just like the theory test, this payment will not be refunded if you fail.
+ - Make sure you stay alert whilst driving, and avoid accidents!