2445 lines
		
	
	
		
			No EOL
		
	
	
		
			141 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			2445 lines
		
	
	
		
			No EOL
		
	
	
		
			141 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| local CoreName = nil
 | |
| local nuiLoaded = false
 | |
| local vehicleEntity = nil
 | |
| local vehicleBlip = nil
 | |
| local vehicleCamera = nil
 | |
| local isCameraActive = false
 | |
| local RotSync = true
 | |
| local controllerProp = nil
 | |
| local firstAwayNotification = false
 | |
| local secondAwayNotification = false
 | |
| local threeAwayNotification = false
 | |
| local NoSignal = false
 | |
| local LowBattery = false
 | |
| local fakePlayerPed = nil
 | |
| local DataShow = false
 | |
| local ActivePlayer = {
 | |
|     type = nil,
 | |
|     ped = nil,
 | |
|     name = nil,
 | |
|     image = nil,
 | |
|     plate = nil,
 | |
|     birthDate = nil
 | |
| }
 | |
| local storeBlips = {}
 | |
| local chargingStationBlips = {}
 | |
| local storePed = {}
 | |
| local chargingStationPed = {}
 | |
| local storeProducts = {}
 | |
| local activeVehicle = {}
 | |
| local activePlugins = {}
 | |
| local PlayerData = nil
 | |
| local firstOpenCam = true
 | |
| local maxFov = 100.0
 | |
| local batteryProtector = false
 | |
| local signalBooster = 1.0
 | |
| local batteryLevel = 100
 | |
| local activePlugin = nil
 | |
| local usedChargingStation = nil
 | |
| local usedChargingStationItem = nil
 | |
| local lastCoordsPlayer = nil
 | |
| 
 | |
| Citizen.CreateThread(function()
 | |
|     if GetResourceState('qb-core') == 'started' and Config.Framework == 'qb-core' then
 | |
|         QBCore = exports['qb-core']:GetCoreObject()
 | |
|         PlayerData = QBCore.Functions.GetPlayerData()
 | |
|         CoreName = 'qb-core'
 | |
|     elseif GetResourceState('qbx_core') == 'started' and Config.Framework == 'qbx_core' then
 | |
|         QBX = exports['qbx_core']
 | |
|         PlayerData = QBX:GetPlayerData()
 | |
|         CoreName = 'qbx_core'
 | |
|     elseif GetResourceState('es_extended') == 'started' and Config.Framework == 'es_extended' then
 | |
|         ESX = exports['es_extended']:getSharedObject()
 | |
|         PlayerData = ESX.GetPlayerData()
 | |
|         CoreName = 'es_extended'
 | |
|     end
 | |
| end)
 | |
| 
 | |
| -- ███████╗██╗   ██╗███╗   ██╗ ██████╗████████╗██╗ ██████╗ ███╗   ██╗███████╗
 | |
| -- ██╔════╝██║   ██║████╗  ██║██╔════╝╚══██╔══╝██║██╔═══██╗████╗  ██║██╔════╝
 | |
| -- █████╗  ██║   ██║██╔██╗ ██║██║        ██║   ██║██║   ██║██╔██╗ ██║███████╗
 | |
| -- ██╔══╝  ██║   ██║██║╚██╗██║██║        ██║   ██║██║   ██║██║╚██╗██║╚════██║
 | |
| -- ██║     ╚██████╔╝██║ ╚████║╚██████╗   ██║   ██║╚██████╔╝██║ ╚████║███████║
 | |
| -- ╚═╝      ╚═════╝ ╚═╝  ╚═══╝ ╚═════╝   ╚═╝   ╚═╝ ╚═════╝ ╚═╝  ╚═══╝╚══════╝
 | |
| 
 | |
| --  ██████╗██╗  ██╗███████╗ ██████╗██╗  ██╗    ███╗   ██╗██╗   ██╗██╗
 | |
| -- ██╔════╝██║  ██║██╔════╝██╔════╝██║ ██╔╝    ████╗  ██║██║   ██║██║
 | |
| -- ██║     ███████║█████╗  ██║     █████╔╝     ██╔██╗ ██║██║   ██║██║
 | |
| -- ██║     ██╔══██║██╔══╝  ██║     ██╔═██╗     ██║╚██╗██║██║   ██║██║
 | |
| -- ╚██████╗██║  ██║███████╗╚██████╗██║  ██╗    ██║ ╚████║╚██████╔╝██║
 | |
| --  ╚═════╝╚═╝  ╚═╝╚══════╝ ╚═════╝╚═╝  ╚═╝    ╚═╝  ╚═══╝ ╚═════╝ ╚═╝
 | |
| 
 | |
| local function CheckNui()
 | |
|     while not nuiLoaded do
 | |
|         Citizen.Wait(100)
 | |
|     end
 | |
| end
 | |
| 
 | |
| -- ███╗   ██╗██╗   ██╗██╗    ███╗   ███╗███████╗███████╗███████╗ █████╗  ██████╗ ███████╗
 | |
| -- ████╗  ██║██║   ██║██║    ████╗ ████║██╔════╝██╔════╝██╔════╝██╔══██╗██╔════╝ ██╔════╝
 | |
| -- ██╔██╗ ██║██║   ██║██║    ██╔████╔██║█████╗  ███████╗███████╗███████║██║  ███╗█████╗  
 | |
| -- ██║╚██╗██║██║   ██║██║    ██║╚██╔╝██║██╔══╝  ╚════██║╚════██║██╔══██║██║   ██║██╔══╝  
 | |
| -- ██║ ╚████║╚██████╔╝██║    ██║ ╚═╝ ██║███████╗███████║███████║██║  ██║╚██████╔╝███████╗
 | |
| -- ╚═╝  ╚═══╝ ╚═════╝ ╚═╝    ╚═╝     ╚═╝╚══════╝╚══════╝╚══════╝╚═╝  ╚═╝ ╚═════╝ ╚══════╝
 | |
| 
 | |
| local function NuiMessage(action, payload)
 | |
|     CheckNui()
 | |
|     SendNUIMessage({
 | |
|         action = action,
 | |
|         payload = payload
 | |
|     })
 | |
| end
 | |
| 
 | |
| -- ██████╗ ██╗      █████╗ ██╗   ██╗     █████╗ ███╗   ██╗██╗███╗   ███╗ █████╗ ████████╗██╗ ██████╗ ███╗   ██╗
 | |
| -- ██╔══██╗██║     ██╔══██╗╚██╗ ██╔╝    ██╔══██╗████╗  ██║██║████╗ ████║██╔══██╗╚══██╔══╝██║██╔═══██╗████╗  ██║
 | |
| -- ██████╔╝██║     ███████║ ╚████╔╝     ███████║██╔██╗ ██║██║██╔████╔██║███████║   ██║   ██║██║   ██║██╔██╗ ██║
 | |
| -- ██╔═══╝ ██║     ██╔══██║  ╚██╔╝      ██╔══██║██║╚██╗██║██║██║╚██╔╝██║██╔══██║   ██║   ██║██║   ██║██║╚██╗██║
 | |
| -- ██║     ███████╗██║  ██║   ██║       ██║  ██║██║ ╚████║██║██║ ╚═╝ ██║██║  ██║   ██║   ██║╚██████╔╝██║ ╚████║
 | |
| -- ╚═╝     ╚══════╝╚═╝  ╚═╝   ╚═╝       ╚═╝  ╚═╝╚═╝  ╚═══╝╚═╝╚═╝     ╚═╝╚═╝  ╚═╝   ╚═╝   ╚═╝ ╚═════╝ ╚═╝  ╚═══╝
 | |
| 
 | |
| local function PlayAnimation(animationName)
 | |
|     local playerPed = PlayerPedId()
 | |
|     local playerCoords = GetEntityCoords(playerPed)
 | |
|     local playerHeading = GetEntityHeading(playerPed)
 | |
|     local animDict = Config.Animation[animationName].dict
 | |
|     local animName = Config.Animation[animationName].anim
 | |
| 
 | |
|     RequestAnimDict(animDict)
 | |
| 
 | |
|     while not HasAnimDictLoaded(animDict) do
 | |
|         Citizen.Wait(0)
 | |
|     end
 | |
| 
 | |
|     TaskPlayAnim(playerPed, animDict, animName, 33.0, 33.0, -1, 50, 0, false, false, false)
 | |
|     SetTimeout(700, function()
 | |
|         ClearPedTasks(playerPed)
 | |
|     end)
 | |
|     RemoveAnimDict(animDict)
 | |
| end
 | |
| 
 | |
| -- ██████╗ ██████╗  █████╗ ██╗    ██╗    ████████╗███████╗██╗  ██╗████████╗    ██████╗ ██████╗ 
 | |
| -- ██╔══██╗██╔══██╗██╔══██╗██║    ██║    ╚══██╔══╝██╔════╝╚██╗██╔╝╚══██╔══╝    ╚════██╗██╔══██╗
 | |
| -- ██║  ██║██████╔╝███████║██║ █╗ ██║       ██║   █████╗   ╚███╔╝    ██║        █████╔╝██║  ██║
 | |
| -- ██║  ██║██╔══██╗██╔══██║██║███╗██║       ██║   ██╔══╝   ██╔██╗    ██║        ╚═══██╗██║  ██║
 | |
| -- ██████╔╝██║  ██║██║  ██║╚███╔███╔╝       ██║   ███████╗██╔╝ ██╗   ██║       ██████╔╝██████╔╝
 | |
| -- ╚═════╝ ╚═╝  ╚═╝╚═╝  ╚═╝ ╚══╝╚══╝        ╚═╝   ╚══════╝╚═╝  ╚═╝   ╚═╝       ╚═════╝ ╚═════╝ 
 | |
| 
 | |
| local function DrawText3D(x, y, z, text)
 | |
|     local onScreen,_x,_y = GetScreenCoordFromWorldCoord(x, y, z)
 | |
|     local px,py,pz=table.unpack(GetFinalRenderedCamCoord())
 | |
|     SetTextScale(0.35, 0.35)
 | |
|     SetTextFont(4)
 | |
|     SetTextProportional(true)  
 | |
|     SetTextColour(255, 255, 255, 215)
 | |
|     BeginTextCommandDisplayText("STRING")
 | |
|     SetTextCentre(true)
 | |
|     AddTextComponentSubstringPlayerName(text)
 | |
|     EndTextCommandDisplayText(_x,_y)
 | |
|     local factor = (string.len(text)) / 370
 | |
|     DrawRect(_x,_y+0.0125, 0.015+ factor, 0.03, 0, 0, 0, 100)
 | |
| end
 | |
| 
 | |
| -- ██████╗ ██╗      █████╗ ██╗   ██╗     ██████╗ ██████╗ ███╗   ██╗████████╗██████╗  ██████╗ ██╗     ██╗     ███████╗██████╗      █████╗ ███╗   ██╗██╗███╗   ███╗
 | |
| -- ██╔══██╗██║     ██╔══██╗╚██╗ ██╔╝    ██╔════╝██╔═══██╗████╗  ██║╚══██╔══╝██╔══██╗██╔═══██╗██║     ██║     ██╔════╝██╔══██╗    ██╔══██╗████╗  ██║██║████╗ ████║
 | |
| -- ██████╔╝██║     ███████║ ╚████╔╝     ██║     ██║   ██║██╔██╗ ██║   ██║   ██████╔╝██║   ██║██║     ██║     █████╗  ██████╔╝    ███████║██╔██╗ ██║██║██╔████╔██║
 | |
| -- ██╔═══╝ ██║     ██╔══██║  ╚██╔╝      ██║     ██║   ██║██║╚██╗██║   ██║   ██╔══██╗██║   ██║██║     ██║     ██╔══╝  ██╔══██╗    ██╔══██║██║╚██╗██║██║██║╚██╔╝██║
 | |
| -- ██║     ███████╗██║  ██║   ██║       ╚██████╗╚██████╔╝██║ ╚████║   ██║   ██║  ██║╚██████╔╝███████╗███████╗███████╗██║  ██║    ██║  ██║██║ ╚████║██║██║ ╚═╝ ██║
 | |
| -- ╚═╝     ╚══════╝╚═╝  ╚═╝   ╚═╝        ╚═════╝ ╚═════╝ ╚═╝  ╚═══╝   ╚═╝   ╚═╝  ╚═╝ ╚═════╝ ╚══════╝╚══════╝╚══════╝╚═╝  ╚═╝    ╚═╝  ╚═╝╚═╝  ╚═══╝╚═╝╚═╝     ╚═╝
 | |
| 
 | |
| local function PlayControllerAnimation()
 | |
|     local playerCoords = GetEntityCoords(fakePlayerPed)
 | |
|     local playerHeading = GetEntityHeading(fakePlayerPed)
 | |
|     local animDict = Config.Animation['controller'].dict
 | |
|     local animName = Config.Animation['controller'].anim
 | |
|     local prop = Config.ControllerObject
 | |
| 
 | |
|     RequestAnimDict(animDict)
 | |
|     while not HasAnimDictLoaded(animDict) do
 | |
|         Citizen.Wait(0)
 | |
|     end
 | |
| 
 | |
|     RequestModel(prop)
 | |
|     while not HasModelLoaded(prop) do
 | |
|         Citizen.Wait(0)
 | |
|     end
 | |
| 
 | |
|     controllerProp = CreateObject(prop, playerCoords, true, true, false)
 | |
|     AttachEntityToEntity(controllerProp, fakePlayerPed, GetPedBoneIndex(fakePlayerPed, 18905), 0.15, 0.02, 0.09, -136.30, -54.8,
 | |
|         5.4, true, true, false, true, 1, true)
 | |
|     SetModelAsNoLongerNeeded(prop)
 | |
| 
 | |
|     TaskPlayAnim(fakePlayerPed, animDict, animName, 3.0, -8, -1, 63, 0, 0, 0, 0)
 | |
| 
 | |
|     Citizen.CreateThread(function()
 | |
|         while vehicleEntity and DoesEntityExist(vehicleEntity) and not NoSignal and not LowBattery and isCameraActive do
 | |
|             if not IsEntityPlayingAnim(fakePlayerPed, animDict, animName, 3) then
 | |
|                 TaskPlayAnim(fakePlayerPed, animDict, animName, 3.0, -8, -1, 63, 0, 0, 0, 0)
 | |
|             end
 | |
|             Citizen.Wait(1000)
 | |
|         end
 | |
|     end)
 | |
| 
 | |
|     Citizen.CreateThread(function()
 | |
|         while vehicleEntity and DoesEntityExist(vehicleEntity) and not NoSignal and not LowBattery and isCameraActive do
 | |
|             if RotSync then
 | |
|                 SetCamRot(vehicleCamera, GetEntityRotation(vehicleEntity))
 | |
|             else
 | |
|                 if IsDisabledControlPressed(0, Config.Controls.ResetCamera) then
 | |
|                     RotSync = true
 | |
|                 end
 | |
|             end
 | |
|             Citizen.Wait(5)
 | |
|         end
 | |
|     end)
 | |
| end
 | |
| 
 | |
| --  ██████╗██╗  ██╗ █████╗ ███╗   ██╗ ██████╗ ███████╗     ██████╗ █████╗ ███╗   ███╗    ██████╗  ██████╗ ████████╗ █████╗ ████████╗██╗ ██████╗ ███╗   ██╗
 | |
| -- ██╔════╝██║  ██║██╔══██╗████╗  ██║██╔════╝ ██╔════╝    ██╔════╝██╔══██╗████╗ ████║    ██╔══██╗██╔═══██╗╚══██╔══╝██╔══██╗╚══██╔══╝██║██╔═══██╗████╗  ██║
 | |
| -- ██║     ███████║███████║██╔██╗ ██║██║  ███╗█████╗      ██║     ███████║██╔████╔██║    ██████╔╝██║   ██║   ██║   ███████║   ██║   ██║██║   ██║██╔██╗ ██║
 | |
| -- ██║     ██╔══██║██╔══██║██║╚██╗██║██║   ██║██╔══╝      ██║     ██╔══██║██║╚██╔╝██║    ██╔══██╗██║   ██║   ██║   ██╔══██║   ██║   ██║██║   ██║██║╚██╗██║
 | |
| -- ╚██████╗██║  ██║██║  ██║██║ ╚████║╚██████╔╝███████╗    ╚██████╗██║  ██║██║ ╚═╝ ██║    ██║  ██║╚██████╔╝   ██║   ██║  ██║   ██║   ██║╚██████╔╝██║ ╚████║
 | |
| --  ╚═════╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═══╝ ╚═════╝ ╚══════╝     ╚═════╝╚═╝  ╚═╝╚═╝     ╚═╝    ╚═╝  ╚═╝ ╚═════╝    ╚═╝   ╚═╝  ╚═╝   ╚═╝   ╚═╝ ╚═════╝ ╚═╝  ╚═══╝
 | |
| 
 | |
| local function ChangeCamRotation()
 | |
|     Citizen.CreateThread(function()
 | |
|         while vehicleEntity and DoesEntityExist(vehicleEntity) and not NoSignal and not LowBattery and isCameraActive do
 | |
|             Citizen.Wait(25)
 | |
|             if IsDisabledControlPressed(0, Config.Controls.CameraRotations.up) then
 | |
|                 RotSync = false
 | |
|                 SetCamRot(vehicleCamera, GetCamRot(vehicleCamera) + vector3(1.0, 0.0, 0.0))
 | |
|             end
 | |
|             if IsDisabledControlPressed(0, Config.Controls.CameraRotations.down) then
 | |
|                 RotSync = false
 | |
|                 SetCamRot(vehicleCamera, GetCamRot(vehicleCamera) - vector3(1.0, 0.0, 0.0))
 | |
|             end
 | |
|             if IsDisabledControlPressed(0, Config.Controls.CameraRotations.left) then
 | |
|                 RotSync = false
 | |
|                 SetCamRot(vehicleCamera, GetCamRot(vehicleCamera) + vector3(0.0, 0.0, 1.0))
 | |
|             end
 | |
|             if IsDisabledControlPressed(0, Config.Controls.CameraRotations.right) then
 | |
|                 RotSync = false
 | |
|                 SetCamRot(vehicleCamera, GetCamRot(vehicleCamera) - vector3(0.0, 0.0, 1.0))
 | |
|             end
 | |
|         end
 | |
|     end)
 | |
