ESX = {} ESX.PlayerData = {} ESX.PlayerLoaded = false ESX.CurrentRequestId = 0 ESX.ServerCallbacks = {} ESX.TimeoutCallbacks = {} ESX.UI = {} ESX.UI.HUD = {} ESX.UI.HUD.RegisteredElements = {} ESX.UI.Menu = {} ESX.UI.Menu.RegisteredTypes = {} ESX.UI.Menu.Opened = {} ESX.Game = {} ESX.Game.Utils = {} ESX.Scaleform = {} ESX.Scaleform.Utils = {} ESX.Streaming = {} ESX.SetTimeout = function(msec, cb) table.insert(ESX.TimeoutCallbacks, { time = GetGameTimer() + msec, cb = cb }) return #ESX.TimeoutCallbacks end ESX.ClearTimeout = function(i) ESX.TimeoutCallbacks[i] = nil end ESX.IsPlayerLoaded = function() return ESX.PlayerLoaded end ESX.GetPlayerData = function() return ESX.PlayerData end ESX.SetPlayerData = function(key, val) ESX.PlayerData[key] = val TriggerEvent('esx:setPlayerData', key, val) end ESX.ShowNotification = function(msg) SetNotificationTextEntry('STRING') AddTextComponentString(msg) DrawNotification(0,1) end ESX.ShowAdvancedNotification = function(sender, subject, msg, textureDict, iconType, flash, saveToBrief, hudColorIndex) if saveToBrief == nil then saveToBrief = true end AddTextEntry('esxAdvancedNotification', msg) BeginTextCommandThefeedPost('esxAdvancedNotification') if hudColorIndex then ThefeedNextPostBackgroundColor(hudColorIndex) end EndTextCommandThefeedPostMessagetext(textureDict, textureDict, false, iconType, sender, subject) EndTextCommandThefeedPostTicker(flash or false, saveToBrief) end ESX.ShowHelpNotification = function(msg, thisFrame, beep, duration) AddTextEntry('esxHelpNotification', msg) if thisFrame then DisplayHelpTextThisFrame('esxHelpNotification', false) else if beep == nil then beep = true end BeginTextCommandDisplayHelp('esxHelpNotification') EndTextCommandDisplayHelp(0, false, beep, duration or -1) end end ESX.ShowFloatingHelpNotification = function(msg, coords) AddTextEntry('esxFloatingHelpNotification', msg) SetFloatingHelpTextWorldPosition(1, coords) SetFloatingHelpTextStyle(1, 1, 2, -1, 3, 0) BeginTextCommandDisplayHelp('esxFloatingHelpNotification') EndTextCommandDisplayHelp(2, false, false, -1) end ESX.TriggerServerCallback = function(name, cb, ...) ESX.ServerCallbacks[ESX.CurrentRequestId] = cb TriggerServerEvent('esx:triggerServerCallback', name, ESX.CurrentRequestId, ...) if ESX.CurrentRequestId < 65535 then ESX.CurrentRequestId = ESX.CurrentRequestId + 1 else ESX.CurrentRequestId = 0 end end ESX.UI.HUD.SetDisplay = function(opacity) SendNUIMessage({ action = 'setHUDDisplay', opacity = opacity }) end ESX.UI.HUD.RegisterElement = function(name, index, priority, html, data) local found = false for i=1, #ESX.UI.HUD.RegisteredElements, 1 do if ESX.UI.HUD.RegisteredElements[i] == name then found = true break end end if found then return end table.insert(ESX.UI.HUD.RegisteredElements, name) SendNUIMessage({ action = 'insertHUDElement', name = name, index = index, priority = priority, html = html, data = data }) ESX.UI.HUD.UpdateElement(name, data) end ESX.UI.HUD.RemoveElement = function(name) for i=1, #ESX.UI.HUD.RegisteredElements, 1 do if ESX.UI.HUD.RegisteredElements[i] == name then table.remove(ESX.UI.HUD.RegisteredElements, i) break end end SendNUIMessage({ action = 'deleteHUDElement', name = name }) end ESX.UI.HUD.UpdateElement = function(name, data) SendNUIMessage({ action = 'updateHUDElement', name = name, data = data }) end ESX.UI.Menu.RegisterType = function(type, open, close) ESX.UI.Menu.RegisteredTypes[type] = { open = open, close = close } end ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change, close) local menu = {} menu.type = type menu.namespace = namespace menu.name = name menu.data = data menu.submit = submit menu.cancel = cancel menu.change = change menu.close = function() ESX.UI.Menu.RegisteredTypes[type].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 == type 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[type].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 table.insert(ESX.UI.Menu.Opened, menu) ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, data) return menu end ESX.UI.Menu.Close = function(type, 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 == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then ESX.UI.Menu.Opened[i].close() ESX.UI.Menu.Opened[i] = nil end end end end ESX.UI.Menu.CloseAll = function() for i=1, #ESX.UI.Menu.Opened, 1 do if ESX.UI.Menu.Opened[i] then ESX.UI.Menu.Opened[i].close() ESX.UI.Menu.Opened[i] = nil end end end ESX.UI.Menu.GetOpened = function(type, 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 == type 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 ESX.UI.Menu.GetOpenedMenus = function() return ESX.UI.Menu.Opened end ESX.UI.Menu.IsOpen = function(type, namespace, name) return ESX.UI.Menu.GetOpened(type, namespace, name) ~= nil end ESX.UI.ShowInventoryItemNotification = function(add, item, count) SendNUIMessage({ action = 'inventoryNotification', add = add, item = item, count = count }) end ESX.Game.GetPedMugshot = function(ped, transparent) if DoesEntityExist(ped) then local mugshot if transparent then mugshot = RegisterPedheadshotTransparent(ped) else mugshot = RegisterPedheadshot(ped) end while not IsPedheadshotReady(mugshot) do Citizen.Wait(0) end return mugshot, GetPedheadshotTxdString(mugshot) else return end end ESX.Game.Teleport = function(entity, coords, cb) local vector = type(coords) == "vector4" and coords or type(coords) == "vector3" and vector4(coords, 0.0) or vec(coords.x, coords.y, coords.z, coords.heading or 0.0) if DoesEntityExist(entity) then RequestCollisionAtCoord(vector.xyz) while not HasCollisionLoadedAroundEntity(entity) do Wait(0) end SetEntityCoords(entity, vector.xyz, false, false, false, false) SetEntityHeading(entity, vector.w) end if cb then cb() end end ESX.Game.SpawnObject = function(object, coords, cb, networked, dynamic) local model = (type(object) == 'number' and model or GetHashKey(object)) local vector = type(coords) == "vector3" and coords or vec(coords.x, coords.y, coords.z) networked = networked == nil and true or false dynamic = dynamic ~= nil and true or false CreateThread(function() ESX.Streaming.RequestModel(model) -- The below has to be done just for CreateObject since for some reason CreateObjects model argument is set -- as an Object instead of a hash so it doesn't automatically hash the item model = type(model) == 'number' and model or GetHashKey(model) local obj = CreateObject(model, vector.xyz, networked, false, dynamic) if cb then cb(obj) end end) end ESX.Game.SpawnLocalObject = function(object, coords, cb) -- Why have 2 separate functions for this? Just call the other one with an extra param ESX.Game.SpawnObject(object, coords, cb, false) end ESX.Game.DeleteVehicle = function(vehicle) SetEntityAsMissionEntity(vehicle, false, true) DeleteVehicle(vehicle) end ESX.Game.DeleteObject = function(object) SetEntityAsMissionEntity(object, false, true) DeleteObject(object) end ESX.Game.SpawnVehicle = function(vehicle, coords, heading, cb, networked) local model = (type(vehicle) == 'number' and vehicle or GetHashKey(vehicle)) local vector = type(coords) == "vector3" and coords or vec(coords.x, coords.y, coords.z) networked = networked == nil and true or false CreateThread(function() ESX.Streaming.RequestModel(model) local vehicle = CreateVehicle(model, vector.xyz, heading, networked, false) if networked then local id = NetworkGetNetworkIdFromEntity(vehicle) SetNetworkIdCanMigrate(id, true) SetEntityAsMissionEntity(vehicle, true, false) end SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetVehicleNeedsToBeHotwired(vehicle, false) SetModelAsNoLongerNeeded(model) SetVehRadioStation(vehicle, 'OFF') RequestCollisionAtCoord(vector.xyz) while not HasCollisionLoadedAroundEntity(vehicle) do Wait(0) end if cb then cb(vehicle) end end) end ESX.Game.SpawnLocalVehicle = function(vehicle, coords, heading, cb) -- Why have 2 separate functions for this? Just call the other one with an extra param ESX.Game.SpawnVehicle(vehicle, coords, heading, cb, false) end ESX.Game.IsVehicleEmpty = function(vehicle) local passengers = GetVehicleNumberOfPassengers(vehicle) local driverSeatFree = IsVehicleSeatFree(vehicle, -1) return passengers == 0 and driverSeatFree end ESX.Game.GetObjects = function() local objects = {} for object in EnumerateObjects() do table.insert(objects, object) end return objects end ESX.Game.GetPeds = function(onlyOtherPeds) local peds, myPed = {}, PlayerPedId() for ped in EnumeratePeds() do if ((onlyOtherPeds and ped ~= myPed) or not onlyOtherPeds) then table.insert(peds, ped) end end return peds end ESX.Game.GetVehicles = function() local vehicles = {} for vehicle in EnumerateVehicles() do table.insert(vehicles, vehicle) end return vehicles end ESX.Game.GetPlayers = function(onlyOtherPlayers, returnKeyValue, returnPeds) local players, myPlayer = {}, PlayerId() for k,player in ipairs(GetActivePlayers()) do local ped = GetPlayerPed(player) if DoesEntityExist(ped) and ((onlyOtherPlayers and player ~= myPlayer) or not onlyOtherPlayers) then if returnKeyValue then players[player] = ped else table.insert(players, returnPeds and ped or player) end end end return players end ESX.Game.GetClosestObject = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetObjects(), false, coords, modelFilter) end ESX.Game.GetClosestPed = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetPeds(true), false, coords, modelFilter) end ESX.Game.GetClosestPlayer = function(coords) return ESX.Game.GetClosestEntity(ESX.Game.GetPlayers(true, true), true, coords, nil) end ESX.Game.GetClosestVehicle = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetVehicles(), false, coords, modelFilter) end ESX.Game.GetPlayersInArea = function(coords, maxDistance) return EnumerateEntitiesWithinDistance(ESX.Game.GetPlayers(true, true), true, coords, maxDistance) end ESX.Game.GetVehiclesInArea = function(coords, maxDistance) return EnumerateEntitiesWithinDistance(ESX.Game.GetVehicles(), false, coords, maxDistance) end ESX.Game.IsSpawnPointClear = function(coords, maxDistance) return #ESX.Game.GetVehiclesInArea(coords, maxDistance) == 0 end ESX.Game.GetClosestEntity = function(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 = PlayerPedId() coords = GetEntityCoords(playerPed) end if modelFilter then filteredEntities = {} for k,entity in pairs(entities) do if modelFilter[GetEntityModel(entity)] then table.insert(filteredEntities, entity) 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 ESX.Game.GetVehicleInDirection = function() local playerPed = PlayerPedId() local playerCoords = GetEntityCoords(playerPed) local inDirection = GetOffsetFromEntityInWorldCoords(playerPed, 0.0, 5.0, 0.0) local rayHandle = StartShapeTestRay(playerCoords, inDirection, 10, playerPed, 0) local numRayHandle, hit, endCoords, surfaceNormal, entityHit = GetShapeTestResult(rayHandle) if hit == 1 and GetEntityType(entityHit) == 2 then local entityCoords = GetEntityCoords(entityHit) return entityHit, entityCoords end return nil end ESX.Game.GetVehicleProperties = function(vehicle) if DoesEntityExist(vehicle) then local colorPrimary, colorSecondary = GetVehicleColours(vehicle) local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) local extras = {} for extraId=0, 12 do if DoesExtraExist(vehicle, extraId) then local state = IsVehicleExtraTurnedOn(vehicle, extraId) == 1 extras[tostring(extraId)] = state end end return { model = GetEntityModel(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, wheels = GetVehicleWheelType(vehicle), windowTint = GetVehicleWindowTint(vehicle), xenonColor = GetVehicleXenonLightsColour(vehicle), 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), 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), modBackWheels = GetVehicleMod(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 = GetVehicleLivery(vehicle) } else return end end ESX.Game.SetVehicleProperties = function(vehicle, props) if DoesEntityExist(vehicle) then local colorPrimary, colorSecondary = GetVehicleColours(vehicle) local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) SetVehicleModKit(vehicle, 0) if props.plate then SetVehicleNumberPlateText(vehicle, props.plate) end if props.plateIndex then SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) end if props.bodyHealth then SetVehicleBodyHealth(vehicle, props.bodyHealth + 0.0) end if props.engineHealth then SetVehicleEngineHealth(vehicle, props.engineHealth + 0.0) end if props.tankHealth then SetVehiclePetrolTankHealth(vehicle, props.tankHealth + 0.0) end if props.fuelLevel then SetVehicleFuelLevel(vehicle, props.fuelLevel + 0.0) end if props.dirtLevel then SetVehicleDirtLevel(vehicle, props.dirtLevel + 0.0) end if props.color1 then SetVehicleColours(vehicle, props.color1, colorSecondary) end if props.color2 then SetVehicleColours(vehicle, props.color1 or colorPrimary, props.color2) end if props.pearlescentColor then SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) end if props.wheelColor then SetVehicleExtraColours(vehicle, props.pearlescentColor or pearlescentColor, props.wheelColor) end if props.wheels then SetVehicleWheelType(vehicle, props.wheels) end if props.windowTint then SetVehicleWindowTint(vehicle, props.windowTint) end if props.neonEnabled 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 then for extraId,enabled in pairs(props.extras) do if enabled then SetVehicleExtra(vehicle, tonumber(extraId), 0) else SetVehicleExtra(vehicle, tonumber(extraId), 1) end end end if props.neonColor then SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) end if props.xenonColor then SetVehicleXenonLightsColour(vehicle, props.xenonColor) end if props.modSmokeEnabled then ToggleVehicleMod(vehicle, 20, true) end if props.tyreSmokeColor then SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3]) end if props.modSpoilers then SetVehicleMod(vehicle, 0, props.modSpoilers, false) end if props.modFrontBumper then SetVehicleMod(vehicle, 1, props.modFrontBumper, false) end if props.modRearBumper then SetVehicleMod(vehicle, 2, props.modRearBumper, false) end if props.modSideSkirt then SetVehicleMod(vehicle, 3, props.modSideSkirt, false) end if props.modExhaust then SetVehicleMod(vehicle, 4, props.modExhaust, false) end if props.modFrame then SetVehicleMod(vehicle, 5, props.modFrame, false) end if props.modGrille then SetVehicleMod(vehicle, 6, props.modGrille, false) end if props.modHood then SetVehicleMod(vehicle, 7, props.modHood, false) end if props.modFender then SetVehicleMod(vehicle, 8, props.modFender, false) end if props.modRightFender then SetVehicleMod(vehicle, 9, props.modRightFender, false) end if props.modRoof then SetVehicleMod(vehicle, 10, props.modRoof, false) end if props.modEngine then SetVehicleMod(vehicle, 11, props.modEngine, false) end if props.modBrakes then SetVehicleMod(vehicle, 12, props.modBrakes, false) end if props.modTransmission then SetVehicleMod(vehicle, 13, props.modTransmission, false) end if props.modHorns then SetVehicleMod(vehicle, 14, props.modHorns, false) end if props.modSuspension then SetVehicleMod(vehicle, 15, props.modSuspension, false) end if props.modArmor then SetVehicleMod(vehicle, 16, props.modArmor, false) end if props.modTurbo then ToggleVehicleMod(vehicle, 18, props.modTurbo) end if props.modXenon then ToggleVehicleMod(vehicle, 22, props.modXenon) end if props.modFrontWheels then SetVehicleMod(vehicle, 23, props.modFrontWheels, false) end if props.modBackWheels then SetVehicleMod(vehicle, 24, props.modBackWheels, false) end if props.modPlateHolder then SetVehicleMod(vehicle, 25, props.modPlateHolder, false) end if props.modVanityPlate then SetVehicleMod(vehicle, 26, props.modVanityPlate, false) end if props.modTrimA then SetVehicleMod(vehicle, 27, props.modTrimA, false) end if props.modOrnaments then SetVehicleMod(vehicle, 28, props.modOrnaments, false) end if props.modDashboard then SetVehicleMod(vehicle, 29, props.modDashboard, false) end if props.modDial then SetVehicleMod(vehicle, 30, props.modDial, false) end if props.modDoorSpeaker then SetVehicleMod(vehicle, 31, props.modDoorSpeaker, false) end if props.modSeats then SetVehicleMod(vehicle, 32, props.modSeats, false) end if props.modSteeringWheel then SetVehicleMod(vehicle, 33, props.modSteeringWheel, false) end if props.modShifterLeavers then SetVehicleMod(vehicle, 34, props.modShifterLeavers, false) end if props.modAPlate then SetVehicleMod(vehicle, 35, props.modAPlate, false) end if props.modSpeakers then SetVehicleMod(vehicle, 36, props.modSpeakers, false) end if props.modTrunk then SetVehicleMod(vehicle, 37, props.modTrunk, false) end if props.modHydrolic then SetVehicleMod(vehicle, 38, props.modHydrolic, false) end if props.modEngineBlock then SetVehicleMod(vehicle, 39, props.modEngineBlock, false) end if props.modAirFilter then SetVehicleMod(vehicle, 40, props.modAirFilter, false) end if props.modStruts then SetVehicleMod(vehicle, 41, props.modStruts, false) end if props.modArchCover then SetVehicleMod(vehicle, 42, props.modArchCover, false) end if props.modAerials then SetVehicleMod(vehicle, 43, props.modAerials, false) end if props.modTrimB then SetVehicleMod(vehicle, 44, props.modTrimB, false) end if props.modTank then SetVehicleMod(vehicle, 45, props.modTank, false) end if props.modWindows then SetVehicleMod(vehicle, 46, props.modWindows, false) end if props.modLivery then SetVehicleMod(vehicle, 48, props.modLivery, false) SetVehicleLivery(vehicle, props.modLivery) end end end ESX.Game.Utils.DrawText3D = function(coords, text, scale, font) local vector = type(coords) == "vector3" and coords or vec(coords.x, coords.y, coords.z) if not scale then scale = 0.35 end if not font then font = 4 end SetTextScale(scale, scale) SetTextFont(font) SetTextProportional(1) SetTextColour(255, 255, 255, 215) SetTextEntry('STRING') SetTextCentre(true) AddTextComponentString(text) SetDrawOrigin(vector.xyz, 0) DrawText(0.0, 0.0) local factor = string.len(text) / 370 DrawRect(0.0, 0.0 + 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75) ClearDrawOrigin() end ESX.ShowInventory = function() local playerPed = PlayerPedId() local elements, currentWeight = {}, 0 for k,v in pairs(ESX.PlayerData.accounts) do if v.money > 0 then local formattedMoney = _U('locale_currency', ESX.Math.GroupDigits(v.money)) local canDrop = v.name ~= 'bank' table.insert(elements, { label = ('%s: %s'):format(v.label, formattedMoney), count = v.money, type = 'item_account', value = v.name, usable = false, rare = false, canRemove = canDrop }) end end for k,v in ipairs(ESX.PlayerData.inventory) do if v.count > 0 then currentWeight = currentWeight + (v.weight * v.count) table.insert(elements, { label = ('%s x%s'):format(v.label, v.count), count = v.count, type = 'item_standard', value = v.name, usable = v.usable, rare = v.rare, canRemove = v.canRemove }) end end for k,v in ipairs(Config.Weapons) do local weaponHash = GetHashKey(v.name) if HasPedGotWeapon(playerPed, weaponHash, false) then local ammo, label = GetAmmoInPedWeapon(playerPed, weaponHash) if v.ammo then label = ('%s - %s %s'):format(v.label, ammo, v.ammo.label) else label = v.label end table.insert(elements, { label = label, count = 1, type = 'item_weapon', value = v.name, usable = false, rare = false, ammo = ammo, canGiveAmmo = (v.ammo ~= nil), canRemove = true }) end end ESX.UI.Menu.CloseAll() ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'inventory', { title = _U('inventory', currentWeight, ESX.PlayerData.maxWeight), align = 'bottom-right', elements = elements }, function(data, menu) menu.close() local player, distance = ESX.Game.GetClosestPlayer() elements = {} if data.current.usable then table.insert(elements, {label = _U('use'), action = 'use', type = data.current.type, value = data.current.value}) end if data.current.canRemove then if player ~= -1 and distance <= 3.0 then table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) end table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) end if data.current.type == 'item_weapon' and data.current.canGiveAmmo and data.current.ammo > 0 and player ~= -1 and distance <= 3.0 then table.insert(elements, {label = _U('giveammo'), action = 'give_ammo', type = data.current.type, value = data.current.value}) end table.insert(elements, {label = _U('return'), action = 'return'}) ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'inventory_item', { title = data.current.label, align = 'bottom-right', elements = elements, }, function(data1, menu1) local item, type = data1.current.value, data1.current.type if data1.current.action == 'give' then local playersNearby = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) if #playersNearby > 0 then local players = {} elements = {} for k,playerNearby in ipairs(playersNearby) do players[GetPlayerServerId(playerNearby)] = true end ESX.TriggerServerCallback('esx:getPlayerNames', function(returnedPlayers) for playerId,playerName in pairs(returnedPlayers) do table.insert(elements, { label = playerName, playerId = playerId }) end ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'give_item_to', { title = _U('give_to'), align = 'bottom-right', elements = elements }, function(data2, menu2) local selectedPlayer, selectedPlayerId = GetPlayerFromServerId(data2.current.playerId), data2.current.playerId playersNearby = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) playersNearby = ESX.Table.Set(playersNearby) if playersNearby[selectedPlayer] then local selectedPlayerPed = GetPlayerPed(selectedPlayer) if IsPedOnFoot(selectedPlayerPed) and not IsPedFalling(selectedPlayerPed) then if type == 'item_weapon' then TriggerServerEvent('esx:giveInventoryItem', selectedPlayerId, type, item, nil) menu2.close() menu1.close() else ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', { title = _U('amount') }, function(data3, menu3) local quantity = tonumber(data3.value) if quantity and quantity > 0 and data.current.count >= quantity then TriggerServerEvent('esx:giveInventoryItem', selectedPlayerId, type, item, quantity) menu3.close() menu2.close() menu1.close() else ESX.ShowNotification(_U('amount_invalid')) end end, function(data3, menu3) menu3.close() end) end else ESX.ShowNotification(_U('in_vehicle')) end else ESX.ShowNotification(_U('players_nearby')) menu2.close() end end, function(data2, menu2) menu2.close() end) end, players) else ESX.ShowNotification(_U('players_nearby')) end elseif data1.current.action == 'remove' then if IsPedOnFoot(playerPed) and not IsPedFalling(playerPed) then local dict, anim = 'weapons@first_person@aim_rng@generic@projectile@sticky_bomb@', 'plant_floor' ESX.Streaming.RequestAnimDict(dict) if type == 'item_weapon' then menu1.close() TaskPlayAnim(playerPed, dict, anim, 8.0, 1.0, 1000, 16, 0.0, false, false, false) Citizen.Wait(1000) TriggerServerEvent('esx:removeInventoryItem', type, item) else ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_remove', { title = _U('amount') }, function(data2, menu2) local quantity = tonumber(data2.value) if quantity and quantity > 0 and data.current.count >= quantity then menu2.close() menu1.close() TaskPlayAnim(playerPed, dict, anim, 8.0, 1.0, 1000, 16, 0.0, false, false, false) Citizen.Wait(1000) TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) else ESX.ShowNotification(_U('amount_invalid')) end end, function(data2, menu2) menu2.close() end) end end elseif data1.current.action == 'use' then TriggerServerEvent('esx:useItem', item) elseif data1.current.action == 'return' then ESX.UI.Menu.CloseAll() ESX.ShowInventory() elseif data1.current.action == 'give_ammo' then local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() local closestPed = GetPlayerPed(closestPlayer) local pedAmmo = GetAmmoInPedWeapon(playerPed, GetHashKey(item)) if IsPedOnFoot(closestPed) and not IsPedFalling(closestPed) then if closestPlayer ~= -1 and closestDistance < 3.0 then if pedAmmo > 0 then ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', { title = _U('amountammo') }, function(data2, menu2) local quantity = tonumber(data2.value) if quantity and quantity > 0 then if pedAmmo >= quantity then TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), 'item_ammo', item, quantity) menu2.close() menu1.close() else ESX.ShowNotification(_U('noammo')) end else ESX.ShowNotification(_U('amount_invalid')) end end, function(data2, menu2) menu2.close() end) else ESX.ShowNotification(_U('noammo')) end else ESX.ShowNotification(_U('players_nearby')) end else ESX.ShowNotification(_U('in_vehicle')) end end end, function(data1, menu1) ESX.UI.Menu.CloseAll() ESX.ShowInventory() end) end, function(data, menu) menu.close() end) end RegisterNetEvent('esx:serverCallback') AddEventHandler('esx:serverCallback', function(requestId, ...) ESX.ServerCallbacks[requestId](...) ESX.ServerCallbacks[requestId] = nil end) RegisterNetEvent('esx:showNotification') AddEventHandler('esx:showNotification', function(msg) ESX.ShowNotification(msg) end) RegisterNetEvent('esx:showAdvancedNotification') AddEventHandler('esx:showAdvancedNotification', function(sender, subject, msg, textureDict, iconType, flash, saveToBrief, hudColorIndex) ESX.ShowAdvancedNotification(sender, subject, msg, textureDict, iconType, flash, saveToBrief, hudColorIndex) end) RegisterNetEvent('esx:showHelpNotification') AddEventHandler('esx:showHelpNotification', function(msg, thisFrame, beep, duration) ESX.ShowHelpNotification(msg, thisFrame, beep, duration) end) -- SetTimeout Citizen.CreateThread(function() while true do Citizen.Wait(0) local letSleep = true local currTime = GetGameTimer() if #ESX.TimeoutCallbacks > 0 then letSleep = false for i=1, #ESX.TimeoutCallbacks, 1 do if ESX.TimeoutCallbacks[i] then if currTime >= ESX.TimeoutCallbacks[i].time then ESX.TimeoutCallbacks[i].cb() ESX.TimeoutCallbacks[i] = nil end end end end if letSleep then Citizen.Wait(500) end end end)