mirror of
https://github.com/esx-framework/esx_core.git
synced 2026-08-29 01:08:54 +00:00
Merge remote-tracking branch 'Astro/refactor/move-modules-to-lib' into 1.14.0
This commit is contained in:
@@ -1,18 +1,62 @@
|
||||
--All client-side functions outsourced from the Core to the lib will be stored here for compatability, e.g:
|
||||
|
||||
ESX.Streaming.RequestModel = xLib.streaming.requestModel
|
||||
ESX.Streaming.RequestStreamedTextureDict = xLib.streaming.requestStreamedTextureDict
|
||||
ESX.Streaming.RequestNamedPtfxAsset = xLib.streaming.requestNamedPtfxAsset
|
||||
ESX.Streaming.RequestAnimSet = xLib.streaming.requestAnimSet
|
||||
ESX.Streaming.RequestAnimDict = xLib.streaming.requestAnimDict
|
||||
ESX.Streaming.RequestWeaponAsset = xLib.streaming.requestWeaponAsset
|
||||
ESX.Game.GetShapeTestResultSync = xLib.Raycast.GetShapeTestResult
|
||||
ESX.Game.RaycastScreen = xLib.Raycast.FromScreen
|
||||
ESX.Game.StartRaycasting = xLib.Raycast.Start
|
||||
ESX.Game.GetClosestEntity = xLib.entity.closest
|
||||
EnumerateEntitiesWithinDistance = xLib.entity.EnumerateWithinDistance
|
||||
ESX.Game.Teleport = xLib.entity.Teleport
|
||||
|
||||
ESX.Streaming = {
|
||||
RequestModel = xLib.streaming.requestModel,
|
||||
RequestStreamedTextureDict = xLib.streaming.requestStreamedTextureDict,
|
||||
RequestNamedPtfxAsset = xLib.streaming.requestNamedPtfxAsset,
|
||||
RequestAnimSet = xLib.streaming.requestAnimSet,
|
||||
RequestAnimDict = xLib.streaming.requestAnimDict,
|
||||
RequestWeaponAsset = xLib.streaming.requestWeaponAsset,
|
||||
}
|
||||
|
||||
ESX.Scaleform = {
|
||||
ShowFreemodeMessage = xLib.scaleform.showFreemodeMessage,
|
||||
ShowBreakingNews = xLib.scaleform.showBreakingNews,
|
||||
ShowPopupWarning = xLib.scaleform.showPopupWarning,
|
||||
ShowTrafficMovie = xLib.scaleform.showTrafficMovie,
|
||||
Utils = {
|
||||
RequestScaleformMovie = xLib.scaleform.utils.requestScaleformMovie,
|
||||
RunMethod = xLib.scaleform.utils.runMethod,
|
||||
},
|
||||
}
|
||||
|
||||
ESX.CreatePointInternal = xLib.points.create
|
||||
ESX.RemovePointInternal = xLib.points.remove
|
||||
ESX.HidePointInternal = xLib.points.hide
|
||||
StartPointsLoop = xLib.points.startLoop
|
||||
ESX.Point = xLib.point
|
||||
|
||||
ESX.RegisterInteraction = xLib.interactions.register
|
||||
ESX.RemoveInteraction = xLib.interactions.remove
|
||||
ESX.GetInteractKey = xLib.interactions.getInteractKey
|
||||
|
||||
ESX.Game.GetPedMugshot = xLib.game.getPedMugshot
|
||||
ESX.Game.SpawnObject = xLib.game.spawnObject
|
||||
ESX.Game.SpawnLocalObject = xLib.game.spawnLocalObject
|
||||
ESX.Game.DeleteVehicle = xLib.game.deleteVehicle
|
||||
ESX.Game.DeleteObject = xLib.game.deleteObject
|
||||
ESX.Game.SpawnVehicle = xLib.game.spawnVehicle
|
||||
ESX.Game.SpawnLocalVehicle = xLib.game.spawnLocalVehicle
|
||||
ESX.Game.IsVehicleEmpty = xLib.game.isVehicleEmpty
|
||||
ESX.Game.GetObjects = xLib.game.getObjects
|
||||
ESX.Game.GetPeds = xLib.game.getPeds
|
||||
ESX.Game.GetVehicles = xLib.game.getVehicles
|
||||
ESX.Game.GetPlayers = xLib.game.getPlayers
|
||||
ESX.Game.GetClosestObject = xLib.game.getClosestObject
|
||||
ESX.Game.GetClosestPed = xLib.game.getClosestPed
|
||||
ESX.Game.GetClosestPlayer = xLib.game.getClosestPlayer
|
||||
ESX.Game.GetClosestVehicle = xLib.game.getClosestVehicle
|
||||
ESX.Game.GetPlayersInArea = xLib.game.getPlayersInArea
|
||||
ESX.Game.GetVehiclesInArea = xLib.game.getVehiclesInArea
|
||||
ESX.Game.IsSpawnPointClear = xLib.game.isSpawnPointClear
|
||||
ESX.Game.GetVehicleInDirection = xLib.game.getVehicleInDirection
|
||||
ESX.Game.GetVehicleProperties = xLib.game.getVehicleProperties
|
||||
ESX.Game.SetVehicleProperties = xLib.game.setVehicleProperties
|
||||
|
||||
function ESX.RegisterInput(command_name, label, input_group, key, on_press, on_release)
|
||||
return xLib.addKeybind({
|
||||
name = command_name,
|
||||
|
||||
@@ -443,676 +443,6 @@ function ESX.UI.ShowInventoryItemNotification(add, item, 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 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 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
|
||||
|
||||
---@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
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
local Point = ESX.Class()
|
||||
|
||||
local nearby, loop = {}, nil
|
||||
|
||||
function Point:constructor(properties)
|
||||
self.coords = properties.coords
|
||||
self.hidden = properties.hidden
|
||||
self.enter = properties.enter
|
||||
self.leave = properties.leave
|
||||
self.inside = properties.inside
|
||||
self.handle = ESX.CreatePointInternal(properties.coords, properties.distance, properties.hidden, function()
|
||||
nearby[self.handle] = self
|
||||
if self.enter then
|
||||
self:enter()
|
||||
end
|
||||
if not loop then
|
||||
loop = true
|
||||
CreateThread(function()
|
||||
while loop do
|
||||
local coords = GetEntityCoords(ESX.PlayerData.ped)
|
||||
for _, point in pairs(nearby) do
|
||||
if point.inside then
|
||||
point:inside(#(coords - point.coords))
|
||||
end
|
||||
end
|
||||
Wait(0)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end, function()
|
||||
nearby[self.handle] = nil
|
||||
if self.leave then
|
||||
self:leave()
|
||||
end
|
||||
if #nearby == 0 then
|
||||
loop = false
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function Point:delete()
|
||||
ESX.RemovePointInternal(self.handle)
|
||||
end
|
||||
|
||||
function Point:toggle(hidden)
|
||||
if hidden == nil then
|
||||
hidden = not self.hidden
|
||||
end
|
||||
self.hidden = hidden
|
||||
ESX.HidePointInternal(self.handle, hidden)
|
||||
end
|
||||
|
||||
return Point
|
||||
@@ -1,10 +1,14 @@
|
||||
-- ESX glue over the generic xLib.cache.
|
||||
-- ped and weapon are tracked by the lib cache; this module mirrors them into
|
||||
-- ESX.PlayerData, re-emits the legacy esx: events resources depend on, and keeps
|
||||
-- the vehicle enter/exit state machine that produces the richer vehicle events.
|
||||
|
||||
Actions = {}
|
||||
Actions._index = Actions
|
||||
|
||||
Actions.inVehicle = false
|
||||
Actions.enteringVehicle = false
|
||||
Actions.inPauseMenu = false
|
||||
Actions.currentWeapon = false
|
||||
|
||||
function Actions:GetSeatPedIsIn()
|
||||
for i = -1, 16 do
|
||||
@@ -55,21 +59,6 @@ function Actions:TrackPedCoordsOnce()
|
||||
end)
|
||||
end
|
||||
|
||||
function Actions:TrackPed()
|
||||
local playerPed = ESX.PlayerData.ped
|
||||
local newPed = PlayerPedId()
|
||||
|
||||
if playerPed ~= newPed then
|
||||
ESX.SetPlayerData("ped", newPed)
|
||||
|
||||
TriggerEvent("esx:playerPedChanged", newPed)
|
||||
|
||||
if Config.EnableDebug then
|
||||
print("[DEBUG] Player ped changed:", newPed)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Actions:TrackPauseMenu()
|
||||
local isActive = IsPauseMenuActive()
|
||||
|
||||
@@ -189,46 +178,43 @@ function Actions:TrackSeat()
|
||||
end
|
||||
end
|
||||
|
||||
function Actions:TrackWeapon()
|
||||
---@type number|false
|
||||
local newWeapon = GetSelectedPedWeapon(ESX.PlayerData.ped)
|
||||
newWeapon = newWeapon ~= `WEAPON_UNARMED` and newWeapon or false
|
||||
|
||||
if newWeapon ~= self.currentWeapon then
|
||||
self.currentWeapon = newWeapon
|
||||
ESX.SetPlayerData("weapon", self.currentWeapon)
|
||||
TriggerEvent("esx:weaponChanged", self.currentWeapon)
|
||||
|
||||
if Config.EnableDebug then
|
||||
print("[DEBUG] Weapon changed:", self.currentWeapon)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Actions:SlowLoop()
|
||||
CreateThread(function()
|
||||
while ESX.PlayerLoaded do
|
||||
self:TrackPauseMenu()
|
||||
self:TrackVehicle()
|
||||
self:TrackWeapon()
|
||||
Wait(500)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function Actions:PedLoop()
|
||||
CreateThread(function()
|
||||
while ESX.PlayerLoaded do
|
||||
self:TrackPed()
|
||||
Wait(0)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function Actions:Init()
|
||||
-- Re-seed the cached values on every (re)login. The change handlers below are
|
||||
-- registered once at file load so a relogin never stacks duplicate handlers.
|
||||
ESX.SetPlayerData("ped", xLib.cache.ped)
|
||||
ESX.SetPlayerData("weapon", xLib.cache.weapon)
|
||||
|
||||
self:SlowLoop()
|
||||
self:PedLoop()
|
||||
self:TrackPedCoordsOnce()
|
||||
end
|
||||
|
||||
-- Mirror the lib cache into ESX.PlayerData and re-emit the legacy esx: events.
|
||||
AddEventHandler("xLib:cache:ped", function(ped)
|
||||
ESX.SetPlayerData("ped", ped)
|
||||
TriggerEvent("esx:playerPedChanged", ped)
|
||||
|
||||
if Config.EnableDebug then
|
||||
print("[DEBUG] Player ped changed:", ped)
|
||||
end
|
||||
end)
|
||||
|
||||
AddEventHandler("xLib:cache:weapon", function(weapon)
|
||||
ESX.SetPlayerData("weapon", weapon)
|
||||
TriggerEvent("esx:weaponChanged", weapon)
|
||||
|
||||
if Config.EnableDebug then
|
||||
print("[DEBUG] Weapon changed:", weapon)
|
||||
end
|
||||
end)
|
||||
|
||||
Actions:Init()
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
local interactions = {}
|
||||
local pressedInteractions = {}
|
||||
|
||||
function ESX.RemoveInteraction(name)
|
||||
if not interactions[name] then return end
|
||||
interactions[name] = nil
|
||||
end
|
||||
|
||||
ESX.RegisterInteraction = function(name, onPress, condition)
|
||||
interactions[name] = {
|
||||
condition = condition or function() return true end,
|
||||
onPress = onPress,
|
||||
creator = GetInvokingResource() or "es_extended"
|
||||
}
|
||||
end
|
||||
|
||||
function ESX.GetInteractKey()
|
||||
local hash = joaat('esx_interact') | 0x80000000
|
||||
return GetControlInstructionalButton(0, hash, true):sub(3)
|
||||
end
|
||||
|
||||
ESX.RegisterInput("esx_interact", "Interact", "keyboard", "e", function()
|
||||
for _, interaction in pairs(interactions) do
|
||||
local success, result = pcall(interaction.condition)
|
||||
if success and result then
|
||||
pressedInteractions[#pressedInteractions+1] = interaction
|
||||
interaction.onPress()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
AddEventHandler("onResourceStop", function(resource)
|
||||
for name, interaction in pairs(interactions) do
|
||||
if interaction.creator == resource then
|
||||
interactions[name] = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
@@ -1,54 +0,0 @@
|
||||
local points = {}
|
||||
|
||||
function ESX.CreatePointInternal(coords, distance, hidden, enter, leave)
|
||||
local point = {
|
||||
coords = coords,
|
||||
distance = distance,
|
||||
hidden = hidden,
|
||||
enter = enter,
|
||||
leave = leave,
|
||||
resource = GetInvokingResource()
|
||||
}
|
||||
local handle = ESX.Table.SizeOf(points) + 1
|
||||
points[handle] = point
|
||||
return handle
|
||||
end
|
||||
|
||||
function ESX.RemovePointInternal(handle)
|
||||
points[handle] = nil
|
||||
end
|
||||
|
||||
function ESX.HidePointInternal(handle, hidden)
|
||||
if points[handle] then
|
||||
points[handle].hidden = hidden
|
||||
end
|
||||
end
|
||||
|
||||
function StartPointsLoop()
|
||||
CreateThread(function()
|
||||
while true do
|
||||
local coords = GetEntityCoords(ESX.PlayerData.ped)
|
||||
for handle, point in pairs(points) do
|
||||
if not point.hidden and #(coords - point.coords) <= point.distance then
|
||||
if not point.nearby then
|
||||
points[handle].nearby = true
|
||||
points[handle].enter()
|
||||
end
|
||||
elseif point.nearby then
|
||||
points[handle].nearby = false
|
||||
points[handle].leave()
|
||||
end
|
||||
end
|
||||
Wait(500)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
AddEventHandler('onResourceStop', function(resource)
|
||||
for handle, point in pairs(points) do
|
||||
if point.resource == resource then
|
||||
points[handle] = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
@@ -52,16 +52,12 @@ client_scripts {
|
||||
'client/modules/wrapper.lua',
|
||||
'client/modules/callback.lua',
|
||||
'client/modules/adjustments.lua',
|
||||
'client/modules/points.lua',
|
||||
|
||||
'client/modules/events.lua',
|
||||
|
||||
'client/modules/actions.lua',
|
||||
'client/modules/death.lua',
|
||||
'client/modules/npwd.lua',
|
||||
'client/modules/interactions.lua',
|
||||
'client/modules/scaleform.lua',
|
||||
'client/modules/streaming.lua',
|
||||
}
|
||||
|
||||
ui_page {
|
||||
|
||||
@@ -87,7 +87,7 @@ if not IsDuplicityVersion() then -- Only register this event for the client
|
||||
end)
|
||||
end
|
||||
|
||||
local external = { { "Class", "class.lua" }, { "Point", "point.lua" } }
|
||||
local external = { { "Class", "class.lua" } }
|
||||
for i = 1, #external do
|
||||
local module = external[i]
|
||||
local path = string.format("client/imports/%s", module[2])
|
||||
|
||||
@@ -1,2 +1,10 @@
|
||||
--[[ All server-side functions outsourced from the Core to the lib will be stored here for compatability, e.g:
|
||||
--]]
|
||||
--All server-side functions outsourced from the Core to the lib will be stored here for compatability, e.g:
|
||||
|
||||
ESX.OneSync.GetPlayersInArea = xLib.onesync.getPlayersInArea
|
||||
ESX.OneSync.GetClosestPlayer = xLib.onesync.getClosestPlayer
|
||||
ESX.OneSync.GetPedsInArea = xLib.onesync.getPedsInArea
|
||||
ESX.OneSync.GetObjectsInArea = xLib.onesync.getObjectsInArea
|
||||
ESX.OneSync.GetVehiclesInArea = xLib.onesync.getVehiclesInArea
|
||||
ESX.OneSync.GetClosestPed = xLib.onesync.getClosestPed
|
||||
ESX.OneSync.GetClosestObject = xLib.onesync.getClosestObject
|
||||
ESX.OneSync.GetClosestVehicle = xLib.onesync.getClosestVehicle
|
||||
|
||||
@@ -1,84 +1,5 @@
|
||||
ESX.OneSync = {}
|
||||
|
||||
---@param source number|vector3
|
||||
---@param closest boolean
|
||||
---@param distance? number
|
||||
---@param ignore? table
|
||||
---@param routingBucket? number
|
||||
local function getNearbyPlayers(source, closest, distance, ignore, routingBucket)
|
||||
local result = {}
|
||||
local count = 0
|
||||
local playerPed
|
||||
local playerCoords
|
||||
ignore = ignore or {}
|
||||
|
||||
if not distance then
|
||||
distance = 100
|
||||
end
|
||||
|
||||
if type(source) == "number" then
|
||||
playerPed = GetPlayerPed(source)
|
||||
|
||||
if not source then
|
||||
error("Received invalid first argument (source); should be playerId")
|
||||
end
|
||||
|
||||
playerCoords = GetEntityCoords(playerPed)
|
||||
|
||||
if not playerCoords then
|
||||
error("Received nil value (playerCoords); perhaps source is nil at first place?")
|
||||
end
|
||||
end
|
||||
|
||||
if type(source) == "vector3" then
|
||||
playerCoords = source
|
||||
|
||||
if not playerCoords then
|
||||
error("Received nil value (playerCoords); perhaps source is nil at first place?")
|
||||
end
|
||||
end
|
||||
|
||||
for _, xPlayer in pairs(ESX.Players) do
|
||||
if not ignore[xPlayer.source] and (not routingBucket or GetPlayerRoutingBucket(xPlayer.source) == routingBucket) then
|
||||
local entity = GetPlayerPed(xPlayer.source)
|
||||
local coords = GetEntityCoords(entity)
|
||||
|
||||
if not closest then
|
||||
local dist = #(playerCoords - coords)
|
||||
if dist <= distance then
|
||||
count = count + 1
|
||||
result[count] = { id = xPlayer.source, ped = NetworkGetNetworkIdFromEntity(entity), coords = coords, dist = dist }
|
||||
end
|
||||
else
|
||||
if xPlayer.source ~= source then
|
||||
local dist = #(playerCoords - coords)
|
||||
if dist <= (result.dist or distance) then
|
||||
result = { id = xPlayer.source, ped = NetworkGetNetworkIdFromEntity(entity), coords = coords, dist = dist }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
---@param source vector3|number playerId or vector3 coordinates
|
||||
---@param maxDistance number
|
||||
---@param ignore? table playerIds to ignore, where the key is playerId and value is true
|
||||
---@param routingBucket? number
|
||||
function ESX.OneSync.GetPlayersInArea(source, maxDistance, ignore, routingBucket)
|
||||
return getNearbyPlayers(source, false, maxDistance, ignore, routingBucket)
|
||||
end
|
||||
|
||||
---@param source vector3|number playerId or vector3 coordinates
|
||||
---@param maxDistance number
|
||||
---@param ignore? table playerIds to ignore, where the key is playerId and value is true
|
||||
---@param routingBucket? number
|
||||
function ESX.OneSync.GetClosestPlayer(source, maxDistance, ignore, routingBucket)
|
||||
return getNearbyPlayers(source, true, maxDistance, ignore, routingBucket)
|
||||
end
|
||||
|
||||
---@param vehicleModel number|string
|
||||
---@param coords vector3|table
|
||||
---@param heading number
|
||||
@@ -304,84 +225,3 @@ function ESX.OneSync.SpawnPedInVehicle(model, vehicle, seat, cb)
|
||||
return Citizen.Await(promise)
|
||||
end
|
||||
end
|
||||
|
||||
local function getNearbyEntities(entities, coords, modelFilter, maxDistance, isPed)
|
||||
local nearbyEntities = {}
|
||||
coords = type(coords) == "number" and GetEntityCoords(GetPlayerPed(coords)) or vector3(coords.x, coords.y, coords.z)
|
||||
for _, entity in pairs(entities) do
|
||||
if not isPed or (isPed and not IsPedAPlayer(entity)) then
|
||||
if not modelFilter or modelFilter[GetEntityModel(entity)] then
|
||||
local entityCoords = GetEntityCoords(entity)
|
||||
if not maxDistance or #(coords - entityCoords) <= maxDistance then
|
||||
nearbyEntities[#nearbyEntities + 1] = NetworkGetNetworkIdFromEntity(entity)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return nearbyEntities
|
||||
end
|
||||
|
||||
---@param coords vector3
|
||||
---@param maxDistance number
|
||||
---@param modelFilter table models to ignore, where the key is the model hash and the value is true
|
||||
---@return table
|
||||
function ESX.OneSync.GetPedsInArea(coords, maxDistance, modelFilter)
|
||||
return getNearbyEntities(GetAllPeds(), coords, modelFilter, maxDistance, true)
|
||||
end
|
||||
|
||||
---@param coords vector3
|
||||
---@param maxDistance number
|
||||
---@param modelFilter table models to ignore, where the key is the model hash and the value is true
|
||||
---@return table
|
||||
function ESX.OneSync.GetObjectsInArea(coords, maxDistance, modelFilter)
|
||||
return getNearbyEntities(GetAllObjects(), coords, modelFilter, maxDistance)
|
||||
end
|
||||
|
||||
---@param coords vector3
|
||||
---@param maxDistance number
|
||||
---@param modelFilter table | nil models to ignore, where the key is the model hash and the value is true
|
||||
---@return table
|
||||
function ESX.OneSync.GetVehiclesInArea(coords, maxDistance, modelFilter)
|
||||
return getNearbyEntities(GetAllVehicles(), coords, modelFilter, maxDistance)
|
||||
end
|
||||
|
||||
local function getClosestEntity(entities, coords, modelFilter, isPed)
|
||||
local distance, closestEntity, closestCoords = 100, 0, vector3(0, 0, 0)
|
||||
coords = type(coords) == "number" and GetEntityCoords(GetPlayerPed(coords)) or vector3(coords.x, coords.y, coords.z)
|
||||
|
||||
for _, entity in pairs(entities) do
|
||||
if not isPed or (isPed and not IsPedAPlayer(entity)) then
|
||||
if not modelFilter or modelFilter[GetEntityModel(entity)] then
|
||||
local entityCoords = GetEntityCoords(entity)
|
||||
local dist = #(coords - entityCoords)
|
||||
if dist < distance then
|
||||
closestEntity, distance, closestCoords = entity, dist, entityCoords
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return NetworkGetNetworkIdFromEntity(closestEntity), distance, closestCoords
|
||||
end
|
||||
|
||||
---@param coords vector3
|
||||
---@param modelFilter table models to ignore, where the key is the model hash and the value is true
|
||||
---@return number entityId, number distance, vector3 coords
|
||||
function ESX.OneSync.GetClosestPed(coords, modelFilter)
|
||||
return getClosestEntity(GetAllPeds(), coords, modelFilter, true)
|
||||
end
|
||||
|
||||
---@param coords vector3
|
||||
---@param modelFilter table models to ignore, where the key is the model hash and the value is true
|
||||
---@return number entityId, number distance, vector3 coords
|
||||
function ESX.OneSync.GetClosestObject(coords, modelFilter)
|
||||
return getClosestEntity(GetAllObjects(), coords, modelFilter)
|
||||
end
|
||||
|
||||
---@param coords vector3
|
||||
---@param modelFilter table models to ignore, where the key is the model hash and the value is true
|
||||
---@return number entityId, number distance, vector3 coords
|
||||
function ESX.OneSync.GetClosestVehicle(coords, modelFilter)
|
||||
return getClosestEntity(GetAllVehicles(), coords, modelFilter)
|
||||
end
|
||||
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
--[[
|
||||
Generic client-side player state cache, modelled on ox_lib cache.
|
||||
Framework agnostic: natives only, no ESX coupling.
|
||||
|
||||
Loaded per-resource VM through the lazy loader. PlayerPedId() and friends
|
||||
return the same value in every client VM, so the cached values are correct
|
||||
in each resource that requires it.
|
||||
|
||||
Exposes the live values as xLib.cache and emits `xLib:cache:<key>` (value, previous)
|
||||
whenever a tracked value changes. `coords` is read on demand from the live ped
|
||||
and never stored.
|
||||
]]
|
||||
|
||||
local playerId = PlayerId()
|
||||
|
||||
local cache = setmetatable({
|
||||
playerId = playerId,
|
||||
ped = PlayerPedId(),
|
||||
vehicle = false,
|
||||
seat = false,
|
||||
weapon = false,
|
||||
}, {
|
||||
__index = function(self, key)
|
||||
if key == "coords" then
|
||||
return GetEntityCoords(self.ped)
|
||||
elseif key == "serverId" then
|
||||
-- resolved lazily: GetPlayerServerId can return -1 before the network
|
||||
-- session is ready, so only cache it once it is valid.
|
||||
local id = GetPlayerServerId(playerId)
|
||||
if id and id ~= -1 then
|
||||
rawset(self, "serverId", id)
|
||||
end
|
||||
return id
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
local function set(key, value)
|
||||
if cache[key] == value then
|
||||
return
|
||||
end
|
||||
|
||||
local previous = cache[key]
|
||||
rawset(cache, key, value)
|
||||
TriggerEvent(("xLib:cache:%s"):format(key), value, previous)
|
||||
end
|
||||
|
||||
local function getSeat(ped, vehicle)
|
||||
for seat = -1, 16 do
|
||||
if GetPedInVehicleSeat(vehicle, seat) == ped then
|
||||
return seat
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
CreateThread(function()
|
||||
while true do
|
||||
local ped = PlayerPedId()
|
||||
if ped ~= cache.ped then
|
||||
set("ped", ped)
|
||||
end
|
||||
|
||||
---@type integer|false
|
||||
local vehicle = GetVehiclePedIsIn(ped, false)
|
||||
vehicle = vehicle ~= 0 and vehicle or false
|
||||
|
||||
if vehicle ~= cache.vehicle then
|
||||
set("vehicle", vehicle)
|
||||
set("seat", vehicle and getSeat(ped, vehicle) or false)
|
||||
elseif vehicle then
|
||||
local seat = getSeat(ped, vehicle)
|
||||
if seat ~= cache.seat then
|
||||
set("seat", seat)
|
||||
end
|
||||
end
|
||||
|
||||
---@type integer|false
|
||||
local weapon = GetSelectedPedWeapon(ped)
|
||||
weapon = weapon ~= `WEAPON_UNARMED` and weapon or false
|
||||
if weapon ~= cache.weapon then
|
||||
set("weapon", weapon)
|
||||
end
|
||||
|
||||
Wait(100)
|
||||
end
|
||||
end)
|
||||
|
||||
return cache
|
||||
@@ -0,0 +1,695 @@
|
||||
---@class gamelib
|
||||
xLib.game = {}
|
||||
|
||||
local function isCallable(val)
|
||||
local valType = type(val)
|
||||
local mt = getmetatable(val)
|
||||
return valType == "function" or (valType == "table" and mt ~= nil and type(mt.__call) == "function")
|
||||
end
|
||||
|
||||
---@param ped integer The ped to get the mugshot of
|
||||
---@param transparent? boolean Whether the mugshot should be transparent
|
||||
function xLib.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 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 xLib.game.spawnObject(object, coords, cb, networked)
|
||||
local model = type(object) == "number" and object or joaat(object)
|
||||
|
||||
xLib.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 xLib.game.spawnLocalObject(object, coords, cb)
|
||||
xLib.game.spawnObject(object, coords, cb, false)
|
||||
end
|
||||
|
||||
---@param vehicle integer The vehicle to delete
|
||||
---@return nil
|
||||
function xLib.game.deleteVehicle(vehicle)
|
||||
SetEntityAsMissionEntity(vehicle, true, true)
|
||||
DeleteVehicle(vehicle)
|
||||
end
|
||||
|
||||
---@param object integer The object to delete
|
||||
---@return nil
|
||||
function xLib.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 xLib.game.spawnVehicle(vehicleModel, coords, heading, cb, networked)
|
||||
if cb and not isCallable(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(PlayerPedId())
|
||||
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 = xLib.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 xLib.game.spawnLocalVehicle(vehicle, coords, heading, cb)
|
||||
xLib.game.spawnVehicle(vehicle, coords, heading, cb, false)
|
||||
end
|
||||
|
||||
---@param vehicle integer The vehicle to check
|
||||
---@return boolean
|
||||
function xLib.game.isVehicleEmpty(vehicle)
|
||||
return GetVehicleNumberOfPassengers(vehicle) == 0 and IsVehicleSeatFree(vehicle, -1)
|
||||
end
|
||||
|
||||
---@return table
|
||||
function xLib.game.getObjects() -- Leave the function for compatibility
|
||||
return GetGamePool("CObject")
|
||||
end
|
||||
|
||||
---@param onlyOtherPeds? boolean Whether to exlude the player ped
|
||||
---@return table
|
||||
function xLib.game.getPeds(onlyOtherPeds)
|
||||
local pool = GetGamePool("CPed")
|
||||
|
||||
if onlyOtherPeds then
|
||||
local myPed = PlayerPedId()
|
||||
for i = 1, #pool do
|
||||
if pool[i] == myPed then
|
||||
table.remove(pool, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return pool
|
||||
end
|
||||
|
||||
---@return table
|
||||
function xLib.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 xLib.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 ~= 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 xLib.game.getClosestObject(coords, modelFilter)
|
||||
return xLib.entity.closest(xLib.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 xLib.game.getClosestPed(coords, modelFilter)
|
||||
return xLib.entity.closest(xLib.game.getPeds(true), false, coords, modelFilter)
|
||||
end
|
||||
|
||||
---@param coords? table | vector3 The coords to get the closest player to
|
||||
---@return integer, integer
|
||||
function xLib.game.getClosestPlayer(coords)
|
||||
return xLib.entity.closest(xLib.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 xLib.game.getClosestVehicle(coords, modelFilter)
|
||||
return xLib.entity.closest(xLib.game.getVehicles(), false, coords, modelFilter)
|
||||
end
|
||||
|
||||
---@param coords table | vector3 The coords to search from
|
||||
---@param maxDistance number The max distance to search within
|
||||
---@return table
|
||||
function xLib.game.getPlayersInArea(coords, maxDistance)
|
||||
return xLib.entity.EnumerateWithinDistance(xLib.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 xLib.game.getVehiclesInArea(coords, maxDistance)
|
||||
return xLib.entity.EnumerateWithinDistance(xLib.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 xLib.game.isSpawnPointClear(coords, maxDistance)
|
||||
return #xLib.game.getVehiclesInArea(coords, maxDistance) == 0
|
||||
end
|
||||
|
||||
---@return integer | nil, vector3 | nil
|
||||
function xLib.game.getVehicleInDirection()
|
||||
local _, hit, coords, _, _, entity = xLib.Raycast.FromScreen(5, 10, PlayerPedId())
|
||||
if hit and IsEntityAVehicle(entity) then
|
||||
return entity, coords
|
||||
end
|
||||
end
|
||||
|
||||
local function round(value, numDecimalPlaces)
|
||||
if numDecimalPlaces then
|
||||
local power = 10 ^ numDecimalPlaces
|
||||
return math.floor((value * power) + 0.5) / power
|
||||
else
|
||||
return math.floor(value + 0.5)
|
||||
end
|
||||
end
|
||||
|
||||
local function trim(value)
|
||||
value = tostring(value)
|
||||
return (string.gsub(value, "^%s*(.-)%s*$", "%1"))
|
||||
end
|
||||
|
||||
---@param vehicle integer The vehicle to get the properties of
|
||||
---@return table | nil
|
||||
function xLib.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 = trim(GetVehicleNumberPlateText(vehicle)),
|
||||
plateIndex = GetVehicleNumberPlateTextIndex(vehicle),
|
||||
|
||||
bodyHealth = round(GetVehicleBodyHealth(vehicle), 1),
|
||||
engineHealth = round(GetVehicleEngineHealth(vehicle), 1),
|
||||
tankHealth = round(GetVehiclePetrolTankHealth(vehicle), 1),
|
||||
|
||||
fuelLevel = round(GetVehicleFuelLevel(vehicle), 1),
|
||||
dirtLevel = 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 xLib.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
|
||||
|
||||
return xLib.game
|
||||
@@ -0,0 +1,54 @@
|
||||
---@class interactionslib
|
||||
xLib.interactions = {}
|
||||
|
||||
local interactions = {}
|
||||
local pressedInteractions = {}
|
||||
|
||||
---@param name string
|
||||
function xLib.interactions.remove(name)
|
||||
if not interactions[name] then return end
|
||||
interactions[name] = nil
|
||||
end
|
||||
|
||||
---@param name string
|
||||
---@param onPress function
|
||||
---@param condition? function
|
||||
function xLib.interactions.register(name, onPress, condition)
|
||||
interactions[name] = {
|
||||
condition = condition or function() return true end,
|
||||
onPress = onPress,
|
||||
creator = GetInvokingResource() or "es_extended"
|
||||
}
|
||||
end
|
||||
|
||||
---@return string
|
||||
function xLib.interactions.getInteractKey()
|
||||
local hash = joaat("esx_interact") | 0x80000000
|
||||
return GetControlInstructionalButton(0, hash, true):sub(3)
|
||||
end
|
||||
|
||||
xLib.addKeybind({
|
||||
name = "esx_interact",
|
||||
description = "Interact",
|
||||
defaultMapper = "keyboard",
|
||||
defaultKey = "e",
|
||||
onPressed = function()
|
||||
for _, interaction in pairs(interactions) do
|
||||
local success, result = pcall(interaction.condition)
|
||||
if success and result then
|
||||
pressedInteractions[#pressedInteractions + 1] = interaction
|
||||
interaction.onPress()
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
AddEventHandler("onResourceStop", function(resource)
|
||||
for name, interaction in pairs(interactions) do
|
||||
if interaction.creator == resource then
|
||||
interactions[name] = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
return xLib.interactions
|
||||
@@ -0,0 +1,164 @@
|
||||
---@class onesynclib
|
||||
xLib.onesync = {}
|
||||
|
||||
---@param source number|vector3
|
||||
---@param closest boolean
|
||||
---@param distance? number
|
||||
---@param ignore? table
|
||||
---@param routingBucket? number
|
||||
local function getNearbyPlayers(source, closest, distance, ignore, routingBucket)
|
||||
local result = {}
|
||||
local count = 0
|
||||
local playerPed
|
||||
local playerCoords
|
||||
ignore = ignore or {}
|
||||
|
||||
if not distance then
|
||||
distance = 100
|
||||
end
|
||||
|
||||
if type(source) == "number" then
|
||||
playerPed = GetPlayerPed(source)
|
||||
|
||||
if not source then
|
||||
error("Received invalid first argument (source); should be playerId")
|
||||
end
|
||||
|
||||
playerCoords = GetEntityCoords(playerPed)
|
||||
|
||||
if not playerCoords then
|
||||
error("Received nil value (playerCoords); perhaps source is nil at first place?")
|
||||
end
|
||||
end
|
||||
|
||||
if type(source) == "vector3" then
|
||||
playerCoords = source
|
||||
|
||||
if not playerCoords then
|
||||
error("Received nil value (playerCoords); perhaps source is nil at first place?")
|
||||
end
|
||||
end
|
||||
|
||||
for _, xPlayer in pairs(ESX.Players) do
|
||||
if not ignore[xPlayer.source] and (not routingBucket or GetPlayerRoutingBucket(xPlayer.source) == routingBucket) then
|
||||
local entity = GetPlayerPed(xPlayer.source)
|
||||
local coords = GetEntityCoords(entity)
|
||||
|
||||
if not closest then
|
||||
local dist = #(playerCoords - coords)
|
||||
if dist <= distance then
|
||||
count = count + 1
|
||||
result[count] = { id = xPlayer.source, ped = NetworkGetNetworkIdFromEntity(entity), coords = coords, dist = dist }
|
||||
end
|
||||
else
|
||||
if xPlayer.source ~= source then
|
||||
local dist = #(playerCoords - coords)
|
||||
if dist <= (result.dist or distance) then
|
||||
result = { id = xPlayer.source, ped = NetworkGetNetworkIdFromEntity(entity), coords = coords, dist = dist }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
---@param source vector3|number playerId or vector3 coordinates
|
||||
---@param maxDistance number
|
||||
---@param ignore? table playerIds to ignore, where the key is playerId and value is true
|
||||
---@param routingBucket? number
|
||||
function xLib.onesync.getPlayersInArea(source, maxDistance, ignore, routingBucket)
|
||||
return getNearbyPlayers(source, false, maxDistance, ignore, routingBucket)
|
||||
end
|
||||
|
||||
---@param source vector3|number playerId or vector3 coordinates
|
||||
---@param maxDistance number
|
||||
---@param ignore? table playerIds to ignore, where the key is playerId and value is true
|
||||
---@param routingBucket? number
|
||||
function xLib.onesync.getClosestPlayer(source, maxDistance, ignore, routingBucket)
|
||||
return getNearbyPlayers(source, true, maxDistance, ignore, routingBucket)
|
||||
end
|
||||
|
||||
local function getNearbyEntities(entities, coords, modelFilter, maxDistance, isPed)
|
||||
local nearbyEntities = {}
|
||||
coords = type(coords) == "number" and GetEntityCoords(GetPlayerPed(coords)) or vector3(coords.x, coords.y, coords.z)
|
||||
for _, entity in pairs(entities) do
|
||||
if not isPed or (isPed and not IsPedAPlayer(entity)) then
|
||||
if not modelFilter or modelFilter[GetEntityModel(entity)] then
|
||||
local entityCoords = GetEntityCoords(entity)
|
||||
if not maxDistance or #(coords - entityCoords) <= maxDistance then
|
||||
nearbyEntities[#nearbyEntities + 1] = NetworkGetNetworkIdFromEntity(entity)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return nearbyEntities
|
||||
end
|
||||
|
||||
---@param coords vector3
|
||||
---@param maxDistance number
|
||||
---@param modelFilter table models to ignore, where the key is the model hash and the value is true
|
||||
---@return table
|
||||
function xLib.onesync.getPedsInArea(coords, maxDistance, modelFilter)
|
||||
return getNearbyEntities(GetAllPeds(), coords, modelFilter, maxDistance, true)
|
||||
end
|
||||
|
||||
---@param coords vector3
|
||||
---@param maxDistance number
|
||||
---@param modelFilter table models to ignore, where the key is the model hash and the value is true
|
||||
---@return table
|
||||
function xLib.onesync.getObjectsInArea(coords, maxDistance, modelFilter)
|
||||
return getNearbyEntities(GetAllObjects(), coords, modelFilter, maxDistance)
|
||||
end
|
||||
|
||||
---@param coords vector3
|
||||
---@param maxDistance number
|
||||
---@param modelFilter table | nil models to ignore, where the key is the model hash and the value is true
|
||||
---@return table
|
||||
function xLib.onesync.getVehiclesInArea(coords, maxDistance, modelFilter)
|
||||
return getNearbyEntities(GetAllVehicles(), coords, modelFilter, maxDistance)
|
||||
end
|
||||
|
||||
local function getClosestEntity(entities, coords, modelFilter, isPed)
|
||||
local distance, closestEntity, closestCoords = 100, 0, vector3(0, 0, 0)
|
||||
coords = type(coords) == "number" and GetEntityCoords(GetPlayerPed(coords)) or vector3(coords.x, coords.y, coords.z)
|
||||
|
||||
for _, entity in pairs(entities) do
|
||||
if not isPed or (isPed and not IsPedAPlayer(entity)) then
|
||||
if not modelFilter or modelFilter[GetEntityModel(entity)] then
|
||||
local entityCoords = GetEntityCoords(entity)
|
||||
local dist = #(coords - entityCoords)
|
||||
if dist < distance then
|
||||
closestEntity, distance, closestCoords = entity, dist, entityCoords
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return NetworkGetNetworkIdFromEntity(closestEntity), distance, closestCoords
|
||||
end
|
||||
|
||||
---@param coords vector3
|
||||
---@param modelFilter table models to ignore, where the key is the model hash and the value is true
|
||||
---@return number entityId, number distance, vector3 coords
|
||||
function xLib.onesync.getClosestPed(coords, modelFilter)
|
||||
return getClosestEntity(GetAllPeds(), coords, modelFilter, true)
|
||||
end
|
||||
|
||||
---@param coords vector3
|
||||
---@param modelFilter table models to ignore, where the key is the model hash and the value is true
|
||||
---@return number entityId, number distance, vector3 coords
|
||||
function xLib.onesync.getClosestObject(coords, modelFilter)
|
||||
return getClosestEntity(GetAllObjects(), coords, modelFilter)
|
||||
end
|
||||
|
||||
---@param coords vector3
|
||||
---@param modelFilter table models to ignore, where the key is the model hash and the value is true
|
||||
---@return number entityId, number distance, vector3 coords
|
||||
function xLib.onesync.getClosestVehicle(coords, modelFilter)
|
||||
return getClosestEntity(GetAllVehicles(), coords, modelFilter)
|
||||
end
|
||||
|
||||
return xLib.onesync
|
||||
@@ -0,0 +1,52 @@
|
||||
---@class xPoint
|
||||
---@field coords vector3
|
||||
---@field hidden? boolean
|
||||
---@field enter? function
|
||||
---@field leave? function
|
||||
---@field inside? function
|
||||
---@field handle integer
|
||||
xLib.point = xLib.class()
|
||||
|
||||
---@param properties table coords, distance, hidden, enter, leave, inside
|
||||
function xLib.point:constructor(properties)
|
||||
self.coords = properties.coords
|
||||
self.hidden = properties.hidden
|
||||
self.enter = properties.enter
|
||||
self.leave = properties.leave
|
||||
self.inside = properties.inside
|
||||
|
||||
self.handle = xLib.points.create(
|
||||
properties.coords,
|
||||
properties.distance,
|
||||
properties.hidden,
|
||||
function()
|
||||
if self.enter then
|
||||
self:enter()
|
||||
end
|
||||
end,
|
||||
function()
|
||||
if self.leave then
|
||||
self:leave()
|
||||
end
|
||||
end,
|
||||
properties.inside and function(dist)
|
||||
self:inside(dist)
|
||||
end or nil
|
||||
)
|
||||
end
|
||||
|
||||
function xLib.point:delete()
|
||||
xLib.points.remove(self.handle)
|
||||
end
|
||||
|
||||
---@param hidden? boolean
|
||||
function xLib.point:toggle(hidden)
|
||||
if hidden == nil then
|
||||
hidden = not self.hidden
|
||||
end
|
||||
|
||||
self.hidden = hidden
|
||||
xLib.points.hide(self.handle, hidden)
|
||||
end
|
||||
|
||||
return xLib.point
|
||||
@@ -0,0 +1,100 @@
|
||||
---@class pointslib
|
||||
xLib.points = {}
|
||||
|
||||
local points = {}
|
||||
local insidePoints = {}
|
||||
local handleCount = 0
|
||||
|
||||
---@param coords vector3
|
||||
---@param distance number
|
||||
---@param hidden? boolean
|
||||
---@param enter function
|
||||
---@param leave function
|
||||
---@param inside? function
|
||||
---@return integer handle
|
||||
function xLib.points.create(coords, distance, hidden, enter, leave, inside)
|
||||
handleCount = handleCount + 1
|
||||
local handle = handleCount
|
||||
|
||||
points[handle] = {
|
||||
coords = coords,
|
||||
distance = distance,
|
||||
hidden = hidden,
|
||||
enter = enter,
|
||||
leave = leave,
|
||||
inside = inside,
|
||||
resource = GetInvokingResource()
|
||||
}
|
||||
|
||||
return handle
|
||||
end
|
||||
|
||||
---@param handle integer
|
||||
function xLib.points.remove(handle)
|
||||
points[handle] = nil
|
||||
insidePoints[handle] = nil
|
||||
end
|
||||
|
||||
---@param handle integer
|
||||
---@param hidden boolean
|
||||
function xLib.points.hide(handle, hidden)
|
||||
if points[handle] then
|
||||
points[handle].hidden = hidden
|
||||
end
|
||||
end
|
||||
|
||||
function xLib.points.startLoop()
|
||||
CreateThread(function()
|
||||
local lastScan = 0
|
||||
|
||||
while true do
|
||||
local coords = GetEntityCoords(PlayerPedId())
|
||||
|
||||
for _, point in pairs(insidePoints) do
|
||||
point.inside(#(coords - point.coords))
|
||||
end
|
||||
|
||||
local now = GetGameTimer()
|
||||
if now - lastScan >= 500 then
|
||||
lastScan = now
|
||||
|
||||
for handle, point in pairs(points) do
|
||||
if not point.hidden and #(coords - point.coords) <= point.distance then
|
||||
if not point.nearby then
|
||||
point.nearby = true
|
||||
|
||||
if point.enter then
|
||||
point.enter()
|
||||
end
|
||||
|
||||
if point.inside then
|
||||
insidePoints[handle] = point
|
||||
end
|
||||
end
|
||||
elseif point.nearby then
|
||||
point.nearby = false
|
||||
|
||||
if point.leave then
|
||||
point.leave()
|
||||
end
|
||||
|
||||
insidePoints[handle] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Wait(next(insidePoints) and 0 or 500)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
AddEventHandler("onResourceStop", function(resource)
|
||||
for handle, point in pairs(points) do
|
||||
if point.resource == resource then
|
||||
points[handle] = nil
|
||||
insidePoints[handle] = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
return xLib.points
|
||||
+45
-25
@@ -1,22 +1,12 @@
|
||||
ESX.Scaleform = {}
|
||||
ESX.Scaleform.Utils = {}
|
||||
---@class scaleformlib
|
||||
xLib.scaleform = {}
|
||||
xLib.scaleform.utils = {}
|
||||
|
||||
function ESX.Scaleform.ShowFreemodeMessage(title, msg, sec)
|
||||
local scaleform = ESX.Scaleform.Utils.RunMethod("MP_BIG_MESSAGE_FREEMODE", "SHOW_SHARD_WASTED_MP_MESSAGE", false, title, msg)
|
||||
|
||||
local endTime = GetGameTimer() + (sec * 1000)
|
||||
while GetGameTimer() < endTime do
|
||||
Wait(0)
|
||||
DrawScaleformMovieFullscreen(scaleform, 255, 255, 255, 255, 0)
|
||||
end
|
||||
|
||||
SetScaleformMovieAsNoLongerNeeded(scaleform)
|
||||
end
|
||||
|
||||
function ESX.Scaleform.ShowBreakingNews(title, msg, bottom, sec)
|
||||
local scaleform = ESX.Scaleform.Utils.RunMethod("BREAKING_NEWS", "SET_TEXT", false, msg, bottom)
|
||||
ESX.Scaleform.Utils.RunMethod(scaleform, "SET_SCROLL_TEXT", false, 0, 0, title)
|
||||
ESX.Scaleform.Utils.RunMethod(scaleform, "DISPLAY_SCROLL_TEXT", false, 0, 0)
|
||||
---@param title string
|
||||
---@param msg string
|
||||
---@param sec number
|
||||
function xLib.scaleform.showFreemodeMessage(title, msg, sec)
|
||||
local scaleform = xLib.scaleform.utils.runMethod("MP_BIG_MESSAGE_FREEMODE", "SHOW_SHARD_WASTED_MP_MESSAGE", false, title, msg)
|
||||
|
||||
local endTime = GetGameTimer() + (sec * 1000)
|
||||
while GetGameTimer() < endTime do
|
||||
@@ -27,8 +17,14 @@ function ESX.Scaleform.ShowBreakingNews(title, msg, bottom, sec)
|
||||
SetScaleformMovieAsNoLongerNeeded(scaleform)
|
||||
end
|
||||
|
||||
function ESX.Scaleform.ShowPopupWarning(title, msg, bottom, sec)
|
||||
local scaleform = ESX.Scaleform.Utils.RunMethod("POPUP_WARNING", "SHOW_POPUP_WARNING", false, 500.0, title, msg, bottom, true)
|
||||
---@param title string
|
||||
---@param msg string
|
||||
---@param bottom string
|
||||
---@param sec number
|
||||
function xLib.scaleform.showBreakingNews(title, msg, bottom, sec)
|
||||
local scaleform = xLib.scaleform.utils.runMethod("BREAKING_NEWS", "SET_TEXT", false, msg, bottom)
|
||||
xLib.scaleform.utils.runMethod(scaleform, "SET_SCROLL_TEXT", false, 0, 0, title)
|
||||
xLib.scaleform.utils.runMethod(scaleform, "DISPLAY_SCROLL_TEXT", false, 0, 0)
|
||||
|
||||
local endTime = GetGameTimer() + (sec * 1000)
|
||||
while GetGameTimer() < endTime do
|
||||
@@ -39,8 +35,12 @@ function ESX.Scaleform.ShowPopupWarning(title, msg, bottom, sec)
|
||||
SetScaleformMovieAsNoLongerNeeded(scaleform)
|
||||
end
|
||||
|
||||
function ESX.Scaleform.ShowTrafficMovie(sec)
|
||||
local scaleform = ESX.Scaleform.Utils.RunMethod("TRAFFIC_CAM", "PLAY_CAM_MOVIE", false)
|
||||
---@param title string
|
||||
---@param msg string
|
||||
---@param bottom string
|
||||
---@param sec number
|
||||
function xLib.scaleform.showPopupWarning(title, msg, bottom, sec)
|
||||
local scaleform = xLib.scaleform.utils.runMethod("POPUP_WARNING", "SHOW_POPUP_WARNING", false, 500.0, title, msg, bottom, true)
|
||||
|
||||
local endTime = GetGameTimer() + (sec * 1000)
|
||||
while GetGameTimer() < endTime do
|
||||
@@ -51,7 +51,22 @@ function ESX.Scaleform.ShowTrafficMovie(sec)
|
||||
SetScaleformMovieAsNoLongerNeeded(scaleform)
|
||||
end
|
||||
|
||||
function ESX.Scaleform.Utils.RequestScaleformMovie(movie)
|
||||
---@param sec number
|
||||
function xLib.scaleform.showTrafficMovie(sec)
|
||||
local scaleform = xLib.scaleform.utils.runMethod("TRAFFIC_CAM", "PLAY_CAM_MOVIE", false)
|
||||
|
||||
local endTime = GetGameTimer() + (sec * 1000)
|
||||
while GetGameTimer() < endTime do
|
||||
Wait(0)
|
||||
DrawScaleformMovieFullscreen(scaleform, 255, 255, 255, 255, 0)
|
||||
end
|
||||
|
||||
SetScaleformMovieAsNoLongerNeeded(scaleform)
|
||||
end
|
||||
|
||||
---@param movie string
|
||||
---@return number
|
||||
function xLib.scaleform.utils.requestScaleformMovie(movie)
|
||||
local scaleform = RequestScaleformMovie(movie)
|
||||
|
||||
while not HasScaleformMovieLoaded(scaleform) do
|
||||
@@ -68,8 +83,11 @@ end
|
||||
---@param returnValue? boolean # Whether to return the value from the method
|
||||
---@param ... number|string|boolean # Arguments to pass to the method
|
||||
---@return number, number? # The scaleform handle, and the return value if `returnValue` is true
|
||||
function ESX.Scaleform.Utils.RunMethod(scaleform, methodName, returnValue, ...)
|
||||
scaleform = type(scaleform) == "number" and scaleform or ESX.Scaleform.Utils.RequestScaleformMovie(scaleform)
|
||||
function xLib.scaleform.utils.runMethod(scaleform, methodName, returnValue, ...)
|
||||
if type(scaleform) ~= "number" then
|
||||
scaleform = xLib.scaleform.utils.requestScaleformMovie(scaleform)
|
||||
end
|
||||
|
||||
BeginScaleformMovieMethod(scaleform, methodName)
|
||||
|
||||
local args = { ... }
|
||||
@@ -97,3 +115,5 @@ function ESX.Scaleform.Utils.RunMethod(scaleform, methodName, returnValue, ...)
|
||||
|
||||
return scaleform
|
||||
end
|
||||
|
||||
return xLib.scaleform
|
||||
@@ -1,3 +1,4 @@
|
||||
---@class streaminglib
|
||||
xLib.streaming = {}
|
||||
|
||||
---@param modelHash number | string
|
||||
@@ -81,4 +82,4 @@ xLib.streaming.requestAudioBank = function(bankName, cb)
|
||||
end
|
||||
|
||||
|
||||
return xLib.streaming
|
||||
return xLib.streaming
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
local registeredCallbacks = {}
|
||||
local resource_name = GetCurrentResourceName() --TODO: Add cache
|
||||
local IS_DEBUG <const> = GetConvar("xLib:debug", "false") == "true"
|
||||
|
||||
|
||||
AddEventHandler('onResourceStop', function(resourceName)
|
||||
@@ -37,13 +38,19 @@ function xLib.setValidCallback(callbackName, isValid)
|
||||
|
||||
if callbackResource == resourceName then return end
|
||||
|
||||
local errMessage = ("^1resource '%s' attempted to overwrite callback '%s' owned by resource '%s'^0"):format(resourceName, callbackName, callbackResource)
|
||||
if IS_DEBUG then
|
||||
local errMessage = ("^1resource '%s' attempted to overwrite callback '%s' owned by resource '%s'^0"):format(resourceName, callbackName, callbackResource)
|
||||
|
||||
return print(('^1SCRIPT ERROR: %s^0\n%s'):format(errMessage,
|
||||
Citizen.InvokeNative(`FORMAT_STACK_TRACE` & 0xFFFFFFFF, nil, 0, Citizen.ResultAsString()) or ''))
|
||||
print(('^1SCRIPT ERROR: %s^0\n%s'):format(errMessage,
|
||||
Citizen.InvokeNative(`FORMAT_STACK_TRACE` & 0xFFFFFFFF, nil, 0, Citizen.ResultAsString()) or ''))
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
print(("set valid callback '%s' for resource '%s'"):format(callbackName, resourceName))
|
||||
if IS_DEBUG then
|
||||
print(("set valid callback '%s' for resource '%s'"):format(callbackName, resourceName))
|
||||
end
|
||||
|
||||
registeredCallbacks[callbackName] = resourceName
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user