| end
 | |
| 
 | |
| --  ██████╗██╗  ██╗███████╗ ██████╗██╗  ██╗    ███████╗██╗ ██████╗ ███╗   ██╗ █████╗ ██╗     
 | |
| -- ██╔════╝██║  ██║██╔════╝██╔════╝██║ ██╔╝    ██╔════╝██║██╔════╝ ████╗  ██║██╔══██╗██║     
 | |
| -- ██║     ███████║█████╗  ██║     █████╔╝     ███████╗██║██║  ███╗██╔██╗ ██║███████║██║     
 | |
| -- ██║     ██╔══██║██╔══╝  ██║     ██╔═██╗     ╚════██║██║██║   ██║██║╚██╗██║██╔══██║██║     
 | |
| -- ╚██████╗██║  ██║███████╗╚██████╗██║  ██╗    ███████║██║╚██████╔╝██║ ╚████║██║  ██║███████╗
 | |
| --  ╚═════╝╚═╝  ╚═╝╚══════╝ ╚═════╝╚═╝  ╚═╝    ╚══════╝╚═╝ ╚═════╝ ╚═╝  ╚═══╝╚═╝  ╚═╝╚══════╝
 | |
| 
 | |
| local function CheckSignal()
 | |
|     Citizen.CreateThread(function()
 | |
|         while vehicleEntity and DoesEntityExist(vehicleEntity) and not NoSignal and not LowBattery and isCameraActive do
 | |
|            if fakePlayerPed then
 | |
|                 local playerPed = PlayerPedId()
 | |
|                 local playerCoords = GetEntityCoords(fakePlayerPed)
 | |
|                 local carCoords = GetEntityCoords(vehicleEntity)
 | |
|                 local distance = #(playerCoords - carCoords)
 | |
|                 local maxDistance = Config.LoseConnectionDistance * signalBooster
 | |
| 
 | |
|                 if distance > maxDistance then
 | |
|                     NuiMessage('Notification', { header = Locales[Config.Locale].WEB['error'], message = Locales[Config.Locale].LUA['vehicle_signal_destroyed'] })
 | |
|                     NuiMessage('NoSignal', { type = 3 })
 | |
|                     NoSignal = true
 | |
| 
 | |
|                     Citizen.SetTimeout(5000, function()
 | |
|                         DoScreenFadeOut(1000)
 | |
|                         Wait(1000)
 | |
|                         RenderScriptCams(false, false, 0, true, true)
 | |
|                         DestroyCam(vehicleCamera, true)
 | |
|                         Config.SetInvBusy(false)
 | |
|                         Config.SetHudDisplay(false)
 | |
|                         NuiMessage('Close')
 | |
|                         SetSeethrough(false)
 | |
|                         SetNightvision(false)
 | |
|                         RenderScriptCams(false, false, 0, true, true)
 | |
|                         isCameraActive = false
 | |
|                         NuiMessage('SetCamera', { active = false })
 | |
|                         ClearPedTasksImmediately(PlayerPedId())
 | |
|                         SetEntityVisible(PlayerPedId(), false, false)
 | |
|                         TaskLeaveVehicle(PlayerPedId(), vehicleEntity, 0)
 | |
|                         local pedCoords = nil
 | |
| 
 | |
|                         if DoesEntityExist(fakePlayerPed) then
 | |
|                             pedCoords = GetEntityCoords(fakePlayerPed)
 | |
|                         else
 | |
|                             pedCoords = lastCoordsPlayer
 | |
|                         end
 | |
| 
 | |
|                         SetEntityCoords(PlayerPedId(), pedCoords)
 | |
|                         DeleteEntity(fakePlayerPed)
 | |
|                         SetEntityVisible(PlayerPedId(), true, false)
 | |
|                         fakePlayerPed = nil
 | |
|                         DoScreenFadeIn(1000)
 | |
|                     end)
 | |
|                     break
 | |
|                 end
 | |
| 
 | |
|                 if distance > maxDistance - 5 then
 | |
|                     if not threeAwayNotification then
 | |
|                         NuiMessage('NoSignal', { type = 2 })
 | |
|                         threeAwayNotification = true
 | |
|                     end
 | |
|                 elseif distance > maxDistance - 15 then
 | |
|                     if not secondAwayNotification then
 | |
|                         NuiMessage('NoSignal', { type = 1 })
 | |
|                         secondAwayNotification = true
 | |
|                     end
 | |
|                 elseif distance > maxDistance - 25 then
 | |
|                     if not firstAwayNotification then
 | |
|                         firstAwayNotification = true
 | |
|                         NuiMessage('Notification', { header = Locales[Config.Locale].WEB['error'], message = Locales[Config.Locale].LUA['vehicle_too_away'] })
 | |
|                     end
 | |
| 
 | |
|                     NuiMessage('NoSignal', { type = 0 })
 | |
|                 else
 | |
|                     firstAwayNotification = false
 | |
|                     secondAwayNotification = false
 | |
|                     threeAwayNotification = false
 | |
|                     NuiMessage('NoSignal', { type = 0 })
 | |
|                 end
 | |
| 
 | |
|                 NuiMessage('UpdateDistance', math.floor(distance))
 | |
|            end
 | |
| 
 | |
|             Citizen.Wait(1000)
 | |
|         end
 | |
|     end)
 | |
| end
 | |
| 
 | |
| --  █████╗  ██████╗████████╗██╗██╗   ██╗███████╗    ██████╗ ██╗      █████╗ ██╗   ██╗███████╗██████╗     ███████╗██╗  ██╗██╗███████╗████████╗
 | |
| -- ██╔══██╗██╔════╝╚══██╔══╝██║██║   ██║██╔════╝    ██╔══██╗██║     ██╔══██╗╚██╗ ██╔╝██╔════╝██╔══██╗    ██╔════╝╚██╗██╔╝██║██╔════╝╚══██╔══╝
 | |
| -- ███████║██║        ██║   ██║██║   ██║█████╗      ██████╔╝██║     ███████║ ╚████╔╝ █████╗  ██████╔╝    █████╗   ╚███╔╝ ██║███████╗   ██║   
 | |
| -- ██╔══██║██║        ██║   ██║╚██╗ ██╔╝██╔══╝      ██╔═══╝ ██║     ██╔══██║  ╚██╔╝  ██╔══╝  ██╔══██╗    ██╔══╝   ██╔██╗ ██║╚════██║   ██║   
 | |
| -- ██║  ██║╚██████╗   ██║   ██║ ╚████╔╝ ███████╗    ██║     ███████╗██║  ██║   ██║   ███████╗██║  ██║    ███████╗██╔╝ ██╗██║███████║   ██║   
 | |
| -- ╚═╝  ╚═╝ ╚═════╝   ╚═╝   ╚═╝  ╚═══╝  ╚══════╝    ╚═╝     ╚══════╝╚═╝  ╚═╝   ╚═╝   ╚══════╝╚═╝  ╚═╝    ╚══════╝╚═╝  ╚═╝╚═╝╚══════╝   ╚═╝   
 | |
| 
 | |
| local function ActivePlayerExist(hit)
 | |
|     if ActivePlayer.ped == hit then
 | |
|         return true
 | |
|     end
 | |
| end
 | |
| 
 | |
| -- ██╗  ██╗ █████╗ ███╗   ██╗██████╗ ██╗     ███████╗    ███████╗ ██████╗  ██████╗ ███╗   ███╗
 | |
| -- ██║  ██║██╔══██╗████╗  ██║██╔══██╗██║     ██╔════╝    ╚══███╔╝██╔═══██╗██╔═══██╗████╗ ████║
 | |
| -- ███████║███████║██╔██╗ ██║██║  ██║██║     █████╗        ███╔╝ ██║   ██║██║   ██║██╔████╔██║
 | |
| -- ██╔══██║██╔══██║██║╚██╗██║██║  ██║██║     ██╔══╝       ███╔╝  ██║   ██║██║   ██║██║╚██╔╝██║
 | |
| -- ██║  ██║██║  ██║██║ ╚████║██████╔╝███████╗███████╗    ███████╗╚██████╔╝╚██████╔╝██║ ╚═╝ ██║
 | |
| -- ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═══╝╚═════╝ ╚══════╝╚══════╝    ╚══════╝ ╚═════╝  ╚═════╝ ╚═╝     ╚═╝
 | |
| 
 | |
| local function HandleZoom(cam)
 | |
|     Citizen.CreateThread(function()
 | |
|         while vehicleEntity and DoesEntityExist(vehicleEntity) and not NoSignal and not LowBattery and isCameraActive do
 | |
|             if IsControlJustPressed(0, Config.Controls.CameraZoom.zoom) then
 | |
|                 if maxFov > GetCamFov(cam) - 1.0 then
 | |
|                     SetCamFov(cam, GetCamFov(cam) + 1.0)
 | |
|                 end
 | |
|             end
 | |
| 
 | |
|             if IsControlJustPressed(0, Config.Controls.CameraZoom.out) then
 | |
|                 SetCamFov(cam, GetCamFov(cam) - 1.0)
 | |
|             end
 | |
|             Citizen.Wait(0)
 | |
|         end
 | |
|     end)
 | |
| end
 | |
| 
 | |
| --  ██████╗██████╗ ███████╗ █████╗ ████████╗███████╗    ███████╗██╗  ██╗ ██████╗ ██████╗ ███████╗
 | |
| -- ██╔════╝██╔══██╗██╔════╝██╔══██╗╚══██╔══╝██╔════╝    ██╔════╝██║  ██║██╔═══██╗██╔══██╗██╔════╝
 | |
| -- ██║     ██████╔╝█████╗  ███████║   ██║   █████╗      ███████╗███████║██║   ██║██████╔╝███████╗
 | |
| -- ██║     ██╔══██╗██╔══╝  ██╔══██║   ██║   ██╔══╝      ╚════██║██╔══██║██║   ██║██╔═══╝ ╚════██║
 | |
| -- ╚██████╗██║  ██║███████╗██║  ██║   ██║   ███████╗    ███████║██║  ██║╚██████╔╝██║     ███████║
 | |
| --  ╚═════╝╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝   ╚═╝   ╚══════╝    ╚══════╝╚═╝  ╚═╝ ╚═════╝ ╚═╝     ╚══════╝
 | |
| 
 | |
| function CreateShops() 
 | |
|     for k, data in pairs(Config.Stores) do
 | |
|         if data.blip.active then
 | |
|             storeBlips[k] = AddBlipForCoord(data.coords.x, data.coords.y, data.coords.z)
 | |
|             SetBlipSprite(storeBlips[k], data.blip.sprite)
 | |
|             SetBlipColour(storeBlips[k], data.blip.color)
 | |
|             SetBlipScale(storeBlips[k], data.blip.scale)
 | |
|             SetBlipAsShortRange(storeBlips[k], true)
 | |
|             BeginTextCommandSetBlipName("STRING")
 | |
|             AddTextComponentSubstringPlayerName(data.blip.name)
 | |
|             EndTextCommandSetBlipName(storeBlips[k])
 | |
|         end
 | |
| 
 | |
|         local current = type(data.ped) == 'number' and data.ped or joaat(data.ped)
 | |
| 
 | |
|         RequestModel(current)
 | |
|         while not HasModelLoaded(current) do
 | |
|             Wait(1)
 | |
|         end
 | |
| 
 | |
|         storePed[k] = CreatePed(0, current, data.coords.x, data.coords.y, data.coords.z-1, data.coords.w, false, false)
 | |
|         FreezeEntityPosition(storePed[k], true)
 | |
|         SetEntityInvincible(storePed[k], true)
 | |
|         SetBlockingOfNonTemporaryEvents(storePed[k], true)
 | |
| 
 | |
|         if Config.Interaction == 'qb-target' then
 | |
|             exports['qb-target']:AddTargetEntity(storePed[k], {
 | |
|                 options = {
 | |
|                     {
 | |
|                         label = Locales[Config.Locale].LUA['open_store'],
 | |
|                         icon = 'fas fa-shop',
 | |
|                         action = function(entity)
 | |
|                             if data.items == 'all' then
 | |
|                                 NuiMessage('OpenStore', { cars = Config.RCCars, categorys = Config.Categorys, crafts = Config.RCCrafts })
 | |
|                                 SetNuiFocus(true, true)
 | |
|                             else
 | |
|                                 if storeProducts[k] then
 | |
|                                     NuiMessage('OpenStore', { cars = Config.RCCars, categorys = Config.Categorys, crafts = Config.RCCrafts })
 | |
|                                     SetNuiFocus(true, true)
 | |
|                                 else
 | |
|                                     print('No products found!')
 | |
|                                 end
 | |
|                             end
 | |
|                         end,
 | |
|                         canInteract = function(entity, distance)
 | |
|                             local PlayerData = nil
 | |
|                             local Job = nil
 | |
|         
 | |
|                             if CoreName == 'qb-core' then
 | |
|                                 PlayerData = QBCore.Functions.GetPlayerData()
 | |
|                                 Job = PlayerData.job.name
 | |
|                             elseif CoreName == 'qbx_core' then
 | |
|                                 PlayerData = QBX:GetPlayerData()
 | |
|                                 Job = PlayerData.job.name
 | |
|                             elseif CoreName == 'es_extended' then
 | |
|                                 PlayerData = ESX.GetPlayerData()
 | |
|                                 Job = PlayerData.job.name
 | |
|                             end
 | |
|         
 | |
|                             if data.jobs == 'all' then
 | |
|                                 return true
 | |
|                             else
 | |
|                                 if data.jobs[Job] then
 | |
|                                     return true
 | |
|                                 else
 | |
|                                     return false
 | |
|                                 end
 | |
|                             end
 | |
|                         end,
 | |
|                     }
 | |
|                 },
 | |
|                 distance = 2.5,
 | |
|             })
 | |
|         elseif Config.Interaction == 'ox_target' then
 | |
|             exports.ox_target:addLocalEntity(storePed[k], {
 | |
|                 name = k .. '_store',
 | |
|                 label = Locales[Config.Locale].LUA['open_store'],
 | |
|                 icon = 'fas fa-shop',
 | |
|                 onSelect = function()
 | |
|                     if data.items == 'all' then
 | |
|                         NuiMessage('OpenStore', { cars = Config.RCCars, categorys = Config.Categorys, crafts = Config.RCCrafts })
 | |
|                         SetNuiFocus(true, true)
 | |
|                     else
 | |
|                         if storeProducts[k] then
 | |
|                             NuiMessage('OpenStore', { cars = Config.RCCars, categorys = Config.Categorys, crafts = Config.RCCrafts })
 | |
|                             SetNuiFocus(true, true)
 | |
|                         else
 | |
|                             print('No products found!')
 | |
|                         end
 | |
|                     end
 | |
|                 end,
 | |
|                 canInteract = function()
 | |
|                     local PlayerData = nil
 | |
|                     local Job = nil
 | |
| 
 | |
|                     if CoreName == 'qb-core' then
 | |
|                         PlayerData = QBCore.Functions.GetPlayerData()
 | |
|                         Job = PlayerData.job.name
 | |
|                     elseif CoreName == 'qbx_core' then
 | |
|                         PlayerData = QBX:GetPlayerData()
 | |
|                         Job = PlayerData.job.name
 | |
|                     elseif CoreName == 'es_extended' then
 | |
|                         PlayerData = ESX.GetPlayerData()
 | |
|                         Job = PlayerData.job.name
 | |
|                     end
 | |
| 
 | |
|                     if data.jobs == 'all' then
 | |
|                         return true
 | |
|                     else
 | |
|                         if data.jobs[Job] then
 | |
|                             return true
 | |
|                         else
 | |
|                             return false
 | |
|                         end
 | |
|                     end
 | |
|                 end
 | |
|             })
 | |
|         elseif Config.Interaction == 'drawtext' then
 | |
|             Citizen.CreateThread(function()
 | |
|                 while true do
 | |
|                     local playerPed = PlayerPedId()
 | |
|                     local playerCoords = GetEntityCoords(playerPed)
 | |
|                     local distance = #(playerCoords - vector3(data.coords.x, data.coords.y, data.coords.z))
 | |
| 
 | |
|                     if distance < 1.5 and (data.jobs == 'all' or data.jobs[PlayerData.job.name]) then
 | |
|                         sleep = 0
 | |
|                         DrawText3D(data.coords.x, data.coords.y, data.coords.z, '[~g~' .. Config.Controls.InteractionKey.text .. '~w~] - ' .. Locales[Config.Locale].LUA['open_store'])
 | |
|                         if IsControlJustPressed(0, Config.Controls.InteractionKey.key) then
 | |
|                             if data.items == 'all' then
 | |
|                                 NuiMessage('OpenStore', { cars = Config.RCCars, categorys = Config.Categorys, crafts = Config.RCCrafts })
 | |
|                                 SetNuiFocus(true, true)
 | |
|                             else
 | |
|                                 if storeProducts[k] then
 | |
|                                     NuiMessage('OpenStore', { cars = Config.RCCars, categorys = Config.Categorys, crafts = Config.RCCrafts })
 | |
|                                     SetNuiFocus(true, true)
 | |
|                                 else
 | |
|                                     print('No products found!')
 | |
|                                 end
 | |
|                             end
 | |
|                         end
 | |
|                     end
 | |
|                     Citizen.Wait(0)
 | |
|                 end
 | |
|             end)
 | |
