---@return boolean ---@diagnostic disable-next-line: duplicate-set-field function ESX.IsPlayerLoaded() return ESX.PlayerLoaded end ---@return table function ESX.GetPlayerData() return ESX.PlayerData end ---@param name string ---@param func function ---@return nil function ESX.SecureNetEvent(name, func) local invoker = GetInvokingResource() local invokingResource = invoker and invoker ~= 'unknown' and invoker or 'es_extended' if not invokingResource then return end if not Core.Events[invokingResource] then Core.Events[invokingResource] = {} end local event = RegisterNetEvent(name, function(...) if source == '' then return end local success, result = pcall(func, ...) if not success then error(("%s"):format(result)) end end) local eventIndex = #Core.Events[invokingResource] + 1 Core.Events[invokingResource][eventIndex] = event end local addonResourcesState = { ['esx_progressbar'] = GetResourceState('esx_progressbar') ~= 'missing', ['esx_notify'] = GetResourceState('esx_notify') ~= 'missing', ['esx_textui'] = GetResourceState('esx_textui') ~= 'missing', ['esx_context'] = GetResourceState('esx_context') ~= 'missing', } local function IsResourceFound(resource) return addonResourcesState[resource] or error(('Resource [^5%s^1] is Missing!'):format(resource)) end function ESX.DisableSpawnManager() if GetResourceState("spawnmanager") == "started" then exports.spawnmanager:setAutoSpawn(false) end end ---@param items string | table The item(s) to search for ---@param count? boolean Whether to return the count of the item as well ---@return table | number function ESX.SearchInventory(items, count) local item if type(items) == 'string' then item, items = items, {items} end local data = {} for i = 1, #ESX.PlayerData.inventory do local e = ESX.PlayerData.inventory[i] for ii = 1, #items do if e.name == items[ii] then data[table.remove(items, ii)] = count and e.count or e break end end if #items == 0 then break end end return not item and data or data[item] end ---@param key string Table key to set ---@param val any Value to set ---@return nil function ESX.SetPlayerData(key, val) local current = ESX.PlayerData[key] ESX.PlayerData[key] = val if key ~= "loadout" then if type(val) == "table" or val ~= current then TriggerEvent("esx:setPlayerData", key, val, current) end end end ---@param freeze boolean Whether to freeze the player ---@return nil function Core.FreezePlayer(freeze) local ped = PlayerPedId() SetPlayerControl(ESX.playerId, not freeze, 0) if freeze then SetEntityCollision(ped, false, false) FreezeEntityPosition(ped, true) else SetEntityCollision(ped, true, true) FreezeEntityPosition(ped, false) end end ---@param skin table Skin data to set ---@param coords table Coords to spawn the player at ---@param cb function Callback function ---@return nil function ESX.SpawnPlayer(skin, coords, cb) local p = promise.new() TriggerEvent("skinchanger:loadSkin", skin, function() p:resolve() end) Citizen.Await(p) RequestCollisionAtCoord(coords.x, coords.y, coords.z) local playerPed = PlayerPedId() local timer = GetGameTimer() Core.FreezePlayer(true) SetEntityCoordsNoOffset(playerPed, coords.x, coords.y, coords.z, false, false, true) SetEntityHeading(playerPed, coords.heading) RequestCollisionAtCoord(coords.x, coords.y, coords.z) while not HasCollisionLoadedAroundEntity(playerPed) and (GetGameTimer() - timer) < 5000 do Wait(0) end NetworkResurrectLocalPlayer(coords.x, coords.y, coords.z, coords.heading, 0, true) TriggerEvent('playerSpawned', coords) cb() end ---@param message string ---@param length? number Timeout in milliseconds ---@param options? ProgressBarOptions ---@return boolean Success Whether the progress bar was successfully created or not function ESX.Progressbar(message, length, options) return IsResourceFound('esx_progressbar') and exports['esx_progressbar']:Progressbar(message, length, options) end function ESX.CancelProgressbar() return IsResourceFound('esx_progressbar') and exports['esx_progressbar']:CancelProgressbar() end ---@param message string The message to show ---@param notifyType? string The type of notification to show ---@param length? number The length of the notification ---@param title? string The title of the notification ---@param position? string The position of the notification ---@return nil function ESX.ShowNotification(message, notifyType, length, title, position) return IsResourceFound('esx_notify') and exports['esx_notify']:Notify(notifyType or "info", length or 5000, message, title, position) end function ESX.TextUI(...) return IsResourceFound('esx_textui') and exports['esx_textui']:TextUI(...) end ---@return nil function ESX.HideUI() return IsResourceFound('esx_textui') and exports['esx_textui']:HideUI() end ---@param sender string ---@param subject string ---@param msg string ---@param textureDict string ---@param iconType integer ---@param flash boolean ---@param saveToBrief? boolean ---@param hudColorIndex? integer ---@return nil function ESX.ShowAdvancedNotification(sender, subject, msg, textureDict, iconType, flash, saveToBrief, hudColorIndex) AddTextEntry("esxAdvancedNotification", msg) BeginTextCommandThefeedPost("esxAdvancedNotification") if hudColorIndex then ThefeedSetNextPostBackgroundColor(hudColorIndex) end EndTextCommandThefeedPostMessagetext(textureDict, textureDict, false, iconType, sender, subject) EndTextCommandThefeedPostTicker(flash, saveToBrief == nil or saveToBrief) end ---@param msg string The message to show ---@param thisFrame? boolean Whether to show the message this frame ---@param beep? boolean Whether to beep ---@param duration? number The duration of the message ---@return nil function ESX.ShowHelpNotification(msg, thisFrame, beep, duration) AddTextEntry("esxHelpNotification", msg) if thisFrame then DisplayHelpTextThisFrame("esxHelpNotification", false) else BeginTextCommandDisplayHelp("esxHelpNotification") EndTextCommandDisplayHelp(0, false, beep == nil or beep, duration or -1) end end ---@param msg string The message to show ---@param coords table The coords to show the message at ---@return nil function ESX.ShowFloatingHelpNotification(msg, coords) AddTextEntry("esxFloatingHelpNotification", msg) SetFloatingHelpTextWorldPosition(1, coords.x, coords.y, coords.z) SetFloatingHelpTextStyle(1, 1, 2, -1, 3, 0) BeginTextCommandDisplayHelp("esxFloatingHelpNotification") EndTextCommandDisplayHelp(2, false, false, -1) end ---@param msg string The message to show ---@param time number The duration of the message ---@return nil function ESX.DrawMissionText(msg, time) ClearPrints() BeginTextCommandPrint('STRING') AddTextComponentSubstringPlayerName(msg) EndTextCommandPrint(time, true) end ---@param str string The string to hash ---@return string The hashed string function ESX.HashString(str) return ('~INPUT_%s~'):format(('%x'):format(joaat(str) & 0x7fffffff + 2 ^ 31):upper()) end function ESX.OpenContext(...) return IsResourceFound('esx_context') and exports['esx_context']:Open(...) end function ESX.PreviewContext(...) return IsResourceFound('esx_context') and exports['esx_context']:Preview(...) end function ESX.CloseContext(...) return IsResourceFound('esx_context') and exports['esx_context']:Close(...) end function ESX.RefreshContext(...) return IsResourceFound('esx_context') and exports['esx_context']:Refresh(...) end ---@param command_name string The command name ---@param label string The label to show ---@param input_group string The input group ---@param key string The key to bind ---@param on_press function The function to call on press ---@param on_release? function The function to call on release function ESX.RegisterInput(command_name, label, input_group, key, on_press, on_release) local command = on_release and '+' .. command_name or command_name RegisterCommand(command, on_press, false) Core.Input[command_name] = ESX.HashString(command) if on_release then RegisterCommand('-' .. command_name, on_release, false) end RegisterKeyMapping(command, label or '', input_group or 'keyboard', key or '') end ---@param menuType string ---@param open function The function to call on open ---@param close function The function to call on close function ESX.UI.Menu.RegisterType(menuType, open, close) ESX.UI.Menu.RegisteredTypes[menuType] = { open = open, close = close, } end ---@class ESXMenu ---@field type string ---@field namespace string ---@field resourceName string ---@field name string ---@field data table ---@field submit? function ---@field cancel? function ---@field change? function ---@field close function ---@field update function ---@field refresh function ---@field setElement function ---@field setElements function ---@field setTitle function ---@field removeElement function ---@param menuType string ---@param namespace string ---@param name string ---@param data table ---@param submit? function ---@param cancel? function ---@param change? function ---@param close? function ---@return ESXMenu function ESX.UI.Menu.Open(menuType, namespace, name, data, submit, cancel, change, close) ---@class ESXMenu local menu = {} menu.type = menuType menu.namespace = namespace menu.resourceName = (GetInvokingResource() or "Unknown") menu.name = name menu.data = data menu.submit = submit menu.cancel = cancel menu.change = change menu.close = function() ESX.UI.Menu.RegisteredTypes[menuType].close(namespace, name) for i = 1, #ESX.UI.Menu.Opened, 1 do if ESX.UI.Menu.Opened[i] then if ESX.UI.Menu.Opened[i].type == menuType and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then ESX.UI.Menu.Opened[i] = nil end end end if close then close() end end menu.update = function(query, newData) for i = 1, #menu.data.elements, 1 do local match = true for k, v in pairs(query) do if menu.data.elements[i][k] ~= v then match = false end end if match then for k, v in pairs(newData) do menu.data.elements[i][k] = v end end end end menu.refresh = function() ESX.UI.Menu.RegisteredTypes[menuType].open(namespace, name, menu.data) end menu.setElement = function(i, key, val) menu.data.elements[i][key] = val end menu.setElements = function(newElements) menu.data.elements = newElements end menu.setTitle = function(val) menu.data.title = val end menu.removeElement = function(query) for i = 1, #menu.data.elements, 1 do for k, v in pairs(query) do if menu.data.elements[i] then if menu.data.elements[i][k] == v then table.remove(menu.data.elements, i) break end end end end end ESX.UI.Menu.Opened[#ESX.UI.Menu.Opened + 1] = menu ESX.UI.Menu.RegisteredTypes[menuType].open(namespace, name, data) return menu end ---@param menuType string ---@param namespace string ---@param name string ---@param cancel? boolean Should the close be classified as a cancel ---@return nil function ESX.UI.Menu.Close(menuType, namespace, name, cancel) for i = 1, #ESX.UI.Menu.Opened, 1 do if ESX.UI.Menu.Opened[i] then if ESX.UI.Menu.Opened[i].type == menuType and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then if not cancel then ESX.UI.Menu.Opened[i].close() else local menu = ESX.UI.Menu.Opened[i] ESX.UI.Menu.RegisteredTypes[menu.type].close(menu.namespace, menu.name) if type(menu.cancel) ~= "nil" then menu.cancel(menu.data, menu) end end ESX.UI.Menu.Opened[i] = nil end end end end ---@param cancel? boolean Should the close be classified as a cancel ---@return nil function ESX.UI.Menu.CloseAll(cancel) for i = 1, #ESX.UI.Menu.Opened, 1 do if ESX.UI.Menu.Opened[i] then if not cancel then ESX.UI.Menu.Opened[i].close() else local menu = ESX.UI.Menu.Opened[i] ESX.UI.Menu.RegisteredTypes[menu.type].close(menu.namespace, menu.name) if type(menu.cancel) ~= "nil" then menu.cancel(menu.data, menu) end end ESX.UI.Menu.Opened[i] = nil end end end ---@param menuType string ---@param namespace string ---@param name string ---@return ESXMenu | nil function ESX.UI.Menu.GetOpened(menuType, namespace, name) for i = 1, #ESX.UI.Menu.Opened, 1 do if ESX.UI.Menu.Opened[i] then if ESX.UI.Menu.Opened[i].type == menuType and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then return ESX.UI.Menu.Opened[i] end end end end ---@return ESXMenu[] function ESX.UI.Menu.GetOpenedMenus() return ESX.UI.Menu.Opened end ESX.UI.Menu.IsOpen = ESX.UI.Menu.GetOpened ---@param add boolean Whether the item is being added or removed ---@param item string The item to show ---@param count number How many of the item to show ---@return nil function ESX.UI.ShowInventoryItemNotification(add, item, count) SendNUIMessage({ action = "inventoryNotification", add = add, item = item, count = count, }) end ---@param ped integer The ped to get the mugshot of ---@param transparent? boolean Whether the mugshot should be transparent function ESX.Game.GetPedMugshot(ped, transparent) if not DoesEntityExist(ped) then return end local mugshot = transparent and RegisterPedheadshotTransparent(ped) or RegisterPedheadshot(ped) while not IsPedheadshotReady(mugshot) do Wait(0) end return mugshot, GetPedheadshotTxdString(mugshot) end ---@param entity integer The entity to get the coords of ---@param coords table | vector3 | vector4 The coords to teleport the entity to ---@param cb? function The callback function function ESX.Game.Teleport(entity, coords, cb) if DoesEntityExist(entity) then RequestCollisionAtCoord(coords.x, coords.y, coords.z) while not HasCollisionLoadedAroundEntity(entity) do Wait(0) end SetEntityCoords(entity, coords.x, coords.y, coords.z, false, false, false, false) SetEntityHeading(entity, coords.w or coords.heading or 0.0) end if cb then cb() end end ---@param object integer | string The object to spawn ---@param coords table | vector3 The coords to spawn the object at ---@param cb? function The callback function ---@param networked? boolean Whether the object should be networked ---@return integer | nil function ESX.Game.SpawnObject(object, coords, cb, networked) local model = type(object) == "number" and object or joaat(object) ESX.Streaming.RequestModel(model) local obj = CreateObject(model, coords.x, coords.y, coords.z, networked == nil or networked, false, true) return cb and cb(obj) or obj end ---@param object integer | string The object to spawn ---@param coords table | vector3 The coords to spawn the object at ---@param cb? function The callback function ---@return nil function ESX.Game.SpawnLocalObject(object, coords, cb) ESX.Game.SpawnObject(object, coords, cb, false) end ---@param vehicle integer The vehicle to delete ---@return nil function ESX.Game.DeleteVehicle(vehicle) SetEntityAsMissionEntity(vehicle, true, true) DeleteVehicle(vehicle) end ---@param object integer The object to delete ---@return nil function ESX.Game.DeleteObject(object) SetEntityAsMissionEntity(object, false, true) DeleteObject(object) end ---@param vehicleModel integer | string The vehicle to spawn ---@param coords table | vector3 The coords to spawn the vehicle at ---@param heading number The heading of the vehicle ---@param cb? fun(vehicle: number) The callback function ---@param networked? boolean Whether the vehicle should be networked ---@return number? vehicle function ESX.Game.SpawnVehicle(vehicleModel, coords, heading, cb, networked) if cb and not ESX.IsFunctionReference(cb) then error("Invalid callback function") end local model = type(vehicleModel) == "number" and vehicleModel or joaat(vehicleModel) local vector = type(coords) == "vector3" and coords or vec(coords.x, coords.y, coords.z) local isNetworked = networked == nil or networked local playerCoords = GetEntityCoords(ESX.PlayerData.ped) if not vector or not playerCoords then return end local dist = #(playerCoords - vector) if dist > 424 then -- Onesync infinity Range (https://docs.fivem.net/docs/scripting-reference/onesync/) local executingResource = GetInvokingResource() or "Unknown" return error(("Resource ^5%s^1 Tried to spawn vehicle on the client but the position is too far away (Out of onesync range)."):format(executingResource)) end local promise = not cb and promise.new() CreateThread(function() local modelHash = ESX.Streaming.RequestModel(model) if not modelHash then if promise then promise:reject(("Tried to spawn invalid vehicle - ^5%s^7!"):format(model)) return end error(("Tried to spawn invalid vehicle - ^5%s^7!"):format(model)) end local vehicle = CreateVehicle(model, vector.x, vector.y, vector.z, heading, isNetworked, true) if networked then local id = NetworkGetNetworkIdFromEntity(vehicle) SetNetworkIdCanMigrate(id, true) SetEntityAsMissionEntity(vehicle, true, true) end SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetVehicleNeedsToBeHotwired(vehicle, false) SetModelAsNoLongerNeeded(model) SetVehRadioStation(vehicle, "OFF") RequestCollisionAtCoord(vector.x, vector.y, vector.z) while not HasCollisionLoadedAroundEntity(vehicle) do Wait(0) end if promise then promise:resolve(vehicle) elseif cb then cb(vehicle) end end) if promise then return Citizen.Await(promise) end end ---@param vehicle integer The vehicle to spawn ---@param coords table | vector3 The coords to spawn the vehicle at ---@param heading number The heading of the vehicle ---@param cb? function The callback function ---@return nil function ESX.Game.SpawnLocalVehicle(vehicle, coords, heading, cb) ESX.Game.SpawnVehicle(vehicle, coords, heading, cb, false) end ---@param vehicle integer The vehicle to check ---@return boolean function ESX.Game.IsVehicleEmpty(vehicle) return GetVehicleNumberOfPassengers(vehicle) == 0 and IsVehicleSeatFree(vehicle, -1) end ---@return table function ESX.Game.GetObjects() -- Leave the function for compatibility return GetGamePool("CObject") end ---@param onlyOtherPeds? boolean Whether to exlude the player ped ---@return table function ESX.Game.GetPeds(onlyOtherPeds) local pool = GetGamePool("CPed") if onlyOtherPeds then local myPed = ESX.PlayerData.ped for i = 1, #pool do if pool[i] == myPed then table.remove(pool, i) break end end end return pool end ---@return table function ESX.Game.GetVehicles() -- Leave the function for compatibility return GetGamePool("CVehicle") end ---@param onlyOtherPlayers? boolean Whether to exclude the player ---@param returnKeyValue? boolean Whether to return the key value pair ---@param returnPeds? boolean Whether to return the peds ---@return table function ESX.Game.GetPlayers(onlyOtherPlayers, returnKeyValue, returnPeds) local players = {} local active = GetActivePlayers() for i = 1, #active do local currentPlayer = active[i] local ped = GetPlayerPed(currentPlayer) if DoesEntityExist(ped) and ((onlyOtherPlayers and currentPlayer ~= ESX.playerId) or not onlyOtherPlayers) then if returnKeyValue then players[currentPlayer] = ped else players[#players + 1] = returnPeds and ped or currentPlayer end end end return players end ---@param coords? table | vector3 The coords to get the closest object to ---@param modelFilter? table The model filter ---@return integer, integer function ESX.Game.GetClosestObject(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetObjects(), false, coords, modelFilter) end ---@param coords? table | vector3 The coords to get the closest ped to ---@param modelFilter? table The model filter ---@return integer, integer function ESX.Game.GetClosestPed(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetPeds(true), false, coords, modelFilter) end ---@param coords? table | vector3 The coords to get the closest player to ---@return integer, integer function ESX.Game.GetClosestPlayer(coords) return ESX.Game.GetClosestEntity(ESX.Game.GetPlayers(true, true), true, coords, nil) end ---@param coords? table | vector3 The coords to get the closest vehicle to ---@param modelFilter? table The model filter ---@return integer, integer function ESX.Game.GetClosestVehicle(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetVehicles(), false, coords, modelFilter) end ---@param entities table The entities to search through ---@param isPlayerEntities boolean Whether the entities are players ---@param coords table | vector3 The coords to search from ---@param maxDistance number The max distance to search within ---@return table local function EnumerateEntitiesWithinDistance(entities, isPlayerEntities, coords, maxDistance) local nearbyEntities = {} if coords then coords = vector3(coords.x, coords.y, coords.z) else local playerPed = ESX.PlayerData.ped coords = GetEntityCoords(playerPed) end for k, entity in pairs(entities) do local distance = #(coords - GetEntityCoords(entity)) if distance <= maxDistance then nearbyEntities[#nearbyEntities + 1] = isPlayerEntities and k or entity end end return nearbyEntities end ---@param coords table | vector3 The coords to search from ---@param maxDistance number The max distance to search within ---@return table function ESX.Game.GetPlayersInArea(coords, maxDistance) return EnumerateEntitiesWithinDistance(ESX.Game.GetPlayers(true, true), true, coords, maxDistance) end ---@param coords table | vector3 The coords to search from ---@param maxDistance number The max distance to search within ---@return table function ESX.Game.GetVehiclesInArea(coords, maxDistance) return EnumerateEntitiesWithinDistance(ESX.Game.GetVehicles(), false, coords, maxDistance) end ---@param coords table | vector3 The coords to search from ---@param maxDistance number The max distance to search within ---@return boolean function ESX.Game.IsSpawnPointClear(coords, maxDistance) return #ESX.Game.GetVehiclesInArea(coords, maxDistance) == 0 end ---@param shape integer The shape to get the test result from ---@return boolean, table, table, integer, integer function ESX.Game.GetShapeTestResultSync(shape) local handle, hit, coords, normal, material, entity repeat handle, hit, coords, normal, material, entity = GetShapeTestResultIncludingMaterial(shape) Wait(0) until handle ~= 1 return hit, coords, normal, material, entity end ---@param depth number The depth to raycast ---@vararg any The arguments to pass to the shape test ---@return table, boolean, table, table, integer, integer function ESX.Game.RaycastScreen(depth, ...) local world, normal = GetWorldCoordFromScreenCoord(.5, .5) local origin = world + normal local target = world + normal * depth return target, ESX.Game.GetShapeTestResultSync(StartShapeTestLosProbe(origin.x, origin.y, origin.z, target.x, target.y, target.z, ...)) end ---@param entities table The entities to search through ---@param isPlayerEntities boolean Whether the entities are players ---@param coords? table | vector3 The coords to search from ---@param modelFilter? table The model filter ---@return integer, integer function ESX.Game.GetClosestEntity(entities, isPlayerEntities, coords, modelFilter) local closestEntity, closestEntityDistance, filteredEntities = -1, -1, nil if coords then coords = vector3(coords.x, coords.y, coords.z) else local playerPed = ESX.PlayerData.ped coords = GetEntityCoords(playerPed) end if modelFilter then filteredEntities = {} for currentEntityIndex = 1, #entities do if modelFilter[GetEntityModel(entities[currentEntityIndex])] then filteredEntities[#filteredEntities + 1] = entities[currentEntityIndex] end end end for k, entity in pairs(filteredEntities or entities) do local distance = #(coords - GetEntityCoords(entity)) if closestEntityDistance == -1 or distance < closestEntityDistance then closestEntity, closestEntityDistance = isPlayerEntities and k or entity, distance end end return closestEntity, closestEntityDistance end ---@return integer | nil, vector3 | nil function ESX.Game.GetVehicleInDirection() local _, hit, coords, _, _, entity = ESX.Game.RaycastScreen(5, 10, ESX.PlayerData.ped) if hit and IsEntityAVehicle(entity) then return entity, coords end end ---@param vehicle integer The vehicle to get the properties of ---@return table | nil function ESX.Game.GetVehicleProperties(vehicle) if not DoesEntityExist(vehicle) then return end ---@type number | number[], number | number[] local colorPrimary, colorSecondary = GetVehicleColours(vehicle) local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) local dashboardColor = GetVehicleDashboardColor(vehicle) local interiorColor = GetVehicleInteriorColour(vehicle) if GetIsVehiclePrimaryColourCustom(vehicle) then colorPrimary = { GetVehicleCustomPrimaryColour(vehicle) } end if GetIsVehicleSecondaryColourCustom(vehicle) then colorSecondary = { GetVehicleCustomSecondaryColour(vehicle) } end local hasCustomXenonColor, customXenonColorR, customXenonColorG, customXenonColorB = GetVehicleXenonLightsCustomColor(vehicle) local customXenonColor = nil if hasCustomXenonColor then customXenonColor = { customXenonColorR, customXenonColorG, customXenonColorB } end local extras = {} for extraId = 0, 20 do if DoesExtraExist(vehicle, extraId) then extras[tostring(extraId)] = IsVehicleExtraTurnedOn(vehicle, extraId) end end local doorsBroken, windowsBroken, tyreBurst = {}, {}, {} local numWheels = tostring(GetVehicleNumberOfWheels(vehicle)) local TyresIndex = { -- Wheel index list according to the number of vehicle wheels. ["2"] = { 0, 4 }, -- Bike and cycle. ["3"] = { 0, 1, 4, 5 }, -- Vehicle with 3 wheels (get for wheels because some 3 wheels vehicles have 2 wheels on front and one rear or the reverse). ["4"] = { 0, 1, 4, 5 }, -- Vehicle with 4 wheels. ["6"] = { 0, 1, 2, 3, 4, 5 }, -- Vehicle with 6 wheels. } if TyresIndex[numWheels] then for _, idx in pairs(TyresIndex[numWheels]) do tyreBurst[tostring(idx)] = IsVehicleTyreBurst(vehicle, idx, false) end end for windowId = 0, 7 do -- 13 RollUpWindow(vehicle, windowId) --fix when you put the car away with the window down windowsBroken[tostring(windowId)] = not IsVehicleWindowIntact(vehicle, windowId) end local numDoors = GetNumberOfVehicleDoors(vehicle) if numDoors and numDoors > 0 then for doorsId = 0, numDoors do doorsBroken[tostring(doorsId)] = IsVehicleDoorDamaged(vehicle, doorsId) end end return { model = GetEntityModel(vehicle), doorsBroken = doorsBroken, windowsBroken = windowsBroken, tyreBurst = tyreBurst, tyresCanBurst = GetVehicleTyresCanBurst(vehicle), plate = ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)), plateIndex = GetVehicleNumberPlateTextIndex(vehicle), bodyHealth = ESX.Math.Round(GetVehicleBodyHealth(vehicle), 1), engineHealth = ESX.Math.Round(GetVehicleEngineHealth(vehicle), 1), tankHealth = ESX.Math.Round(GetVehiclePetrolTankHealth(vehicle), 1), fuelLevel = ESX.Math.Round(GetVehicleFuelLevel(vehicle), 1), dirtLevel = ESX.Math.Round(GetVehicleDirtLevel(vehicle), 1), color1 = colorPrimary, color2 = colorSecondary, pearlescentColor = pearlescentColor, wheelColor = wheelColor, dashboardColor = dashboardColor, interiorColor = interiorColor, wheels = GetVehicleWheelType(vehicle), windowTint = GetVehicleWindowTint(vehicle), xenonColor = GetVehicleXenonLightsColor(vehicle), customXenonColor = customXenonColor, neonEnabled = { IsVehicleNeonLightEnabled(vehicle, 0), IsVehicleNeonLightEnabled(vehicle, 1), IsVehicleNeonLightEnabled(vehicle, 2), IsVehicleNeonLightEnabled(vehicle, 3) }, neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), extras = extras, tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(vehicle)), modSpoilers = GetVehicleMod(vehicle, 0), modFrontBumper = GetVehicleMod(vehicle, 1), modRearBumper = GetVehicleMod(vehicle, 2), modSideSkirt = GetVehicleMod(vehicle, 3), modExhaust = GetVehicleMod(vehicle, 4), modFrame = GetVehicleMod(vehicle, 5), modGrille = GetVehicleMod(vehicle, 6), modHood = GetVehicleMod(vehicle, 7), modFender = GetVehicleMod(vehicle, 8), modRightFender = GetVehicleMod(vehicle, 9), modRoof = GetVehicleMod(vehicle, 10), modRoofLivery = GetVehicleRoofLivery(vehicle), modEngine = GetVehicleMod(vehicle, 11), modBrakes = GetVehicleMod(vehicle, 12), modTransmission = GetVehicleMod(vehicle, 13), modHorns = GetVehicleMod(vehicle, 14), modSuspension = GetVehicleMod(vehicle, 15), modArmor = GetVehicleMod(vehicle, 16), modTurbo = IsToggleModOn(vehicle, 18), modSmokeEnabled = IsToggleModOn(vehicle, 20), modXenon = IsToggleModOn(vehicle, 22), modFrontWheels = GetVehicleMod(vehicle, 23), modCustomFrontWheels = GetVehicleModVariation(vehicle, 23), modBackWheels = GetVehicleMod(vehicle, 24), modCustomBackWheels = GetVehicleModVariation(vehicle, 24), modPlateHolder = GetVehicleMod(vehicle, 25), modVanityPlate = GetVehicleMod(vehicle, 26), modTrimA = GetVehicleMod(vehicle, 27), modOrnaments = GetVehicleMod(vehicle, 28), modDashboard = GetVehicleMod(vehicle, 29), modDial = GetVehicleMod(vehicle, 30), modDoorSpeaker = GetVehicleMod(vehicle, 31), modSeats = GetVehicleMod(vehicle, 32), modSteeringWheel = GetVehicleMod(vehicle, 33), modShifterLeavers = GetVehicleMod(vehicle, 34), modAPlate = GetVehicleMod(vehicle, 35), modSpeakers = GetVehicleMod(vehicle, 36), modTrunk = GetVehicleMod(vehicle, 37), modHydrolic = GetVehicleMod(vehicle, 38), modEngineBlock = GetVehicleMod(vehicle, 39), modAirFilter = GetVehicleMod(vehicle, 40), modStruts = GetVehicleMod(vehicle, 41), modArchCover = GetVehicleMod(vehicle, 42), modAerials = GetVehicleMod(vehicle, 43), modTrimB = GetVehicleMod(vehicle, 44), modTank = GetVehicleMod(vehicle, 45), modWindows = GetVehicleMod(vehicle, 46), modLivery = GetVehicleMod(vehicle, 48) == -1 and GetVehicleLivery(vehicle) or GetVehicleMod(vehicle, 48), modLightbar = GetVehicleMod(vehicle, 49), } end ---@param vehicle integer The vehicle to set the properties of ---@param props table The properties to set ---@return nil function ESX.Game.SetVehicleProperties(vehicle, props) if not DoesEntityExist(vehicle) then return end local colorPrimary, colorSecondary = GetVehicleColours(vehicle) local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) SetVehicleModKit(vehicle, 0) if props.tyresCanBurst ~= nil then SetVehicleTyresCanBurst(vehicle, props.tyresCanBurst) end if props.plate ~= nil then SetVehicleNumberPlateText(vehicle, props.plate) end if props.plateIndex ~= nil then SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) end if props.bodyHealth ~= nil then SetVehicleBodyHealth(vehicle, props.bodyHealth + 0.0) end if props.engineHealth ~= nil then SetVehicleEngineHealth(vehicle, props.engineHealth + 0.0) end if props.tankHealth ~= nil then SetVehiclePetrolTankHealth(vehicle, props.tankHealth + 0.0) end if props.fuelLevel ~= nil then SetVehicleFuelLevel(vehicle, props.fuelLevel + 0.0) end if props.dirtLevel ~= nil then SetVehicleDirtLevel(vehicle, props.dirtLevel + 0.0) end if props.color1 ~= nil then if type(props.color1) == "table" then SetVehicleCustomPrimaryColour(vehicle, props.color1[1], props.color1[2], props.color1[3]) else SetVehicleColours(vehicle, props.color1, colorSecondary) end end if props.color2 ~= nil then if type(props.color2) == "table" then SetVehicleCustomSecondaryColour(vehicle, props.color2[1], props.color2[2], props.color2[3]) else SetVehicleColours(vehicle, props.color1 or colorPrimary, props.color2) end end if props.pearlescentColor ~= nil then SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) end if props.interiorColor ~= nil then SetVehicleInteriorColor(vehicle, props.interiorColor) end if props.dashboardColor ~= nil then SetVehicleDashboardColor(vehicle, props.dashboardColor) end if props.wheelColor ~= nil then SetVehicleExtraColours(vehicle, props.pearlescentColor or pearlescentColor, props.wheelColor) end if props.wheels ~= nil then SetVehicleWheelType(vehicle, props.wheels) end if props.windowTint ~= nil then SetVehicleWindowTint(vehicle, props.windowTint) end if props.neonEnabled ~= nil then SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]) SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]) SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]) SetVehicleNeonLightEnabled(vehicle, 3, props.neonEnabled[4]) end if props.extras ~= nil then for extraId, enabled in pairs(props.extras) do extraId = tonumber(extraId) if extraId then SetVehicleExtra(vehicle, extraId, not enabled) end end end if props.neonColor ~= nil then SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) end if props.xenonColor ~= nil then SetVehicleXenonLightsColor(vehicle, props.xenonColor) end if props.customXenonColor ~= nil then SetVehicleXenonLightsCustomColor(vehicle, props.customXenonColor[1], props.customXenonColor[2], props.customXenonColor[3]) end if props.modSmokeEnabled ~= nil then ToggleVehicleMod(vehicle, 20, true) end if props.tyreSmokeColor ~= nil then SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3]) end if props.modSpoilers ~= nil then SetVehicleMod(vehicle, 0, props.modSpoilers, false) end if props.modFrontBumper ~= nil then SetVehicleMod(vehicle, 1, props.modFrontBumper, false) end if props.modRearBumper ~= nil then SetVehicleMod(vehicle, 2, props.modRearBumper, false) end if props.modSideSkirt ~= nil then SetVehicleMod(vehicle, 3, props.modSideSkirt, false) end if props.modExhaust ~= nil then SetVehicleMod(vehicle, 4, props.modExhaust, false) end if props.modFrame ~= nil then SetVehicleMod(vehicle, 5, props.modFrame, false) end if props.modGrille ~= nil then SetVehicleMod(vehicle, 6, props.modGrille, false) end if props.modHood ~= nil then SetVehicleMod(vehicle, 7, props.modHood, false) end if props.modFender ~= nil then SetVehicleMod(vehicle, 8, props.modFender, false) end if props.modRightFender ~= nil then SetVehicleMod(vehicle, 9, props.modRightFender, false) end if props.modRoof ~= nil then SetVehicleMod(vehicle, 10, props.modRoof, false) end if props.modRoofLivery ~= nil then SetVehicleRoofLivery(vehicle, props.modRoofLivery) end if props.modEngine ~= nil then SetVehicleMod(vehicle, 11, props.modEngine, false) end if props.modBrakes ~= nil then SetVehicleMod(vehicle, 12, props.modBrakes, false) end if props.modTransmission ~= nil then SetVehicleMod(vehicle, 13, props.modTransmission, false) end if props.modHorns ~= nil then SetVehicleMod(vehicle, 14, props.modHorns, false) end if props.modSuspension ~= nil then SetVehicleMod(vehicle, 15, props.modSuspension, false) end if props.modArmor ~= nil then SetVehicleMod(vehicle, 16, props.modArmor, false) end if props.modTurbo ~= nil then ToggleVehicleMod(vehicle, 18, props.modTurbo) end if props.modXenon ~= nil then ToggleVehicleMod(vehicle, 22, props.modXenon) end if props.modFrontWheels ~= nil then SetVehicleMod(vehicle, 23, props.modFrontWheels, props.modCustomFrontWheels) end if props.modBackWheels ~= nil then SetVehicleMod(vehicle, 24, props.modBackWheels, props.modCustomBackWheels) end if props.modPlateHolder ~= nil then SetVehicleMod(vehicle, 25, props.modPlateHolder, false) end if props.modVanityPlate ~= nil then SetVehicleMod(vehicle, 26, props.modVanityPlate, false) end if props.modTrimA ~= nil then SetVehicleMod(vehicle, 27, props.modTrimA, false) end if props.modOrnaments ~= nil then SetVehicleMod(vehicle, 28, props.modOrnaments, false) end if props.modDashboard ~= nil then SetVehicleMod(vehicle, 29, props.modDashboard, false) end if props.modDial ~= nil then SetVehicleMod(vehicle, 30, props.modDial, false) end if props.modDoorSpeaker ~= nil then SetVehicleMod(vehicle, 31, props.modDoorSpeaker, false) end if props.modSeats ~= nil then SetVehicleMod(vehicle, 32, props.modSeats, false) end if props.modSteeringWheel ~= nil then SetVehicleMod(vehicle, 33, props.modSteeringWheel, false) end if props.modShifterLeavers ~= nil then SetVehicleMod(vehicle, 34, props.modShifterLeavers, false) end if props.modAPlate ~= nil then SetVehicleMod(vehicle, 35, props.modAPlate, false) end if props.modSpeakers ~= nil then SetVehicleMod(vehicle, 36, props.modSpeakers, false) end if props.modTrunk ~= nil then SetVehicleMod(vehicle, 37, props.modTrunk, false) end if props.modHydrolic ~= nil then SetVehicleMod(vehicle, 38, props.modHydrolic, false) end if props.modEngineBlock ~= nil then SetVehicleMod(vehicle, 39, props.modEngineBlock, false) end if props.modAirFilter ~= nil then SetVehicleMod(vehicle, 40, props.modAirFilter, false) end if props.modStruts ~= nil then SetVehicleMod(vehicle, 41, props.modStruts, false) end if props.modArchCover ~= nil then SetVehicleMod(vehicle, 42, props.modArchCover, false) end if props.modAerials ~= nil then SetVehicleMod(vehicle, 43, props.modAerials, false) end if props.modTrimB ~= nil then SetVehicleMod(vehicle, 44, props.modTrimB, false) end if props.modTank ~= nil then SetVehicleMod(vehicle, 45, props.modTank, false) end if props.modWindows ~= nil then SetVehicleMod(vehicle, 46, props.modWindows, false) end if props.modLivery ~= nil then SetVehicleMod(vehicle, 48, props.modLivery, false) SetVehicleLivery(vehicle, props.modLivery) end if props.windowsBroken ~= nil then for k, v in pairs(props.windowsBroken) do if v then k = tonumber(k) if k then RemoveVehicleWindow(vehicle, k) end end end end if props.doorsBroken ~= nil then for k, v in pairs(props.doorsBroken) do if v then k = tonumber(k) if k then SetVehicleDoorBroken(vehicle, k, true) end end end end if props.tyreBurst ~= nil then for k, v in pairs(props.tyreBurst) do if v then k = tonumber(k) if k then SetVehicleTyreBurst(vehicle, k, true, 1000.0) end end end end end ---@param coords vector3 | table coords to get the closest pickup to ---@param text string The text to display ---@param size? number The size of the text ---@param font? number The font of the text ---@return nil function ESX.Game.Utils.DrawText3D(coords, text, size, font) local vector = type(coords) == "vector3" and coords or vec(coords.x, coords.y, coords.z) local camCoords = GetFinalRenderedCamCoord() local distance = #(vector - camCoords) size = size or 1 font = font or 0 local scale = (size / distance) * 2 local fov = (1 / GetGameplayCamFov()) * 100 scale = scale * fov SetTextScale(0.0, 0.55 * scale) SetTextFont(font) SetTextProportional(true) SetTextColour(255, 255, 255, 215) BeginTextCommandDisplayText("STRING") SetTextCentre(true) AddTextComponentSubstringPlayerName(text) SetDrawOrigin(vector.x, vector.y, vector.z, 0) EndTextCommandDisplayText(0.0, 0.0) ClearDrawOrigin() end ---@param account string Account name (money/bank/black_money) ---@return table|nil function ESX.GetAccount(account) for i = 1, #ESX.PlayerData.accounts, 1 do if ESX.PlayerData.accounts[i].name == account then return ESX.PlayerData.accounts[i] end end return nil end function ESX.ShowInventory() if not Config.EnableDefaultInventory then return end exports.esx_inventory:ShowInventory() end RegisterNetEvent('esx:showNotification', ESX.ShowNotification) RegisterNetEvent('esx:showAdvancedNotification', ESX.ShowAdvancedNotification) RegisterNetEvent('esx:showHelpNotification', ESX.ShowHelpNotification) AddEventHandler("onResourceStop", function(resourceName) for i = 1, #ESX.UI.Menu.Opened, 1 do if ESX.UI.Menu.Opened[i] then if ESX.UI.Menu.Opened[i].resourceName == resourceName or ESX.UI.Menu.Opened[i].namespace == resourceName then ESX.UI.Menu.Opened[i].close() ESX.UI.Menu.Opened[i] = nil end end end end) -- Credits to txAdmin for the list. local mismatchedTypes = { [`airtug`] = "automobile", -- trailer [`avisa`] = "submarine", -- boat [`blimp`] = "heli", -- plane [`blimp2`] = "heli", -- plane [`blimp3`] = "heli", -- plane [`caddy`] = "automobile", -- trailer [`caddy2`] = "automobile", -- trailer [`caddy3`] = "automobile", -- trailer [`chimera`] = "automobile", -- bike [`docktug`] = "automobile", -- trailer [`forklift`] = "automobile", -- trailer [`kosatka`] = "submarine", -- boat [`mower`] = "automobile", -- trailer [`policeb`] = "bike", -- automobile [`ripley`] = "automobile", -- trailer [`rrocket`] = "automobile", -- bike [`sadler`] = "automobile", -- trailer [`sadler2`] = "automobile", -- trailer [`scrap`] = "automobile", -- trailer [`slamtruck`] = "automobile", -- trailer [`Stryder`] = "automobile", -- bike [`submersible`] = "submarine", -- boat [`submersible2`] = "submarine", -- boat [`thruster`] = "heli", -- automobile [`towtruck`] = "automobile", -- trailer [`towtruck2`] = "automobile", -- trailer [`tractor`] = "automobile", -- trailer [`tractor2`] = "automobile", -- trailer [`tractor3`] = "automobile", -- trailer [`trailersmall2`] = "trailer", -- automobile [`utillitruck`] = "automobile", -- trailer [`utillitruck2`] = "automobile", -- trailer [`utillitruck3`] = "automobile", -- trailer } ---@param model number|string ---@return string | boolean function ESX.GetVehicleTypeClient(model) model = type(model) == "string" and joaat(model) or model if not IsModelInCdimage(model) then return false end if not IsModelAVehicle(model) then return false end if mismatchedTypes[model] then return mismatchedTypes[model] end local vehicleType = GetVehicleClassFromName(model) local types = { [8] = "bike", [11] = "trailer", [13] = "bike", [14] = "boat", [15] = "heli", [16] = "plane", [21] = "train", } return types[vehicleType] or "automobile" end ESX.GetVehicleType = ESX.GetVehicleTypeClient