mirror of
https://github.com/esx-framework/esx_core.git
synced 2026-08-29 01:08:54 +00:00
Merge branch 'esx_lib' into esx_lib
This commit is contained in:
@@ -9,4 +9,31 @@ function ESX.RegisterInput(command_name, label, input_group, key, on_press, on_r
|
|||||||
onPressed = on_press,
|
onPressed = on_press,
|
||||||
onReleased = on_release
|
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
|
||||||
|
|||||||
@@ -457,26 +457,6 @@ function ESX.Game.GetPedMugshot(ped, transparent)
|
|||||||
return mugshot, GetPedheadshotTxdString(mugshot)
|
return mugshot, GetPedheadshotTxdString(mugshot)
|
||||||
end
|
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 object integer | string The object to spawn
|
||||||
---@param coords table | vector3 The coords to spawn the object at
|
---@param coords table | vector3 The coords to spawn the object at
|
||||||
---@param cb? function The callback function
|
---@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)
|
return ESX.Game.GetClosestEntity(ESX.Game.GetVehicles(), false, coords, modelFilter)
|
||||||
end
|
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 coords table | vector3 The coords to search from
|
||||||
---@param maxDistance number The max distance to search within
|
---@param maxDistance number The max distance to search within
|
||||||
---@return table
|
---@return table
|
||||||
@@ -720,63 +674,6 @@ function ESX.Game.IsSpawnPointClear(coords, maxDistance)
|
|||||||
return #ESX.Game.GetVehiclesInArea(coords, maxDistance) == 0
|
return #ESX.Game.GetVehiclesInArea(coords, maxDistance) == 0
|
||||||
end
|
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
|
---@return integer | nil, vector3 | nil
|
||||||
function ESX.Game.GetVehicleInDirection()
|
function ESX.Game.GetVehicleInDirection()
|
||||||
local _, hit, coords, _, _, entity = ESX.Game.RaycastScreen(5, 10, ESX.PlayerData.ped)
|
local _, hit, coords, _, _, entity = ESX.Game.RaycastScreen(5, 10, ESX.PlayerData.ped)
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user