|         end
 | |
|     end
 | |
| end
 | |
| 
 | |
| function CreateChargingStation()
 | |
|     for k, data in pairs(Config.Charges) do
 | |
|         if data.blip.active then
 | |
|             chargingStationBlips[k] = AddBlipForCoord(data.coords.x, data.coords.y, data.coords.z)
 | |
|             SetBlipSprite(chargingStationBlips[k], data.blip.sprite)
 | |
|             SetBlipColour(chargingStationBlips[k], data.blip.color)
 | |
|             SetBlipScale(chargingStationBlips[k], data.blip.scale)
 | |
|             SetBlipAsShortRange(chargingStationBlips[k], true)
 | |
|             BeginTextCommandSetBlipName("STRING")
 | |
|             AddTextComponentSubstringPlayerName(data.blip.name)
 | |
|             EndTextCommandSetBlipName(chargingStationBlips[k])
 | |
|         end
 | |
| 
 | |
|         local current = type(data.ped) == 'number' and data.ped or joaat(data.ped)
 | |
| 
 | |
|         RequestModel(current)
 | |
|         while not HasModelLoaded(current) do
 | |
|             Wait(1)
 | |
|         end
 | |
| 
 | |
|         chargingStationPed[k] = CreatePed(0, current, data.coords.x, data.coords.y, data.coords.z-1, data.coords.w, false, false)
 | |
|         FreezeEntityPosition(chargingStationPed[k], true)
 | |
|         SetEntityInvincible(chargingStationPed[k], true)
 | |
|         SetBlockingOfNonTemporaryEvents(chargingStationPed[k], true)
 | |
| 
 | |
|         if Config.Interaction == 'qb-target' then
 | |
|             exports['qb-target']:AddTargetEntity(chargingStationPed[k], {
 | |
|                 options = {
 | |
|                     {
 | |
|                         label = Locales[Config.Locale].LUA['open_charging_station'],
 | |
|                         icon = 'fas fa-bolt',
 | |
|                         action = function(entity)
 | |
|                             lib.registerContext({
 | |
|                                 id = 'charging_station_menu',
 | |
|                                 title = Locales[Config.Locale].LUA['charging_station'],
 | |
|                                 options = {
 | |
|                                     {
 | |
|                                         title = Locales[Config.Locale].LUA['charge_vehicle_header'],
 | |
|                                         description = Locales[Config.Locale].LUA['charge_vehicle_desc'],
 | |
|                                         onSelect = function()
 | |
|                                             local myVehicle = {}
 | |
|                                             local vehicleData = nil
 | |
|                                             local isLoading = false
 | |
|         
 | |
|                                             lib.callback('0r-rccar:server:getVehicleForCharge', false, function(vehicle)
 | |
|                                                 vehicleData = vehicle
 | |
|                                                 isLoading = true
 | |
|                                             end)
 | |
|         
 | |
|                                             while not isLoading do
 | |
|                                                 Wait(100)
 | |
|                                             end
 | |
|         
 | |
|                                             if vehicleData then
 | |
|                                                 if vehicleData ~= '[]' then
 | |
|                                                     for k, v in pairs(vehicleData) do
 | |
|                                                         local batteryLevel = tonumber(v.battery) or 0
 | |
|                                                         
 | |
|                                                         table.insert(myVehicle, {
 | |
|                                                             title = v.label,
 | |
|                                                             description = Locales[Config.Locale].LUA['battery'] ..': ' .. batteryLevel .. '%' .. ' | ' ..  Locales[Config.Locale].LUA['price'] .. ': $' .. Config.ChargePrice .. '' .. ' | ' .. Locales[Config.Locale].LUA['serie_number'] .. ': ' .. v.serie .. '',
 | |
|                                                             onSelect = function()
 | |
| 
 | |
|                                                                 local isLoading = false
 | |
| 
 | |
|                                                                 lib.callback('0r-rccar:server:checkMoney', false, function(result)
 | |
|                                                                     if not result then
 | |
|                                                                         if CoreName == 'qb-core' then
 | |
|                                                                             QBCore.Functions.Notify(Locales[Config.Locale].LUA['not_enough_money'], 'error')
 | |
|                                                                         elseif CoreName == 'qbx_core' then
 | |
|                                                                             QBX:Notify(Locales[Config.Locale].LUA['not_enough_money'], 'error')
 | |
|                                                                         elseif CoreName == 'es_extended' then
 | |
|                                                                             ESX.ShowNotification(Locales[Config.Locale].LUA['not_enough_money'])
 | |
|                                                                         end
 | |
|                                                                         return
 | |
|                                                                     end
 | |
|                                                                     isLoading = true
 | |
|                                                                 end, Config.ChargePrice)
 | |
| 
 | |
|                                                                 while not isLoading do
 | |
|                                                                     Wait(100)
 | |
|                                                                 end
 | |
| 
 | |
|                                                                 local chargeTime = 1000 * Config.ChargingProcess.Charging.Time
 | |
|                                                                 local chargeBatteryLevel = batteryLevel
 | |
|                                                                 usedChargingStation = true
 | |
|                                                                 TriggerServerEvent('0r-rccar:server:chargeVehicle', v.serie, v.name)
 | |
|                                                                 usedChargingStationItem = v
 | |
|                                                 
 | |
|                                                                 Citizen.CreateThread(function()
 | |
|                                                                     while chargeTime > 0 and usedChargingStation and chargeBatteryLevel < 100 do
 | |
|                                                                         
 | |
|                                                                         chargeBatteryLevel = chargeBatteryLevel + 1
 | |
|             
 | |
|                                                                         usedChargingStationItem.battery = chargeBatteryLevel
 | |
|                                                 
 | |
|                                                                         if chargeBatteryLevel >= 100 then
 | |
|                                                                             chargeBatteryLevel = 100
 | |
|                                                                             if CoreName == 'qb-core' then
 | |
|                                                                                 QBCore.Functions.Notify(Locales[Config.Locale].LUA['vehicle_charge_full'], 'success')
 | |
|                                                                             elseif CoreName == 'qbx_core' then
 | |
|                                                                                 QBX:Notify(Locales[Config.Locale].LUA['vehicle_charge_full'], 'success')
 | |
|                                                                             elseif CoreName == 'es_extended' then
 | |
|                                                                                 ESX.ShowNotification(Locales[Config.Locale].LUA['vehicle_charge_full'], 'success')
 | |
|                                                                             end
 | |
|                                                                         end
 | |
|                                                 
 | |
|                                                                         Wait(chargeTime)
 | |
|                                                                     end
 | |
|                                                                 end)
 | |
|                                                             end,
 | |
|                                                         })
 | |
|                                                     end
 | |
|                                                 else
 | |
|                                                     table.insert(myVehicle, {
 | |
|                                                         title = Locales[Config.Locale].LUA['no_vehicle_found'],
 | |
|                                                     })
 | |
|                                                 end
 | |
|                                             
 | |
|                                                 table.insert(myVehicle, {
 | |
|                                                     title = Locales[Config.Locale].LUA['return_back'],
 | |
|                                                     menu = 'charging_station_menu',
 | |
|                                                 })
 | |
|         
 | |
|                                                 lib.registerContext({
 | |
|                                                     id = 'charging_station_vehicle',
 | |
|                                                     title = Locales[Config.Locale].LUA['charge_vehicle_header'],
 | |
|                                                     options = myVehicle,
 | |
|                                                 })
 | |
|         
 | |
|                                                 lib.hideContext(true)
 | |
|                                                 lib.showContext('charging_station_vehicle')
 | |
|                                             end
 | |
|                                         end,
 | |
|                                     },
 | |
|                                     {
 | |
|                                         title = Locales[Config.Locale].LUA['check_vehicle_header'],
 | |
|                                         description = Locales[Config.Locale].LUA['check_vehicle_desc'],
 | |
|                                         onSelect = function()
 | |
|                                             if usedChargingStation then
 | |
|                                                 lib.registerContext({
 | |
|                                                     id = 'charging_station_vehicle',
 | |
|                                                     title = Locales[Config.Locale].LUA['check_vehicle_header'],
 | |
|                                                     options = {
 | |
|                                                         {
 | |
|                                                             title = usedChargingStationItem.label,
 | |
|                                                             description =  Locales[Config.Locale].LUA['battery'] ..': ' .. usedChargingStationItem.battery .. '%' .. ' | ' .. Locales[Config.Locale].LUA['serie_number'] .. ': ' .. usedChargingStationItem.serie .. '',
 | |
|                                                             onSelect = function()
 | |
|                                                                 usedChargingStation = false
 | |
|                                                                 local response = lib.callback.await('0r-rccar:server:undoChargeVehicle', false, usedChargingStationItem.serie, usedChargingStationItem.name, usedChargingStationItem.battery)
 | |
|                                                                 usedChargingStationItem = nil
 | |
|                                                             end,
 | |
|                                                         },
 | |
|                                                         {
 | |
|                                                             title = Locales[Config.Locale].LUA['return_back'],
 | |
|                                                             menu = 'charging_station_menu',
 | |
|                                                         },
 | |
|                                                     },
 | |
|                                                 })
 | |
|         
 | |
|                                                 lib.hideContext(true)
 | |
|                                                 lib.showContext('charging_station_vehicle')
 | |
|                                             else
 | |
|                                                 if CoreName == 'qb-core' then
 | |
|                                                     QBCore.Functions.Notify(Locales[Config.Locale].LUA['vehicle_not_charged'], 'error')
 | |
|                                                 elseif CoreName == 'qbx_core' then
 | |
|                                                     QBX:Notify(Locales[Config.Locale].LUA['vehicle_not_charged'], 'error')
 | |
|                                                 elseif CoreName == 'es_extended' then
 | |
|                                                     ESX.ShowNotification(Locales[Config.Locale].LUA['vehicle_not_charged'])
 | |
|                                                 end
 | |
|                                             end
 | |
|                                         end,
 | |
|                                     },
 | |
|                                 },
 | |
|                             })
 | |
|         
 | |
|                             lib.showContext('charging_station_menu')
 | |
|                         end,
 | |
|                         canInteract = function(entity, distance)
 | |
|                             local PlayerData = nil
 | |
|                             local Job = nil
 | |
|         
 | |
|                             if CoreName == 'qb-core' then
 | |
|                                 PlayerData = QBCore.Functions.GetPlayerData()
 | |
|                                 Job = PlayerData.job.name
 | |
|                             elseif CoreName == 'qbx_core' then
 | |
|                                 PlayerData = QBX:GetPlayerData()
 | |
|                                 Job = PlayerData.job.name
 | |
|                             elseif CoreName == 'es_extended' then
 | |
|                                 PlayerData = ESX.GetPlayerData()
 | |
|                                 Job = PlayerData.job.name
 | |
|                             end
 | |
|         
 | |
|                             if data.jobs == 'all' then
 | |
|                                 return true
 | |
|                             else
 | |
|                                 if data.jobs[Job] then
 | |
|                                     return true
 | |
|                                 else
 | |
|                                     return false
 | |
|                                 end
 | |
|                             end
 | |
|                         end,
 | |
|                     }
 | |
|                 },
 | |
|                 distance = 2.5,
 | |
|             })
 | |
|         elseif Config.Interaction == 'ox_target' then
 | |
|             exports.ox_target:addLocalEntity(chargingStationPed[k], {
 | |
|                 name = k.. '_charging_station',
 | |
|                 label = Locales[Config.Locale].LUA['open_charging_station'],
 | |
|                 icon = 'fas fa-bolt',
 | |
|                 onSelect = function()
 | |
|                     lib.registerContext({
 | |
|                         id = 'charging_station_menu',
 | |
|                         title = Locales[Config.Locale].LUA['charging_station'],
 | |
|                         options = {
 | |
|                             {
 | |
|                                 title = Locales[Config.Locale].LUA['charge_vehicle_header'],
 | |
|                                 description = Locales[Config.Locale].LUA['charge_vehicle_desc'],
 | |
|                                 onSelect = function()
 | |
|                                     local myVehicle = {}
 | |
|                                     local vehicleData = nil
 | |
|                                     local isLoading = false
 | |
| 
 | |
|                                     lib.callback('0r-rccar:server:getVehicleForCharge', false, function(vehicle)
 | |
|                                         vehicleData = vehicle
 | |
|                                         isLoading = true
 | |
|                                     end)
 | |
| 
 | |
|                                     while not isLoading do
 | |
|                                         Wait(100)
 | |
|                                     end
 | |
| 
 | |
|                                     if vehicleData then
 | |
|                                         if vehicleData ~= '[]' then
 | |
|                                             for k, v in pairs(vehicleData) do
 | |
|                                                 local batteryLevel = tonumber(v.battery) or 0
 | |
|                                                 
 | |
|                                                 table.insert(myVehicle, {
 | |
|                                                     title = v.label,
 | |
|                                                     description = Locales[Config.Locale].LUA['battery'] ..': ' .. batteryLevel .. '%' .. ' | ' ..  Locales[Config.Locale].LUA['price'] .. ': $' .. Config.ChargePrice .. '' .. ' | ' .. Locales[Config.Locale].LUA['serie_number'] .. ': ' .. v.serie .. '',
 | |
|                                                     onSelect = function()
 | |
| 
 | |
|                                                         local isLoading = false
 | |
| 
 | |
|                                                         lib.callback('0r-rccar:server:checkMoney', false, function(result)
 | |
|                                                             if not result then
 | |
|                                                                 if CoreName == 'qb-core' then
 | |
|                                                                     QBCore.Functions.Notify(Locales[Config.Locale].LUA['not_enough_money'], 'error')
 | |
|                                                                 elseif CoreName == 'qbx_core' then
 | |
|                                                                     QBX:Notify(Locales[Config.Locale].LUA['not_enough_money'], 'error')
 | |
|                                                                 elseif CoreName == 'es_extended' then
 | |
|                                                                     ESX.ShowNotification(Locales[Config.Locale].LUA['not_enough_money'])
 | |
|                                                                 end
 | |
|                                                                 return
 | |
|                                                             end
 | |
|                                                             isLoading = true
 | |
|                                                         end, Config.ChargePrice)
 | |
| 
 | |
|                                                         while not isLoading do
 | |
|                                                             Wait(100)
 | |
|                                                         end
 | |
| 
 | |
|                                                         local chargeTime = 1000 * Config.ChargingProcess.Charging.Time
 | |
|                                                         local chargeBatteryLevel = batteryLevel
 | |
|                                                         usedChargingStation = true
 | |
|                                                         TriggerServerEvent('0r-rccar:server:chargeVehicle', v.serie, v.name)
 | |
|                                                         usedChargingStationItem = v
 | |
|                                         
 | |
|                                                         Citizen.CreateThread(function()
 | |
|                                                             while chargeTime > 0 and usedChargingStation and chargeBatteryLevel < 100 do
 | |
|                                                                 
 | |
|                                                                 chargeBatteryLevel = chargeBatteryLevel + 1
 | |
|     
 | |
|                                                                 usedChargingStationItem.battery = chargeBatteryLevel
 | |
|                                         
 | |
|                                                                 if chargeBatteryLevel >= 100 then
 | |
|                                                                     chargeBatteryLevel = 100
 | |
|                                                                     if CoreName == 'qb-core' then
 | |
|                                                                         QBCore.Functions.Notify(Locales[Config.Locale].LUA['vehicle_charge_full'], 'success')
 | |
|                                                                     elseif CoreName == 'qbx_core' then
 | |
|                                                                         QBX:Notify(Locales[Config.Locale].LUA['vehicle_charge_full'], 'success')
 | |
|                                                                     elseif CoreName == 'es_extended' then
 | |
|                                                                         ESX.ShowNotification(Locales[Config.Locale].LUA['vehicle_charge_full'], 'success')
 | |
|                                                                     end
 | |
|                                                                 end
 | |
|                                         
 | |
|                                                                 Wait(chargeTime)
 | |
|                                                             end
 | |
|                                                         end)
 | |
|                                                     end,
 | |
|                                                 })
 | |
|                                             end
 | |
|                                         else
 | |
|                                             table.insert(myVehicle, {
 | |
|                                                 title = Locales[Config.Locale].LUA['no_vehicle_found'],
 | |
|                                             })
 | |
|                                         end
 | |
|                                     
 | |
|                                         table.insert(myVehicle, {
 | |
|                                             title = Locales[Config.Locale].LUA['return_back'],
 | |
|                                             menu = 'charging_station_menu',
 | |
|                                         })
 | |
| 
 | |
|                                         lib.registerContext({
 | |
|                                             id = 'charging_station_vehicle',
 | |
|                                             title = Locales[Config.Locale].LUA['charge_vehicle_header'],
 | |
|                                             options = myVehicle,
 | |
|                                         })
 | |
| 
 | |
|                                         lib.hideContext(true)
 | |
|                                         lib.showContext('charging_station_vehicle')
 | |
|                                     end
 | |
|                                 end,
 | |
|                             },
 | |
|                             {
 | |
|                                 title = Locales[Config.Locale].LUA['check_vehicle_header'],
 | |
|                                 description = Locales[Config.Locale].LUA['check_vehicle_desc'],
 | |
|                                 onSelect = function()
 | |
|                                     if usedChargingStation then
 | |
|                                         lib.registerContext({
 | |
|                                             id = 'charging_station_vehicle',
 | |
|                                             title = Locales[Config.Locale].LUA['check_vehicle_header'],
 | |
|                                             options = {
 | |
|                                                 {
 | |
|                                                     title = usedChargingStationItem.label,
 | |
|                                                     description =  Locales[Config.Locale].LUA['battery'] ..': ' .. usedChargingStationItem.battery .. '%' .. ' | ' .. Locales[Config.Locale].LUA['serie_number'] .. ': ' .. usedChargingStationItem.serie .. '',
 | |
|                                                     onSelect = function()
 | |
|                                                         usedChargingStation = false
 | |
|                                                         local response = lib.callback.await('0r-rccar:server:undoChargeVehicle', false, usedChargingStationItem.serie, usedChargingStationItem.name, usedChargingStationItem.battery)
 | |
|                                                         usedChargingStationItem = nil
 | |
|                                                     end,
 | |
|                                                 },
 | |
|                                                 {
 | |
|                                                     title = Locales[Config.Locale].LUA['return_back'],
 | |
|                                                     menu = 'charging_station_menu',
 | |
|                                                 },
 | |
|                                             },
 | |
|                                         })
 | |
| 
 | |
|                                         lib.hideContext(true)
 | |
|                                         lib.showContext('charging_station_vehicle')
 | |
|                                     else
 | |
|                                         if CoreName == 'qb-core' then
 | |
|                                             QBCore.Functions.Notify(Locales[Config.Locale].LUA['vehicle_not_charged'], 'error')
 | |
|                                         elseif CoreName == 'qbx_core' then
 | |
|                                             QBX:Notify(Locales[Config.Locale].LUA['vehicle_not_charged'], 'error')
 | |
|                                         elseif CoreName == 'es_extended' then
 | |
|                                             ESX.ShowNotification(Locales[Config.Locale].LUA['vehicle_not_charged'])
 | |
|                                         end
 | |
|                                     end
 | |
|                                 end,
 | |
|                             },
 | |
|                         },
 | |
|                     })
 | |
| 
 | |
|                     lib.showContext('charging_station_menu')
 | |
|                 end,
 | |
|                 canInteract = function()
 | |
|                     local PlayerData = nil
 | |
|                     local Job = nil
 | |
| 
 | |
|                     if CoreName == 'qb-core' then
 | |
|                         PlayerData = QBCore.Functions.GetPlayerData()
 | |
|                         Job = PlayerData.job.name
 | |
|                     elseif CoreName == 'qbx_core' then
 | |
|                         PlayerData = QBX:GetPlayerData()
 | |
|                         Job = PlayerData.job.name
 | |
|                     elseif CoreName == 'es_extended' then
 | |
|                         PlayerData = ESX.GetPlayerData()
 | |
|                         Job = PlayerData.job.name
 | |
|                     end
 | |
| 
 | |
|                     if data.jobs == 'all' then
 | |
|                         return true
 | |
|                     else
 | |
|                         if data.jobs[Job] then
 | |
|                             return true
 | |
|                         else
 | |
|                             return false
 | |
|                         end
 | |
|                     end
 | |
|                 end
 | |
|             })
 | |
