166 lines
4.1 KiB
Lua
166 lines
4.1 KiB
Lua
|
|
Globals = {}
|
||
|
|
Functions = {}
|
||
|
|
Locale = Locales[Config.Locale or "en"]
|
||
|
|
|
||
|
|
-- Height offset for interaction points/zones above ground level
|
||
|
|
-- Stored coords are at ground + this offset, visualizations use GetGroundZFor_3dCoord
|
||
|
|
Globals.InteractionZOffset = 1.0
|
||
|
|
|
||
|
|
exports("locale", function() return Locale end)
|
||
|
|
exports("config", function() return Config end)
|
||
|
|
|
||
|
|
---@param text string
|
||
|
|
---@param debugtype? "warning"|"debug"
|
||
|
|
function DebugPrint(text, debugtype, ...)
|
||
|
|
if not Config.Debug then return end
|
||
|
|
|
||
|
|
local prefix = "^2[DEBUG]^7"
|
||
|
|
if debugtype == "warning" then prefix = "^3[WARNING]^7" end
|
||
|
|
|
||
|
|
local args = {...}
|
||
|
|
local output = ""
|
||
|
|
for i = 1, #args do
|
||
|
|
if type(args[i]) == "table" then
|
||
|
|
output = output .. json.encode(args[i])
|
||
|
|
elseif type(args[i]) ~= "string" then
|
||
|
|
output = output .. tostring(args[i])
|
||
|
|
else
|
||
|
|
output = output .. args[i]
|
||
|
|
end
|
||
|
|
|
||
|
|
if i ~= #args then output = output .. " " end
|
||
|
|
end
|
||
|
|
|
||
|
|
print(prefix, text, output)
|
||
|
|
end
|
||
|
|
|
||
|
|
---@param vehicle integer
|
||
|
|
function JGDeleteVehicle(vehicle)
|
||
|
|
if not DoesEntityExist(vehicle) then return end
|
||
|
|
|
||
|
|
if GetResourceState("AdvancedParking") == "started" then
|
||
|
|
exports["AdvancedParking"]:DeleteVehicle(vehicle, false)
|
||
|
|
else
|
||
|
|
DeleteEntity(vehicle)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
---@param vehicle integer
|
||
|
|
---@param plate string
|
||
|
|
function SetVehiclePlateText(vehicle, plate)
|
||
|
|
if GetResourceState("AdvancedParking") == "started" then
|
||
|
|
exports["AdvancedParking"]:UpdatePlate(vehicle, plate)
|
||
|
|
else
|
||
|
|
SetVehicleNumberPlateText(vehicle, plate)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
---@param model string | number
|
||
|
|
---@return number hash
|
||
|
|
function ConvertModelToHash(model)
|
||
|
|
return type(model) == "string" and joaat(model) or model --[[@as number]]
|
||
|
|
end
|
||
|
|
|
||
|
|
---@param plate string
|
||
|
|
function IsValidGTAPlate(plate)
|
||
|
|
-- Check if the plate matches the pattern and is not longer than 8 characters
|
||
|
|
-- %w matches alphanumeric characters, %s matches space characters
|
||
|
|
-- The pattern checks for a string starting with 0 or more alphanumeric or space characters
|
||
|
|
if #plate <= 8 and plate:match("^[%w%s]*$") then return true end
|
||
|
|
return false
|
||
|
|
end
|
||
|
|
|
||
|
|
---@param table table
|
||
|
|
function TableKeys(table)
|
||
|
|
if not table then return {} end
|
||
|
|
|
||
|
|
local keys = {}
|
||
|
|
for k, _ in pairs(table) do
|
||
|
|
keys[#keys+1] = k
|
||
|
|
end
|
||
|
|
|
||
|
|
return keys
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Round a number to so-many decimal of places,
|
||
|
|
-- Which can be negative, e.g. -1 places rounds to 10's
|
||
|
|
---@param num integer
|
||
|
|
---@param dp? integer
|
||
|
|
---@return number
|
||
|
|
function Round(num, dp)
|
||
|
|
dp = dp or 0
|
||
|
|
local mult = 10^(dp or 0)
|
||
|
|
return math.floor(num * mult + 0.5) / mult
|
||
|
|
end
|
||
|
|
|
||
|
|
---@param list table
|
||
|
|
---@param item string|number
|
||
|
|
---@return boolean
|
||
|
|
function IsItemInList(list, item)
|
||
|
|
if #list == 0 then
|
||
|
|
return true
|
||
|
|
end
|
||
|
|
|
||
|
|
for _, value in ipairs(list) do
|
||
|
|
if value == item then
|
||
|
|
return true
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
return false
|
||
|
|
end
|
||
|
|
|
||
|
|
---@param s string
|
||
|
|
---@return string
|
||
|
|
function Trim(s)
|
||
|
|
return (s:gsub("^%s*(.-)%s*$", "%1"))
|
||
|
|
end
|
||
|
|
|
||
|
|
function TableValues(table)
|
||
|
|
local values = {}
|
||
|
|
for _, val in pairs(table) do
|
||
|
|
values[#values+1] = val
|
||
|
|
end
|
||
|
|
return values
|
||
|
|
end
|
||
|
|
|
||
|
|
---Case-insensitive table key lookup
|
||
|
|
---@param tbl table The table to search
|
||
|
|
---@param key string The key to find (case-insensitive)
|
||
|
|
---@return any value The value if found, nil otherwise
|
||
|
|
---@return string|nil actualKey The actual key in the table if found
|
||
|
|
function GetCaseInsensitive(tbl, key)
|
||
|
|
if not tbl or not key then return nil, nil end
|
||
|
|
|
||
|
|
-- Try exact match first
|
||
|
|
if tbl[key] ~= nil then return tbl[key], key end
|
||
|
|
|
||
|
|
-- Try case-insensitive match
|
||
|
|
local lowerKey = string.lower(key)
|
||
|
|
for k, v in pairs(tbl) do
|
||
|
|
if type(k) == "string" and string.lower(k) == lowerKey then
|
||
|
|
return v, k
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
return nil, nil
|
||
|
|
end
|
||
|
|
|
||
|
|
---Checks if a job/gang passes a whitelist
|
||
|
|
---@param whitelist JobGangWhitelist|nil
|
||
|
|
---@param name string|nil
|
||
|
|
---@param grade number|nil
|
||
|
|
---@return boolean
|
||
|
|
function CheckJobGangWhitelist(whitelist, name, grade)
|
||
|
|
if not whitelist or not next(whitelist) then return true end
|
||
|
|
if not name or not grade then return false end
|
||
|
|
|
||
|
|
local allowedGrades = whitelist[name]
|
||
|
|
if not allowedGrades then return false end
|
||
|
|
|
||
|
|
for _, allowedGrade in ipairs(allowedGrades) do
|
||
|
|
if allowedGrade == grade then return true end
|
||
|
|
end
|
||
|
|
|
||
|
|
return false
|
||
|
|
end
|