Files
red-valley/cache/files/t1ger_lib/resource.rpf

2039 lines
86 KiB
Plaintext
Raw Normal View History

2026-03-29 21:41:17 +03:00
RPF2 <00><00><00><00>q<00>(<00>|H<00>)<00>) <00>4
<00>g`><00>`>'jHj<4 `4 Ke&pe&VN<00>N/.fxapclientframework.luaminigamesdrilling.luamodulesscaleforms.luatarget.luavehicleprops.luautils.luaconfig.luafxmanifest.luaFXAP<1A>$<24><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><>r{7<><37><EFBFBD>o<><6F>{<7B>T)<29><><EFBFBD>`<60><>z<EFBFBD>8<EFBFBD>U)<29><03><><EFBFBD>@$<24><><EFBFBD>)<1B>h$'g<><13> 9<>|<7C> <0C><>j<5<>I<EFBFBD>+i<>J<EFBFBD>A֬u<D6AC>j<EFBFBD><6A>@$<24>'<27>d<EFBFBD><64><EFBFBD>Z;R<><15><><EFBFBD><EFBFBD><EFBFBD>s<EFBFBD><31>X<EFBFBD>>0<><30>T<EFBFBD><54>.9<EFBFBD><EFBFBD>C]<5D>f`s<>xFl,<2C><>EI+?<04><EFBFBD><13><><EFBFBD>]- <09><><EFBFBD>dCore = {
PlayerData = {},
PlayerJob = {},
Police = {Count = 0, Players = {}},
Vehicles = {},
FrameworkReady = function()
if Framework == 'ESX' then
while not ESX do Wait(500); end
while ESX.GetPlayerData().job == nil do
Citizen.Wait(500)
end
Core.PlayerData = Core.GetPlayerData()
return true
elseif Framework == 'QB' then
while not QBCore do Wait(500); end
while not QBCore.Functions.GetPlayerData().job do Wait(500); end
Core.PlayerData = Core.GetPlayerData()
return true
end
return true
end,
TriggerCallback = function(name, cb, ...)
if ESX ~= nil then
ESX.TriggerServerCallback(name, cb, ...)
elseif QBCore ~= nil then
QBCore.Functions.TriggerCallback(name, cb, ...)
end
end,
Notification = function(data)
if Config.UseFrameworkNotification then
if ESX ~= nil then
ESX.ShowNotification(data.message, false, true, nil)
elseif QBCore ~= nil then
QBCore.Functions.Notify(data.message)
end
else
Lib.Notification(data)
end
end,
GetPlayerData = function()
if Framework == 'ESX' then
Core.PlayerData = ESX.GetPlayerData()
Core.SetPlayerJob()
return ESX.GetPlayerData()
elseif Framework == 'QB' then
Core.PlayerData = QBCore.Functions.GetPlayerData()
Core.SetPlayerJob()
return QBCore.Functions.GetPlayerData()
end
end,
GetFullName = function(src)
local fullName, done = nil, false
Core.TriggerCallback('t1ger_lib:getFullName', function(name)
fullName = name
done = true
end, src)
while not done do
Wait(1)
end
return fullName
end,
SetPlayerJob = function()
local table = {}
while not Core.PlayerData.job do
Wait(200)
end
if Framework == 'ESX' then
table.name = Core.PlayerData.job.name
table.label = Core.PlayerData.job.label
table.grade = Core.PlayerData.job.grade
table.gradeLabel = Core.PlayerData.job.grade_label
table.isPolice = Config.PoliceJobs[Core.PlayerData.job.name] or false
if Config.Debug then
print("Job Updated: ", table.name, table.label, table.isPolice, table.grade, table.gradeLabel)
end
elseif Framework == 'QB' then
table.name = Core.PlayerData.job.name
table.label = Core.PlayerData.job.label
table.grade = Core.PlayerData.job.grade.level
table.onDuty = Core.PlayerData.job.onduty or nil
table.isPolice = Config.PoliceJobs[Core.PlayerData.job.name] or false
if Config.Debug then
print("Job Updated: ", table.name, table.label, table.onDuty, table.isPolice, table.grade)
end
end
Core.PlayerJob = table
TriggerEvent('t1ger_lib:onJobUpdate', Core.PlayerJob)
end,
GetJob = function()
return Core.PlayerJob
end,
ToggleDuty = function()
if Framework == 'QB' then
TriggerServerEvent(Config.Triggers['QB'].dutyToggle)
end
end,
HasItem = function(item, amount, cb)
Core.TriggerCallback('t1ger_lib:hasItem', function(result)
cb(result)
end, item, amount)
end,
GetPlayerMoney = function(cb, account)
Core.TriggerCallback('t1ger_lib:getMoney', function(money)
cb(money)
end, account or nil)
end,
OpenStash = function(id, label, slots, weight, owner)
if Config.Inventory == 'ox-inventory' then
exports.ox_inventory:openInventory('stash', {id = id})
elseif Config.Inventory == 'qb-inventory' then
TriggerServerEvent('t1ger_lib:server:openInventory', id, label, slots, weight, owner)
--[[TriggerServerEvent('inventory:server:OpenInventory', 'stash', id, {maxweight = weight, slots = slots})
TriggerEvent('inventory:client:SetCurrentStash', id)]]
elseif Config.Inventory == 'mf-inventory' then
exports['mf-inventory']:openOtherInventory(id)
elseif Config.Inventory == 'qs-inventory' then
TriggerServerEvent('inventory:server:OpenInventory', 'stash', 'Stash_'..id, {maxweight = weight, slots = slots})
TriggerEvent('inventory:client:SetCurrentStash', 'Stash_'..id)
elseif Config.Inventory == 'core-inventory' then
TriggerServerEvent('core_inventory:server:openInventory', 'stash-'..id:gsub('/',''):gsub(':',''):gsub('#',''), 'stash', nil, nil)
elseif Config.Inventory == 'codem-inventory' then
TriggerServerEvent('codem-inventory:server:openstash', id, slots, weight, label)
elseif Config.Inventory == 'custom' then
-- export/event to open stash/storage inventory
end
end,
SpawnVehicle = function(model, coords, heading, cb, networked)
if ESX ~= nil then
ESX.Game.SpawnVehicle(model, coords, heading, cb, networked)
elseif QBCore ~= nil then
QBCore.Functions.SpawnVehicle(model, cb, coords, networked)
end
end,
DeleteVehicle = function(vehicle)
if ESX ~= nil then
ESX.Game.DeleteVehicle(vehicle)
elseif QBCore ~= nil then
QBCore.Functions.DeleteVehicle(vehicle)
end
end,
SetVehicleProperties = function(vehicle, props)
local ent = Entity(vehicle).state
ent:set('t1ger_lib:setVehicleProps', props, true)
--[[if ESX ~= nil then
ESX.Game.SetVehicleProperties(vehicle, props)
elseif QBCore ~= nil then
QBCore.Functions.SetVehicleProperties(vehicle, props)
end]]
end,
GetVehicleProperties = function(vehicle)
return GetVehicleProperties(vehicle)
--[[if ESX ~= nil then
return ESX.Game.GetVehicleProperties(vehicle)
elseif QBCore ~= nil then
return QBCore.Functions.GetVehicleProperties(vehicle)
end]]
end,
GetVehicleFuelLevel = function(vehicle)
return GetVehicleFuelLevel(vehicle)
end,
ImpoundVehicle = function(vehicle, plate)
local props = Core.GetVehicleProperties(vehicle)
if Config.Garage == 'default' then
TriggerServerEvent('t1ger_lib:server:impoundVehicle', plate, props)
elseif Config.Garage == 't1ger-garage' then
exports['t1ger_garage']:SetVehicleImpounded(vehicle, false)
elseif Config.Garage == 'cd-garage' then
print('insert your impound event/function in here, to update state of the vehicle')
-- put cd garage impound function here
end
Core.DeleteVehicle(vehicle)
end,
GetPoliceCount = function()
return Core.Police.Count
end,
GetPolicePlayers = function()
return Core.Police.Players
end,
GetVehiclePrice = function(model, cb)
local vehiclePrice = 0
if Config.VehiclePrice == 'handling' then
vehiclePrice = GetVehicleModelValue(model)
else
if Core.Vehicles[tostring(model)] == nil or next(Core.Vehicles[tostring(model)]) == nil then
local fetched = false
Core.TriggerCallback('t1ger_lib:getCoreVehicles', function(result)
Core.Vehicles = result
if Core.Vehicles[tostring(model)] ~= nil and next(Core.Vehicles[tostring(model)]) then
local price = Core.Vehicles[tostring(model)].price
vehiclePrice = price ~= nil and price or 0
end
fetched = true
end)
while fetched == false do
Wait(1)
end
else
local price = Core.Vehicles[tostring(model)].price
vehiclePrice = price ~= nil and price or 0
end
end
cb(vehiclePrice)
end,
GetVehicles = function(model, cb)
local vehicle = nil
if Core.Vehicles[tostring(model)] == nil or next(Core.Vehicles[tostring(model)]) == nil then
Core.TriggerCallback('t1ger_lib:getCoreVehicles', function(result)
Core.Vehicles = result
if Core.Vehicles[tostring(model)] ~= nil and next(Core.Vehicles[tostring(model)]) then
vehicle = Core.Vehicles[tostring(model)]
else
vehicle = false
end
end)
else
vehicle = Core.Vehicles[tostring(model)]
end
while vehicle == nil do
Wait(1)
end
cb(vehicle)
end,
}
RegisterNetEvent(Config.Triggers[Framework].load)
AddEventHandler(Config.Triggers[Framework].load, function(xPlayer)
Core.PlayerData = Core.GetPlayerData()
Core.SetPlayerJob()
if Core.GetJob().isPolice == true then
TriggerServerEvent('t1ger_lib:server:playerLoaded')
end
end)
RegisterNetEvent(Config.Triggers[Framework].job)
AddEventHandler(Config.Triggers[Framework].job, function(job)
Core.PlayerData.job = job
Core.SetPlayerJob()
TriggerServerEvent('t1ger_lib:server:setJob', job)
end)
if Framework == 'QB' then
RegisterNetEvent(Config.Triggers[Framework].uObjCL, function()
QBCore = exports[Config.Triggers[Framework].resource]:GetCoreObject()
end)
end
RegisterNetEvent('t1ger_lib:client:updatePolice')
AddEventHandler('t1ger_lib:client:updatePolice', function(count, players)
Core.Police.Count = count
Core.Police.Players = players
end)
Core.VehicleMeta = {
Fetch = function(plate)
local metadata = nil
Core.TriggerCallback('t1ger_lib:vehiclemeta:fetch', function(result)
metadata = result
end, plate)
while metadata == nil do
Wait(1)
end
return metadata
end,
Update = function(plate, metadata)
TriggerServerEvent('t1ger_lib:vehiclemeta:update', plate, metadata)
end,
}
exports('SetVehicleProperties', Core.SetVehicleProperties)
exports('GetVehicleProperties', Core.GetVehicleProperties)-- Credits to meta-hub @ https://github.com/meta-hub/fivem-drilling
Drilling = {
DisabledControls = {30, 31, 44, 199, 35, 24, 140},
}
Drilling.Start = function(callback)
if not Drilling.Active then
Drilling.Active = true
Drilling.Init()
Drilling.Update(callback)
end
end
Drilling.Init = function()
if Drilling.Scaleform then
Lib.Scaleforms.UnloadMovie(Drilling.Scaleform)
end
Drilling.Scaleform = Lib.Scaleforms.LoadMovie("DRILLING")
Drilling.DrillSpeed = 0.0
Drilling.DrillPos = 0.0
Drilling.DrillTemp = 0.0
Drilling.HoleDepth = 0.1
Lib.Scaleforms.PopFloat(Drilling.Scaleform, "SET_SPEED", 0.0)
Lib.Scaleforms.PopFloat(Drilling.Scaleform, "SET_DRILL_POSITION", 0.0)
Lib.Scaleforms.PopFloat(Drilling.Scaleform, "SET_TEMPERATURE", 0.0)
Lib.Scaleforms.PopFloat(Drilling.Scaleform, "SET_HOLE_DEPTH", 0.0)
end
Drilling.Update = function(callback)
while Drilling.Active do
Drilling.Draw()
Drilling.DisableControls()
Drilling.HandleControls()
-- stop/cancel drilling:
if IsControlJustPressed(0, 202) then -- BACKSPACE / ESC
Drilling.Active = false
Drilling.Result = false
end
Wait(0)
end
callback(Drilling.Result)
end
Drilling.Draw = function()
DrawScaleformMovieFullscreen(Drilling.Scaleform, 255, 255, 255, 255, 255)
end
Drilling.HandleControls = function()
local last = { pos = Drilling.DrillPos, speed = Drilling.DrillSpeed, temp = Drilling.DrillTemp }
-- Drill Position Forward:
if IsControlJustPressed(0,172) then
Drilling.DrillPos = math.min(1.0, Drilling.DrillPos + 0.005)
elseif IsControlPressed(0,172) then
Drilling.DrillPos = math.min(1.0, Drilling.DrillPos + (0.1 * GetFrameTime() / (math.max(0.1, Drilling.DrillTemp) * 10)))
end
-- Drill Position Backwards:
if IsControlJustPressed(0,173) then
Drilling.DrillPos = math.max(0.0, Drilling.DrillPos - 0.01)
elseif IsControlPressed(0,173) then
Drilling.DrillPos = math.max(0.0, Drilling.DrillPos - (0.1 * GetFrameTime()))
end
-- Drill Speed Increase:
if IsControlJustPressed(0,175) then
Drilling.DrillSpeed = math.min(1.0, Drilling.DrillSpeed + 0.05)
elseif IsControlPressed(0,175) then
Drilling.DrillSpeed = math.min(1.0, Drilling.DrillSpeed + (0.5 * GetFrameTime()))
end
-- Drill Speed Decrease:
if IsControlJustPressed(0,174) then
Drilling.DrillSpeed = math.max(0.0, Drilling.DrillSpeed - 0.05)
elseif IsControlPressed(0,174) then
Drilling.DrillSpeed = math.max(0.0, Drilling.DrillSpeed - (0.5 * GetFrameTime()))
end
if Drilling.DrillSpeed ~= last.speed then
Lib.Scaleforms.PopFloat(Drilling.Scaleform, "SET_SPEED", Drilling.DrillSpeed)
end
if Drilling.DrillPos > Drilling.HoleDepth then
if Drilling.DrillSpeed > 0.1 then
Drilling.DrillTemp = math.min(1.0, Drilling.DrillTemp + ((1.0 * GetFrameTime()) * Drilling.DrillSpeed))
Drilling.HoleDepth = Drilling.DrillPos
else
Drilling.DrillPos = Drilling.HoleDepth
end
else
Drilling.DrillTemp = math.max(0.0, Drilling.DrillTemp - (1.0 * GetFrameTime()))
end
if Drilling.DrillPos ~= last.pos then
Lib.Scaleforms.PopFloat(Drilling.Scaleform, "SET_DRILL_POSITION", Drilling.DrillPos)
end
if last.temp ~= Drilling.DrillTemp then
Lib.Scaleforms.PopFloat(Drilling.Scaleform, "SET_TEMPERATURE", Drilling.DrillTemp)
end
if Drilling.DrillTemp >= 1.0 then
Drilling.Result = false
Drilling.Active = false
elseif Drilling.DrillPos >= 1.0 then
Drilling.Result = true
Drilling.Active = false
end
end
Drilling.DisableControls = function()
for _,control in ipairs(Drilling.DisabledControls) do
DisableControlAction(0, control, true)
end
end
Drilling.EnableControls = function()
for _,control in ipairs(Drilling.DisabledControls) do
DisableControlAction(0, control, true)
end
end
Drilling.Minigame = function()
local success = false
Drilling.Start(function(cb)
success = cb
end)
return success
end
Lib.Drilling = Drilling
exports('Drilling', Drilling.Minigame)-- Credits to meta-hub @ https://github.com/meta-hub/meta_libs/blob/master/meta_libs/client/classes/Scaleforms.lua
Scaleforms = {}
-- Load scaleforms
Scaleforms.LoadMovie = function(name)
local scaleform = RequestScaleformMovie(name)
while not HasScaleformMovieLoaded(scaleform) do Wait(0); end
return scaleform
end
Scaleforms.LoadInteractive = function(name)
local scaleform = RequestScaleformMovieInteractive(name)
while not HasScaleformMovieLoaded(scaleform) do Wait(0); end
return scaleform
end
Scaleforms.UnloadMovie = function(scaleform)
SetScaleformMovieAsNoLongerNeeded(scaleform)
end
-- Text & labels
Scaleforms.LoadAdditionalText = function(gxt,count)
for i=0,count,1 do
if not HasThisAdditionalTextLoaded(gxt,i) then
ClearAdditionalText(i, true)
RequestAdditionalText(gxt, i)
while not HasThisAdditionalTextLoaded(gxt,i) do Wait(0); end
end
end
end
Scaleforms.SetLabels = function(scaleform,labels)
PushScaleformMovieFunction(scaleform, "SET_LABELS")
for i=1,#labels,1 do
local txt = labels[i]
BeginTextCommandScaleformString(txt)
EndTextCommandScaleformString()
end
PopScaleformMovieFunctionVoid()
end
-- Push method vals wrappers
Scaleforms.PopMulti = function(scaleform,method,...)
PushScaleformMovieFunction(scaleform,method)
for _,v in pairs({...}) do
local trueType = Scaleforms.TrueType(v)
if trueType == "string" then
PushScaleformMovieFunctionParameterString(v)
elseif trueType == "boolean" then
PushScaleformMovieFunctionParameterBool(v)
elseif trueType == "int" then
PushScaleformMovieFunctionParameterInt(v)
elseif trueType == "float" then
PushScaleformMovieFunctionParameterFloat(v)
end
end
PopScaleformMovieFunctionVoid()
end
Scaleforms.PopFloat = function(scaleform,method,val)
PushScaleformMovieFunction(scaleform,method)
PushScaleformMovieFunctionParameterFloat(val)
PopScaleformMovieFunctionVoid()
end
Scaleforms.PopInt = function(scaleform,method,val)
PushScaleformMovieFunction(scaleform,method)
PushScaleformMovieFunctionParameterInt(val)
PopScaleformMovieFunctionVoid()
end
Scaleforms.PopBool = function(scaleform,method,val)
PushScaleformMovieFunction(scaleform,method)
PushScaleformMovieFunctionParameterBool(val)
PopScaleformMovieFunctionVoid()
end
-- Push no args
Scaleforms.PopRet = function(scaleform,method)
PushScaleformMovieFunction(scaleform, method)
return PopScaleformMovieFunction()
end
Scaleforms.PopVoid = function(scaleform,method)
PushScaleformMovieFunction(scaleform, method)
PopScaleformMovieFunctionVoid()
end
-- Get return
Scaleforms.RetBool = function(ret)
return GetScaleformMovieFunctionReturnBool(ret)
end
Scaleforms.RetInt = function(ret)
return GetScaleformMovieFunctionReturnInt(ret)
end
-- Util functions
Scaleforms.TrueType = function(val)
if type(val) ~= "number" then return type(val); end
local s = tostring(val)
if string.find(s,'.') then
return "float"
else
return "int"
end
end
Lib.Scaleforms = ScaleformsLib.RandomNameId = 0
Lib.AddGlobalVehicle = function(args)
if Config.TargetSystem == 'ox-target' then
exports['ox_target']:addGlobalVehicle(args.options)
elseif Config.TargetSystem == 'qb-target' then
local newOptions = {}
for k,v in pairs(args.options) do
local NewFunction = nil
if v.onSelect ~= nil then
NewFunction = function(entity)
local data = {entity = entity, coords = GetEntityCoords(entity)}
v.onSelect(data)
end
end
table.insert(newOptions, {num = v.num or nil, type = v.type, event = v.event or nil, icon = v.icon, label = v.label, action = NewFunction or nil, canInteract = v.canInteract})
end
exports['qb-target']:AddGlobalVehicle({
options = newOptions,
distance = args.distance,
canInteract = args.canInteract,
})
elseif Config.TargetSystem == 'meta-target' then
local newOptions = {}
for k,v in ipairs(args.options) do
local NewFunction = function(entity)
local data = {entity = entity, coords = GetEntityCoords(entity)}
if v.onSelect ~= nil then
v.onSelect(data)
else
TriggerEvent(v.event, data)
end
end
table.insert(newOptions, {label = v.label, index = k, onSelect = NewFunction})
end
Lib.RandomNameId = Lib.RandomNameId + 1
local targetName = 'obj'..Lib.RandomNameId
local canInteract = function(target, pos, ent)
return args.canInteract(ent)
end
exports['meta_target']:addObject(targetName, 'Obj', 'fa-solid fa-globe', args.distance, false, newOptions, {}, GetInvokingResource(), canInteract)
end
end
Lib.AddGlobalObject = function(args)
if Config.TargetSystem == 'ox-target' then
exports['ox_target']:addGlobalObject(args.options)
elseif Config.TargetSystem == 'qb-target' then
local newOptions = {}
for k,v in pairs(args.options) do
local NewFunction = nil
if v.onSelect ~= nil then
NewFunction = function(entity)
local data = {entity = entity, coords = GetEntityCoords(entity)}
v.onSelect(data)
end
end
table.insert(newOptions, {num = v.num or nil, type = v.type, event = v.event or nil, icon = v.icon, label = v.label, action = NewFunction or nil, canInteract = v.canInteract})
end
exports['qb-target']:AddGlobalObject({
options = newOptions,
distance = args.distance,
canInteract = args.canInteract,
})
elseif Config.TargetSystem == 'meta-target' then
local newOptions = {}
for k,v in ipairs(args.options) do
local NewFunction = function(entity)
local data = {entity = entity, coords = GetEntityCoords(entity)}
if v.onSelect ~= nil then
v.onSelect(data)
else
TriggerEvent(v.event, data)
end
end
table.insert(newOptions, {label = v.label, index = k, onSelect = NewFunction})
end
Lib.RandomNameId = Lib.RandomNameId + 1
local targetName = 'obj'..Lib.RandomNameId
local canInteract = function(target, pos, ent)
return args.canInteract(ent)
end
exports['meta_target']:addObject(targetName, 'Obj', 'fa-solid fa-globe', args.distance, false, newOptions, {}, GetInvokingResource(), canInteract)
end
end
Lib.AddGlobalPed = function(args)
if Config.TargetSystem == 'ox-target' then
exports['ox_target']:addGlobalPed(args.options)
elseif Config.TargetSystem == 'qb-target' then
local newOptions = {}
for k,v in pairs(args.options) do
table.insert(newOptions, {num = v.num or nil, type = v.type, event = v.event or nil, icon = v.icon, label = v.label, action = v.onSelect or nil, canInteract = v.canInteract})
end
exports['qb-target']:AddGlobalPed({
options = newOptions,
distance = args.distance,
canInteract = args.canInteract,
})
elseif Config.TargetSystem == 'meta-target' then
local newOptions = {}
for k,v in ipairs(args.options) do
local NewFunction = function(target,option,entity)
local args = {entity = entity}
TriggerEvent(v.event, args)
end
table.insert(newOptions, {label = v.label, index = k, onSelect = NewFunction})
end
Lib.RandomNameId = Lib.RandomNameId + 1
local targetName = 'ped'..Lib.RandomNameId
local canInteract = function(target, pos, ent)
return args.canInteract(ent)
end
exports['meta_target']:addPed(targetName, 'Ped', args.options[1].icon, args.distance, false, newOptions, {}, GetInvokingResource(), canInteract)
end
end
Lib.AddModel = function(models, args)
if Config.TargetSystem == 'ox-target' then
exports['ox_target']:addModel(models, args.options)
elseif Config.TargetSystem == 'qb-target' then
local newOptions = {}
for k,v in pairs(args.options) do
local NewFunction = nil
if v.onSelect ~= nil then
NewFunction = function(entity)
local data = {entity = entity, coords = GetEntityCoords(entity)}
v.onSelect(data)
end
end
table.insert(newOptions, {num = v.num or nil, type = v.type, event = v.event or nil, icon = v.icon, label = v.label, action = NewFunction or nil, canInteract = v.canInteract})
end
exports['qb-target']:AddTargetModel(models, {
options = newOptions,
distance = args.distance,
canInteract = args.canInteract,
})
elseif Config.TargetSystem == 'meta-target' then
local newOptions = {}
for k,v in ipairs(args.options) do
local NewFunction = function(entity)
local data = {entity = entity, coords = GetEntityCoords(entity)}
if v.onSelect ~= nil then
v.onSelect(data)
else
TriggerEvent(v.event, data)
end
end
table.insert(newOptions, {label = v.label, index = k, onSelect = NewFunction})
end
local canInteract = args.canInteract
if canInteract then
canInteract = function(target, pos, ent)
return args.canInteract(ent)
end
end
exports['meta_target']:addModels(args.options[1].name, 'Model', args.options[1].icon, models, args.distance, false, newOptions, {}, GetInvokingResource(), canInteract or nil)
end
end
Lib.AddLocalEntity = function(entity, args)
if Config.TargetSystem == 'ox-target' then
exports['ox_target']:addLocalEntity(entity, args.options)
elseif Config.TargetSystem == 'qb-target' then
local newOptions = {}
for k,v in pairs(args.options) do
local NewFunction = nil
if v.onSelect ~= nil then
NewFunction = function(entity)
local data = {entity = entity, coords = GetEntityCoords(entity)}
v.onSelect(data)
end
end
table.insert(newOptions, {num = v.num or nil, type = v.type, event = v.event or nil, icon = v.icon, label = v.label, action = NewFunction or nil, canInteract = v.canInteract})
end
exports['qb-target']:AddTargetEntity(entity, {
options = newOptions,
distance = args.distance,
canInteract = args.canInteract,
})
elseif Config.TargetSystem == 'meta-target' then
local newOptions = {}
for k,v in ipairs(args.options) do
local NewFunction = function(entity)
local data = {entity = entity, coords = GetEntityCoords(entity)}
if v.onSelect ~= nil then
v.onSelect(data)
else
TriggerEvent(v.event, data)
end
end
table.insert(newOptions, {label = v.label, index = k, onSelect = NewFunction})
end
local canInteract = args.canInteract
if canInteract then
canInteract = function(target, pos, ent)
return args.canInteract(ent)
end
end
exports['meta_target']:addLocalEnt(args.options[1].name, 'NPC', args.options[1].icon, entity, args.distance, false, newOptions, {}, GetInvokingResource(), canInteract or nil)
end
end
Lib.RemoveModel = function(model, args, label)
if Config.TargetSystem == 'ox-target' then
exports.ox_target:removeModel(model, args)
elseif Config.TargetSystem == 'qb-target' then
exports['qb-target']:RemoveTargetModel(model, label)
elseif Config.TargetSystem == 'meta-target' then
exports['meta_target']:removeTarget(args)
end
end
Lib.RemoveLocalEntity = function(entity, args, label)
if Config.TargetSystem == 'ox-target' then
exports.ox_target:removeLocalEntity(entity, args)
elseif Config.TargetSystem == 'qb-target' then
exports['qb-target']:RemoveTargetEntity(entity, label)
elseif Config.TargetSystem == 'meta-target' then
exports['meta_target']:removeTarget(args)
end
end-- Credits to Linden @ https://github.com/overextended/ox_lib/blob/master/resource/vehicleProperties/client.lua
local gameBuild = GetGameBuildNumber()
---@param vehicle number
---@return VehicleProperties?
GetVehicleProperties = function(vehicle)
if DoesEntityExist(vehicle) then
---@type number | number[], number | number[]
local colorPrimary, colorSecondary = GetVehicleColours(vehicle)
local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle)
local paintType1 = GetVehicleModColor_1(vehicle)
local paintType2 = GetVehicleModColor_2(vehicle)
-- Custom Colors:
if GetIsVehiclePrimaryColourCustom(vehicle) then
colorPrimary = { GetVehicleCustomPrimaryColour(vehicle) }
end
if GetIsVehicleSecondaryColourCustom(vehicle) then
colorSecondary = { GetVehicleCustomSecondaryColour(vehicle) }
end
-- Custom Xenon (RGB):
local hasCustomXenon, customXenonR, customXenonG, customXenonB = GetVehicleXenonLightsCustomColor(vehicle)
local customXenon = nil
if hasCustomXenon then
customXenon = {customXenonR, customXenonG, customXenonB}
end
local extras = {}
for i = 0, 14 do
if DoesExtraExist(vehicle, i) then
extras[tostring(i)] = IsVehicleExtraTurnedOn(vehicle, i) and 0 or 1
end
end
local modLiveryCount = (GetVehicleLiveryCount(vehicle) - 1)
local modLivery = GetVehicleLivery(vehicle)
if modLiveryCount <= 0 or modLivery == -1 then
modLivery = GetVehicleMod(vehicle, 48)
end
local vehicleWindows = {}
for index = 0, 7 do
RollUpWindow(vehicle, index)
vehicleWindows[tostring(index)] = IsVehicleWindowIntact(vehicle, index) and 1 or 2
end
local vehicleDoors = {}
local numDoors = GetNumberOfVehicleDoors(vehicle)
if numDoors and numDoors > 0 then
for doorId = 0, numDoors do
vehicleDoors[tostring(doorId)] = IsVehicleDoorDamaged(vehicle, doorId) and 2 or 1
end
end
local vehicleTyres = {}
local numWheels = GetVehicleNumberOfWheels(vehicle)
if numWheels and numWheels > 0 then
for wheelIndex,v in pairs(Lib.VehicleWheels[tostring(numWheels)]) do
vehicleTyres[wheelIndex] = IsVehicleTyreBurst(vehicle, v.index, false) and 2 or 1
end
end
local neons = {}
for i = 0, 3 do
neons[tostring(i)] = IsVehicleNeonLightEnabled(vehicle, i)
end
local plate = GetVehicleNumberPlateText(vehicle)
return {
model = GetEntityModel(vehicle),
plate = Config.TrimPlates and Lib.Trim(plate) or plate,
plateIndex = GetVehicleNumberPlateTextIndex(vehicle),
bodyHealth = math.floor(GetVehicleBodyHealth(vehicle) + 0.5),
engineHealth = math.floor(GetVehicleEngineHealth(vehicle) + 0.5),
tankHealth = math.floor(GetVehiclePetrolTankHealth(vehicle) + 0.5),
fuelLevel = math.floor(GetVehicleFuelLevel(vehicle) + 0.5),
oilLevel = math.floor(GetVehicleOilLevel(vehicle) + 0.5),
dirtLevel = math.floor(GetVehicleDirtLevel(vehicle) + 0.5),
paintType1 = paintType1,
paintType2 = paintType2,
color1 = colorPrimary,
color2 = colorSecondary,
pearlescentColor = pearlescentColor,
interiorColor = GetVehicleInteriorColor(vehicle),
dashboardColor = GetVehicleDashboardColour(vehicle),
wheelColor = wheelColor,
wheelWidth = GetVehicleWheelWidth(vehicle),
wheelSize = GetVehicleWheelSize(vehicle),
wheels = GetVehicleWheelType(vehicle),
windowTint = GetVehicleWindowTint(vehicle),
xenonColor = GetVehicleXenonLightsColor(vehicle),
customXenon = customXenon,
neonEnabled = neons,
neonColor = { GetVehicleNeonLightsColour(vehicle) },
extras = extras,
tyreSmokeColor = { GetVehicleTyreSmokeColor(vehicle) },
modSpoilers = GetVehicleMod(vehicle, 0),
modFrontBumper = GetVehicleMod(vehicle, 1),
modRearBumper = GetVehicleMod(vehicle, 2),
modSideSkirt = GetVehicleMod(vehicle, 3),
modExhaust = GetVehicleMod(vehicle, 4),
modFrame = GetVehicleMod(vehicle, 5),
modGrille = GetVehicleMod(vehicle, 6),
modHood = GetVehicleMod(vehicle, 7),
modFender = GetVehicleMod(vehicle, 8),
modRightFender = GetVehicleMod(vehicle, 9),
modRoof = GetVehicleMod(vehicle, 10),
modEngine = GetVehicleMod(vehicle, 11),
modBrakes = GetVehicleMod(vehicle, 12),
modTransmission = GetVehicleMod(vehicle, 13),
modHorns = GetVehicleMod(vehicle, 14),
modSuspension = GetVehicleMod(vehicle, 15),
modArmor = GetVehicleMod(vehicle, 16),
modNitrous = GetVehicleMod(vehicle, 17),
modTurbo = IsToggleModOn(vehicle, 18),
modSubwoofer = GetVehicleMod(vehicle, 19),
modSmokeEnabled = IsToggleModOn(vehicle, 20),
modHydraulics = IsToggleModOn(vehicle, 21),
modXenon = IsToggleModOn(vehicle, 22),
modFrontWheels = GetVehicleMod(vehicle, 23),
modBackWheels = GetVehicleMod(vehicle, 24),
modCustomTiresF = GetVehicleModVariation(vehicle, 23),
modCustomTiresR = GetVehicleModVariation(vehicle, 24),
modPlateHolder = GetVehicleMod(vehicle, 25),
modVanityPlate = GetVehicleMod(vehicle, 26),
modTrimA = GetVehicleMod(vehicle, 27),
modOrnaments = GetVehicleMod(vehicle, 28),
modDashboard = GetVehicleMod(vehicle, 29),
modDial = GetVehicleMod(vehicle, 30),
modDoorSpeaker = GetVehicleMod(vehicle, 31),
modSeats = GetVehicleMod(vehicle, 32),
modSteeringWheel = GetVehicleMod(vehicle, 33),
modShifterLeavers = GetVehicleMod(vehicle, 34),
modAPlate = GetVehicleMod(vehicle, 35),
modSpeakers = GetVehicleMod(vehicle, 36),
modTrunk = GetVehicleMod(vehicle, 37),
modHydrolic = GetVehicleMod(vehicle, 38),
modEngineBlock = GetVehicleMod(vehicle, 39),
modAirFilter = GetVehicleMod(vehicle, 40),
modStruts = GetVehicleMod(vehicle, 41),
modArchCover = GetVehicleMod(vehicle, 42),
modAerials = GetVehicleMod(vehicle, 43),
modTrimB = GetVehicleMod(vehicle, 44),
modTank = GetVehicleMod(vehicle, 45),
modWindows = GetVehicleMod(vehicle, 46),
modDoorR = GetVehicleMod(vehicle, 47),
modLivery = modLivery,
modRoofLivery = GetVehicleRoofLivery(vehicle),
modLightbar = GetVehicleMod(vehicle, 49),
vehicleWindows = vehicleWindows,
vehicleDoors = vehicleDoors,
vehicleTyres = vehicleTyres,
bulletProofTyres = GetVehicleTyresCanBurst(vehicle),
driftTyres = gameBuild >= 2372 and GetDriftTyresEnabled(vehicle),
-- no setters?
-- leftHeadlight = GetIsLeftVehicleHeadlightDamaged(vehicle),
-- rightHeadlight = GetIsRightVehicleHeadlightDamaged(vehicle),
-- frontBumper = IsVehicleBumperBrokenOff(vehicle, true),
-- rearBumper = IsVehicleBumperBrokenOff(vehicle, false),
}
end
end
---@param vehicle number
---@param props VehicleProperties
SetVehicleProperties = function(vehicle, props)
if not DoesEntityExist(vehicle) then
return
end
local colorPrimary, colorSecondary = GetVehicleColours(vehicle)
local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle)
SetVehicleModKit(vehicle, 0)
if props.extras then
for id, toggle in pairs(props.extras) do
local extraId = tonumber(id)
if type(toggle) == 'boolean' then
if toggle then
SetVehicleExtra(vehicle, extraId, 0)
else
SetVehicleExtra(vehicle, extraId, 1)
end
else
SetVehicleExtra(vehicle, extraId, toggle)
end
end
end
if props.plate then
SetVehicleNumberPlateText(vehicle, props.plate)
end
if props.plateIndex then
SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex)
end
if props.bodyHealth then
SetVehicleBodyHealth(vehicle, props.bodyHealth + 0.0)
end
if props.engineHealth then
SetVehicleEngineHealth(vehicle, props.engineHealth + 0.0)
end
if props.tankHealth then
SetVehiclePetrolTankHealth(vehicle, props.tankHealth + 0.0)
end
if props.fuelLevel then
SetVehicleFuelLevel(vehicle, props.fuelLevel + 0.0)
end
if props.oilLevel then
SetVehicleOilLevel(vehicle, props.oilLevel + 0.0)
end
if props.dirtLevel then
SetVehicleDirtLevel(vehicle, props.dirtLevel + 0.0)
end
if props.color1 then
if type(props.color1) == 'number' then
ClearVehicleCustomPrimaryColour(vehicle)
SetVehicleModColor_1(vehicle, props.paintType1, props.color1, pearlescentColor)
SetVehicleColours(vehicle, props.color1, type(props.color2) == 'number' and props.color2 or colorSecondary)
else
if props.paintType1 then
SetVehicleModColor_1(vehicle, props.paintType1, 0, pearlescentColor)
end
ClearVehicleCustomPrimaryColour(vehicle)
SetVehicleCustomPrimaryColour(vehicle, props.color1[1], props.color1[2], props.color1[3])
end
end
if props.color2 then
if type(props.color2) == 'number' then
ClearVehicleCustomSecondaryColour(vehicle)
SetVehicleModColor_2(vehicle, props.paintType2, props.color2)
SetVehicleColours(vehicle, type(props.color1) == 'number' and props.color1 or colorPrimary, props.color2)
if type(props.color1) ~= 'number' then
SetVehicleModColor_1(vehicle, props.paintType1, 0, pearlescentColor)
end
else
if props.paintType2 then
SetVehicleModColor_2(vehicle, props.paintType2, 0)
end
SetVehicleCustomSecondaryColour(vehicle, props.color2[1], props.color2[2], props.color2[3])
end
end
if props.pearlescentColor or props.wheelColor then
SetVehicleExtraColours(vehicle, props.pearlescentColor or pearlescentColor, props.wheelColor or wheelColor)
end
if props.interiorColor then
SetVehicleInteriorColor(vehicle, props.interiorColor)
end
if props.dashboardColor then
SetVehicleDashboardColor(vehicle, props.dashboardColor)
end
if props.wheels then
SetVehicleWheelType(vehicle, props.wheels)
end
if props.wheelSize then
SetVehicleWheelSize(vehicle, props.wheelSize)
end
if props.wheelWidth then
SetVehicleWheelWidth(vehicle, props.wheelWidth)
end
if props.windowTint then
SetVehicleWindowTint(vehicle, props.windowTint)
end
if props.neonEnabled then
for k,v in pairs(props.neonEnabled) do
SetVehicleNeonLightEnabled(vehicle, tonumber(k), v)
end
end
if props.vehicleWindows then
for index, state in pairs(props.vehicleWindows) do
if state == 2 then
RemoveVehicleWindow(vehicle, tonumber(index))
end
end
end
if props.vehicleDoors then
for index, state in pairs(props.vehicleDoors) do
if state == 2 then
SetVehicleDoorBroken(vehicle, tonumber(index), true)
end
end
end
if props.vehicleTyres then
for index, state in pairs(props.vehicleTyres) do
if state == 2 then
SetVehicleTyreBurst(vehicle, tonumber(index), true, 1000.0)
end
end
end
if props.neonColor then
SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3])
end
if props.modSmokeEnabled ~= nil then
ToggleVehicleMod(vehicle, 20, props.modSmokeEnabled)
end
if props.tyreSmokeColor then
SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3])
end
if props.modSpoilers then
SetVehicleMod(vehicle, 0, props.modSpoilers, false)
end
if props.modFrontBumper then
SetVehicleMod(vehicle, 1, props.modFrontBumper, false)
end
if props.modRearBumper then
SetVehicleMod(vehicle, 2, props.modRearBumper, false)
end
if props.modSideSkirt then
SetVehicleMod(vehicle, 3, props.modSideSkirt, false)
end
if props.modExhaust then
SetVehicleMod(vehicle, 4, props.modExhaust, false)
end
if props.modFrame then
SetVehicleMod(vehicle, 5, props.modFrame, false)
end
if props.modGrille then
SetVehicleMod(vehicle, 6, props.modGrille, false)
end
if props.modHood then
SetVehicleMod(vehicle, 7, props.modHood, false)
end
if props.modFender then
SetVehicleMod(vehicle, 8, props.modFender, false)
end
if props.modRightFender then
SetVehicleMod(vehicle, 9, props.modRightFender, false)
end
if props.modRoof then
SetVehicleMod(vehicle, 10, props.modRoof, false)
end
if props.modEngine then
SetVehicleMod(vehicle, 11, props.modEngine, false)
end
if props.modBrakes then
SetVehicleMod(vehicle, 12, props.modBrakes, false)
end
if props.modTransmission then
SetVehicleMod(vehicle, 13, props.modTransmission, false)
end
if props.modHorns then
SetVehicleMod(vehicle, 14, props.modHorns, false)
end
if props.modSuspension then
SetVehicleMod(vehicle, 15, props.modSuspension, false)
end
if props.modArmor then
SetVehicleMod(vehicle, 16, props.modArmor, false)
end
if props.modNitrous then
SetVehicleMod(vehicle, 17, props.modNitrous, false)
end
if props.modTurbo ~= nil then
ToggleVehicleMod(vehicle, 18, props.modTurbo)
end
if props.modSubwoofer ~= nil then
ToggleVehicleMod(vehicle, 19, props.modSubwoofer)
end
if props.modHydraulics ~= nil then
ToggleVehicleMod(vehicle, 21, props.modHydraulics)
end
if props.modXenon ~= nil then
ToggleVehicleMod(vehicle, 22, props.modXenon)
end
if props.xenonColor then
if type(props.xenonColor) == 'table' then
props.customXenon = {props.xenonColor[1], props.xenonColor[2], props.xenonColor[3]}
SetVehicleXenonLightsCustomColor(vehicle, props.customXenon[1], props.customXenon[2], props.customXenon[3])
else
ClearVehicleXenonLightsCustomColor(vehicle)
SetVehicleXenonLightsColor(vehicle, props.xenonColor)
end
end
if props.customXenon ~= nil or props.customXenonColor ~= nil then
props.customXenon = props.customXenonColor ~= nil and props.customXenonColor or props.customXenon
SetVehicleXenonLightsCustomColor(vehicle, props.customXenon[1], props.customXenon[2], props.customXenon[3])
end
if props.modFrontWheels then
SetVehicleMod(vehicle, 23, props.modFrontWheels, props.modCustomTiresF)
end
if props.modBackWheels then
SetVehicleMod(vehicle, 24, props.modBackWheels, props.modCustomTiresR)
end
if props.modPlateHolder then
SetVehicleMod(vehicle, 25, props.modPlateHolder, false)
end
if props.modVanityPlate then
SetVehicleMod(vehicle, 26, props.modVanityPlate, false)
end
if props.modTrimA then
SetVehicleMod(vehicle, 27, props.modTrimA, false)
end
if props.modOrnaments then
SetVehicleMod(vehicle, 28, props.modOrnaments, false)
end
if props.modDashboard then
SetVehicleMod(vehicle, 29, props.modDashboard, false)
end
if props.modDial then
SetVehicleMod(vehicle, 30, props.modDial, false)
end
if props.modDoorSpeaker then
SetVehicleMod(vehicle, 31, props.modDoorSpeaker, false)
end
if props.modSeats then
SetVehicleMod(vehicle, 32, props.modSeats, false)
end
if props.modSteeringWheel then
SetVehicleMod(vehicle, 33, props.modSteeringWheel, false)
end
if props.modShifterLeavers then
SetVehicleMod(vehicle, 34, props.modShifterLeavers, false)
end
if props.modAPlate then
SetVehicleMod(vehicle, 35, props.modAPlate, false)
end
if props.modSpeakers then
SetVehicleMod(vehicle, 36, props.modSpeakers, false)
end
if props.modTrunk then
SetVehicleMod(vehicle, 37, props.modTrunk, false)
end
if props.modHydrolic then
SetVehicleMod(vehicle, 38, props.modHydrolic, false)
end
if props.modEngineBlock then
SetVehicleMod(vehicle, 39, props.modEngineBlock, false)
end
if props.modAirFilter then
SetVehicleMod(vehicle, 40, props.modAirFilter, false)
end
if props.modStruts then
SetVehicleMod(vehicle, 41, props.modStruts, false)
end
if props.modArchCover then
SetVehicleMod(vehicle, 42, props.modArchCover, false)
end
if props.modAerials then
SetVehicleMod(vehicle, 43, props.modAerials, false)
end
if props.modTrimB then
SetVehicleMod(vehicle, 44, props.modTrimB, false)
end
if props.modTank then
SetVehicleMod(vehicle, 45, props.modTank, false)
end
if props.modWindows then
SetVehicleMod(vehicle, 46, props.modWindows, false)
end
if props.modDoorR then
SetVehicleMod(vehicle, 47, props.modDoorR, false)
end
if props.modLivery then
SetVehicleMod(vehicle, 48, props.modLivery, false)
SetVehicleLivery(vehicle, props.modLivery)
end
if props.modRoofLivery then
SetVehicleRoofLivery(vehicle, props.modRoofLivery)
end
if props.modLightbar then
SetVehicleMod(vehicle, 49, props.modLightbar, false)
end
if props.bulletProofTyres ~= nil then
SetVehicleTyresCanBurst(vehicle, props.bulletProofTyres)
end
if gameBuild >= 2372 and props.driftTyres ~= nil then
SetDriftTyresEnabled(vehicle, props.driftTyres)
if type(props.driftTyres) == 'boolean' and props.driftTyres == true or props.driftTyres == 1 then
SetReduceDriftVehicleSuspension(vehicle, true)
else
SetReduceDriftVehicleSuspension(vehicle, false)
end
end
end
AddStateBagChangeHandler('t1ger_lib:setVehicleProps' --[[key filter]], nil --[[bag filter]], function(bagName, key, value, _unused, replicated)
Wait(0)
if not value then
return
end
local net = tonumber(bagName:gsub('entity:', ''), 10)
local vehicle = net and NetworkGetEntityFromNetworkId(net)
if DoesEntityExist(vehicle) then
SetVehicleProperties(vehicle, value)
end
end)
Lib = {
VehicleWheels = {
['2'] = { -- Bike and cycle.
['0'] = {label = 'Wheel Front', bone = 'wheel_lf', index = 0, wheelId = 0},
['4'] = {label = 'Wheel Rear', bone = 'wheel_lr', index = 4, wheelId = 1},
},
['3'] = { -- Vehicle with 3 wheels (get for wheels because some 3 wheels vehicles have 2 wheels on front and one rear or the reverse).
['0'] = {label = 'Wheel Front (L)', bone = 'wheel_lf', index = 0, wheelId = 0},
['1'] = {label = 'Wheel Front (R)', bone = 'wheel_rf', index = 1, wheelId = 1},
['4'] = {label = 'Wheel Rear (L)', bone = 'wheel_lr', index = 4, wheelId = 2},
['5'] = {label = 'Wheel Rear (R)', bone = 'wheel_rr', index = 5, wheelId = 3},
},
['4'] = { -- Vehicle with 4 wheels.
['0'] = {label = 'Wheel Front (L)', bone = 'wheel_lf', index = 0, wheelId = 0},
['1'] = {label = 'Wheel Front (R)', bone = 'wheel_rf', index = 1, wheelId = 1},
['4'] = {label = 'Wheel Rear (L)', bone = 'wheel_lr', index = 4, wheelId = 2},
['5'] = {label = 'Wheel Rear (R)', bone = 'wheel_rr', index = 5, wheelId = 3},
},
['6'] = { -- Vehicle with 6 wheels.
['0'] = {label = 'Wheel Front (L)', bone = 'wheel_lf', index = 0, wheelId = 0},
['1'] = {label = 'Wheel Front (R)', bone = 'wheel_rf', index = 1, wheelId = 1},
['2'] = {label = 'Wheel Middle (L)', bone = 'wheel_lm1', index = 2, wheelId = 4},
['3'] = {label = 'Wheel Middle (R)', bone = 'wheel_rm1', index = 3, wheelId = 5},
['4'] = {label = 'Wheel Rear (L)', bone = 'wheel_lr', index = 4, wheelId = 2},
['5'] = {label = 'Wheel Rear (R)', bone = 'wheel_rr', index = 5, wheelId = 3},
},
['8'] = { -- Vehicle with 8 wheels.
['0'] = {label = 'Wheel Front (L)', bone = 'wheel_lf', index = 0, wheelId = 0},
['1'] = {label = 'Wheel Front (R)', bone = 'wheel_rf', index = 1, wheelId = 1},
['2'] = {label = 'Wheel Middle (L)', bone = 'wheel_lm1', index = 2, wheelId = 4},
['3'] = {label = 'Wheel Middle (R)', bone = 'wheel_rm1', index = 3, wheelId = 5},
['4'] = {label = 'Wheel Rear (L)', bone = 'wheel_lr', index = 4, wheelId = 2},
['5'] = {label = 'Wheel Rear (R)', bone = 'wheel_rr', index = 5, wheelId = 3},
},
},
VehicleDoors = {
['0'] = {label = 'Door Front (L)', bone = 'door_dside_f', bone2 = 'seat_dside_f', index = 0},
['1'] = {label = 'Door Front (R)', bone = 'door_pside_f', bone2 = 'seat_pside_f', index = 1},
['2'] = {label = 'Door Rear (L)', bone = 'door_dside_r', bone2 = 'seat_dside_r', index = 2},
['3'] = {label = 'Door Rear (R)', bone = 'door_pside_r', bone2 = 'seat_pside_r', index = 3},
['4'] = {label = 'Hood', bone = 'bonnet', index = 4},
['5'] = {label = 'Trunk', bone = 'boot', index = 5},
},
VehicleWindows = {
['0'] = {label = 'Window Front (L)', bone = 'window_lf', index = 0},
['1'] = {label = 'Window Front (R)', bone = 'window_rf', index = 1},
['2'] = {label = 'Window Rear (L)', bone = 'window_lr', index = 2},
['3'] = {label = 'Window Rear (R)', bone = 'window_rr', index = 3},
['6'] = {label = 'Windscreen Front', bone = 'windscreen', index = 6},
['7'] = {label = 'Windscreen Rear', bone = 'windscreen_r', index = 7},
},
-- Load Anim
LoadAnim = function(animDict)
RequestAnimDict(animDict); while not HasAnimDictLoaded(animDict) do Citizen.Wait(1) end
end,
-- Load Model
LoadModel = function(model)
if not HasModelLoaded(model) and IsModelInCdimage(model) then
RequestModel(model)
while not HasModelLoaded(model) do
Wait(0)
end
end
end,
-- Load Ptfx
LoadPtfxAsset = function(dict)
RequestNamedPtfxAsset(dict)
local count = 10000
while not HasNamedPtfxAssetLoaded(dict) do
Wait(1)
count = count - 1
if count <= 0 then
break
end
end
end,
-- load the textures so we can see the rope
LoadRopeTexture = function()
RopeLoadTextures()
while not RopeAreTexturesLoaded() do
Wait(0)
end
end,
-- Function to Display Help Text:
DisplayHelpText = function(str)
SetTextComponentFormat("STRING")
AddTextComponentString(str)
DisplayHelpTextFromStringLabel(0, 0, 1, -1)
end,
-- Round Fnction:
RoundNumber = function(num, numDecimalPlaces)
local mult = 10^(numDecimalPlaces or 0)
return math.floor(num * mult + 0.5) / mult
end,
-- Comma Function:
CommaValue = function(n) -- credit http://richard.warburton.it
local roundNumber = Lib.RoundNumber(n, 2)
local left,num,right = string.match(roundNumber,'^([^%d]*%d)(%d*)(.-)$')
return left..(num:reverse():gsub('(%d%d%d)','%1,'):reverse())..right..'0'
end,
GetRGBA = function(input)
local vec = lib.math.tovector(input, 0, 255, false)
return {
r = math.floor(vec[1]),
g = math.floor(vec[2]),
b = math.floor(vec[3]),
a = math.floor(vec[4] * 255)
}
end,
FormatNumber = function(amount, decimal, prefix)
local str_amount, formatted, famount, remain
decimal = decimal or 2 -- default 2 decimal places
famount = math.abs(Lib.RoundNumber(amount,decimal))
famount = math.floor(famount)
remain = Lib.RoundNumber(math.abs(amount) - famount, decimal)
formatted = Lib.CommaValue(famount)
-- attach the decimal portion
if (decimal > 0) then
remain = string.sub(tostring(remain),3)
formatted = formatted .. "." .. remain .. string.rep("0", decimal - string.len(remain))
end
-- attach prefix string e.g '$'
formatted = (prefix or "") .. formatted
return formatted
end,
FirstCharUpper = function(str)
return (str:gsub("^%l", string.upper))
end,
-- Trim (for plates especially):
Trim = function(input)
if input then
return (string.gsub(input, "^%s*(.-)%s*$", "%1"))
else
return nil
end
end,
-- Boolean to Number
BooleanToNumber = function(bool)
return bool and 1 or 0
end,
-- Draw 3D Text
Draw3DText = function(x, y, z, text)
local boolean, _x, _y = GetScreenCoordFromWorldCoord(x, y, z)
SetTextScale(0.32, 0.32); SetTextFont(4); SetTextProportional(1)
SetTextColour(255, 255, 255, 255)
SetTextEntry("STRING"); SetTextCentre(1); AddTextComponentString(text)
DrawText(_x, _y)
local factor = (string.len(text) / 500)
DrawRect(_x, (_y + 0.0125), (0.015 + factor), 0.03, 0, 0, 0, 80)
end,
-- Get Control of Entity:
GetControlOfEntity = function(entity)
local netTime = 100
NetworkRequestControlOfEntity(entity)
while not NetworkHasControlOfEntity(entity) and netTime > 0 do
NetworkRequestControlOfEntity(entity)
Wait(1)
netTime = (netTime - 1)
end
end,
-- Standard Notification:
Notification = function(data)
if Config.UseFrameworkNotification then
Core.Notification(data.message)
else
lib.notify({
title = data.title,
description = data.message,
type = data.type,
position = 'top',
})
end
end,
-- Advanced Notification:
AdvancedNotification = function(textureDict, textureName, iconType, title, showInBrief, subtitle, message)
RequestStreamedTextureDict(textureDict)
BeginTextCommandThefeedPost("STRING")
AddTextComponentSubstringPlayerName(message)
EndTextCommandThefeedPostMessagetext(textureDict, textureName, false, iconType, title, subtitle)
EndTextCommandThefeedPostTicker(false, showInBrief)
end,
PoliceNotification = function(coords, street, data)
lib.notify({
title = data.title,
description = data.description,
duration = data.duration,
position = data.position,
type = data.type,
icon = data.icon,
})
end,
TriggerPoliceNotification = function(coords, street, data)
if Config.PoliceNotification == 'default' then
TriggerServerEvent('t1ger_lib:server:policeNotification', coords, street, data)
elseif Config.PoliceNotification == 'cd_' then
local cd_playerInfo = exports['cd_dispatch']:GetPlayerInfo()
local policeJobs = {}
for k,v in pairs(Config.PoliceJobs) do
table.insert(policeJobs, k)
end
TriggerServerEvent('cd_dispatch:AddNotification', {
job_table = policeJobs,
coords = cd_playerInfo.coords,
title = data.title,
message = data.description,
flash = 0,
unique_id = cd_playerInfo.unique_id,
sound = 1,
blip = {
sprite = 431,
scale = 1.2,
colour = 3,
flashes = false,
text = data.blipText,
time = 5,
radius = 0,
}
})
elseif Config.PoliceNotification == 'custom' then
-- coords (player coords)
-- street (street name )
-- data (table) containing: title, description, blipText, duration, position, type, icon
-- to fetch other values inside the table, u need to find the TriggerPoliceNotification functions inside the resources and alter it there.
-- add your own police event etc in here.
end
end,
CreateObject = function(object, coords, heading, cb, networked)
networked = networked == nil and true or networked
if networked then
Core.TriggerCallback('t1ger_lib:server:createObject', function(networkId)
if cb then
local obj = NetworkGetEntityFromNetworkId(networkId)
local attempts = 0
while not DoesEntityExist(obj) do
obj = NetworkGetEntityFromNetworkId(networkId)
Wait(0)
attempts = attempts + 1
if attempts > 100 then
break
end
end
cb(obj, networkId)
end
end, object, coords, heading)
else
local model = type(object) == 'number' and object or joaat(object)
local vector = type(coords) == "vector3" and coords or vec(coords.x, coords.y, coords.z)
Lib.LoadModel(model)
local obj = CreateObject(model, vector.xyz, networked, false, true)
if cb then
cb(obj)
end
end
end,
NetworkGetEntity = function(netId)
local entity = NetworkGetEntityFromNetworkId(netId)
local attempts = 0
while not DoesEntityExist(entity) do
entity = NetworkGetEntityFromNetworkId(netId)
Wait(0)
attempts = attempts + 1
if attempts > 100 then
break
end
end
return entity, attempts
end,
IsPlayerInsideVehicle = function(player)
if IsPedInAnyVehicle(player, false) then
local vehicle = GetVehiclePedIsIn(player, false)
if vehicle ~= nil or vehicle ~= 0 then
return true
else
return false
end
end
end,
GetClosestVehicle = function(coords, maxDistance, includePlayerVehicle)
local vehicles = GetGamePool('CVehicle')
local closestVehicle, closestCoords
maxDistance = maxDistance or 2.0
for i = 1, #vehicles do
local vehicle = vehicles[i]
if not cache.vehicle or vehicle ~= cache.vehicle or includePlayerVehicle then
local vehicleCoords = GetEntityCoords(vehicle)
local distance = #(coords - vehicleCoords)
if distance < maxDistance then
maxDistance = distance
closestVehicle = vehicle
closestCoords = vehicleCoords
end
end
end
return closestVehicle, closestCoords
end,
GetVehicleInDirection = function(pos)
local ped = PlayerPedId()
local plyCoords = pos or GetEntityCoords(ped)
local direction = GetOffsetFromEntityInWorldCoords(ped, 0.0, 5.0, 0.0)
local rayHandle = StartExpensiveSynchronousShapeTestLosProbe(plyCoords, direction, 10, ped, 0)
local numRayHandle, hit, endCoords, surfaceNormal, entityHit = GetShapeTestResult(rayHandle)
if hit == 1 and GetEntityType(entityHit) == 2 then
local entityCoords = GetEntityCoords(entityHit)
return entityHit, entityCoords
end
return nil
end,
GetClosestPlayer = function(coords)
return Lib.GetClosestEntity(Lib.GetPlayers(true, true), true, coords, nil)
end,
GetPlayersInArea = function(coords, maxDistance)
return Lib.EnumerateEntitiesWithinDistance(Lib.GetPlayers(true, true), true, coords, maxDistance)
end,
GetPlayers = function(onlyOtherPlayers, returnKeyValue, returnPeds)
local players, myPlayer = {}, PlayerId()
for k, player in ipairs(GetActivePlayers()) do
local ped = GetPlayerPed(player)
if DoesEntityExist(ped) and ((onlyOtherPlayers and player ~= myPlayer) or not onlyOtherPlayers) then
if returnKeyValue then
players[player] = ped
else
players[#players + 1] = returnPeds and ped or player
end
end
end
return players
end,
GetClosestPlayer2 = function(coords, maxDistance, includePlayer)
local players = GetActivePlayers()
local closestId, closestPed, closestCoords
maxDistance = maxDistance or 2.0
for i = 1, #players do
local playerId = players[i]
if playerId ~= PlayerId() or includePlayer then
local playerPed = GetPlayerPed(playerId)
local playerCoords = GetEntityCoords(playerPed)
local distance = #(coords - playerCoords)
if distance < maxDistance then
maxDistance = distance
closestId = playerId
closestPed = playerPed
closestCoords = playerCoords
end
end
end
return closestId, closestPed, closestCoords
end,
GetClosestEntity = function(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 k, entity in pairs(entities) do
if modelFilter[GetEntityModel(entity)] then
filteredEntities[#filteredEntities + 1] = entity
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,
EnumerateEntitiesWithinDistance = function(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,
KeybindToString = function(input)
local keybindString = GetControlInstructionalButton(0, input, true):gsub('t_', '')
return keybindString
end,
IsEntityValid = function(entity)
if not entity or entity == -1 then
return false
end
return DoesEntityExist(entity)
end,
IsVehicleLocked = function(vehEntity)
if Config.VehicleKeys == 'default' then
local lockedStatus = GetVehicleDoorLockStatus(vehEntity)
if lockedStatus == 1 or lockedStatus == 0 then
return false
elseif lockedStatus == 2 or lockedStatus == 10 then
return true
end
elseif Config.VehicleKeys == 't1ger-keys' then
local lockedStatus = exports['t1ger_keys']:GetVehicleLockedStatus(vehEntity)
if lockedStatus == 1 or lockedStatus == 0 then
return false
elseif lockedStatus == 2 or lockedStatus == 10 then
return true
end
elseif Config.VehicleKeys == 'custom' then
local doorstate = exports["qs-vehiclekeys"]:GetDoorState(vehEntity)
if doorstate == 1 or doorstate == 0 then
return false
elseif doorstatus == 2 or doorstatus == 10 then
return true
end
end
end,
}
RegisterNetEvent('t1ger_lib:utils:notification')
AddEventHandler('t1ger_lib:utils:notification', function(msg)
Lib.Notification(msg)
end)
RegisterNetEvent('t1ger_lib:utils:policeNotification')
AddEventHandler('t1ger_lib:utils:policeNotification', function(coords, street, msg)
Lib.PoliceNotification(coords, street, msg)
end)
-- FOR SUPPORT: https://discord.gg/FdHkq5q
------------------------------------------
Config = {}
Config.Debug = false -- boolean | true enables debug prints, setting to false disables debug prints
-- Framework Triggers:
Config.Triggers = { -- Triggers to update if you've changed them or if your anticheat requires it:
['ESX'] = { -- update your triggers/event-names here if changed:
resource = 'es_extended', -- esx resource name
obj = 'esx:getSharedObject',
load = 'esx:playerLoaded',
job = 'esx:setJob'
},
['QB'] = { -- update your triggers/event-names here if changed:
resource = 'qb-core', -- qb-core resource name
obj = 'QBCore:GetObject',
load = 'QBCore:Client:OnPlayerLoaded',
job = 'QBCore:Client:OnJobUpdate',
uObjCL = 'QBCore:Client:UpdateObject',
uObjSV = 'QBCore:Server:UpdateObject',
dutyToggle = 'QBCore:ToggleDuty',
},
} -- Do not delete anything from here!!!
-- Specify which custom inventory system you are using!
Config.Inventory = 'qs-inventory' --[[
'ox-inventory' - ox_inventory (free): https://github.com/overextended/ox_inventory
'qb-inventory' - qb-inventory (free): https://docs.qbcore.org/qbcore-documentation/qbcore-resources/qb-inventory
'mf-inventory' - modfreakz inventory (paid)
'qs-inventory' - quasar inventory (paid)
'core-inventory' - core inventory (paid)
'codem-inventory' - codeM inventory (paid)
'custom' - custom inventory, your own implementation!!
]]
-- Specify which target system you are using!
Config.TargetSystem = 'qb-target' --[[
'ox-target' - ox_target (free): https://github.com/overextended/ox_target
'qb-target' - qb_target (free): https://github.com/qbcore-framework/qb-target
'meta-target' - meta_target (free): https://github.com/meta-hub/meta_target
'custom' - custom inventory, your own implementation!!
]]
Config.Garage = 'qs-advancedgarages' --[[ only support the below garage systems, please leave this at 'default' else.
'default' - default esx_garage or default qb_garages
't1ger-garage' - T1GER Garage: https://youtu.be/7qgiFW0Qi2Q
'cd-garage' - Codesign Garage: https://docs.codesign.pro/paid-scripts/garage
'renzu-garage' - Renzu Garage: https://github.com/renzuzu/renzu_garage
'jg-advancedgarages' - JG Advanced Garages: https://docs.jgscripts.com/advanced-garages/
'rcore-garage' - rCore Garage: https://documentation.rcore.cz/paid-resources/rcore_garage
'okok-garage' - OkOk Garage: https://docs.okokscripts.io/scripts/okokgarage
'codeM-garage' - CodeM mGarage: https://codem.gitbook.io/codem-documentation/m-series/mgarage
'qs-advancedgarages' - Quasar Advanced Garages: https://docs.quasar-store.com/assets-and-guides/advanced-garages
'custom' - custom inventory, your own implementation!!
]]
Config.SocietyAccount = 'qb-management' --[[ -- only support the below society systems.
'esx_addonaccount' - https://github.com/esx-framework/esx_addonaccount
'qb-banking' - https://docs.qbcore.org/qbcore-documentation/qbcore-resources/qb-banking
'qb-management' - https://docs.qbcore.org/qbcore-documentation/qbcore-resources/qb-management
'renewed-banking' - https://github.com/Renewed-Scripts/Renewed-Banking
'custom' - you need to modify functions yourself!!!
]]
Config.TrimPlates = true -- trimplates is default in ESX/QBCore inside vehicle props.
Config.PoliceJobs = {['police'], ['lspd']} -- whitelisted police jobs to fetch online police count
Config.PoliceNotification = 'default' -- 'default' is builtIn police alerts, 'cd_' for codesign, 'custom' to use another (implement function inside TriggerPoliceNotification in t1ger_lib/utils.lua)
Config.AcePermissions = {'command'} -- (command is default gives admin access to all commands) add your ace permissions in here, used to check if player has perms/admin.
Config.UseFrameworkNotification = true -- Use default ESX/QB notification or use your own custom from Lib.Notification
Config.VehicleKeys = 'custom' -- use 'default' or 't1ger-keys' or 'custom'. default natives to check locked/unlocked or t1ger_keys exports or custom (your own).
Config.VehiclePrice = 'auto' --[[ -- select one of the options below
If using default esx vehicles table or default qb/shared/vehicles.lua then leave it at auto.
If using custom database table/columns or if using custom lua file for vehicles, then go to server/framework.lua and find the function CreateCoreVehicles and update the values
'auto' - set this to automatically set database if esx or lua if qbcore
'database' - set this if your vehicle prices are stored in a database table
'lua' - set this if your vehicle prices are stored in a lua file, for example qb/shared/vehicles.lua
'handling' - set this if you are GOAT and if your vehicle prices are stored in the vehicle's handling.meta file
]]
Config.VehicleMeta = {Props = { ['mileage'] = true, ['service'] = true, ['health'] = true }} -- do not touch!
Framework = GetResourceState(Config.Triggers['QB'].resource):find('started') and 'QB' or GetResourceState(Config.Triggers['ESX'].resource):find('started') and 'ESX'
Player_Vehicles_DB = {}
if not Framework then
error('Unable to determine framework, resource was renamed.')
else
print("Detected Framework: "..Framework)
if Framework == 'ESX' then
ESX = exports[Config.Triggers[Framework].resource]:getSharedObject()
Player_Vehicles_DB = {table = 'owned_vehicles', owner = 'owner', stored = 'stored', props = 'vehicle', garage = 'parking'}
if Config.VehiclePrice == 'auto' then
Config.VehiclePrice = 'database'
end
elseif Framework == 'QB' then
QBCore = exports[Config.Triggers[Framework].resource]:GetCoreObject()
Player_Vehicles_DB = {table = 'player_vehicles', owner = 'citizenid', stored = 'state', props = 'mods', garage = 'garage'}
if Config.VehiclePrice == 'auto' then
Config.VehiclePrice = 'lua'
end
end
if next(Player_Vehicles_DB) then
if Config.Garage == 't1ger-garage' then
Player_Vehicles_DB.stored = 'state'
Player_Vehicles_DB.garage = 'garage'
elseif Config.Garage == 'cd-garage' then
Player_Vehicles_DB.stored = 'in_garage'
Player_Vehicles_DB.garage = 'garage_id'
elseif Config.Garage == 'renzu-garage' then
Player_Vehicles_DB.stored = 'stored'
Player_Vehicles_DB.garage = 'garage_id'
elseif Config.Garage == 'jg-advancedgarages' then
Player_Vehicles_DB.stored = 'in_garage'
Player_Vehicles_DB.garage = 'garage_id'
elseif Config.Garage == 'rcore-garage' then
Player_Vehicles_DB.stored = 'stored'
Player_Vehicles_DB.garage = 'stored_in_garage'
elseif Config.Garage == 'codeM-garage' then
Player_Vehicles_DB.stored = 'stored'
Player_Vehicles_DB.garage = 'parking'
elseif Config.Garage == 'qs-advancedgarages' then
Player_Vehicles_DB.garage = 'garage'
end
end
end
function GetLib()
return Core, Config, Framework
end
function GetUtils()
return Lib
end
fx_version 'cerulean'
games {'gta5'}
lua54 "yes"
author 'T1GER#9080'
discord 'https://discord.gg/FdHkq5q'
description 'T1GER Library'
version '2.6.2'
documentation 'https://docs.t1ger.net/resources/t1ger-library/'
dependency 'ox_lib'
shared_scripts {
'@ox_lib/init.lua',
'config.lua'
}
client_scripts {
'client/framework.lua',
'client/utils.lua',
'client/modules/*.lua',
'client/minigames/*.lua'
}
server_scripts {
'@mysql-async/lib/MySQL.lua',
'server/framework.lua',
'server/utils.lua',
'server/modules/*.lua',
--[[server.lua]]
}
exports {
'GetLib',
'GetUtils'
}
server_exports {
'GetLib',
'GetUtils',
'CreateVehicleMeta'
}
escrow_ignore {
'config.lua',
'client/modules/*.lua',
'client/minigames/*.lua',
'client/framework.lua',
'client/utils.lua',
'server/modules/*.lua',
'server/framework.lua',
'server/utils.lua'
}
dependency '/assetpacks'