mirror of
https://github.com/esx-framework/esx_core.git
synced 2026-08-29 01:08:54 +00:00
Merge remote-tracking branch 'Snail/esx_lib' into 1.14.0
This commit is contained in:
@@ -5,4 +5,42 @@ ESX.Streaming.RequestStreamedTextureDict = xLib.streaming.requestStreamedTexture
|
||||
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.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
|
||||
|
||||
function ESX.RegisterInput(command_name, label, input_group, key, on_press, on_release)
|
||||
return xLib.addKeybind({
|
||||
name = command_name,
|
||||
description = label,
|
||||
defaultMapper = input_group,
|
||||
defaultKey = key,
|
||||
onPressed = on_press,
|
||||
onReleased = on_release
|
||||
})
|
||||
end
|
||||
|
||||
---@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
|
||||
|
||||
@@ -246,22 +246,6 @@ function ESX.RefreshContext(...)
|
||||
return IsResourceFound('esx_context') and exports['esx_context']:Refresh(...)
|
||||
end
|
||||
|
||||
---@param command_name string The command name
|
||||
---@param label string The label to show
|
||||
---@param input_group string The input group
|
||||
---@param key string The key to bind
|
||||
---@param on_press function The function to call on press
|
||||
---@param on_release? function The function to call on release
|
||||
function ESX.RegisterInput(command_name, label, input_group, key, on_press, on_release)
|
||||
local command = on_release and '+' .. command_name or command_name
|
||||
RegisterCommand(command, on_press, false)
|
||||
Core.Input[command_name] = ESX.HashString(command)
|
||||
if on_release then
|
||||
RegisterCommand('-' .. command_name, on_release, false)
|
||||
end
|
||||
RegisterKeyMapping(command, label or '', input_group or 'keyboard', key or '')
|
||||
end
|
||||
|
||||
---@param menuType string
|
||||
---@param open function The function to call on open
|
||||
---@param close function The function to call on close
|
||||
@@ -474,26 +458,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
|
||||
@@ -690,32 +654,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
|
||||
@@ -737,63 +675,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)
|
||||
|
||||
@@ -6,6 +6,7 @@ lua54 'yes'
|
||||
version '1.13.5'
|
||||
|
||||
shared_scripts {
|
||||
'@esx_lib/imports.lua',
|
||||
'locale.lua',
|
||||
|
||||
'shared/config/main.lua',
|
||||
@@ -47,6 +48,7 @@ server_scripts {
|
||||
client_scripts {
|
||||
'client/main.lua',
|
||||
'client/functions.lua',
|
||||
'client/compat.lua',
|
||||
'client/modules/wrapper.lua',
|
||||
'client/modules/callback.lua',
|
||||
'client/modules/adjustments.lua',
|
||||
@@ -60,8 +62,6 @@ client_scripts {
|
||||
'client/modules/interactions.lua',
|
||||
'client/modules/scaleform.lua',
|
||||
'client/modules/streaming.lua',
|
||||
|
||||
'shared/compat.lua'
|
||||
}
|
||||
|
||||
ui_page {
|
||||
|
||||
@@ -2,4 +2,20 @@
|
||||
|
||||
ESX.SetTimeout = xLib.timeout.setTimeout
|
||||
ESX.ClearTimeout = xLib.timeout.clearTimeout
|
||||
ESX.Await = xLib.waitFor
|
||||
ESX.Await = xLib.waitFor
|
||||
ESX.Table.SizeOf = xLib.table.size
|
||||
ESX.Table.Set = xLib.table.set
|
||||
ESX.Table.IndexOf = xLib.table.indexOf
|
||||
ESX.Table.LastIndexOf = xLib.table.lastIndexOf
|
||||
ESX.Table.Find = xLib.table.find
|
||||
ESX.Table.FindIndex = xLib.table.findIndex
|
||||
ESX.Table.Filter = xLib.table.filter
|
||||
ESX.Table.Map = xLib.table.map
|
||||
ESX.Table.Reverse = xLib.table.reverse
|
||||
ESX.Table.Clone = xLib.table.clone
|
||||
ESX.Table.Concat = xLib.table.concat
|
||||
ESX.Table.Join = xLib.table.join
|
||||
ESX.Table.TableContains = xLib.table.contains
|
||||
ESX.Table.Sort = xLib.table.sort
|
||||
ESX.Table.ToArray = xLib.table.toArray
|
||||
ESX.Table.Wipe = xLib.table.wipe
|
||||
|
||||
@@ -1,241 +0,0 @@
|
||||
ESX.Table = {}
|
||||
|
||||
-- nil proof alternative to #table
|
||||
---@param t table
|
||||
---@return number
|
||||
function ESX.Table.SizeOf(t)
|
||||
local count = 0
|
||||
|
||||
for _, _ in pairs(t) do
|
||||
count = count + 1
|
||||
end
|
||||
|
||||
return count
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@return table
|
||||
function ESX.Table.Set(t)
|
||||
local set = {}
|
||||
for _, v in ipairs(t) do
|
||||
set[v] = true
|
||||
end
|
||||
return set
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@param value any
|
||||
---@return number
|
||||
function ESX.Table.IndexOf(t, value)
|
||||
for i = 1, #t, 1 do
|
||||
if t[i] == value then
|
||||
return i
|
||||
end
|
||||
end
|
||||
|
||||
return -1
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@param value any
|
||||
---@return number
|
||||
function ESX.Table.LastIndexOf(t, value)
|
||||
for i = #t, 1, -1 do
|
||||
if t[i] == value then
|
||||
return i
|
||||
end
|
||||
end
|
||||
|
||||
return -1
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@param cb function
|
||||
---@return any
|
||||
function ESX.Table.Find(t, cb)
|
||||
for i = 1, #t, 1 do
|
||||
if cb(t[i]) then
|
||||
return t[i]
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@param cb function
|
||||
---@return number
|
||||
function ESX.Table.FindIndex(t, cb)
|
||||
for i = 1, #t, 1 do
|
||||
if cb(t[i]) then
|
||||
return i
|
||||
end
|
||||
end
|
||||
|
||||
return -1
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@param cb function
|
||||
---@return table
|
||||
function ESX.Table.Filter(t, cb)
|
||||
local newTable = {}
|
||||
|
||||
for i = 1, #t, 1 do
|
||||
if cb(t[i]) then
|
||||
newTable[#newTable + 1] = t[i]
|
||||
end
|
||||
end
|
||||
|
||||
return newTable
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@param cb function
|
||||
---@return table
|
||||
function ESX.Table.Map(t, cb)
|
||||
local newTable = {}
|
||||
|
||||
for i = 1, #t, 1 do
|
||||
newTable[i] = cb(t[i], i)
|
||||
end
|
||||
|
||||
return newTable
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@return table
|
||||
function ESX.Table.Reverse(t)
|
||||
local newTable = {}
|
||||
|
||||
for i = #t, 1, -1 do
|
||||
table.insert(newTable, t[i])
|
||||
end
|
||||
|
||||
return newTable
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@return table
|
||||
function ESX.Table.Clone(t)
|
||||
if type(t) ~= "table" then
|
||||
return t
|
||||
end
|
||||
|
||||
local meta = getmetatable(t)
|
||||
local target = {}
|
||||
|
||||
for k, v in pairs(t) do
|
||||
if type(v) == "table" then
|
||||
target[k] = ESX.Table.Clone(v)
|
||||
else
|
||||
target[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
setmetatable(target, meta)
|
||||
|
||||
return target
|
||||
end
|
||||
|
||||
---@param t1 table
|
||||
---@param t2 table
|
||||
---@return table
|
||||
function ESX.Table.Concat(t1, t2)
|
||||
local t3 = ESX.Table.Clone(t1)
|
||||
|
||||
for i = 1, #t2, 1 do
|
||||
table.insert(t3, t2[i])
|
||||
end
|
||||
|
||||
return t3
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@param sep string
|
||||
---@return string
|
||||
function ESX.Table.Join(t, sep)
|
||||
local str = ""
|
||||
|
||||
for i = 1, #t, 1 do
|
||||
if i > 1 then
|
||||
str = str .. (sep or ",")
|
||||
end
|
||||
|
||||
str = str .. t[i]
|
||||
end
|
||||
|
||||
return str
|
||||
end
|
||||
|
||||
-- Credits: https://github.com/JonasDev99/qb-garages/blob/b0335d67cb72a6b9ac60f62a87fb3946f5c2f33d/server/main.lua#L5
|
||||
---@param tab table
|
||||
---@param val any
|
||||
---@return boolean
|
||||
function ESX.Table.TableContains(tab, val)
|
||||
if type(val) == "table" then
|
||||
for _, value in pairs(tab) do
|
||||
if ESX.Table.TableContains(val, value) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
else
|
||||
for _, value in pairs(tab) do
|
||||
if value == val then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Credit: https://stackoverflow.com/a/15706820
|
||||
-- Description: sort function for pairs
|
||||
---@param t table
|
||||
---@param order function
|
||||
---@return function
|
||||
function ESX.Table.Sort(t, order)
|
||||
-- collect the keys
|
||||
local keys = {}
|
||||
|
||||
for k, _ in pairs(t) do
|
||||
keys[#keys + 1] = k
|
||||
end
|
||||
|
||||
-- if order function given, sort by it by passing the table and keys a, b,
|
||||
-- otherwise just sort the keys
|
||||
if order then
|
||||
table.sort(keys, function(a, b)
|
||||
return order(t, a, b)
|
||||
end)
|
||||
else
|
||||
table.sort(keys)
|
||||
end
|
||||
|
||||
-- return the iterator function
|
||||
local i = 0
|
||||
|
||||
return function()
|
||||
i = i + 1
|
||||
if keys[i] then
|
||||
return keys[i], t[keys[i]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@return Array
|
||||
function ESX.Table.ToArray(t)
|
||||
local array = {}
|
||||
for _, v in pairs(t) do
|
||||
array[#array + 1] = v
|
||||
end
|
||||
return array
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@return table
|
||||
function ESX.Table.Wipe(t)
|
||||
return table.wipe(t)
|
||||
end
|
||||
@@ -0,0 +1,92 @@
|
||||
--[[
|
||||
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 KeybindProps
|
||||
---@field name string
|
||||
---@field description string
|
||||
---@field defaultMapper? string (see: https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/)
|
||||
---@field defaultKey? string
|
||||
---@field disabled? boolean
|
||||
---@field disable? fun(self: CKeybind, toggle: boolean)
|
||||
---@field onPressed? fun(self: CKeybind)
|
||||
---@field onReleased? fun(self: CKeybind)
|
||||
---@field remove? fun(self: CKeybind)
|
||||
---@field [string] any
|
||||
|
||||
---@class CKeybind : KeybindProps
|
||||
---@field currentKey string
|
||||
---@field disabled boolean
|
||||
---@field isPressed boolean
|
||||
---@field hash number
|
||||
---@field getCurrentKey fun(): string
|
||||
---@field isControlPressed fun(): boolean
|
||||
|
||||
local keybinds = {}
|
||||
|
||||
local IsPauseMenuActive = IsPauseMenuActive
|
||||
local GetControlInstructionalButton = GetControlInstructionalButton
|
||||
|
||||
local keybind_mt = {
|
||||
disabled = false,
|
||||
isPressed = false,
|
||||
defaultKey = '',
|
||||
defaultMapper = 'keyboard',
|
||||
}
|
||||
|
||||
function keybind_mt:__index(index)
|
||||
return index == 'currentKey' and self:getCurrentKey() or keybind_mt[index]
|
||||
end
|
||||
|
||||
function keybind_mt:getCurrentKey()
|
||||
return GetControlInstructionalButton(0, self.hash, true):sub(3)
|
||||
end
|
||||
|
||||
function keybind_mt:isControlPressed()
|
||||
return self.isPressed
|
||||
end
|
||||
|
||||
function keybind_mt:disable(toggle)
|
||||
self.disabled = toggle
|
||||
end
|
||||
|
||||
function keybind_mt:remove()
|
||||
if not keybinds[self.name] then return end
|
||||
keybinds[self.name] = nil
|
||||
end
|
||||
|
||||
---@param data KeybindProps
|
||||
---@return CKeybind
|
||||
function xLib.addKeybind(data)
|
||||
data.hash = joaat("+" .. data.name) | 0x80000000
|
||||
keybinds[data.name] = setmetatable(data, keybind_mt)
|
||||
|
||||
RegisterCommand('+' .. data.name, function()
|
||||
if not keybinds[data.name] then return end
|
||||
if data.disabled or IsPauseMenuActive() then return end
|
||||
data.isPressed = true
|
||||
if data.onPressed then data:onPressed() end
|
||||
end)
|
||||
|
||||
RegisterCommand('-' .. data.name, function()
|
||||
if not keybinds[data.name] then return end
|
||||
if data.disabled or IsPauseMenuActive() then return end
|
||||
data.isPressed = false
|
||||
if data.onReleased then data:onReleased() end
|
||||
end)
|
||||
|
||||
RegisterKeyMapping('+' .. data.name, data.description, data.defaultMapper, data.defaultKey)
|
||||
|
||||
SetTimeout(500, function()
|
||||
TriggerEvent('chat:removeSuggestion', ('/+%s'):format(data.name))
|
||||
TriggerEvent('chat:removeSuggestion', ('/-%s'):format(data.name))
|
||||
end)
|
||||
|
||||
return data
|
||||
end
|
||||
|
||||
return xLib.addKeybind
|
||||
@@ -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
|
||||
@@ -130,4 +130,230 @@ function xLib.table.dump(tbl)
|
||||
end
|
||||
end
|
||||
|
||||
-- nil proof alternative to #table
|
||||
---@param t table
|
||||
---@return number
|
||||
function xLib.table.sizeOf(t)
|
||||
local count = 0
|
||||
|
||||
for _, _ in pairs(t) do
|
||||
count = count + 1
|
||||
end
|
||||
|
||||
return count
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@return table
|
||||
function xLib.table.set(t)
|
||||
local set = {}
|
||||
for _, v in ipairs(t) do
|
||||
set[v] = true
|
||||
end
|
||||
return set
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@param value any
|
||||
---@return number
|
||||
function xLib.table.indexOf(t, value)
|
||||
for i = 1, #t, 1 do
|
||||
if t[i] == value then
|
||||
return i
|
||||
end
|
||||
end
|
||||
|
||||
return -1
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@param value any
|
||||
---@return number
|
||||
function xLib.table.lastIndexOf(t, value)
|
||||
for i = #t, 1, -1 do
|
||||
if t[i] == value then
|
||||
return i
|
||||
end
|
||||
end
|
||||
|
||||
return -1
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@param cb function
|
||||
---@return any
|
||||
function xLib.table.find(t, cb)
|
||||
for i = 1, #t, 1 do
|
||||
if cb(t[i]) then
|
||||
return t[i]
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@param cb function
|
||||
---@return number
|
||||
function xLib.table.findIndex(t, cb)
|
||||
for i = 1, #t, 1 do
|
||||
if cb(t[i]) then
|
||||
return i
|
||||
end
|
||||
end
|
||||
|
||||
return -1
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@param cb function
|
||||
---@return table
|
||||
function xLib.table.map(t, cb)
|
||||
local newTable = {}
|
||||
|
||||
for i = 1, #t, 1 do
|
||||
newTable[i] = cb(t[i], i)
|
||||
end
|
||||
|
||||
return newTable
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@return table
|
||||
function xLib.table.reverse(t)
|
||||
local newTable = {}
|
||||
|
||||
for i = #t, 1, -1 do
|
||||
table.insert(newTable, t[i])
|
||||
end
|
||||
|
||||
return newTable
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@return table
|
||||
function xLib.table.clone(t)
|
||||
if type(t) ~= "table" then
|
||||
return t
|
||||
end
|
||||
|
||||
local meta = getmetatable(t)
|
||||
local target = {}
|
||||
|
||||
for k, v in pairs(t) do
|
||||
if type(v) == "table" then
|
||||
target[k] = xLib.table.clone(v)
|
||||
else
|
||||
target[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
setmetatable(target, meta)
|
||||
|
||||
return target
|
||||
end
|
||||
|
||||
---@param t1 table
|
||||
---@param t2 table
|
||||
---@return table
|
||||
function xLib.table.concat(t1, t2)
|
||||
local t3 = xLib.table.clone(t1)
|
||||
|
||||
for i = 1, #t2, 1 do
|
||||
table.insert(t3, t2[i])
|
||||
end
|
||||
|
||||
return t3
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@param sep string
|
||||
---@return string
|
||||
function xLib.table.join(t, sep)
|
||||
local str = ""
|
||||
|
||||
for i = 1, #t, 1 do
|
||||
if i > 1 then
|
||||
str = str .. (sep or ",")
|
||||
end
|
||||
|
||||
str = str .. t[i]
|
||||
end
|
||||
|
||||
return str
|
||||
end
|
||||
|
||||
-- Credits: https://github.com/JonasDev99/qb-garages/blob/b0335d67cb72a6b9ac60f62a87fb3946f5c2f33d/server/main.lua#L5
|
||||
---@param tab table
|
||||
---@param val any
|
||||
---@return boolean
|
||||
function xLib.table.contains(tab, val)
|
||||
if type(val) == "table" then
|
||||
for _, value in pairs(tab) do
|
||||
if xLib.table.contains(val, value) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
else
|
||||
for _, value in pairs(tab) do
|
||||
if value == val then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Credit: https://stackoverflow.com/a/15706820
|
||||
-- Description: sort function for pairs
|
||||
---@param t table
|
||||
---@param order function
|
||||
---@return function
|
||||
function xLib.table.sort(t, order)
|
||||
-- collect the keys
|
||||
local keys = {}
|
||||
|
||||
for k, _ in pairs(t) do
|
||||
keys[#keys + 1] = k
|
||||
end
|
||||
|
||||
-- if order function given, sort by it by passing the table and keys a, b,
|
||||
-- otherwise just sort the keys
|
||||
if order then
|
||||
table.sort(keys, function(a, b)
|
||||
return order(t, a, b)
|
||||
end)
|
||||
else
|
||||
table.sort(keys)
|
||||
end
|
||||
|
||||
-- return the iterator function
|
||||
local i = 0
|
||||
|
||||
return function()
|
||||
i = i + 1
|
||||
if keys[i] then
|
||||
return keys[i], t[keys[i]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@return Array
|
||||
function xLib.table.toArray(t)
|
||||
local array = {}
|
||||
for _, v in pairs(t) do
|
||||
array[#array + 1] = v
|
||||
end
|
||||
return array
|
||||
end
|
||||
|
||||
---@param t table
|
||||
---@return table
|
||||
function xLib.table.wipe(t)
|
||||
return table.wipe(t)
|
||||
end
|
||||
|
||||
|
||||
return xLib.table
|
||||
|
||||
Reference in New Issue
Block a user