|         elseif Config.Interaction == 'drawtext' then
 | |
|             Citizen.CreateThread(function()
 | |
|                 while true do
 | |
|                     local playerPed = PlayerPedId()
 | |
|                     local playerCoords = GetEntityCoords(playerPed)
 | |
|                     local distance = #(playerCoords - vector3(data.coords.x, data.coords.y, data.coords.z))
 | |
|                     local sleep = 1000
 | |
| 
 | |
|                     if distance < 1.5 and (data.jobs == 'all' or data.jobs[PlayerData.job.name]) then
 | |
|                         sleep = 0
 | |
|                         DrawText3D(data.coords.x, data.coords.y, data.coords.z, '[~g~' .. Config.Controls.InteractionKey.text .. '~w~] - ' .. Locales[Config.Locale].LUA['open_charging_station'])
 | |
|                         if IsControlJustPressed(0, Config.Controls.InteractionKey.key) then
 | |
|                             lib.registerContext({
 | |
|                                 id = 'charging_station_menu',
 | |
|                                 title = Locales[Config.Locale].LUA['charging_station'],
 | |
|                                 options = {
 | |
|                                     {
 | |
|                                         title = Locales[Config.Locale].LUA['charge_vehicle_header'],
 | |
|                                         description = Locales[Config.Locale].LUA['charge_vehicle_desc'],
 | |
|                                         onSelect = function()
 | |
|                                             local myVehicle = {}
 | |
|                                             local vehicleData = nil
 | |
|                                             local isLoading = false
 | |
|         
 | |
|                                             lib.callback('0r-rccar:server:getVehicleForCharge', false, function(vehicle)
 | |
|                                                 vehicleData = vehicle
 | |
|                                                 isLoading = true
 | |
|                                             end)
 | |
|         
 | |
|                                             while not isLoading do
 | |
|                                                 Wait(100)
 | |
|                                             end
 | |
|         
 | |
|                                             if vehicleData then
 | |
|                                                 if vehicleData ~= '[]' then
 | |
|                                                     for k, v in pairs(vehicleData) do
 | |
|                                                         local batteryLevel = tonumber(v.battery) or 0
 | |
|                                                         
 | |
|                                                         table.insert(myVehicle, {
 | |
|                                                             title = v.label,
 | |
|                                                             description = Locales[Config.Locale].LUA['battery'] ..': ' .. batteryLevel .. '%' .. ' | ' ..  Locales[Config.Locale].LUA['price'] .. ': $' .. Config.ChargePrice .. '' .. ' | ' .. Locales[Config.Locale].LUA['serie_number'] .. ': ' .. v.serie .. '',
 | |
|                                                             onSelect = function()
 | |
| 
 | |
|                                                                 local isLoading = false
 | |
| 
 | |
|                                                                 lib.callback('0r-rccar:server:checkMoney', false, function(result)
 | |
|                                                                     if not result then
 | |
|                                                                         if CoreName == 'qb-core' then
 | |
|                                                                             QBCore.Functions.Notify(Locales[Config.Locale].LUA['not_enough_money'], 'error')
 | |
|                                                                         elseif CoreName == 'qbx_core' then
 | |
|                                                                             QBX:Notify(Locales[Config.Locale].LUA['not_enough_money'], 'error')
 | |
|                                                                         elseif CoreName == 'es_extended' then
 | |
|                                                                             ESX.ShowNotification(Locales[Config.Locale].LUA['not_enough_money'])
 | |
|                                                                         end
 | |
|                                                                         return
 | |
|                                                                     end
 | |
|                                                                     isLoading = true
 | |
|                                                                 end, Config.ChargePrice)
 | |
| 
 | |
|                                                                 while not isLoading do
 | |
|                                                                     Wait(100)
 | |
|                                                                 end
 | |
| 
 | |
|                                                                 local chargeTime = 1000 * Config.ChargingProcess.Charging.Time
 | |
|                                                                 local chargeBatteryLevel = batteryLevel
 | |
|                                                                 usedChargingStation = true
 | |
|                                                                 TriggerServerEvent('0r-rccar:server:chargeVehicle', v.serie, v.name)
 | |
|                                                                 usedChargingStationItem = v
 | |
|                                                 
 | |
|                                                                 Citizen.CreateThread(function()
 | |
|                                                                     while chargeTime > 0 and usedChargingStation and chargeBatteryLevel < 100 do
 | |
|                                                                         
 | |
|                                                                         chargeBatteryLevel = chargeBatteryLevel + 1
 | |
|             
 | |
|                                                                         usedChargingStationItem.battery = chargeBatteryLevel
 | |
|                                                 
 | |
|                                                                         if chargeBatteryLevel >= 100 then
 | |
|                                                                             chargeBatteryLevel = 100
 | |
|                                                                             if CoreName == 'qb-core' then
 | |
|                                                                                 QBCore.Functions.Notify(Locales[Config.Locale].LUA['vehicle_charge_full'], 'success')
 | |
|                                                                             elseif CoreName == 'qbx_core' then
 | |
|                                                                                 QBX:Notify(Locales[Config.Locale].LUA['vehicle_charge_full'], 'success')
 | |
|                                                                             elseif CoreName == 'es_extended' then
 | |
|                                                                                 ESX.ShowNotification(Locales[Config.Locale].LUA['vehicle_charge_full'], 'success')
 | |
|                                                                             end
 | |
|                                                                         end
 | |
|                                                 
 | |
|                                                                         Wait(chargeTime)
 | |
|                                                                     end
 | |
|                                                                 end)
 | |
|                                                             end,
 | |
|                                                         })
 | |
|                                                     end
 | |
|                                                 else
 | |
|                                                     table.insert(myVehicle, {
 | |
|                                                         title = Locales[Config.Locale].LUA['no_vehicle_found'],
 | |
|                                                     })
 | |
|                                                 end
 | |
|                                             
 | |
|                                                 table.insert(myVehicle, {
 | |
|                                                     title = Locales[Config.Locale].LUA['return_back'],
 | |
|                                                     menu = 'charging_station_menu',
 | |
|                                                 })
 | |
|         
 | |
|                                                 lib.registerContext({
 | |
|                                                     id = 'charging_station_vehicle',
 | |
|                                                     title = Locales[Config.Locale].LUA['charge_vehicle_header'],
 | |
|                                                     options = myVehicle,
 | |
|                                                 })
 | |
|         
 | |
|                                                 lib.hideContext(true)
 | |
|                                                 lib.showContext('charging_station_vehicle')
 | |
|                                             end
 | |
|                                         end,
 | |
|                                     },
 | |
|                                     {
 | |
|                                         title = Locales[Config.Locale].LUA['check_vehicle_header'],
 | |
|                                         description = Locales[Config.Locale].LUA['check_vehicle_desc'],
 | |
|                                         onSelect = function()
 | |
|                                             if usedChargingStation then
 | |
|                                                 lib.registerContext({
 | |
|                                                     id = 'charging_station_vehicle',
 | |
|                                                     title = Locales[Config.Locale].LUA['check_vehicle_header'],
 | |
|                                                     options = {
 | |
|                                                         {
 | |
|                                                             title = usedChargingStationItem.label,
 | |
|                                                             description =  Locales[Config.Locale].LUA['battery'] ..': ' .. usedChargingStationItem.battery .. '%' .. ' | ' .. Locales[Config.Locale].LUA['serie_number'] .. ': ' .. usedChargingStationItem.serie .. '',
 | |
|                                                             onSelect = function()
 | |
|                                                                 usedChargingStation = false
 | |
|                                                                 local response = lib.callback.await('0r-rccar:server:undoChargeVehicle', false, usedChargingStationItem.serie, usedChargingStationItem.name, usedChargingStationItem.battery)
 | |
|                                                                 usedChargingStationItem = nil
 | |
|                                                             end,
 | |
|                                                         },
 | |
|                                                         {
 | |
|                                                             title = Locales[Config.Locale].LUA['return_back'],
 | |
|                                                             menu = 'charging_station_menu',
 | |
|                                                         },
 | |
|                                                     },
 | |
|                                                 })
 | |
|         
 | |
|                                                 lib.hideContext(true)
 | |
|                                                 lib.showContext('charging_station_vehicle')
 | |
|                                             else
 | |
|                                                 if CoreName == 'qb-core' then
 | |
|                                                     QBCore.Functions.Notify(Locales[Config.Locale].LUA['vehicle_not_charged'], 'error')
 | |
|                                                 elseif CoreName == 'qbx_core' then
 | |
|                                                     QBX:Notify(Locales[Config.Locale].LUA['vehicle_not_charged'], 'error')
 | |
|                                                 elseif CoreName == 'es_extended' then
 | |
|                                                     ESX.ShowNotification(Locales[Config.Locale].LUA['vehicle_not_charged'])
 | |
|                                                 end
 | |
|                                             end
 | |
|                                         end,
 | |
|                                     },
 | |
|                                 },
 | |
|                             })
 | |
|         
 | |
|                             lib.showContext('charging_station_menu')
 | |
|                         end
 | |
|                     end
 | |
|                     Citizen.Wait(sleep)
 | |
|                 end
 | |
|             end)
 | |
|         end
 | |
|     end
 | |
| end
 | |
| 
 | |
| -- ██████╗ ███████╗ ██████╗ ██╗███████╗████████╗███████╗██████╗      ██████╗ ██████╗ ███╗   ██╗████████╗███████╗██╗  ██╗████████╗    ███╗   ███╗███████╗███╗   ██╗██╗   ██╗
 | |
| -- ██╔══██╗██╔════╝██╔════╝ ██║██╔════╝╚══██╔══╝██╔════╝██╔══██╗    ██╔════╝██╔═══██╗████╗  ██║╚══██╔══╝██╔════╝╚██╗██╔╝╚══██╔══╝    ████╗ ████║██╔════╝████╗  ██║██║   ██║
 | |
| -- ██████╔╝█████╗  ██║  ███╗██║███████╗   ██║   █████╗  ██████╔╝    ██║     ██║   ██║██╔██╗ ██║   ██║   █████╗   ╚███╔╝    ██║       ██╔████╔██║█████╗  ██╔██╗ ██║██║   ██║
 | |
| -- ██╔══██╗██╔══╝  ██║   ██║██║╚════██║   ██║   ██╔══╝  ██╔══██╗    ██║     ██║   ██║██║╚██╗██║   ██║   ██╔══╝   ██╔██╗    ██║       ██║╚██╔╝██║██╔══╝  ██║╚██╗██║██║   ██║
 | |
| -- ██║  ██║███████╗╚██████╔╝██║███████║   ██║   ███████╗██║  ██║    ╚██████╗╚██████╔╝██║ ╚████║   ██║   ███████╗██╔╝ ██╗   ██║       ██║ ╚═╝ ██║███████╗██║ ╚████║╚██████╔╝
 | |
| -- ╚═╝  ╚═╝╚══════╝ ╚═════╝ ╚═╝╚══════╝   ╚═╝   ╚══════╝╚═╝  ╚═╝     ╚═════╝ ╚═════╝ ╚═╝  ╚═══╝   ╚═╝   ╚══════╝╚═╝  ╚═╝   ╚═╝       ╚═╝     ╚═╝╚══════╝╚═╝  ╚═══╝ ╚═════╝ 
 | |
| 
 | |
| local function RegisterContextMenu()
 | |
