Merge branch 'esx_lib' into esx_lib

This commit is contained in:
Kremu
2026-01-14 16:24:01 +01:00
committed by GitHub
5 changed files with 310 additions and 104 deletions
+28 -1
View File
@@ -9,4 +9,31 @@ function ESX.RegisterInput(command_name, label, input_group, key, on_press, on_r
onPressed = on_press,
onReleased = on_release
})
end
end
ESX.Game.GetShapeTestResultSync = xLib.Raycast.GetShapeTestResult
ESX.Game.RaycastScreen = xLib.Raycast.FromScreen
ESX.Game.StartRaycasting = xLib.Raycast.Start
---@param raycast table The raycast object returned from ESX.Game.StartRaycasting
ESX.Game.StopRaycasting = function(raycast)
if raycast and raycast.active then
raycast:Stop()
end
end
---@param raycast table The raycast object returned from ESX.Game.StartRaycasting
ESX.Game.IsRaycastActive = function(raycast)
if raycast and raycast.active then
return raycast:IsActive()
end
return false
end
---@param raycast table The raycast object returned from ESX.Game.StartRaycasting
ESX.Game.GetRaycastResult = function(raycast)
if raycast and raycast.active then
return raycast.result
end
return nil
end
ESX.Game.GetClosestEntity = xLib.entity.closest
EnumerateEntitiesWithinDistance = xLib.entity.EnumerateWithinDistance
ESX.Game.Teleport = xLib.entity.Teleport
-103
View File
@@ -457,26 +457,6 @@ function ESX.Game.GetPedMugshot(ped, transparent)
return mugshot, GetPedheadshotTxdString(mugshot)
end
---@param entity integer The entity to get the coords of
---@param coords table | vector3 | vector4 The coords to teleport the entity to
---@param cb? function The callback function
function ESX.Game.Teleport(entity, coords, cb)
if DoesEntityExist(entity) then
RequestCollisionAtCoord(coords.x, coords.y, coords.z)
while not HasCollisionLoadedAroundEntity(entity) do
Wait(0)
end
SetEntityCoords(entity, coords.x, coords.y, coords.z, false, false, false, false)
SetEntityHeading(entity, coords.w or coords.heading or 0.0)
end
if cb then
cb()
end
end
---@param object integer | string The object to spawn
---@param coords table | vector3 The coords to spawn the object at
---@param cb? function The callback function
@@ -673,32 +653,6 @@ function ESX.Game.GetClosestVehicle(coords, modelFilter)
return ESX.Game.GetClosestEntity(ESX.Game.GetVehicles(), false, coords, modelFilter)
end
---@param entities table The entities to search through
---@param isPlayerEntities boolean Whether the entities are players
---@param coords table | vector3 The coords to search from
---@param maxDistance number The max distance to search within
---@return table
local function EnumerateEntitiesWithinDistance(entities, isPlayerEntities, coords, maxDistance)
local nearbyEntities = {}
if coords then
coords = vector3(coords.x, coords.y, coords.z)
else
local playerPed = ESX.PlayerData.ped
coords = GetEntityCoords(playerPed)
end
for k, entity in pairs(entities) do
local distance = #(coords - GetEntityCoords(entity))
if distance <= maxDistance then
nearbyEntities[#nearbyEntities + 1] = isPlayerEntities and k or entity
end
end
return nearbyEntities
end
---@param coords table | vector3 The coords to search from
---@param maxDistance number The max distance to search within
---@return table
@@ -720,63 +674,6 @@ function ESX.Game.IsSpawnPointClear(coords, maxDistance)
return #ESX.Game.GetVehiclesInArea(coords, maxDistance) == 0
end
---@param shape integer The shape to get the test result from
---@return boolean, table, table, integer, integer
function ESX.Game.GetShapeTestResultSync(shape)
local handle, hit, coords, normal, material, entity
repeat
handle, hit, coords, normal, material, entity = GetShapeTestResultIncludingMaterial(shape)
Wait(0)
until handle ~= 1
return hit, coords, normal, material, entity
end
---@param depth number The depth to raycast
---@vararg any The arguments to pass to the shape test
---@return table, boolean, table, table, integer, integer
function ESX.Game.RaycastScreen(depth, ...)
local world, normal = GetWorldCoordFromScreenCoord(.5, .5)
local origin = world + normal
local target = world + normal * depth
return target, ESX.Game.GetShapeTestResultSync(StartShapeTestLosProbe(origin.x, origin.y, origin.z, target.x, target.y, target.z, ...))
end
---@param entities table The entities to search through
---@param isPlayerEntities boolean Whether the entities are players
---@param coords? table | vector3 The coords to search from
---@param modelFilter? table The model filter
---@return integer, integer
function ESX.Game.GetClosestEntity(entities, isPlayerEntities, coords, modelFilter)
local closestEntity, closestEntityDistance, filteredEntities = -1, -1, nil
if coords then
coords = vector3(coords.x, coords.y, coords.z)
else
local playerPed = ESX.PlayerData.ped
coords = GetEntityCoords(playerPed)
end
if modelFilter then
filteredEntities = {}
for currentEntityIndex = 1, #entities do
if modelFilter[GetEntityModel(entities[currentEntityIndex])] then
filteredEntities[#filteredEntities + 1] = entities[currentEntityIndex]
end
end
end
for k, entity in pairs(filteredEntities or entities) do
local distance = #(coords - GetEntityCoords(entity))
if closestEntityDistance == -1 or distance < closestEntityDistance then
closestEntity, closestEntityDistance = isPlayerEntities and k or entity, distance
end
end
return closestEntity, closestEntityDistance
end
---@return integer | nil, vector3 | nil
function ESX.Game.GetVehicleInDirection()
local _, hit, coords, _, _, entity = ESX.Game.RaycastScreen(5, 10, ESX.PlayerData.ped)
+120
View File
@@ -0,0 +1,120 @@
--[[
https://github.com/overextended/ox_lib
This file is licensed under LGPL-3.0 or higher <https://www.gnu.org/licenses/lgpl-3.0.en.html>
Copyright © 2025 Linden <https://github.com/thelindat>
]]
---@class DuiProperties
---@field url string
---@field width number
---@field height number
---@field debug? boolean
---@class Dui
---@field private_id string
---@field private_debug boolean
---@field url string
---@field duiObject number
---@field duiHandle string
---@field runtimeTxd number
---@field txdObject number
---@field dictName string
---@field txtName string
xLib.dui = xLib.class()
local resource<const> = GetCurrentResourceName()
---@type table<string, Dui>
local Duis = {}
local currentId = 0
---@param data DuiProperties
function xLib.dui:constructor(data)
local time = GetGameTimer()
local id = ("%s_%s_%s"):format(resource, time, currentId)
currentId = currentId + 1
local dictName = ("%s_dui_dict_%s"):format(resource, id)
local txtName = ("%s_lib_dui_txt_%s"):format(resource, id)
local duiObject = CreateDui(data.url, data.width, data.height)
local duiHandle = GetDuiHandle(duiObject)
local runtimeTxd = CreateRuntimeTxd(dictName)
local txdObject = CreateRuntimeTextureFromDuiHandle(runtimeTxd, txtName, duiHandle)
self.private_id = id
self.private_debug = data.debug or false
self.url = data.url
self.duiObject = duiObject
self.duiHandle = duiHandle
self.runtimeTxd = runtimeTxd
self.txdObject = txdObject
self.dictName = dictName
self.txtName = txtName
Duis[id] = self
if self.private_debug then
print(("Dui %s created"):format(id))
end
end
function xLib.dui:remove()
SetDuiUrl(self.duiObject, "about:blank")
DestroyDui(self.duiObject)
Duis[self.private_id] = nil
if self.private_debug then
print(("Dui %s removed"):format(self.private_id))
end
end
---@param url string
function xLib.dui:setUrl(url)
self.url = url
SetDuiUrl(self.duiObject, url)
if self.private_debug then
print(("Dui %s url set to %s"):format(self.private_id, url))
end
end
---@param message table
function xLib.dui:sendMessage(message)
SendDuiMessage(self.duiObject, json.encode(message))
if self.private_debug then
print(("Dui %s message sent with data :"):format(self.private_id), json.encode(message, { indent = true }))
end
end
---@param x number
---@param y number
function xLib.dui:sendMouseMove(x, y)
SendDuiMouseMove(self.duiObject, x, y)
end
---@param button "left" | "middle" | "right"
function xLib.dui:sendMouseDown(button)
SendDuiMouseDown(self.duiObject, button)
end
---@param button "left" | "middle" | "right"
function xLib.dui:sendMouseUp(button)
SendDuiMouseUp(self.duiObject, button)
end
---@param deltaX number
---@param deltaY number
function xLib.dui:sendMouseWheel(deltaX, deltaY)
SendDuiMouseWheel(self.duiObject, deltaY, deltaX)
end
AddEventHandler("onResourceStop", function(resourceName)
if resource ~= resourceName then return end
for id in next, Duis do
Duis[id]:remove()
end
end)
return xLib.dui
+85
View File
@@ -0,0 +1,85 @@
xLib.entity = {}
---@param entities table The entities to search through
---@param isPlayerEntities boolean Whether the entities are players
---@param coords? table | vector3 The coords to search from
---@param modelFilter? table The model filter
---@return integer, integer
function xLib.entity.closest(entities, isPlayerEntities, coords, modelFilter)
local closestEntity, closestEntityDistance, filteredEntities = -1, -1, nil
if coords then
coords = vector3(coords.x, coords.y, coords.z)
else
local playerPed = PlayerPedId()
coords = GetEntityCoords(playerPed)
end
if modelFilter then
filteredEntities = {}
for currentEntityIndex = 1, #entities do
if modelFilter[GetEntityModel(entities[currentEntityIndex])] then
filteredEntities[#filteredEntities + 1] = entities[currentEntityIndex]
end
end
end
for k, entity in pairs(filteredEntities or entities) do
local distance = #(coords - GetEntityCoords(entity))
if closestEntityDistance == -1 or distance < closestEntityDistance then
closestEntity, closestEntityDistance = isPlayerEntities and k or entity, distance
end
end
return closestEntity, closestEntityDistance
end
---@param entities table The entities to search through
---@param isPlayerEntities boolean Whether the entities are players
---@param coords? table | vector3 The coords to search from
---@param maxDistance number The maximum distance
---@return table
function xLib.entity.EnumerateWithinDistance(entities, isPlayerEntities, coords, maxDistance)
local nearbyEntities = {}
if coords then
coords = vector3(coords.x, coords.y, coords.z)
else
local playerPed = PlayerPedId()
coords = GetEntityCoords(playerPed)
end
for k, entity in pairs(entities) do
local distance = #(coords - GetEntityCoords(entity))
if distance <= maxDistance then
nearbyEntities[#nearbyEntities + 1] = isPlayerEntities and k or entity
end
end
return nearbyEntities
end
---@param entity integer The entity to get the coords of
---@param coords table | vector3 | vector4 The coords to teleport the entity to
---@param cb? function The callback function
function xLib.entity.Teleport(entity, coords, cb)
if DoesEntityExist(entity) then
RequestCollisionAtCoord(coords.x, coords.y, coords.z)
while not HasCollisionLoadedAroundEntity(entity) do
Wait(0)
end
SetEntityCoords(entity, coords.x, coords.y, coords.z, false, false, false, false)
SetEntityHeading(entity, coords.w or coords.heading or 0.0)
end
if cb then
cb()
end
end
return xLib.entity
+77
View File
@@ -0,0 +1,77 @@
xLib.Raycast = {}
xLib.Raycast.__index = xLib.Raycast
local unpack = table.unpack
local GetShapeTestResultIncludingMaterial = GetShapeTestResultIncludingMaterial
local StartShapeTestLosProbe = StartShapeTestLosProbe
local GetWorldCoordFromScreenCoord = GetWorldCoordFromScreenCoord
---@param shape integer The shape test handle to wait for
---@return boolean, table, table, integer, integer
function xLib.Raycast.GetShapeTestResult(shape)
local handle, hit, coords, normal, material, entity
repeat
handle, hit, coords, normal, material, entity = GetShapeTestResultIncludingMaterial(shape)
Wait(0)
until handle ~= 1
return hit, coords, normal, material, entity
end
---@param depth number The raycast distance
---@vararg any Additional arguments to pass to shape test
---@return table, boolean, table, table, integer, integer
function xLib.Raycast.FromScreen(depth, ...)
local worldCoords, normalVector = GetWorldCoordFromScreenCoord(0.5, 0.5)
local origin = worldCoords + normalVector
local target = worldCoords + normalVector * depth
return target, xLib.Raycast.GetShapeTestResult(StartShapeTestLosProbe(origin.x, origin.y, origin.z, target.x, target.y, target.z, ...))
end
-- Start continuous raycasting
---@param depth number The raycast distance
---@vararg any Additional arguments to pass to shape test
function xLib.Raycast.Start(depth, ...)
local self = setmetatable({}, xLib.Raycast)
self.refreshRate = refreshRate
self.depth = depth
self.args = {...}
self.active = true
self._thread = CreateThread(function()
while self.active do
local target, hit, coords, normal, material, entity = xLib.Raycast.FromScreen(self.depth, unpack(self.args))
self.result = {
hit = hit,
coords = coords,
normal = normal,
material = material,
entity = entity,
}
Wait(1)
end
end)
return self
end
-- Stop raycasting
function xLib.Raycast:Stop()
if not self and not self.active then return end
self.active = false
if self._thread then
self._thread = nil
end
end
-- Check if the raycating is active
---@return boolean
function xLib.Raycast:IsActive()
if not self and not self.active then return end
return self.active
end
return xLib.Raycast