2025-04-07 01:41:12 +00:00

216 lines
6.0 KiB
Lua

local utils = {}
local GetWorldCoordFromScreenCoord = GetWorldCoordFromScreenCoord
local StartShapeTestLosProbe = StartShapeTestLosProbe
local GetShapeTestResultIncludingMaterial = GetShapeTestResultIncludingMaterial
---@param flag number
---@return boolean hit
---@return number entityHit
---@return vector3 endCoords
---@return vector3 surfaceNormal
---@return number materialHash
function utils.raycastFromCamera(flag)
local coords, normal = GetWorldCoordFromScreenCoord(0.5, 0.5)
local destination = coords + normal * 10
local handle = StartShapeTestLosProbe(coords.x, coords.y, coords.z, destination.x, destination.y, destination.z,
flag, cache.ped, 4)
while true do
Wait(0)
local retval, hit, endCoords, surfaceNormal, materialHash, entityHit = GetShapeTestResultIncludingMaterial(
handle)
if retval ~= 1 then
---@diagnostic disable-next-line: return-type-mismatch
return hit, entityHit, endCoords, surfaceNormal, materialHash
end
end
end
function utils.getTexture()
return lib.requestStreamedTextureDict('shared'), 'emptydot_32'
end
-- SetDrawOrigin is limited to 32 calls per frame. Set as 0 to disable.
local drawZoneSprites = GetConvarInt('ox_target:drawSprite', 24)
local SetDrawOrigin = SetDrawOrigin
local DrawSprite = DrawSprite
local ClearDrawOrigin = ClearDrawOrigin
local colour = vector(155, 155, 155, 175)
local hover = vector(98, 135, 236, 255)
local currentZones = {}
local previousZones = {}
local drawZones = {}
local drawN = 0
local width = 0.02
local height = width * GetAspectRatio(false)
if drawZoneSprites == 0 then drawZoneSprites = -1 end
---@param coords vector3
---@return CZone[], boolean
function utils.getNearbyZones(coords)
if not Zones then return currentZones, false end
local n = 0
local nearbyZones = lib.zones.getNearbyZones()
drawN = 0
previousZones, currentZones = currentZones, table.wipe(previousZones)
for i = 1, #nearbyZones do
local zone = nearbyZones[i]
local contains = zone:contains(coords)
if contains then
n += 1
currentZones[n] = zone
end
if drawN <= drawZoneSprites and zone.drawSprite ~= false and (contains or (zone.distance or 7) < 7) then
drawN += 1
drawZones[drawN] = zone
zone.colour = contains and hover or nil
end
end
local previousN = #previousZones
if n ~= previousN then
return currentZones, true
end
if n > 0 then
for i = 1, n do
local zoneA = currentZones[i]
local found = false
for j = 1, previousN do
local zoneB = previousZones[j]
if zoneA == zoneB then
found = true
break
end
end
if not found then
return currentZones, true
end
end
end
return currentZones, false
end
function utils.drawZoneSprites(dict, texture)
if drawN == 0 then return end
for i = 1, drawN do
local zone = drawZones[i]
local spriteColour = zone.colour or colour
if zone.drawSprite ~= false then
SetDrawOrigin(zone.coords.x, zone.coords.y, zone.coords.z)
DrawSprite(dict, texture, 0, 0, width, height, 0, spriteColour.r, spriteColour.g, spriteColour.b,
spriteColour.a)
end
end
ClearDrawOrigin()
end
function utils.hasExport(export)
local resource, exportName = string.strsplit('.', export)
return pcall(function()
return exports[resource][exportName]
end)
end
local playerItems = {}
function utils.getItems()
return playerItems
end
---@param filter string | string[] | table<string, number>
---@param hasAny boolean?
---@return boolean
function utils.hasPlayerGotItems(filter, hasAny)
if not playerItems then return true end
local _type = type(filter)
if _type == 'string' then
return (playerItems[filter] or 0) > 0
elseif _type == 'table' then
local tabletype = table.type(filter)
if tabletype == 'hash' then
for name, amount in pairs(filter) do
local hasItem = (playerItems[name] or 0) >= amount
if hasAny then
if hasItem then return true end
elseif not hasItem then
return false
end
end
elseif tabletype == 'array' then
for i = 1, #filter do
local hasItem = (playerItems[filter[i]] or 0) > 0
if hasAny then
if hasItem then return true end
elseif not hasItem then
return false
end
end
end
end
return not hasAny
end
---stub
---@param filter string | string[] | table<string, number>
---@return boolean
function utils.hasPlayerGotGroup(filter)
return true
end
SetTimeout(0, function()
if utils.hasExport('ox_inventory.Items') then
setmetatable(playerItems, {
__index = function(self, index)
self[index] = exports.ox_inventory:Search('count', index) or 0
return self[index]
end
})
AddEventHandler('ox_inventory:itemCount', function(name, count)
playerItems[name] = count
end)
end
if utils.hasExport('ox_core.GetPlayer') then
require 'client.framework.ox'
elseif utils.hasExport('es_extended.getSharedObject') then
require 'client.framework.esx'
elseif utils.hasExport('qbx_core.HasGroup') then
require 'client.framework.qbx'
elseif utils.hasExport('ND_Core.getPlayer') then
require 'client.framework.nd'
end
end)
function utils.warn(msg)
local trace = Citizen.InvokeNative(`FORMAT_STACK_TRACE` & 0xFFFFFFFF, nil, 0, Citizen.ResultAsString())
local _, _, src = string.strsplit('\n', trace, 4)
warn(('%s ^0%s\n'):format(msg, src:gsub(".-%(", '(')))
end
return utils