|     lib.registerContext({
 | |
|         id = 'manage_rccar_menu',
 | |
|         title = Locales[Config.Locale].LUA['manage_rc_car'],
 | |
|         options = {
 | |
|             {
 | |
|                 title = Locales[Config.Locale].LUA['open_camera_header'],
 | |
|                 description = Locales[Config.Locale].LUA['open_camera_desc'],
 | |
|                 onSelect = function()
 | |
|                     lib.hideContext(true)
 | |
|                     NoSignal = false
 | |
|                     DoScreenFadeOut(1000)
 | |
|                     Wait(1000)
 | |
|                     SpawnPed()
 | |
|                     SetCam()
 | |
|                     isCameraActive = true
 | |
|                     Config.SetInvBusy(true)
 | |
|                     Config.SetHudDisplay(true)
 | |
|                     PlayControllerAnimation()
 | |
|                     SetPedIntoVehicle(PlayerPedId(), vehicleEntity, -1)
 | |
|                     CheckPlugins()
 | |
|                     ChangeCamRotation()
 | |
|                     CheckSignal()
 | |
|                     HandleZoom(vehicleCamera)
 | |
|                     maxFov = GetCamFov(vehicleCamera)
 | |
|                     HideHUDThisFrame()
 | |
|                     NuiMessage('UpdateBattery', batteryLevel)
 | |
|                     ChargingProcess()
 | |
|                     OpenPluginsMenu()
 | |
| 
 | |
|                     RenderScriptCams(true, false, 0, true, true)
 | |
| 
 | |
|                     Citizen.CreateThread(function()
 | |
|                         local wasDead = false 
 | |
|                     
 | |
|                         while vehicleEntity and DoesEntityExist(vehicleEntity) and not NoSignal and not LowBattery and isCameraActive and not wasDead do
 | |
|                             Citizen.Wait(1000)
 | |
|                             
 | |
|                             if DoesEntityExist(fakePlayerPed) then
 | |
|                                 if IsEntityDead(fakePlayerPed) then
 | |
|                                     if not wasDead then
 | |
|                                         wasDead = true 
 | |
|                                         DoScreenFadeOut(1000)
 | |
|                                         Wait(1000)
 | |
|                                         isCameraActive = false
 | |
|                                         Config.SetInvBusy(false)
 | |
|                                         Config.SetHudDisplay(false)
 | |
|                                         SetSeethrough(false)
 | |
|                                         SetNightvision(false)
 | |
|                                         RenderScriptCams(false, false, 0, true, true)
 | |
|                                         NuiMessage('SetCamera', { active = false })
 | |
|                                         ClearPedTasksImmediately(PlayerPedId())
 | |
|                                         SetEntityVisible(PlayerPedId(), false, false)
 | |
|                                         TaskLeaveVehicle(PlayerPedId(), vehicleEntity, 0)
 | |
|                                         local pedCoords = nil
 | |
| 
 | |
|                                         if DoesEntityExist(fakePlayerPed) then
 | |
|                                             pedCoords = GetEntityCoords(fakePlayerPed)
 | |
|                                         else
 | |
|                                             pedCoords = lastCoordsPlayer
 | |
|                                         end
 | |
| 
 | |
|                                         SetEntityCoords(PlayerPedId(), pedCoords)
 | |
|                                         DeleteEntity(fakePlayerPed)
 | |
|                                         DeleteEntity(controllerProp)
 | |
|                                         SetEntityVisible(PlayerPedId(), true, false)
 | |
|                                         SetEntityHealth(PlayerPedId(), 0)
 | |
|                                         fakePlayerPed = nil
 | |
|                                         DoScreenFadeIn(1000)
 | |
|                                         TriggerServerEvent('0r-rccar:server:saveVehicle', activeVehicle, batteryLevel)
 | |
|                                         break
 | |
|                                     end
 | |
|                                 else
 | |
|                                     wasDead = false
 | |
|                                 end
 | |
|                             end
 | |
|                         end
 | |
|                     end)
 | |
| 
 | |
|                     Citizen.CreateThread(function()
 | |
|                         while vehicleEntity and DoesEntityExist(vehicleEntity) and not NoSignal and not LowBattery and isCameraActive do
 | |
|                             Citizen.Wait(0)
 | |
|                     
 | |
|                             local playerPed = PlayerPedId()
 | |
|                             local vehicle = GetVehiclePedIsIn(playerPed, false)
 | |
|                     
 | |
|                             if vehicle ~= 0 then
 | |
|                                 if IsPedArmed(playerPed, 6) then
 | |
|                                     SetCurrentPedWeapon(playerPed, GetHashKey("WEAPON_UNARMED"), true)
 | |
|                                 end
 | |
|                             end
 | |
|                     
 | |
|                             Citizen.Wait(500)
 | |
|                         end
 | |
|                     end)
 | |
| 
 | |
|                     Citizen.CreateThread(function()
 | |
|                         while vehicleEntity and DoesEntityExist(vehicleEntity) and not NoSignal and not LowBattery and isCameraActive do
 | |
|                             local ped = PlayerPedId()
 | |
|                             local coords = GetEntityCoords(ped)
 | |
|                             local streetName, crossingRoad = GetStreetNameAtCoord(coords.x, coords.y, coords.z)
 | |
| 
 | |
|                             NuiMessage('UpdateStreet', GetStreetNameFromHashKey(streetName))
 | |
| 
 | |
|                             Wait(1000)
 | |
|                         end
 | |
|                     end)
 | |
|                     
 | |
| 
 | |
|                     if firstOpenCam then
 | |
|                         local playerdata = {
 | |
|                             fullName = nil,
 | |
|                             job = nil,
 | |
|                             grade = nil,
 | |
|                         }
 | |
| 
 | |
|                         if CoreName == 'qb-core' then
 | |
|                             local PlayerData = QBCore.Functions.GetPlayerData()
 | |
| 
 | |
|                             playerdata.fullName = PlayerData.charinfo.firstname .. ' ' .. PlayerData.charinfo.lastname
 | |
|                             playerdata.job = PlayerData.job.name
 | |
|                             playerdata.grade = PlayerData.job.grade.name
 | |
|                         elseif CoreName == 'qbx_core' then
 | |
|                             local PlayerData = QBX:GetPlayerData()
 | |
| 
 | |
|                             playerdata.Fullname = PlayerData.charinfo.firstname .. ' ' .. PlayerData.charinfo.lastname
 | |
|                             playerdata.job = PlayerData.job.name
 | |
|                             playerdata.grade = PlayerData.job.grade.name
 | |
|                         elseif CoreName == 'es_extended' then
 | |
|                             local PlayerData = ESX.GetPlayerData()
 | |
| 
 | |
|                             playerdata.Fullname = PlayerData.firstName .. ' ' .. PlayerData.lastName
 | |
|                             playerdata.job = PlayerData.job.name
 | |
|                             playerdata.grade = PlayerData.job.grade_name
 | |
|                         end
 | |
| 
 | |
|                         firstOpenCam = true
 | |
|                         NuiMessage('SetCamera', { active = true, first = true, playerData = playerdata, carName = activeVehicle.item.label })
 | |
|                     else
 | |
|                         NuiMessage('SetCamera', { active = true, first = false })
 | |
|                     end
 | |
| 
 | |
|                     Citizen.CreateThread(function()
 | |
|                         while vehicleEntity and DoesEntityExist(vehicleEntity) and not NoSignal and not LowBattery do
 | |
|                             if IsControlJustPressed(0, Config.Controls.ToggleCamera) then
 | |
|                                 if isCameraActive then
 | |
|                                     DoScreenFadeOut(1000)
 | |
|                                     Wait(1000)
 | |
|                                     isCameraActive = false
 | |
|                                     Config.SetInvBusy(false)
 | |
|                                     Config.SetHudDisplay(false)
 | |
|                                     SetSeethrough(false)
 | |
|                                     SetNightvision(false)
 | |
|                                     RenderScriptCams(false, false, 0, true, true)
 | |
|                                     NuiMessage('SetCamera', { active = false })
 | |
|                                     ClearPedTasksImmediately(PlayerPedId())
 | |
|                                     SetEntityVisible(PlayerPedId(), false, false)
 | |
|                                     TaskLeaveVehicle(PlayerPedId(), vehicleEntity, 0)
 | |
|                                     local pedCoords = nil
 | |
| 
 | |
|                                     if DoesEntityExist(fakePlayerPed) then
 | |
|                                         pedCoords = GetEntityCoords(fakePlayerPed)
 | |
|                                     else
 | |
|                                         pedCoords = lastCoordsPlayer
 | |
|                                     end
 | |
| 
 | |
|                                     SetEntityCoords(PlayerPedId(), pedCoords)
 | |
|                                     DeleteEntity(fakePlayerPed)
 | |
|                                     DeleteEntity(controllerProp)
 | |
|                                     SetEntityVisible(PlayerPedId(), true, false)
 | |
|                                     fakePlayerPed = nil
 | |
|                                     DoScreenFadeIn(1000)
 | |
|                                     TriggerServerEvent('0r-rccar:server:saveVehicle', activeVehicle, batteryLevel)
 | |
|                                     break
 | |
|                                 end
 | |
|                             end
 | |
|                             Citizen.Wait(0)
 | |
|                         end
 | |
|                     end)
 | |
| 
 | |
|                     Citizen.CreateThread(function()
 | |
|                         while true do
 | |
|                             Citizen.Wait(0)
 | |
| 
 | |
|                             if not vehicleEntity and not DoesEntityExist(vehicleEntity) and NoSignal and LowBattery and not isCameraActive then
 | |
|                                 if DoesEntityExist(fakePlayerPed) then
 | |
|                                     DeleteEntity(fakePlayerPed)
 | |
|                                     fakePlayerPed = nil
 | |
|                                     break
 | |
|                                 else
 | |
|                                     break
 | |
|                                 end
 | |
|                             end
 | |
|                         end
 | |
|                     end)
 | |
| 
 | |
|                     DoScreenFadeIn(1000)
 | |
|                 end
 | |
|             },
 | |
|             {
 | |
|                 title = Locales[Config.Locale].LUA['pick_up_vehicle_header'],
 | |
|                 description = Locales[Config.Locale].LUA['pick_up_vehicle_desc'],
 | |
|                 onSelect = function()
 | |
|                     if vehicleEntity and DoesEntityExist(vehicleEntity) then
 | |
|                         local playerPed = PlayerPedId()
 | |
|                         local playerCoords = GetEntityCoords(playerPed)
 | |
|                         local carCoords = GetEntityCoords(vehicleEntity)
 | |
|                         local distance = #(playerCoords - carCoords)
 | |
| 
 | |
|                         if distance < 5 then
 | |
|                             PlayAnimation('pickup_object')
 | |
|                             Citizen.Wait(750)
 | |
|                             DeleteEntity(vehicleEntity)
 | |
|                             RemoveBlip(vehicleBlip)
 | |
|                             NuiMessage('ResetExtensions')
 | |
|                             vehicleEntity = nil
 | |
|                             vehicleBlip = nil
 | |
|                             vehicleCamera = nil
 | |
|                             isCameraActive = false
 | |
|                             RotSync = true
 | |
|                             controllerProp = nil
 | |
|                             firstAwayNotification = false
 | |
|                             secondAwayNotification = false
 | |
|                             threeAwayNotification = false
 | |
|                             NoSignal = false
 | |
|                             LowBattery = false
 | |
|                             fakePlayerPed = nil
 | |
|                             DataShow = false
 | |
|                             ActivePlayer = {
 | |
|                                 type = nil,
 | |
|                                 ped = nil,
 | |
|                                 name = nil,
 | |
|                                 image = nil,
 | |
|                                 plate = nil,
 | |
|                                 birthDate = nil
 | |
|                             }
 | |
|                             storeBlips = {}
 | |
|                             chargingStationBlips = {}
 | |
|                             storePed = {}
 | |
|                             chargingStationPed = {}
 | |
|                             storeProducts = {}
 | |
|                             activeVehicle = {}
 | |
|                             activePlugins = {}
 | |
|                             firstOpenCam = true
 | |
|                             maxFov = 100.0
 | |
|                             batteryProtector = false
 | |
|                             signalBooster = 1.0
 | |
|                             batteryLevel = 100
 | |
|                             activePlugin = nil
 | |
|                             usedChargingStation = nil
 | |
|                             usedChargingStationItem = nil
 | |
|                         end
 | |
|                     end
 | |
|                 end,
 | |
|             },
 | |
|             {
 | |
|                 title = Locales[Config.Locale].LUA['manage_vehicle_ext_header'],
 | |
|                 description = Locales[Config.Locale].LUA['manage_vehicle_ext_desc'],
 | |
|                 onSelect = function()
 | |
|                     lib.hideContext(true)
 | |
|                     GetExtensions()
 | |
|                 end,
 | |
|             },
 | |
|         }
 | |
|     })
 | |
|     
 | |
|     lib.showContext('manage_rccar_menu')
 | |
| end
 | |
| 
 | |
| local function tableLength(t)
 | |
|     local count = 0
 | |
|     for _ in pairs(t) do
 | |
|         count = count + 1
 | |
|     end
 | |
|     return count
 | |
| end
 | |
| 
 | |
| function GetExtensions()
 | |
| 
 | |
|     local extensions = {}
 | |
| 
 | |
|     local temp_extensions = promise.new()
 | |
| 
 | |
|     lib.callback('0r-rccar:server:getActivePlugins', false, function(data)
 | |
|         temp_extensions:resolve(data)
 | |
|     end, activeVehicle)
 | |
|     local resolved_extensions = Citizen.Await(temp_extensions)
 | |
| 
 | |
|     local data = json.decode(resolved_extensions)
 | |
| 
 | |
|     if data and type(data) == "table" and tableLength(data) > 0 then
 | |
|         for k, v in pairs(data) do
 | |
|             table.insert(extensions, {
 | |
|                 title = v.label,
 | |
|                 description = v.description,
 | |
|                 onSelect = function()
 | |
|                     lib.hideContext(true)
 | |
|                     RemoveExtension(activeVehicle, v)
 | |
|                 end
 | |
|             })
 | |
|         end
 | |
|     else
 | |
|         extensions = {
 | |
|             {
 | |
|                 title = Locales[Config.Locale].LUA['no_extensions_found'],
 | |
|             }
 | |
|         }
 | |
|     end
 | |
| 
 | |
|     table.insert(extensions, {
 | |
|         title = Locales[Config.Locale].LUA['add_extension'],
 | |
|         onSelect = function()
 | |
|             lib.hideContext(true)
 | |
|             AddExtension(activeVehicle)
 | |
|         end
 | |
|     })
 | |
| 
 | |
|     table.insert(extensions, {
 | |
|         title = Locales[Config.Locale].LUA['return_back'],
 | |
|         menu = 'manage_rccar_menu',
 | |
|     })
 | |
| 
 | |
|     lib.registerContext({
 | |
|         id = 'manage_rccar_extensions',
 | |
|         title = Locales[Config.Locale].LUA['manage_vehicle_ext_header'],
 | |
|         options = extensions
 | |
|     })
 | |
| 
 | |
|     lib.showContext('manage_rccar_extensions')
 | |
| end
 | |
| 
 | |
| function RemoveExtension(data, removedExtension)
 | |
|     lib.registerContext({
 | |
|         id = 'remove_rccar_extensions',
 | |
|         title = string.format(Locales[Config.Locale].LUA['remove_extension'], removedExtension.label),
 | |
|         options = {
 | |
|             {
 | |
|                 title = Locales[Config.Locale].LUA['yes'],
 | |
|                 onSelect = function()
 | |
|                     local temp_remove = promise.new()
 | |
| 
 | |
|                     lib.callback('0r-rccar:server:removeExtension', false, function(data)
 | |
|                         temp_remove:resolve(data)
 | |
|                     end, data, removedExtension)
 | |
|                     local resolved_remove = Citizen.Await(temp_remove)
 | |
| 
 | |
|                     if resolved_remove then
 | |
|                         GetExtensions()
 | |
|                     end
 | |
|                 end,
 | |
|             },
 | |
|             {
 | |
|                 title = Locales[Config.Locale].LUA['no'],
 | |
|                 onSelect = function()
 | |
|                     lib.hideContext(true)
 | |
|                     GetExtensions()
 | |
|                 end,
 | |
|             },
 | |
|         }
 | |
|     })
 | |
| 
 | |
|     lib.showContext('remove_rccar_extensions')
 | |
| end
 | |
| 
 | |
| function AddExtension(activeVehicle)
 | |
| 
 | |
|     local extensions = {}
 | |
| 
 | |
|     local temp_extensions = promise.new()
 | |
| 
 | |
|     lib.callback('0r-rccar:server:getNewExtensions', false, function(data)
 | |
|         temp_extensions:resolve(data)
 | |
|     end, activeVehicle)
 | |
|     local resolved_extensions = Citizen.Await(temp_extensions)
 | |
| 
 | |
|     if resolved_extensions and type(resolved_extensions) == "table" and tableLength(resolved_extensions) > 0 then
 | |
|         for k, v in pairs(resolved_extensions) do
 | |
|             table.insert(extensions, {
 | |
|                 title = v.item.label,
 | |
|                 description = v.item.description,
 | |
|                 onSelect = function()
 | |
|                     local temp_add = promise.new()
 | |
| 
 | |
|                     lib.callback('0r-rccar:server:addExtension', false, function(x)
 | |
|                         temp_add:resolve(x)
 | |
|                     end, activeVehicle, v)
 | |
|                     local resolved_add = Citizen.Await(temp_add)
 | |
| 
 | |
|                     if resolved_add then
 | |
|                         GetExtensions()
 | |
|                     end
 | |
|                 end
 | |
|             })
 | |
|         end
 | |
|     else
 | |
|         extensions = {
 | |
|             {
 | |
|                 title = Locales[Config.Locale].LUA['no_extensions_found'],
 | |
|             }
 | |
|         }
 | |
|     end
 | |
| 
 | |
|     table.insert(extensions, {
 | |
|         title = Locales[Config.Locale].LUA['return_back'],
 | |
|         menu = 'manage_rccar_extensions',
 | |
|     })
 | |
| 
 | |
|     lib.registerContext({
 | |
|         id = 'add_rccar_extensions',
 | |
|         title = Locales[Config.Locale].LUA['add_extension'],
 | |
|         options = extensions
 | |
|     })
 | |
| 
 | |
|     lib.showContext('add_rccar_extensions')
 | |
| end
 | |
| 
 | |
| --  ██████╗ ███████╗████████╗    ███████╗████████╗██████╗ ███████╗███████╗████████╗    ███╗   ██╗ █████╗ ███╗   ███╗███████╗
 | |
| -- ██╔════╝ ██╔════╝╚══██╔══╝    ██╔════╝╚══██╔══╝██╔══██╗██╔════╝██╔════╝╚══██╔══╝    ████╗  ██║██╔══██╗████╗ ████║██╔════╝
 | |
| -- ██║  ███╗█████╗     ██║       ███████╗   ██║   ██████╔╝█████╗  █████╗     ██║       ██╔██╗ ██║███████║██╔████╔██║█████╗  
 | |
| -- ██║   ██║██╔══╝     ██║       ╚════██║   ██║   ██╔══██╗██╔══╝  ██╔══╝     ██║       ██║╚██╗██║██╔══██║██║╚██╔╝██║██╔══╝  
 | |
| -- ╚██████╔╝███████╗   ██║       ███████║   ██║   ██║  ██║███████╗███████╗   ██║       ██║ ╚████║██║  ██║██║ ╚═╝ ██║███████╗
 | |
| --  ╚═════╝ ╚══════╝   ╚═╝       ╚══════╝   ╚═╝   ╚═╝  ╚═╝╚══════╝╚══════╝   ╚═╝       ╚═╝  ╚═══╝╚═╝  ╚═╝╚═╝     ╚═╝╚══════╝
 | |
| 
 | |
| local function GetStreetName()
 | |
|     local playerPed = PlayerPedId()
 | |
|     local playerCoords = GetEntityCoords(playerPed)
 | |
|     local streetName, crossing = GetStreetNameAtCoord(playerCoords.x, playerCoords.y, playerCoords.z)
 | |
|     local streetName = GetStreetNameFromHashKey(streetName)
 | |
| 
 | |
|     return streetName
 | |
| end
 | |
| 
 | |
