From 4c7e767a1dc8c4de3a41f38717eaea00e8ce24ba Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Thu, 21 Sep 2017 12:23:36 -0400 Subject: [PATCH] update(feat): Multi-Language Support chore(coding-style): Fix Indentation --- .editorconfig | 9 + __resource.lua | 33 ++- client/main.lua | 441 +++++++++++++++--------------- config.lua | 273 +++++++++--------- html/questions_en.js | 71 +++++ html/scripts.js | 2 +- html/ui_en.html | 98 +++++++ locales/en.lua | 29 ++ locales/fr.lua | 29 ++ localization/en_esx_dmvschool.sql | 8 + server/main.lua | 26 +- 11 files changed, 633 insertions(+), 386 deletions(-) create mode 100644 .editorconfig create mode 100644 html/questions_en.js create mode 100644 html/ui_en.html create mode 100644 locales/en.lua create mode 100644 locales/fr.lua create mode 100644 localization/en_esx_dmvschool.sql 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!

+
+
+ Start +
+
+

Progress

+ +
+
+ +
+
+

+

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+

Progress

+ +
+
+ +
+
+

Good work!



You did well during the examination.

You can close this window, and go take your road test(s).
+
+
+ Close +
+
+

Progress

+ +
+
+
+
+

You failed



You weren't ready for this test, try again later...

+
+
+ Close +
+
+

Progress

+ +
+
+
+
+ + + + + + + diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..646f8839 --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,29 @@ +Locales['en'] = { + + ['you_paid'] = 'you paid ~g~$', + ['go_next_point'] = 'go to the next point!', + ['in_town_speed'] = 'entered town, pay attention to your speed! Speed Limit: ~y~', + ['next_point_speed'] = 'go to the next point! Speed Limit: ~y~', + ['stop_for_ped'] = '~r~Stop~s~ for the pedestrian ~y~crossing', + ['good_lets_cont'] = '~g~Good~s~, continue.', + ['stop_look_left'] = '~r~Stop~s~ and look ~y~left~s~. Speed Limit:~y~ ', + ['good_turn_right'] = '~g~Good~s~, turn right and follow the line', + ['watch_traffic_lightson'] = 'watch traffic, and ~y~turn on your lights~s~!', + ['stop_for_passing'] = '~r~Stop~s~ for passing vehicles!', + ['hway_time'] = 'it\'s time to drive on the highway! Speed Limit:~y~ ', + ['gratz_stay_alert'] = 'congrats, stay ~r~alert~s~ whilst driving!', + ['passed_test'] = 'you ~g~passed~s~ the test', + ['failed_test'] = 'you ~r~failed~s~ the test', + ['theory_test'] = 'theoretical Driving Test $', + ['road_test_car'] = 'driving Test $', + ['road_test_bike'] = 'motorcycle Skills Test $', + ['road_test_truck'] = 'cDL Skills Test $', + ['driving_school'] = 'driving School', + ['press_open_menu'] = 'press ~INPUT_CONTEXT~ to open the menu', + ['driving_school_blip'] = 'driving School', + ['driving_test_complete'] = 'driving test completed', + ['driving_too_fast'] = '~r~You\'re driving too fast!~s~ Speed Limit:~y~ ', + ['errors'] = 'errors: ~r~', + ['you_damaged_veh'] = 'you damaged the vehicle', + +} diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..c0d75435 --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,29 @@ +Locales['fr'] = { + + ['you_paid'] = 'vous avez payé ~g~$', + ['go_next_point'] = 'allez vers le prochain passage !', + ['in_town_speed'] = 'entrée en ville, attention à votre vitesse ! Vitesse limite : ~y~', + ['next_point_speed'] = 'allez vers le prochain passage ! Vitesse limite : ~y~', + ['stop_for_ped'] = 'faite rapidement un ~r~stop~s~ pour le piéton qui ~y~traverse', + ['good_lets_cont'] = '~g~Bien!~s~ continuons!', + ['stop_look_left'] = 'marquer rapidement un ~r~stop~s~ et regardez à votre ~y~gauche~s~. Vitesse limite : ~y~', + ['good_turn_right'] = '~g~Bien!~s~ prenez à ~y~droite~s~ et suivez votre file', + ['watch_traffic_lightson'] = 'observez le traffic ~y~allumez vos feux~s~ !', + ['stop_for_passing'] = 'marquez le stop pour laisser passer les véhicules !', + ['hway_time'] = 'il est temps d\'aller sur la rocade ! Vitesse limite : ~y~', + ['gratz_stay_alert'] = 'bravo, restez vigiliant!', + ['passed_test'] = 'vous avez ~g~réussi~s~ le test', + ['failed_test'] = 'vous avez ~r~raté~s~ le test', + ['theory_test'] = 'examen du code $', + ['road_test_car'] = 'examen de conduite [voiture] $', + ['road_test_bike'] = 'examen de conduite [moto] $', + ['road_test_truck'] = 'examen de conduite [camion] $', + ['driving_school'] = 'ecole de conduite', + ['press_open_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour ouvrir le menu', + ['driving_school_blip'] = 'auto-école', + ['driving_test_complete'] = 'test de conduite terminé', + ['driving_too_fast'] = 'vous roulez trop vite, vitesse limite : ~y~', + ['errors'] = 'erreurs : ~r~', + ['you_damaged_veh'] = 'vous avez endommagé votre véhicule', + +} diff --git a/localization/en_esx_dmvschool.sql b/localization/en_esx_dmvschool.sql new file mode 100644 index 00000000..db2034e9 --- /dev/null +++ b/localization/en_esx_dmvschool.sql @@ -0,0 +1,8 @@ +USE `essentialmode`; + +INSERT INTO `licenses` (`type`, `label`) VALUES + ('dmv', 'Driving Permit'), + ('drive', 'Drivers License'), + ('drive_bike', 'Motorcycle License'), + ('drive_truck', 'Commercial Drivers License') +; diff --git a/server/main.lua b/server/main.lua index d81d4daa..2906c7d7 100644 --- a/server/main.lua +++ b/server/main.lua @@ -3,32 +3,32 @@ ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) AddEventHandler('esx:playerLoaded', function(source) - TriggerEvent('esx_license:getLicenses', source, function(licenses) - TriggerClientEvent('esx_dmvschool:loadLicenses', source, licenses) - end) + TriggerEvent('esx_license:getLicenses', source, function(licenses) + TriggerClientEvent('esx_dmvschool:loadLicenses', source, licenses) + end) end) RegisterNetEvent('esx_dmvschool:addLicense') AddEventHandler('esx_dmvschool:addLicense', function(type) - local _source = source + local _source = source - TriggerEvent('esx_license:addLicense', _source, type, function() - TriggerEvent('esx_license:getLicenses', _source, function(licenses) - TriggerClientEvent('esx_dmvschool:loadLicenses', _source, licenses) - end) - end) + TriggerEvent('esx_license:addLicense', _source, type, function() + TriggerEvent('esx_license:getLicenses', _source, function(licenses) + TriggerClientEvent('esx_dmvschool:loadLicenses', _source, licenses) + end) + end) end) RegisterNetEvent('esx_dmvschool:pay') AddEventHandler('esx_dmvschool:pay', function(price) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) - xPlayer.removeMoney(price) + xPlayer.removeMoney(price) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez payé ~g~$' .. price) + TriggerClientEvent('esx:showNotification', _source, _U('you_paid') .. price) end)