| --  ██████╗██████╗ ███████╗ █████╗ ████████╗█████`██╗    ████████╗██╗  ██╗██████╗ ███████╗ █████╗ ██████╗ 
 | |
| -- ██╔════╝██╔══██╗██╔════╝██╔══██╗╚══██╔══╝██╔════╝    ╚══██╔══╝██║  ██║██╔══██╗██╔════╝██╔══██╗██╔══██╗
 | |
| -- ██║     ██████╔╝█████╗  ███████║   ██║   █████╗         ██║   ███████║██████╔╝█████╗  ███████║██║  ██║
 | |
| -- ██║     ██╔══██╗██╔══╝  ██╔══██║   ██║   ██╔══╝         ██║   ██╔══██║██╔══██╗██╔══╝  ██╔══██║██║  ██║
 | |
| -- ╚██████╗██║  ██║███████╗██║  ██║   ██║   ███████╗       ██║   ██║  ██║██║  ██║███████╗██║  ██║██████╔╝
 | |
| --  ╚═════╝╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝   ╚═╝   ╚══════╝       ╚═╝   ╚═╝  ╚═╝╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝╚═════╝ 
 | |
| --  ██████╗██╗  ██╗███████╗ ██████╗██╗  ██╗    ███╗   ██╗██╗   ██╗██╗
 | |
| -- ██╔════╝██║  ██║██╔════╝██╔════╝██║ ██╔╝    ████╗  ██║██║   ██║██║
 | |
| -- ██║     ███████║█████╗  ██║     █████╔╝     ██╔██╗ ██║██║   ██║██║
 | |
| -- ██║     ██╔══██║██╔══╝  ██║     ██╔═██╗     ██║╚██╗██║██║   ██║██║
 | |
| -- ╚██████╗██║  ██║███████╗╚██████╗██║  ██╗    ██║ ╚████║╚██████╔╝██║
 | |
| --  ╚═════╝╚═╝  ╚═╝╚══════╝ ╚═════╝╚═╝  ╚═╝    ╚═╝  ╚═══╝ ╚═════╝ ╚═╝
 | |
| 
 | |
| Citizen.CreateThread(function()
 | |
|     while not nuiLoaded do
 | |
|         if NetworkIsSessionStarted() then
 | |
|             SendNUIMessage({
 | |
|                 action = "CheckNui",
 | |
|             })
 | |
|         end
 | |
|         Citizen.Wait(2000)
 | |
|     end
 | |
| end)
 | |
| 
 | |
| Citizen.CreateThread(function()
 | |
|     for k, v in pairs(Config.Stores) do
 | |
|         if not storeProducts[k] then
 | |
|             storeProducts[k] = {}
 | |
|         end
 | |
| 
 | |
|         if v.items ~= "all" then
 | |
|             for _, car in pairs(Config.RCCars) do
 | |
|                 if v.items and v.items[car.item.name] then
 | |
|                     table.insert(storeProducts[k], car)
 | |
|                 end
 | |
|             end
 | |
|         end
 | |
|     end
 | |
| end)
 | |
| 
 | |
| Citizen.CreateThread(function()
 | |
|     NuiMessage('SetLocale', Locales[Config.Locale].WEB)
 | |
| end)
 | |
| 
 | |
| -- ██████╗ ███████╗ ██████╗ ██╗███████╗████████╗███████╗██████╗     ███████╗██╗   ██╗███████╗███╗   ██╗████████╗
 | |
| -- ██╔══██╗██╔════╝██╔════╝ ██║██╔════╝╚══██╔══╝██╔════╝██╔══██╗    ██╔════╝██║   ██║██╔════╝████╗  ██║╚══██╔══╝
 | |
| -- ██████╔╝█████╗  ██║  ███╗██║███████╗   ██║   █████╗  ██████╔╝    █████╗  ██║   ██║█████╗  ██╔██╗ ██║   ██║   
 | |
| -- ██╔══██╗██╔══╝  ██║   ██║██║╚════██║   ██║   ██╔══╝  ██╔══██╗    ██╔══╝  ╚██╗ ██╔╝██╔══╝  ██║╚██╗██║   ██║   
 | |
| -- ██║  ██║███████╗╚██████╔╝██║███████║   ██║   ███████╗██║  ██║    ███████╗ ╚████╔╝ ███████╗██║ ╚████║   ██║   
 | |
| -- ╚═╝  ╚═╝╚══════╝ ╚═════╝ ╚═╝╚══════╝   ╚═╝   ╚══════╝╚═╝  ╚═╝    ╚══════╝  ╚═══╝  ╚══════╝╚═╝  ╚═══╝   ╚═╝   
 | |
| 
 | |
| RegisterNetEvent('onResourceStart')
 | |
| AddEventHandler('onResourceStart', function(resource)
 | |
|     if resource == GetCurrentResourceName() then
 | |
|         CreateShops()
 | |
| 
 | |
|         if Config.ChargeSystem then
 | |
|             CreateChargingStation()
 | |
|         end
 | |
|     end
 | |
| end)
 | |
| 
 | |
| --  ██████╗ ███╗   ██╗    ██████╗ ███████╗███████╗ ██████╗ ██╗   ██╗██████╗  ██████╗███████╗    ███████╗████████╗ ██████╗ ██████╗ 
 | |
| -- ██╔═══██╗████╗  ██║    ██╔══██╗██╔════╝██╔════╝██╔═══██╗██║   ██║██╔══██╗██╔════╝██╔════╝    ██╔════╝╚══██╔══╝██╔═══██╗██╔══██╗
 | |
| -- ██║   ██║██╔██╗ ██║    ██████╔╝█████╗  ███████╗██║   ██║██║   ██║██████╔╝██║     █████╗      ███████╗   ██║   ██║   ██║██████╔╝
 | |
| -- ██║   ██║██║╚██╗██║    ██╔══██╗██╔══╝  ╚════██║██║   ██║██║   ██║██╔══██╗██║     ██╔══╝      ╚════██║   ██║   ██║   ██║██╔═══╝ 
 | |
| -- ╚██████╔╝██║ ╚████║    ██║  ██║███████╗███████║╚██████╔╝╚██████╔╝██║  ██║╚██████╗███████╗    ███████║   ██║   ╚██████╔╝██║     
 | |
| --  ╚═════╝ ╚═╝  ╚═══╝    ╚═╝  ╚═╝╚══════╝╚══════╝ ╚═════╝  ╚═════╝ ╚═╝  ╚═╝ ╚═════╝╚══════╝    ╚══════╝   ╚═╝    ╚═════╝ ╚═╝     
 | |
| 
 | |
| RegisterNetEvent('onResourceStop')
 | |
| AddEventHandler('onResourceStop', function(resource)
 | |
|     if resource == GetCurrentResourceName() then
 | |
|         DoScreenFadeIn(1000)
 | |
|         if vehicleEntity or DoesEntityExist(vehicleEntity) then
 | |
|             DeleteEntity(vehicleEntity)
 | |
|         end
 | |
| 
 | |
|         if vehicleBlip or DoesBlipExist(vehicleBlip) then
 | |
|             RemoveBlip(vehicleBlip)
 | |
|         end
 | |
| 
 | |
|         if vehicleCamera or DoesCamExist(vehicleCamera) then
 | |
|             DestroyCam(vehicleCamera)
 | |
|         end
 | |
| 
 | |
|         if controllerProp or DoesEntityExist(controllerProp) then
 | |
|             DeleteEntity(controllerProp)
 | |
|         end
 | |
| 
 | |
|         if fakePlayerPed or DoesEntityExist(fakePlayerPed) then
 | |
|             DeleteEntity(fakePlayerPed)
 | |
|             DoScreenFadeIn(1000)
 | |
|         end
 | |
| 
 | |
|         if #storeBlips > 0 then
 | |
|             for k, v in pairs(storeBlips) do
 | |
|                 if DoesBlipExist(v) then
 | |
|                     RemoveBlip(v)
 | |
|                 end
 | |
|             end
 | |
|         end
 | |
| 
 | |
|         if #storePed > 0 then
 | |
|             for k, v in pairs(storePed) do
 | |
|                 if DoesEntityExist(v) then
 | |
|                     DeleteEntity(v)
 | |
|                 end
 | |
|             end
 | |
|         end
 | |
| 
 | |
|         if #chargingStationBlips > 0 then
 | |
|             for k, v in pairs(chargingStationBlips) do
 | |
|                 if DoesBlipExist(v) then
 | |
|                     RemoveBlip(v)
 | |
|                 end
 | |
|             end
 | |
|         end
 | |
| 
 | |
|         if #chargingStationPed > 0 then
 | |
|             for k, v in pairs(chargingStationPed) do
 | |
|                 if DoesEntityExist(v) then
 | |
|                     DeleteEntity(v)
 | |
|                 end
 | |
|             end
 | |
|         end
 | |
| 
 | |
|         SetSeethrough(false)
 | |
|         SetNightvision(false)
 | |
| 
 | |
|         ClearPedTasks(PlayerPedId())
 | |
|     end
 | |
| end)
 | |
| 
 | |
| RegisterNetEvent('QBCore:Client:OnPlayerLoaded')
 | |
| AddEventHandler('QBCore:Client:OnPlayerLoaded', function()
 | |
|     if CoreName == 'qb-core' then
 | |
|         PlayerData = QBCore.Functions.GetPlayerData()
 | |
|     elseif CoreName == 'qbx_core' then
 | |
|         PlayerData = QBX:GetPlayerData()
 | |
|     end
 | |
|     CreateShops()
 | |
| 
 | |
|     if Config.ChargeSystem then
 | |
|         CreateChargingStation()
 | |
|     end
 | |
| end)
 | |
| 
 | |
| RegisterNetEvent('esx:playerLoaded')
 | |
| AddEventHandler('esx:playerLoaded',function(xPlayer, isNew, skin)
 | |
|     PlayerData = xPlayer
 | |
|     CreateShops()
 | |
| 
 | |
|     if Config.ChargeSystem then
 | |
|         CreateChargingStation()
 | |
|     end
 | |
| end)
 | |
| 
 | |
| RegisterNetEvent('esx:setJob')
 | |
| AddEventHandler('esx:setJob',function(job, lastJob)
 | |
|     PlayerData.job = job
 | |
| end)
 | |
| 
 | |
| RegisterNetEvent('QBCore:Client:OnJobUpdate', function(job)
 | |
|     PlayerData.job = job
 | |
| end)
 | |
| 
 | |
| -- ███████╗██████╗  █████╗ ██╗    ██╗███╗   ██╗    ██╗   ██╗███████╗██╗  ██╗██╗ ██████╗██╗     ███████╗
 | |
| -- ██╔════╝██╔══██╗██╔══██╗██║    ██║████╗  ██║    ██║   ██║██╔════╝██║  ██║██║██╔════╝██║     ██╔════╝
 | |
| -- ███████╗██████╔╝███████║██║ █╗ ██║██╔██╗ ██║    ██║   ██║█████╗  ███████║██║██║     ██║     █████╗  
 | |
| -- ╚════██║██╔═══╝ ██╔══██║██║███╗██║██║╚██╗██║    ╚██╗ ██╔╝██╔══╝  ██╔══██║██║██║     ██║     ██╔══╝  
 | |
| -- ███████║██║     ██║  ██║╚███╔███╔╝██║ ╚████║     ╚████╔╝ ███████╗██║  ██║██║╚██████╗███████╗███████╗
 | |
| -- ╚══════╝╚═╝     ╚═╝  ╚═╝ ╚══╝╚══╝ ╚═╝  ╚═══╝      ╚═══╝  ╚══════╝╚═╝  ╚═╝╚═╝ ╚═════╝╚══════╝╚══════╝
 | |
| 
 | |
| function SpawnVehicle(type)
 | |
|     local playerPed = PlayerPedId()
 | |
|     local playerCoords = GetEntityCoords(playerPed)
 | |
|     vehicleEntity = nil
 | |
| 
 | |
|     RequestModel(type)
 | |
|     local time = GetGameTimer()
 | |
|     while not HasModelLoaded(type) do
 | |
|         Citizen.Wait(0)
 | |
|         if GetGameTimer() - time > 5000 then
 | |
|             print(string.format(Locales[Config.Locale].LUA['failed_to_load_model'], type))
 | |
|             return
 | |
|         end
 | |
|     end
 | |
| 
 | |
|     PlayAnimation('put_object')
 | |
|     Wait(700)
 | |
|     local frontCoords = GetOffsetFromEntityInWorldCoords(playerPed, 0.0, 1.0, 0.0)
 | |
|     vehicleEntity = CreateVehicle(type, frontCoords, GetEntityHeading(playerPed), true, false)
 | |
|     SetModelAsNoLongerNeeded(type)
 | |
|     SetVehicleOnGroundProperly(vehicleEntity)
 | |
|     SetVehicleEngineOn(vehicleEntity, true, true, false)
 | |
|     SetVehicleModKit(vehicleEntity, 0)
 | |
|     SetVehicleMod(vehicleEntity, 433, math.random(0, GetNumVehicleMods(vehicleEntity, 433)), false)
 | |
|     SetEntityAsMissionEntity(vehicleEntity, true, true)
 | |
|     SetVehicleHasBeenOwnedByPlayer(vehicleEntity, true)
 | |
|     SetVehicleDoorsLocked(vehicleEntity, 2)
 | |
| 
 | |
|     if activeVehicle.item.name == 'rc_bandito_offroad' then
 | |
|         SetVehicleMod(vehicleEntity, 5, 3)
 | |
|     elseif activeVehicle.item.name == 'rc_bandito_trophy' then
 | |
|         SetVehicleMod(vehicleEntity, 5, 7)
 | |
|     elseif activeVehicle.item.name == 'rc_bandito_gang' then
 | |
|         SetVehicleMod(vehicleEntity, 5, 11)
 | |
|     elseif activeVehicle.item.name == 'rc_bandito_big' then
 | |
|         SetVehicleMod(vehicleEntity, 5, 15)
 | |
|         SetVehicleCustomPrimaryColour(vehicleEntity, 3, 36, 252)
 | |
|         SetVehicleCustomSecondaryColour(vehicleEntity, 3, 36, 252)
 | |
|     elseif activeVehicle.item.name == 'rc_bandito_midnight' then
 | |
|         SetVehicleMod(vehicleEntity, 5, 19)
 | |
|     end
 | |
| 
 | |
|     Config.GiveKeys(GetVehicleNumberPlateText(vehicleEntity), vehicleEntity)
 | |
| 
 | |
|     if Config.DisableCollision then
 | |
|         SetEntityNoCollisionEntity(vehicleEntity, playerPed, false)
 | |
|         Citizen.CreateThread(function()
 | |
|             while DoesEntityExist(vehicleEntity) do
 | |
|                 Citizen.Wait(5000)
 | |
|                 local players = GetActivePlayers()
 | |
|                 for _, player in pairs(players) do
 | |
|                     local playerPed = GetPlayerPed(player)
 | |
|                     SetEntityNoCollisionEntity(vehicleEntity, playerPed, false)
 | |
|                 end
 | |
|             end
 | |
|         end)
 | |
|     end
 | |
| end
 | |
| 
 | |
| -- ███████╗██████╗  █████╗ ██╗    ██╗███╗   ██╗    ██████╗ ███████╗██████╗ 
 | |
| -- ██╔════╝██╔══██╗██╔══██╗██║    ██║████╗  ██║    ██╔══██╗██╔════╝██╔══██╗
 | |
| -- ███████╗██████╔╝███████║██║ █╗ ██║██╔██╗ ██║    ██████╔╝█████╗  ██║  ██║
 | |
| -- ╚════██║██╔═══╝ ██╔══██║██║███╗██║██║╚██╗██║    ██╔═══╝ ██╔══╝  ██║  ██║
 | |
| -- ███████║██║     ██║  ██║╚███╔███╔╝██║ ╚████║    ██║     ███████╗██████╔╝
 | |
| -- ╚══════╝╚═╝     ╚═╝  ╚═╝ ╚══╝╚══╝ ╚═╝  ╚═══╝    ╚═╝     ╚══════╝╚═════╝ 
 | |
| 
 | |
| function SpawnPed()
 | |
|     local playerPed = PlayerPedId()
 | |
|     local playerCoords = GetEntityCoords(playerPed)
 | |
|     local playerModel = GetEntityModel(playerPed)
 | |
| 
 | |
|     RequestModel(playerModel)
 | |
|     while not HasModelLoaded(playerModel) do
 | |
|         Wait(0)
 | |
|     end
 | |
| 
 | |
|     lastCoordsPlayer = playerCoords
 | |
|     local spawnCoords = vector3(playerCoords.x, playerCoords.y, playerCoords.z)
 | |
| 
 | |
|     local temp_model = promise.new()
 | |
|     local temp_data = promise.new()
 | |
| 
 | |
|     lib.callback('0r-rccar:server:getSkin', false, function(model, data)
 | |
|         temp_model:resolve(model)
 | |
|         temp_data:resolve(data)
 | |
|     end)
 | |
|     local resolved_model = Citizen.Await(temp_model)
 | |
|     local resolved_data = Citizen.Await(temp_data)
 | |
|     
 | |
|     skinData = { model = resolved_model, data = resolved_data }
 | |
|     
 | |
|     fakePlayerPed = CreatePed(4, playerModel, spawnCoords.x, spawnCoords.y, spawnCoords.z, 0.0, true, false)
 | |
|     SetBlockingOfNonTemporaryEvents(fakePlayerPed, true)
 | |
|     SetEntityHeading(fakePlayerPed, GetEntityHeading(playerPed))
 | |
|     SetEntityVisible(fakePlayerPed, false, false)
 | |
|     
 | |
|     SetModelAsNoLongerNeeded(playerModel)
 | |
|     SetEntityAsMissionEntity(fakePlayerPed, true, true)
 | |
|     SetEntityVisible(fakePlayerPed, true, false)
 | |
|     ApplyCharacterCustomization(fakePlayerPed, skinData.data)
 | |
| end
 | |
| 
 | |
| -- ███████╗███████╗████████╗    ██████╗ ██╗     ██╗██████╗ 
 | |
| -- ██╔════╝██╔════╝╚══██╔══╝    ██╔══██╗██║     ██║██╔══██╗
 | |
| -- ███████╗█████╗     ██║       ██████╔╝██║     ██║██████╔╝
 | |
| -- ╚════██║██╔══╝     ██║       ██╔══██╗██║     ██║██╔═══╝ 
 | |
| -- ███████║███████╗   ██║       ██████╔╝███████╗██║██║     
 | |
| -- ╚══════╝╚══════╝   ╚═╝       ╚═════╝ ╚══════╝╚═╝╚═╝     
 | |
| 
 | |
| function SetBlip()
 | |
|     if DoesEntityExist(vehicleEntity) and Config.BlipSettings.Vehicle.active then
 | |
|         local vehicleCoords = GetEntityCoords(vehicleEntity, true)
 | |
|         vehicleBlip = AddBlipForCoord(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z)
 | |
|         SetBlipSprite(vehicleBlip, Config.BlipSettings.Vehicle.sprite)
 | |
|         SetBlipColour(vehicleBlip, Config.BlipSettings.Vehicle.color)
 | |
|         SetBlipScale(vehicleBlip, Config.BlipSettings.Vehicle.scale)
 | |
|         SetBlipAsShortRange(vehicleBlip, true)
 | |
|         BeginTextCommandSetBlipName("STRING")
 | |
|         AddTextComponentSubstringPlayerName(Config.BlipSettings.Vehicle.name)
 | |
|         EndTextCommandSetBlipName(vehicleBlip)
 | |
|     end
 | |
| 
 | |
|     Citizen.CreateThread(function()
 | |
|         while vehicleEntity do
 | |
|             if DoesEntityExist(vehicleEntity) and Config.BlipSettings.Vehicle.active then
 | |
|                 local updatedCoords = GetEntityCoords(vehicleEntity, true)
 | |
|                 SetBlipCoords(vehicleBlip, updatedCoords.x, updatedCoords.y, updatedCoords.z)
 | |
|             else
 | |
|                 RemoveBlip(vehicleBlip)
 | |
|                 vehicleBlip = nil
 | |
|                 break
 | |
|             end
 | |
|             Citizen.Wait(2000)
 | |
|         end
 | |
|     end)
 | |
| end
 | |
| 
 | |
| -- ███████╗███████╗████████╗     ██████╗ █████╗ ███╗   ███╗
 | |
| -- ██╔════╝██╔════╝╚══██╔══╝    ██╔════╝██╔══██╗████╗ ████║
 | |
| -- ███████╗█████╗     ██║       ██║     ███████║██╔████╔██║
 | |
| -- ╚════██║██╔══╝     ██║       ██║     ██╔══██║██║╚██╔╝██║
 | |
| -- ███████║███████╗   ██║       ╚██████╗██║  ██║██║ ╚═╝ ██║
 | |
| -- ╚══════╝╚══════╝   ╚═╝        ╚═════╝╚═╝  ╚═╝╚═╝     ╚═╝
 | |
| 
 | |
| function SetCam()
 | |
|     vehicleCamera = CreateCam("DEFAULT_SCRIPTED_CAMERA", true)
 | |
|     AttachCamToEntity(vehicleCamera, vehicleEntity, 0.0, 0.0, 0.4, true)
 | |
|     SetCamRot(vehicleCamera, GetEntityRotation(vehicleEntity))
 | |
| end
 | |
| 
 | |
| --  ██████╗██╗  ██╗███████╗ ██████╗██╗  ██╗    ██████╗ ██╗     ██╗   ██╗ ██████╗ ██╗███╗   ██╗███████╗
 | |
| -- ██╔════╝██║  ██║██╔════╝██╔════╝██║ ██╔╝    ██╔══██╗██║     ██║   ██║██╔════╝ ██║████╗  ██║██╔════╝
 | |
| -- ██║     ███████║█████╗  ██║     █████╔╝     ██████╔╝██║     ██║   ██║██║  ███╗██║██╔██╗ ██║███████╗
 | |
| -- ██║     ██╔══██║██╔══╝  ██║     ██╔═██╗     ██╔═══╝ ██║     ██║   ██║██║   ██║██║██║╚██╗██║╚════██║
 | |
| -- ╚██████╗██║  ██║███████╗╚██████╗██║  ██╗    ██║     ███████╗╚██████╔╝╚██████╔╝██║██║ ╚████║███████║
 | |
| --  ╚═════╝╚═╝  ╚═╝╚══════╝ ╚═════╝╚═╝  ╚═╝    ╚═╝     ╚══════╝ ╚═════╝  ╚═════╝ ╚═╝╚═╝  ╚═══╝╚══════╝
 | |
| 
 | |
| function CheckPlugins()
 | |
|     if activePlugins then
 | |
|         for k, v in pairs(activePlugins) do
 | |
|             if v.name == 'rc_advancedcamera' then
 | |
|                 StartPlugins('AdvancedCamera')
 | |
|             end
 | |
|     
 | |
|             if v.name == 'rc_nitrous' then
 | |
|                 StartPlugins('Nitrous')
 | |
|             end
 | |
|     
 | |
|             if v.name == 'rc_battery' then
 | |
|                 StartPlugins('BatteryProtector')
 | |
|             end
 | |
|     
 | |
|             if v.name == 'rc_signal' then
 | |
|                 StartPlugins('SignalBooster')
 | |
|             end
 | |
|     
 | |
|             if v.name == 'rc_bomb' then
 | |
|                 NuiMessage('StartPlugins', { type = 'Bomb', status = true })
 | |
|             end
 | |
|     
 | |
|             if v.name == 'rc_jump' then
 | |
|                 StartPlugins('Jump')
 | |
|             end
 | |
|     
 | |
|             if v.name == 'rc_teaser' then
 | |
|                 NuiMessage('StartPlugins', { type = 'Teaser', status = true })
 | |
|             end
 | |
|         end
 | |
|     end
 | |
| 
 | |
|     if activeVehicle and activeVehicle.item and activeVehicle.item.type and activeVehicle.item.type == 'emergency' then
 | |
|         NuiMessage('StartPlugins', { type = 'ScanIdentifier', status = true })
 | |
|     end
 | |
| end
 | |
| 
 | |
| function StartPlugins(type)
 | |
|     if type == 'AdvancedCamera' then
 | |
|         local activeFilter = 'NRM'
 | |
|         Citizen.CreateThread(function()
 | |
|             while vehicleEntity and DoesEntityExist(vehicleEntity) and not NoSignal and not LowBattery and isCameraActive do
 | |
|                 if IsControlJustPressed(0, Config.Controls.ChangeCameraFilter) then
 | |
|                     if activeFilter == 'NRM' then
 | |
|                         activeFilter = 'NGTV'
 | |
|                         SetNightvision(true)
 | |
|                     elseif activeFilter == 'NGTV' then
 | |
|                         activeFilter = 'THRML'
 | |
|                         SetNightvision(false)
 | |
|                         SetSeethrough(true)
 | |
|                     elseif activeFilter == 'THRML' then
 | |
|                         activeFilter = 'NRM'
 | |
|                         SetSeethrough(false)
 | |
|                     end
 | |
|     
 | |
|                     NuiMessage('ChangeCameraType', activeFilter)
 | |
|                 end
 | |
|     
 | |
|                 Citizen.Wait(0)
 | |
|             end
 | |
|         end)
 | |
|     end
 | |
| 
 | |
|     if type == 'Nitrous' then
 | |
|         local nitrousActive = false
 | |
|         local usableNitro = true
 | |
| 
 | |
|         Citizen.CreateThread(function()
 | |
|             while vehicleEntity and DoesEntityExist(vehicleEntity) and not NoSignal and not LowBattery and isCameraActive do
 | |
|                 Citizen.Wait(0)
 | |
| 
 | |
|                 local ped = PlayerPedId()
 | |
|                 if IsPedInAnyVehicle(ped, false) then
 | |
|                     local vehicle = GetVehiclePedIsIn(ped, false)
 | |
| 
 | |
|                     if IsControlPressed(0, Config.Controls.NitrousKey) and usableNitro then
 | |
|                         SetVehicleEngineTorqueMultiplier(vehicle, Config.NitrousPower)
 | |
| 
 | |
|                         ModifyVehicleTopSpeed(vehicle, 50.0)
 | |
|                         SetVehicleReduceGrip(vehicle, false)
 | |
| 
 | |
|                         nitrousActive = true
 | |
|                     else
 | |
|                         SetVehicleEngineTorqueMultiplier(vehicle, 1.0)
 | |
|                         ModifyVehicleTopSpeed(vehicle, 0.0)
 | |
|                         SetVehicleReduceGrip(vehicle, false)
 | |
| 
 | |
|                         nitrousActive = false
 | |
|                     end
 | |
|                 else
 | |
|                     SetVehicleEngineTorqueMultiplier(GetVehiclePedIsIn(ped, true), 1.0)
 | |
| 
 | |
|                     nitrousActive = false
 | |
|                 end
 | |
|             end
 | |
|         end)
 | |
| 
 | |
|         local usedTime = 0
 | |
|         Citizen.CreateThread(function()
 | |
|             
 | |
|             while vehicleEntity and DoesEntityExist(vehicleEntity) and not NoSignal and not LowBattery and isCameraActive do
 | |
|                 Citizen.Wait(1000)
 | |
| 
 | |
|                 if nitrousActive then
 | |
|                     usedTime = usedTime + 1000
 | |
|                     if usedTime >= 5000 then
 | |
|                         usableNitro = false
 | |
| 
 | |
|                         SetTimeout(30000, function()
 | |
|                             usableNitro = true
 | |
|                             usedTime = 0
 | |
|                         end)
 | |
|                     end
 | |
|                 end
 | |
|             end
 | |
|         end)
 | |
|     end
 | |
| 
 | |
|     if type == 'BatteryProtector' then
 | |
|         batteryProtector = true
 | |
|     end
 | |
| 
 | |
|     if type == 'SignalBooster' then
 | |
|         signalBooster = Config.SignalBooster
 | |
|     end
 | |
| 
 | |
|     if type == 'Bomb' then
 | |
|         return true
 | |
|     end
 | |
| 
 | |
|     if type == 'Jump' then
 | |
|         local lastUsed = 0
 | |
|         Citizen.CreateThread(function()
 | |
|             while vehicleEntity and DoesEntityExist(vehicleEntity) and not NoSignal and not LowBattery and isCameraActive do
 | |
|                 Citizen.Wait(0)
 | |
| 
 | |
|                 local ped = PlayerPedId()
 | |
|                 if IsPedInAnyVehicle(ped, false) then
 | |
|                     local vehicle = GetVehiclePedIsIn(ped, false)
 | |
| 
 | |
|                     if IsControlJustPressed(1, Config.Controls.JumpKey) and (GetGameTimer() - lastUsed > 2000) then
 | |
|                         lastUsed = GetGameTimer()
 | |
| 
 | |
|                         ApplyForceToEntity(vehicle, 1, 0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0, true, true, true, true, true)
 | |
|                     end
 | |
|                 end
 | |
|             end
 | |
|         end)
 | |
|     end
 | |
| 
 | |
|     if type == 'ScanIdentifier' then
 | |
|         Citizen.CreateThread(function()
 | |
|             while vehicleEntity and DoesEntityExist(vehicleEntity) and not NoSignal and not LowBattery and isCameraActive and activePlugin == 'ScanIdentifier' do
 | |
|                 local sleep = 1000
 | |
|                 if isCameraActive then
 | |
|                     local camCoords = GetCamCoord(vehicleCamera)
 | |
|                     local camRot = GetCamRot(vehicleCamera, 2)
 | |
|                     
 | |
|                     local forwardVector = vector3(
 | |
|                         -math.sin(math.rad(camRot.z)) * math.abs(math.cos(math.rad(camRot.x))),
 | |
|                         math.cos(math.rad(camRot.z)) * math.abs(math.cos(math.rad(camRot.x))),
 | |
|                         math.sin(math.rad(camRot.x))
 | |
|                     )
 | |
|                     
 | |
|                     local distance = 300.0
 | |
|             
 | |
|                     local shape = StartExpensiveSynchronousShapeTestLosProbe(
 | |
|                         camCoords.x, camCoords.y, camCoords.z,
 | |
|                         camCoords.x + forwardVector.x * distance,
 | |
|                         camCoords.y + forwardVector.y * distance,
 | |
|                         camCoords.z + forwardVector.z * distance,
 | |
|                         10, PlayerPedId(), 0
 | |
|                     )
 | |
|             
 | |
|                     local shapeTestHandle, hit, endCoords, surfaceNormal, entityHit = GetShapeTestResult(shape)
 | |
|     
 | |
|                     if hit ~= 0 and entityHit ~= 0 then
 | |
|                         if not ActivePlayerExist(entityHit) then
 | |
|                             if IsEntityAPed(entityHit) then
 | |
|                                 local result = nil
 | |
|                                 local mugshot = nil
 | |
|             
 | |
|                                 result = GetBase64(entityHit)
 | |
|         
 | |
|                                 if result.success then
 | |
|                                     mugshot = result.base64
 | |
|                                 end
 | |
|             
 | |
|                                 if IsPedAPlayer(entityHit) then
 | |
|                                     lib.callback('0r-rccar:server:scanPlayer', false, function(data)
 | |
|                                         ActivePlayer = {
 | |
|                                             type = 'player',
 | |
|                                             ped = entityHit,
 | |
|                                             name = data.name or 'Unknown',
 | |
|                                             image = mugshot or 'assets/image/avatar.png',
 | |
|                                             birthDate = data.birthDate or 'Unknown',
 | |
|                                         }
 | |
|             
 | |
|                                         DataShow = true
 | |
|                                         NuiMessage('ShowData', ActivePlayer)
 | |
|                                     end, NetworkGetNetworkIdFromEntity(entityHit))
 | |
|                                 else
 | |
|                                     ActivePlayer = {
 | |
|                                         type = 'player',
 | |
|                                         ped = entityHit,
 | |
|                                         name = 'Unknown',
 | |
|                                         image = mugshot or 'assets/image/avatar.png',
 | |
|                                         birthDate = 'Unknown',
 | |
|                                     }
 | |
|             
 | |
|                                     DataShow = true
 | |
|                                     NuiMessage('ShowData', ActivePlayer)
 | |
|                                 end
 | |
|                             elseif IsEntityAVehicle(entityHit) then
 | |
|                                 ActivePlayer = {
 | |
|                                     type = 'vehicle',
 | |
|                                     ped = entityHit,
 | |
|                                     name = GetDisplayNameFromVehicleModel(GetEntityModel(entityHit)),
 | |
|                                     plate = GetVehicleNumberPlateText(entityHit),
 | |
|                                 }
 | |
|             
 | |
|                                 DataShow = true
 | |
|                                 NuiMessage('ShowData', ActivePlayer)
 | |
|                             end
 | |
|                         else
 | |
|                             if not DataShow then
 | |
|                                 DataShow = true
 | |
|     
 | |
|                                 NuiMessage('ShowData', ActivePlayer)
 | |
|                             end
 | |
|                         end
 | |
|                         sleep = 5
 | |
|                     else
 | |
|                         if DataShow then
 | |
|                             DataShow = false
 | |
|                             NuiMessage('HideData')
 | |
|                         end
 | |
|                     end
 | |
|                 end
 | |
|     
 | |
|                 Citizen.Wait(sleep)
 | |
|             end
 | |
|         end)
 | |
|     end
 | |
| 
 | |
|     if type == 'Teaser' then
 | |
|         CreateThread(function()
 | |
|             RequestWeaponAsset(GetHashKey('WEAPON_STUNGUN'))
 | |
|             while not HasWeaponAssetLoaded(GetHashKey('WEAPON_STUNGUN')) do
 | |
|                 Wait(10)
 | |
|             end
 | |
|         
 | |
|             while vehicleEntity and DoesEntityExist(vehicleEntity) and not NoSignal and not LowBattery and isCameraActive and activePlugin == 'Teaser' do
 | |
|                 local ped = PlayerPedId()
 | |
|         
 | |
|                 if IsControlJustPressed(0, 24) then
 | |
|                     
 | |
|                     local camCoords = GetCamCoord(vehicleCamera)
 | |
|                     local camRot = GetCamRot(vehicleCamera, 2)
 | |
|                     
 | |
|                     local forwardVector = vector3(
 | |
|                         -math.sin(math.rad(camRot.z)) * math.abs(math.cos(math.rad(camRot.x))),
 | |
|                         math.cos(math.rad(camRot.z)) * math.abs(math.cos(math.rad(camRot.x))),
 | |
|                         math.sin(math.rad(camRot.x))
 | |
|                     )
 | |
|                     
 | |
|                     local distance = 300.0
 | |
|         
 | |
|                     local shape = StartExpensiveSynchronousShapeTestLosProbe(
 | |
|                         camCoords.x, camCoords.y, camCoords.z,
 | |
|                         camCoords.x + forwardVector.x * distance,
 | |
|                         camCoords.y + forwardVector.y * distance,
 | |
|                         camCoords.z + forwardVector.z * distance,
 | |
|                         10, PlayerPedId(), 0
 | |
|                     )
 | |
|                     
 | |
|                     local shapeTestHandle, hit, endCoords, surfaceNormal, entityHit = GetShapeTestResult(shape)
 | |
|                     
 | |
|                     if hit == 1 and DoesEntityExist(entityHit) and IsEntityAPed(entityHit) then
 | |
|                         if IsPedAPlayer(entityHit) then
 | |
|                             local targetCoords = GetEntityCoords(entityHit)
 | |
|                             ShootSingleBulletBetweenCoords(camCoords.x, camCoords.y, camCoords.z, targetCoords.x, targetCoords.y, targetCoords.z, 0, true, GetHashKey('WEAPON_STUNGUN'), ped, true, false, 1000.0)
 | |
|                         end
 | |
|                     end
 | |
|                 end
 | |
|                 Wait(0)
 | |
|             end
 | |
|         end)
 | |
|     end
 | |
| end
 | |
| 
 | |
| function HideHUDThisFrame()
 | |
| 	Citizen.CreateThread(function()
 | |
|         while vehicleEntity and DoesEntityExist(vehicleEntity) and not NoSignal and not LowBattery and isCameraActive do
 | |
|             Wait(0)
 | |
|             HideHelpTextThisFrame()
 | |
|             HideHudAndRadarThisFrame()
 | |
|             HideHudComponentThisFrame(19) -- weapon wheel
 | |
|             HideHudComponentThisFrame(1) -- Wanted Stars
 | |
|             HideHudComponentThisFrame(2) -- Weapon icon
 | |
|             HideHudComponentThisFrame(3) -- Cash
 | |
|             HideHudComponentThisFrame(4) -- MP CASH
 | |
|             HideHudComponentThisFrame(13) -- Cash Change
 | |
|             HideHudComponentThisFrame(11) -- Floating Help Text
 | |
|             HideHudComponentThisFrame(12) -- more floating help text
 | |
|             HideHudComponentThisFrame(15) -- Subtitle Text
 | |
|             HideHudComponentThisFrame(18) -- Game Stream
 | |
| 
 | |
|             if IsPauseMenuActive() then
 | |
|                 SetFrontendActive(false)
 | |
|             end
 | |
| 
 | |
|             DisableControlAction(0, 75, true)
 | |
|             DisableControlAction(0, 322, true)
 | |
|             DisableControlAction(0, 73, true)
 | |
|             DisableControlAction(0, 178, true)
 | |
|             DisableControlAction(0, 23, true)
 | |
|         end
 | |
|     end)
 | |
| end
 | |
| 
 | |
| function ChargingProcess()
 | |
|     Citizen.CreateThread(function()
 | |
|         while vehicleEntity and DoesEntityExist(vehicleEntity) and not NoSignal and not LowBattery and Config.ChargeSystem do
 | |
|             Wait(1000 * Config.ChargingProcess.Disappearing.Time)
 | |
|     
 | |
|             local DecreasingAmount = Config.ChargingProcess.Disappearing.Decreasing
 | |
|             if batteryProtector then
 | |
|                 DecreasingAmount = DecreasingAmount * Config.BatterySaving
 | |
|             end
 | |
|     
 | |
|             if batteryLevel - DecreasingAmount < 0 then
 | |
|                 batteryLevel = 0
 | |
|             else
 | |
|                 batteryLevel = batteryLevel - DecreasingAmount
 | |
|             end
 | |
|     
 | |
|             NuiMessage('UpdateBattery', batteryLevel)
 | |
|     
 | |
|             if batteryLevel == 0 then
 | |
|                 LowBattery = true
 | |
|                 break
 | |
|             end
 | |
|     
 | |
|         end
 | |
|     end)
 | |
| end
 | |
| 
 | |
| function OpenPluginsMenu()
 | |
|     Citizen.CreateThread(function()
 | |
|         while vehicleEntity and DoesEntityExist(vehicleEntity) and not NoSignal and not LowBattery do
 | |
|             if IsControlJustPressed(0, Config.Controls.OpenPluginsMenu) then
 | |
|                 NuiMessage('OpenPluginsMenu')
 | |
|                 SetNuiFocus(true, true)
 | |
|             end
 | |
| 
 | |
|             Citizen.Wait(0)
 | |
|         end
 | |
|     end)
 | |
| end
 | |
| 
 | |
| local timeoutActive = false
 | |
| 
 | |
| local function CheckVehicleStatus()
 | |
|     Citizen.CreateThread(function()
 | |
|         while vehicleEntity and DoesEntityExist(vehicleEntity) and not NoSignal and not LowBattery do
 | |
|             Wait(1000)
 | |
|             local engineHealth = GetVehicleEngineHealth(vehicleEntity) / 10.0
 | |
| 
 | |
|             NuiMessage('UpdateDamage', engineHealth)
 | |
| 
 | |
|             if engineHealth <= 84.0 then
 | |
|                 SetVehicleEngineHealth(vehicleEntity, 0.0)
 | |
|                 SetVehicleUndriveable(vehicleEntity, true)
 | |
|                 NuiMessage('Notification', { header = Locales[Config.Locale].WEB['error'], message = Locales[Config.Locale].LUA['engine_broken'] })
 | |
|                 local coords = GetEntityCoords(vehicleEntity)
 | |
|                 local retval = StartScriptFire(coords.x, coords.y, coords.z, 25, false)
 | |
| 
 | |
|                 if not timeoutActive then
 | |
|                     timeoutActive = true
 | |
|                     SetTimeout(3000, function()
 | |
|                         if isCameraActive then
 | |
|                             DoScreenFadeOut(1000)
 | |
|                             Wait(1000)
 | |
|                             isCameraActive = false
 | |
|                             Config.SetInvBusy(false)
 | |
|                             Config.SetHudDisplay(false)
 | |
|                             SetSeethrough(false)
 | |
|                             SetNightvision(false)
 | |
|                             RenderScriptCams(false, false, 0, true, true)
 | |
|                             NuiMessage('SetCamera', { active = false })
 | |
|                             ClearPedTasksImmediately(PlayerPedId())
 | |
|                             SetEntityVisible(PlayerPedId(), false, false)
 | |
|                             TaskLeaveVehicle(PlayerPedId(), vehicleEntity, 0)
 | |
|                             local pedCoords = nil
 | |
| 
 | |
|                             if DoesEntityExist(fakePlayerPed) then
 | |
|                                 pedCoords = GetEntityCoords(fakePlayerPed)
 | |
|                             else
 | |
|                                 pedCoords = lastCoordsPlayer
 | |
|                             end
 | |
| 
 | |
|                             SetEntityCoords(PlayerPedId(), pedCoords)
 | |
|                             DeleteEntity(fakePlayerPed)
 | |
|                             DeleteEntity(controllerProp)
 | |
|                             RemoveScriptFire(retval)
 | |
|                             DeleteEntity(vehicleEntity)
 | |
|                             vehicleEntity = nil
 | |
|                             SetEntityVisible(PlayerPedId(), true, false)
 | |
|                             fakePlayerPed = nil
 | |
|                             DoScreenFadeIn(1000)
 | |
|                             TriggerServerEvent('0r-rccar:server:saveVehicle', activeVehicle, batteryLevel)
 | |
|                         else
 | |
|                             Config.SetInvBusy(false)
 | |
|                             Config.SetHudDisplay(false)
 | |
|                             DeleteEntity(vehicleEntity)
 | |
|                             vehicleEntity = nil
 | |
|                             SetSeethrough(false)
 | |
|                             SetNightvision(false)
 | |
|                             NuiMessage('SetCamera', { active = false })
 | |
|                             RemoveScriptFire(retval)
 | |
|                             TriggerServerEvent('0r-rccar:server:saveVehicle', activeVehicle, batteryLevel)
 | |
|                         end
 | |
|                         timeoutActive = false
 | |
|                     end)
 | |
|                 end
 | |
|             end
 | |
|         end
 | |
|     end)
 | |
| end
 | |
| 
 | |
| -- ██╗   ██╗███████╗███████╗    ██████╗  ██████╗     ██████╗ █████╗ ██████╗ 
 | |
| -- ██║   ██║██╔════╝██╔════╝    ██╔══██╗██╔════╝    ██╔════╝██╔══██╗██╔══██╗
 | |
| -- ██║   ██║███████╗█████╗      ██████╔╝██║         ██║     ███████║██████╔╝
 | |
| -- ██║   ██║╚════██║██╔══╝      ██╔══██╗██║         ██║     ██╔══██║██╔══██╗
 | |
| -- ╚██████╔╝███████║███████╗    ██║  ██║╚██████╗    ╚██████╗██║  ██║██║  ██║
 | |
| --  ╚═════╝ ╚══════╝╚══════╝    ╚═╝  ╚═╝ ╚═════╝     ╚═════╝╚═╝  ╚═╝╚═╝  ╚═╝
 | |
| 
 | |
| RegisterNetEvent('0r-rccar:client:useRcCar')
 | |
| AddEventHandler('0r-rccar:client:useRcCar', function(data)
 | |
|     if DoesEntityExist(vehicleEntity) and vehicleEntity then
 | |
|         if CoreName == 'qb-core' then
 | |
|             QBCore.Functions.Notify(Locales[Config.Locale].LUA['already_have_car'], 'error')
 | |
|         elseif CoreName == 'qbx_core' then
 | |
|             QBX:Notify(Locales[Config.Locale].LUA['already_have_car'], 'error')
 | |
|         elseif CoreName == 'es_extended' then
 | |
|             ESX.ShowNotification(Locales[Config.Locale].LUA['already_have_car'], 'error')
 | |
|         end
 | |
| 
 | |
|         return
 | |
|     end
 | |
| 
 | |
|     activeVehicle = data
 | |
|     SpawnVehicle(data.vehicle.prop)
 | |
|     SetBlip()
 | |
|     CheckVehicleStatus()
 | |
| 
 | |
|     if Config.Interaction == 'ox_target' then
 | |
|         exports.ox_target:addLocalEntity(vehicleEntity, {
 | |
|             name = 'manage_vehicle',
 | |
|             label = Locales[Config.Locale].LUA['manage_vehicle'],
 | |
|             icon = 'fas fa-car',
 | |
|             distance = 3.0,
 | |
|             onSelect = function(entity)
 | |
|                 RegisterContextMenu()
 | |
|             end
 | |
|         })
 | |
|     elseif Config.Interaction == 'qb-target' then
 | |
|         exports['qb-target']:AddTargetEntity(vehicleEntity, {
 | |
|             options = {
 | |
|                 {
 | |
|                     icon = 'fas fa-car',
 | |
|                     label = Locales[Config.Locale].LUA['manage_vehicle'],
 | |
|                     action = function(entity)
 | |
|                         RegisterContextMenu()
 | |
|                     end,
 | |
|                 }
 | |
|             },
 | |
|             distance = 2.5,
 | |
|         })
 | |
|     elseif Config.Interaction == 'drawtext' then
 | |
|         Citizen.CreateThread(function()
 | |
|             while DoesEntityExist(vehicleEntity) do
 | |
|                 local sleep = 1000
 | |
|                 local playerCoords = GetEntityCoords(PlayerPedId())
 | |
|                 local carCoords = GetEntityCoords(vehicleEntity)
 | |
|                 local distance = #(playerCoords - carCoords)
 | |
| 
 | |
|                 if distance < 2.5 and not isCameraActive then
 | |
|                     DrawText3D(carCoords.x, carCoords.y, carCoords.z + 1.0, '[~g~' .. Config.Controls.InteractionKey.text .. '~w~] - ' .. Locales[Config.Locale].LUA['manage_vehicle'])
 | |
|                     sleep = 3
 | |
|                     if IsControlJustPressed(0, Config.Controls.InteractionKey.key) then
 | |
|                         RegisterContextMenu()
 | |
|                     end
 | |
|                 end
 | |
|                 Citizen.Wait(sleep)
 | |
|             end
 | |
|         end)
 | |
|     end
 | |
| 
 | |
|     activePlugins = {}
 | |
|     isLoading = false
 | |
| 
 | |
|     lib.callback('0r-rccar:server:getActivePlugins', false, function(result)
 | |
|         activePlugins = json.decode(result)
 | |
|         isLoading = true
 | |
|     end, data)
 | |
| 
 | |
|     while not isLoading do
 | |
|         Wait(100)
 | |
|     end
 | |
| 
 | |
|     batteryLevel = 100
 | |
|     isLoading = false
 | |
| 
 | |
|     lib.callback('0r-rccar:server:getBatteryLevel', false, function(result)
 | |
|         batteryLevel = result
 | |
|         isLoading = true
 | |
|     end, data)
 | |
| 
 | |
|     while not isLoading do
 | |
|         Wait(100)
 | |
|     end
 | |
| end)
 | |
| 
 | |
| RegisterNetEvent('0r-rccar:client:refreshExtension')
 | |
| AddEventHandler('0r-rccar:client:refreshExtension', function(data)
 | |
|     activePlugins = data
 | |
| end)
 | |
| 
 | |
| -- ██████╗ ███████╗ ██████╗ ██╗███████╗████████╗███████╗██████╗     ███╗   ██╗██╗   ██╗██╗     ██████╗ █████╗ ██╗     ██╗     ██████╗  █████╗  ██████╗██╗  ██╗
 | |
| -- ██╔══██╗██╔════╝██╔════╝ ██║██╔════╝╚══██╔══╝██╔════╝██╔══██╗    ████╗  ██║██║   ██║██║    ██╔════╝██╔══██╗██║     ██║     ██╔══██╗██╔══██╗██╔════╝██║ ██╔╝
 | |
| -- ██████╔╝█████╗  ██║  ███╗██║███████╗   ██║   █████╗  ██████╔╝    ██╔██╗ ██║██║   ██║██║    ██║     ███████║██║     ██║     ██████╔╝███████║██║     █████╔╝ 
 | |
| -- ██╔══██╗██╔══╝  ██║   ██║██║╚════██║   ██║   ██╔══╝  ██╔══██╗    ██║╚██╗██║██║   ██║██║    ██║     ██╔══██║██║     ██║     ██╔══██╗██╔══██║██║     ██╔═██╗ 
 | |
| -- ██║  ██║███████╗╚██████╔╝██║███████║   ██║   ███████╗██║  ██║    ██║ ╚████║╚██████╔╝██║    ╚██████╗██║  ██║███████╗███████╗██████╔╝██║  ██║╚██████╗██║  ██╗
 | |
| -- ╚═╝  ╚═╝╚══════╝ ╚═════╝ ╚═╝╚══════╝   ╚═╝   ╚══════╝╚═╝  ╚═╝    ╚═╝  ╚═══╝ ╚═════╝ ╚═╝     ╚═════╝╚═╝  ╚═╝╚══════╝╚══════╝╚═════╝ ╚═╝  ╚═╝ ╚═════╝╚═╝  ╚═╝
 | |
| 
 | |
| --  ██████╗██╗  ██╗███████╗ ██████╗██╗  ██╗    ███╗   ██╗██╗   ██╗██╗
 | |
| -- ██╔════╝██║  ██║██╔════╝██╔════╝██║ ██╔╝    ████╗  ██║██║   ██║██║
 | |
| -- ██║     ███████║█████╗  ██║     █████╔╝     ██╔██╗ ██║██║   ██║██║
 | |
| -- ██║     ██╔══██║██╔══╝  ██║     ██╔═██╗     ██║╚██╗██║██║   ██║██║
 | |
| -- ╚██████╗██║  ██║███████╗╚██████╗██║  ██╗    ██║ ╚████║╚██████╔╝██║
 | |
| --  ╚═════╝╚═╝  ╚═╝╚══════╝ ╚═════╝╚═╝  ╚═╝    ╚═╝  ╚═══╝ ╚═════╝ ╚═╝
 | |
| 
 | |
| RegisterNUICallback('CloseMenu', function()
 | |
|     SetNuiFocus(false, false)
 | |
| end)
 | |
| 
 | |
| RegisterNUICallback('CheckNui', function()
 | |
|     nuiLoaded = true
 | |
| end)
 | |
| 
 | |
| RegisterNUICallback('BuyCar', function(data, cb)
 | |
|     lib.callback('0r-rccar:server:buyCar', false, function(res)
 | |
|         cb(res)
 | |
|     end, data)
 | |
| end)
 | |
| 
 | |
| RegisterNUICallback('Crafting', function(data, cb)
 | |
|     lib.callback('0r-rccar:server:crafting', false, function(res)
 | |
|         cb(res)
 | |
|     end, data)
 | |
| end)
 | |
| 
 | |
| RegisterNUICallback('GetCraftResources', function(data, cb)
 | |
|     lib.callback('0r-rccar:server:getItemCount', false, function(res)
 | |
|         cb(res)
 | |
|     end, data)
 | |
| end)
 | |
| 
 | |
| RegisterNUICallback('CraftingFinish', function(data)
 | |
|     lib.callback('0r-rccar:server:craftingFinish', false, function(res)
 | |
|         return true
 | |
|     end, data)
 | |
| end)
 | |
| 
 | |
| RegisterNUICallback('ActivePlugin', function(data)
 | |
|     activePlugin = data
 | |
|     StartPlugins(data)
 | |
| end)
 | |
| 
 | |
| RegisterNUICallback('LastTimerSecond', function()
 | |
|     if isCameraActive then
 | |
|         DoScreenFadeOut(1000)
 | |
|         Wait(1000)
 | |
|         isCameraActive = false
 | |
|         Config.SetInvBusy(false)
 | |
|         Config.SetHudDisplay(false)
 | |
|         SetSeethrough(false)
 | |
|         SetNightvision(false)
 | |
|         RenderScriptCams(false, false, 0, true, true)
 | |
|         NuiMessage('SetCamera', { active = false })
 | |
|         ClearPedTasksImmediately(PlayerPedId())
 | |
|         SetEntityVisible(PlayerPedId(), false, false)
 | |
|         TaskLeaveVehicle(PlayerPedId(), vehicleEntity, 0)
 | |
|         local pedCoords = nil
 | |
| 
 | |
|         if DoesEntityExist(fakePlayerPed) then
 | |
|             pedCoords = GetEntityCoords(fakePlayerPed)
 | |
|         else
 | |
|             pedCoords = lastCoordsPlayer
 | |
|         end
 | |
| 
 | |
|         SetEntityCoords(PlayerPedId(), pedCoords)
 | |
|         DeleteEntity(fakePlayerPed)
 | |
|         DeleteEntity(controllerProp)
 | |
|         SetEntityVisible(PlayerPedId(), true, false)
 | |
|         fakePlayerPed = nil
 | |
|         DoScreenFadeIn(1000)
 | |
|     end
 | |
| end)
 | |
| 
 | |
| RegisterNUICallback('TimerFinish', function()
 | |
|     local coords = GetEntityCoords(vehicleEntity)
 | |
|     AddExplosion(coords.x, coords.y, coords.z, 0, 20.0, true, false, true)
 | |
|     DeleteEntity(vehicleEntity)
 | |
|     vehicleEntity = nil
 | |
|     TriggerServerEvent('0r-rccar:server:bombVehicle', activeVehicle)
 | |
| end) | 
