Scripts/resources/[qb]/[qb_core]/qb-target/client.lua

1143 lines
33 KiB
Lua
Raw Normal View History

2024-12-29 20:03:28 +00:00
local GetEntityCoords = GetEntityCoords
local Wait = Wait
local IsDisabledControlPressed = IsDisabledControlPressed
local GetEntityBoneIndexByName = GetEntityBoneIndexByName
local GetWorldPositionOfEntityBone = GetWorldPositionOfEntityBone
local SetPauseMenuActive = SetPauseMenuActive
local DisableAllControlActions = DisableAllControlActions
local EnableControlAction = EnableControlAction
local NetworkGetEntityIsNetworked = NetworkGetEntityIsNetworked
local NetworkGetNetworkIdFromEntity = NetworkGetNetworkIdFromEntity
local GetEntityModel = GetEntityModel
local IsPedAPlayer = IsPedAPlayer
local GetEntityType = GetEntityType
local PlayerPedId = PlayerPedId
local GetShapeTestResult = GetShapeTestResult
local StartShapeTestLosProbe = StartShapeTestLosProbe
local SetDrawOrigin = SetDrawOrigin
local DrawSprite = DrawSprite
local ClearDrawOrigin = ClearDrawOrigin
local HasStreamedTextureDictLoaded = HasStreamedTextureDictLoaded
local RequestStreamedTextureDict = RequestStreamedTextureDict
local currentResourceName = GetCurrentResourceName()
local Config, Types, Players, Entities, Models, Zones, nuiData, sendData, sendDistance = Config, {{}, {}, {}}, {}, {}, {}, {}, {}, {}, {}
local playerPed, targetActive, hasFocus, success, pedsReady, allowTarget = PlayerPedId(), false, false, false, false, true
local screen = {}
local table_wipe = table.wipe
local pairs = pairs
local CheckOptions
local Bones = Load('bones')
local listSprite = {}
---------------------------------------
--- Source: https://github.com/citizenfx/lua/blob/luaglm-dev/cfx/libs/scripts/examples/scripting_gta.lua
--- Credits to gottfriedleibniz
local glm = require 'glm'
-- Cache common functions
local glm_rad = glm.rad
local glm_quatEuler = glm.quatEulerAngleZYX
local glm_rayPicking = glm.rayPicking
-- Cache direction vectors
local glm_up = glm.up()
local glm_forward = glm.forward()
local function ScreenPositionToCameraRay()
local pos = GetFinalRenderedCamCoord()
local rot = glm_rad(GetFinalRenderedCamRot(2))
local q = glm_quatEuler(rot.z, rot.y, rot.x)
return pos, glm_rayPicking(
q * glm_forward,
q * glm_up,
glm_rad(screen.fov),
screen.ratio,
0.10000, -- GetFinalRenderedCamNearClip(),
10000.0, -- GetFinalRenderedCamFarClip(),
0, 0
)
end
---------------------------------------
-- Functions
local function DrawTarget()
CreateThread(function()
while not HasStreamedTextureDictLoaded("shared") do Wait(10) RequestStreamedTextureDict("shared", true) end
local sleep
local r, g, b, a
while targetActive do
sleep = 500
for _, zone in pairs(listSprite) do
sleep = 0
r = zone.targetoptions.drawColor?[1] or Config.DrawColor[1]
g = zone.targetoptions.drawColor?[2] or Config.DrawColor[2]
b = zone.targetoptions.drawColor?[3] or Config.DrawColor[3]
a = zone.targetoptions.drawColor?[4] or Config.DrawColor[4]
if zone.success then
r = zone.targetoptions.successDrawColor?[1] or Config.SuccessDrawColor[1]
g = zone.targetoptions.successDrawColor?[2] or Config.SuccessDrawColor[2]
b = zone.targetoptions.successDrawColor?[3] or Config.SuccessDrawColor[3]
a = zone.targetoptions.successDrawColor?[4] or Config.SuccessDrawColor[4]
end
SetDrawOrigin(zone.center.x, zone.center.y, zone.center.z, 0)
DrawSprite("shared", "emptydot_32", 0, 0, 0.02, 0.035, 0, r, g, b, a)
ClearDrawOrigin()
end
Wait(sleep)
end
listSprite = {}
end)
end
local function RaycastCamera(flag, playerCoords)
if not playerPed then playerPed = PlayerPedId() end
if not playerCoords then playerCoords = GetEntityCoords(playerPed) end
local rayPos, rayDir = ScreenPositionToCameraRay()
local destination = rayPos + 10000 * rayDir
local rayHandle = StartShapeTestLosProbe(rayPos.x, rayPos.y, rayPos.z, destination.x, destination.y, destination.z, flag or -1, playerPed, 0)
while true do
local result, _, endCoords, _, entityHit = GetShapeTestResult(rayHandle)
if result ~= 1 then
local distance = playerCoords and #(playerCoords - endCoords)
return endCoords, distance, entityHit, entityHit and GetEntityType(entityHit) or 0
end
Wait(0)
end
end
exports('RaycastCamera', RaycastCamera)
local function DisableNUI()
SetNuiFocus(false, false)
SetNuiFocusKeepInput(false)
hasFocus = false
end
exports('DisableNUI', DisableNUI)
local function EnableNUI(options)
if not targetActive or hasFocus then return end
SetCursorLocation(0.5, 0.5)
SetNuiFocus(true, true)
SetNuiFocusKeepInput(true)
hasFocus = true
SendNUIMessage({response = "validTarget", data = options})
end
exports('EnableNUI', EnableNUI)
local function LeftTarget()
SetNuiFocus(false, false)
SetNuiFocusKeepInput(false)
success, hasFocus = false, false
table_wipe(sendData)
SendNUIMessage({response = "leftTarget"})
end
exports('LeftTarget', LeftTarget)
local function DisableTarget(forcedisable)
if (not targetActive and hasFocus and not Config.Toggle) or not forcedisable then return end
SetNuiFocus(false, false)
SetNuiFocusKeepInput(false)
Wait(100)
targetActive, success, hasFocus = false, false, false
SendNUIMessage({response = "closeTarget"})
end
exports('DisableTarget', DisableTarget)
local function DrawOutlineEntity(entity, bool)
if not Config.EnableOutline or IsEntityAPed(entity) then return end
SetEntityDrawOutline(entity, bool)
SetEntityDrawOutlineColor(Config.OutlineColor[1], Config.OutlineColor[2], Config.OutlineColor[3], Config.OutlineColor[4])
end
exports('DrawOutlineEntity', DrawOutlineEntity)
local function SetupOptions(datatable, entity, distance, isZone)
if not isZone then table_wipe(sendDistance) end
table_wipe(nuiData)
local slot = 0
for _, data in pairs(datatable) do
if CheckOptions(data, entity, distance) then
slot = data.num or slot + 1
sendData[slot] = data
sendData[slot].entity = entity
nuiData[slot] = {
icon = data.icon,
targeticon = data.targeticon,
label = data.label
}
if not isZone then
sendDistance[data.distance] = true
end
else
if not isZone then
sendDistance[data.distance] = false
end
end
end
return slot
end
exports('SetupOptions', SetupOptions)
local function CheckEntity(flag, datatable, entity, distance)
if not next(datatable) then return end
local slot = SetupOptions(datatable, entity, distance)
if not next(nuiData) then
LeftTarget()
DrawOutlineEntity(entity, false)
return
end
success = true
SendNUIMessage({response = "foundTarget", data = nuiData[slot].targeticon})
DrawOutlineEntity(entity, true)
while targetActive and success do
local _, dist, entity2 = RaycastCamera(flag)
if entity ~= entity2 then
LeftTarget()
DrawOutlineEntity(entity, false)
break
elseif not hasFocus and IsDisabledControlPressed(0, Config.MenuControlKey) then
EnableNUI(nuiData)
DrawOutlineEntity(entity, false)
else
for k, v in pairs(sendDistance) do
if v and dist > k then
LeftTarget()
DrawOutlineEntity(entity, false)
break
end
end
end
Wait(0)
end
LeftTarget()
DrawOutlineEntity(entity, false)
end
exports('CheckEntity', CheckEntity)
local function CheckBones(coords, entity, bonelist)
local closestBone = -1
local closestDistance = 20
local closestPos, closestBoneName
for _, v in pairs(bonelist) do
if Bones.Options[v] then
local boneId = GetEntityBoneIndexByName(entity, v)
local bonePos = GetWorldPositionOfEntityBone(entity, boneId)
local distance = #(coords - bonePos)
if closestBone == -1 or distance < closestDistance then
closestBone, closestDistance, closestPos, closestBoneName = boneId, distance, bonePos, v
end
end
end
if closestBone ~= -1 then return closestBone, closestPos, closestBoneName
else return false end
end
exports('CheckBones', CheckBones)
local function EnableTarget()
if not allowTarget or success or (not Config.Standalone and not LocalPlayer.state['isLoggedIn']) or IsNuiFocused() or (Config.DisableInVehicle and IsPedInAnyVehicle(playerPed or PlayerPedId(), false)) then return end
if not CheckOptions then CheckOptions = _ENV.CheckOptions end
if targetActive or not CheckOptions then return end
targetActive = true
playerPed = PlayerPedId()
screen.ratio = GetAspectRatio(true)
screen.fov = GetFinalRenderedCamFov()
if Config.DrawSprite then DrawTarget() end
SendNUIMessage({response = "openTarget"})
CreateThread(function()
repeat
SetPauseMenuActive(false)
DisableAllControlActions(0)
EnableControlAction(0, 30, true)
EnableControlAction(0, 31, true)
if not hasFocus then
EnableControlAction(0, 1, true)
EnableControlAction(0, 2, true)
end
Wait(0)
until not targetActive
end)
local flag
while targetActive do
local sleep = 0
if flag == 30 then flag = -1 else flag = 30 end
local coords, distance, entity, entityType = RaycastCamera(flag)
if distance <= Config.MaxDistance then
if entityType > 0 then
-- Local(non-net) entity targets
if Entities[entity] then
CheckEntity(flag, Entities[entity], entity, distance)
end
-- Owned entity targets
if NetworkGetEntityIsNetworked(entity) then
local data = Entities[NetworkGetNetworkIdFromEntity(entity)]
if data then CheckEntity(flag, data, entity, distance) end
end
-- Player and Ped targets
if entityType == 1 then
local data = Models[GetEntityModel(entity)]
if IsPedAPlayer(entity) then data = Players end
if data and next(data) then CheckEntity(flag, data, entity, distance) end
-- Vehicle bones and models
elseif entityType == 2 then
local closestBone, _, closestBoneName = CheckBones(coords, entity, Bones.Vehicle)
local datatable = Bones.Options[closestBoneName]
if datatable and next(datatable) and closestBone then
local slot = SetupOptions(datatable, entity, distance)
if next(nuiData) then
success = true
SendNUIMessage({response = "foundTarget", data = nuiData[slot].targeticon})
DrawOutlineEntity(entity, true)
while targetActive and success do
local _, dist, entity2 = RaycastCamera(flag)
if entity == entity2 then
local closestBone2 = CheckBones(coords, entity, Bones.Vehicle)
if closestBone ~= closestBone2 then
LeftTarget()
DrawOutlineEntity(entity, false)
break
elseif not hasFocus and IsDisabledControlPressed(0, Config.MenuControlKey) then
EnableNUI(nuiData)
DrawOutlineEntity(entity, false)
else
for k, v in pairs(sendDistance) do
if v and dist > k then
LeftTarget()
DrawOutlineEntity(entity, false)
break
end
end
end
else
LeftTarget()
DrawOutlineEntity(entity, false)
break
end
Wait(0)
end
LeftTarget()
DrawOutlineEntity(entity, false)
end
end
-- Vehicle model targets
local data = Models[GetEntityModel(entity)]
if data then CheckEntity(flag, data, entity, distance) end
-- Entity targets
elseif entityType > 2 then
local data = Models[GetEntityModel(entity)]
if data then CheckEntity(flag, data, entity, distance) end
end
-- Generic targets
if not success then
local data = Types[entityType]
if data and next(data) then CheckEntity(flag, data, entity, distance) end
end
else sleep += 20 end
if not success then
-- Zone targets
local closestDis, closestZone
for k, zone in pairs(Zones) do
if distance < (closestDis or Config.MaxDistance) and distance <= zone.targetoptions.distance and zone:isPointInside(coords) then
closestDis = distance
closestZone = zone
end
if Config.DrawSprite then
if #(coords - zone.center) < (zone.targetoptions.drawDistance or Config.DrawDistance) then
listSprite[k] = zone
else
listSprite[k] = nil
end
end
end
if closestZone then
local slot = SetupOptions(closestZone.targetoptions.options, entity, distance, true)
if next(nuiData) then
success = true
SendNUIMessage({response = "foundTarget", data = nuiData[slot].targeticon})
if Config.DrawSprite then
listSprite[closestZone.name].success = true
end
DrawOutlineEntity(entity, true)
while targetActive and success do
local newCoords, dist = RaycastCamera(flag)
if not closestZone:isPointInside(newCoords) or dist > closestZone.targetoptions.distance then
LeftTarget()
DrawOutlineEntity(entity, false)
break
elseif not hasFocus and IsDisabledControlPressed(0, Config.MenuControlKey) then
EnableNUI(nuiData)
DrawOutlineEntity(entity, false)
end
Wait(0)
end
if Config.DrawSprite and listSprite[closestZone.name] then -- Check for when the targetActive is false and it removes the zone from listSprite
listSprite[closestZone.name].success = false
end
LeftTarget()
DrawOutlineEntity(entity, false)
end
else sleep += 20 end
else LeftTarget() DrawOutlineEntity(entity, false) end
else sleep += 20 end
Wait(sleep)
end
DisableTarget(false)
end
local function AddCircleZone(name, center, radius, options, targetoptions)
local centerType = type(center)
center = (centerType == 'table' or centerType == 'vector4') and vec3(center.x, center.y, center.z) or center
Zones[name] = CircleZone:Create(center, radius, options)
targetoptions.distance = targetoptions.distance or Config.MaxDistance
Zones[name].targetoptions = targetoptions
return Zones[name]
end
exports("AddCircleZone", AddCircleZone)
local function AddBoxZone(name, center, length, width, options, targetoptions)
local centerType = type(center)
center = (centerType == 'table' or centerType == 'vector4') and vec3(center.x, center.y, center.z) or center
Zones[name] = BoxZone:Create(center, length, width, options)
targetoptions.distance = targetoptions.distance or Config.MaxDistance
Zones[name].targetoptions = targetoptions
return Zones[name]
end
exports("AddBoxZone", AddBoxZone)
local function AddPolyZone(name, points, options, targetoptions)
local _points = {}
local pointsType = type(points[1])
if pointsType == 'table' or pointsType == 'vector3' or pointsType == 'vector4' then
for i = 1, #points do
_points[i] = vec2(points[i].x, points[i].y)
end
end
Zones[name] = PolyZone:Create(#_points > 0 and _points or points, options)
targetoptions.distance = targetoptions.distance or Config.MaxDistance
Zones[name].targetoptions = targetoptions
return Zones[name]
end
exports("AddPolyZone", AddPolyZone)
local function AddComboZone(zones, options, targetoptions)
Zones[options.name] = ComboZone:Create(zones, options)
targetoptions.distance = targetoptions.distance or Config.MaxDistance
Zones[options.name].targetoptions = targetoptions
return Zones[options.name]
end
exports("AddComboZone", AddComboZone)
local function AddEntityZone(name, entity, options, targetoptions)
Zones[name] = EntityZone:Create(entity, options)
targetoptions.distance = targetoptions.distance or Config.MaxDistance
Zones[name].targetoptions = targetoptions
return Zones[name]
end
exports("AddEntityZone", AddEntityZone)
local function RemoveZone(name)
if not Zones[name] then return end
if Zones[name].destroy then Zones[name]:destroy() end
Zones[name] = nil
end
exports("RemoveZone", RemoveZone)
local function SetOptions(tbl, distance, options)
for _, v in pairs(options) do
if v.required_item then
v.item = v.required_item
v.required_item = nil
end
if not v.distance or v.distance > distance then v.distance = distance end
tbl[v.label] = v
end
end
exports("SetOptions", SetOptions)
local function AddTargetBone(bones, parameters)
local distance, options = parameters.distance or Config.MaxDistance, parameters.options
if type(bones) == 'table' then
for _, bone in pairs(bones) do
if not Bones.Options[bone] then Bones.Options[bone] = {} end
SetOptions(Bones.Options[bone], distance, options)
end
elseif type(bones) == 'string' then
if not Bones.Options[bones] then Bones.Options[bones] = {} end
SetOptions(Bones.Options[bones], distance, options)
end
end
exports("AddTargetBone", AddTargetBone)
local function RemoveTargetBone(bones, labels)
if type(bones) == 'table' then
for _, bone in pairs(bones) do
if type(labels) == 'table' then
for _, v in pairs(labels) do
if Bones.Options[bone] then
Bones.Options[bone][v] = nil
end
end
elseif type(labels) == 'string' then
if Bones.Options[bone] then
Bones.Options[bone][labels] = nil
end
end
end
else
if type(labels) == 'table' then
for _, v in pairs(labels) do
if Bones.Options[bones] then
Bones.Options[bones][v] = nil
end
end
elseif type(labels) == 'string' then
if Bones.Options[bones] then
Bones.Options[bones][labels] = nil
end
end
end
end
exports("RemoveTargetBone", RemoveTargetBone)
local function AddTargetEntity(entities, parameters)
local distance, options = parameters.distance or Config.MaxDistance, parameters.options
if type(entities) == 'table' then
for _, entity in pairs(entities) do
if NetworkGetEntityIsNetworked(entity) then entity = NetworkGetNetworkIdFromEntity(entity) end -- Allow non-networked entities to be targeted
if not Entities[entity] then Entities[entity] = {} end
SetOptions(Entities[entity], distance, options)
end
elseif type(entities) == 'number' then
if NetworkGetEntityIsNetworked(entities) then entities = NetworkGetNetworkIdFromEntity(entities) end -- Allow non-networked entities to be targeted
if not Entities[entities] then Entities[entities] = {} end
SetOptions(Entities[entities], distance, options)
end
end
exports("AddTargetEntity", AddTargetEntity)
local function RemoveTargetEntity(entities, labels)
if type(entities) == 'table' then
for _, entity in pairs(entities) do
if NetworkGetEntityIsNetworked(entity) then entity = NetworkGetNetworkIdFromEntity(entity) end -- Allow non-networked entities to be targeted
if type(labels) == 'table' then
for k, v in pairs(labels) do
if Entities[entity] then
Entities[entity][v] = nil
end
end
elseif type(labels) == 'string' then
if Entities[entity] then
Entities[entity][labels] = nil
end
end
end
elseif type(entities) == 'number' then
if NetworkGetEntityIsNetworked(entities) then entities = NetworkGetNetworkIdFromEntity(entities) end -- Allow non-networked entities to be targeted
if type(labels) == 'table' then
for _, v in pairs(labels) do
if Entities[entities] then
Entities[entities][v] = nil
end
end
elseif type(labels) == 'string' then
if Entities[entities] then
Entities[entities][labels] = nil
end
end
end
end
exports("RemoveTargetEntity", RemoveTargetEntity)
local function AddTargetModel(models, parameters)
local distance, options = parameters.distance or Config.MaxDistance, parameters.options
if type(models) == 'table' then
for _, model in pairs(models) do
if type(model) == 'string' then model = joaat(model) end
if not Models[model] then Models[model] = {} end
SetOptions(Models[model], distance, options)
end
else
if type(models) == 'string' then models = joaat(models) end
if not Models[models] then Models[models] = {} end
SetOptions(Models[models], distance, options)
end
end
exports("AddTargetModel", AddTargetModel)
local function RemoveTargetModel(models, labels)
if type(models) == 'table' then
for _, model in pairs(models) do
if type(model) == 'string' then model = joaat(model) end
if type(labels) == 'table' then
for k, v in pairs(labels) do
if Models[model] then
Models[model][v] = nil
end
end
elseif type(labels) == 'string' then
if Models[model] then
Models[model][labels] = nil
end
end
end
else
if type(models) == 'string' then models = joaat(models) end
if type(labels) == 'table' then
for k, v in pairs(labels) do
if Models[models] then
Models[models][v] = nil
end
end
elseif type(labels) == 'string' then
if Models[models] then
Models[models][labels] = nil
end
end
end
end
exports("RemoveTargetModel", RemoveTargetModel)
local function AddGlobalType(type, parameters)
local distance, options = parameters.distance or Config.MaxDistance, parameters.options
SetOptions(Types[type], distance, options)
end
exports("AddGlobalType", AddGlobalType)
local function AddGlobalPed(parameters) AddGlobalType(1, parameters) end
exports("AddGlobalPed", AddGlobalPed)
local function AddGlobalVehicle(parameters) AddGlobalType(2, parameters) end
exports("AddGlobalVehicle", AddGlobalVehicle)
local function AddGlobalObject(parameters) AddGlobalType(3, parameters) end
exports("AddGlobalObject", AddGlobalObject)
local function AddGlobalPlayer(parameters)
local distance, options = parameters.distance or Config.MaxDistance, parameters.options
SetOptions(Players, distance, options)
end
exports("AddGlobalPlayer", AddGlobalPlayer)
local function RemoveGlobalType(typ, labels)
if type(labels) == 'table' then
for _, v in pairs(labels) do
Types[typ][v] = nil
end
elseif type(labels) == 'string' then
Types[typ][labels] = nil
end
end
exports("RemoveGlobalType", RemoveGlobalType)
local function RemoveGlobalPlayer(labels)
if type(labels) == 'table' then
for _, v in pairs(labels) do
Players[v] = nil
end
elseif type(labels) == 'string' then
Players[labels] = nil
end
end
exports("RemoveGlobalPlayer", RemoveGlobalPlayer)
function SpawnPeds()
if pedsReady or not next(Config.Peds) then return end
for k, v in pairs(Config.Peds) do
if not v.currentpednumber or v.currentpednumber == 0 then
local spawnedped = 0
RequestModel(v.model)
while not HasModelLoaded(v.model) do
Wait(0)
end
if type(v.model) == 'string' then v.model = joaat(v.model) end
if v.minusOne then
spawnedped = CreatePed(0, v.model, v.coords.x, v.coords.y, v.coords.z - 1.0, v.coords.w, v.networked or false, false)
else
spawnedped = CreatePed(0, v.model, v.coords.x, v.coords.y, v.coords.z, v.coords.w, v.networked or false, false)
end
if v.freeze then
FreezeEntityPosition(spawnedped, true)
end
if v.invincible then
SetEntityInvincible(spawnedped, true)
end
if v.blockevents then
SetBlockingOfNonTemporaryEvents(spawnedped, true)
end
if v.animDict and v.anim then
RequestAnimDict(v.animDict)
while not HasAnimDictLoaded(v.animDict) do
Wait(0)
end
TaskPlayAnim(spawnedped, v.animDict, v.anim, 8.0, 0, -1, v.flag or 1, 0, 0, 0, 0)
end
if v.scenario then
SetPedCanPlayAmbientAnims(spawnedped, true)
TaskStartScenarioInPlace(spawnedped, v.scenario, 0, true)
end
if v.target then
if v.target.useModel then
AddTargetModel(v.model, {
options = v.target.options,
distance = v.target.distance
})
else
AddTargetEntity(spawnedped, {
options = v.target.options,
distance = v.target.distance
})
end
end
Config.Peds[k].currentpednumber = spawnedped
end
end
pedsReady = true
end
function DeletePeds()
if not pedsReady or not next(Config.Peds) then return end
for k, v in pairs(Config.Peds) do
DeletePed(v.currentpednumber)
Config.Peds[k].currentpednumber = 0
end
pedsReady = false
end
exports("DeletePeds", DeletePeds)
local function SpawnPed(data)
local spawnedped = 0
local key, value = next(data)
if type(value) == 'table' and type(key) ~= 'string' then
for _, v in pairs(data) do
if v.spawnNow then
RequestModel(v.model)
while not HasModelLoaded(v.model) do
Wait(0)
end
if type(v.model) == 'string' then v.model = joaat(v.model) end
if v.minusOne then
spawnedped = CreatePed(0, v.model, v.coords.x, v.coords.y, v.coords.z - 1.0, v.coords.w or 0.0, v.networked or false, true)
else
spawnedped = CreatePed(0, v.model, v.coords.x, v.coords.y, v.coords.z, v.coords.w or 0.0, v.networked or false, true)
end
if v.freeze then
FreezeEntityPosition(spawnedped, true)
end
if v.invincible then
SetEntityInvincible(spawnedped, true)
end
if v.blockevents then
SetBlockingOfNonTemporaryEvents(spawnedped, true)
end
if v.animDict and v.anim then
RequestAnimDict(v.animDict)
while not HasAnimDictLoaded(v.animDict) do
Wait(0)
end
TaskPlayAnim(spawnedped, v.animDict, v.anim, 8.0, 0, -1, v.flag or 1, 0, 0, 0, 0)
end
if v.scenario then
SetPedCanPlayAmbientAnims(spawnedped, true)
TaskStartScenarioInPlace(spawnedped, v.scenario, 0, true)
end
if v.target then
if v.target.useModel then
AddTargetModel(v.model, {
options = v.target.options,
distance = v.target.distance
})
else
AddTargetEntity(spawnedped, {
options = v.target.options,
distance = v.target.distance
})
end
end
v.currentpednumber = spawnedped
end
local nextnumber = #Config.Peds + 1
if nextnumber <= 0 then nextnumber = 1 end
Config.Peds[nextnumber] = v
end
else
if data.spawnNow then
RequestModel(data.model)
while not HasModelLoaded(data.model) do
Wait(0)
end
if type(data.model) == 'string' then data.model = joaat(data.model) end
if data.minusOne then
spawnedped = CreatePed(0, data.model, data.coords.x, data.coords.y, data.coords.z - 1.0, data.coords.w, data.networked or false, true)
else
spawnedped = CreatePed(0, data.model, data.coords.x, data.coords.y, data.coords.z, data.coords.w, data.networked or false, true)
end
if data.freeze then
FreezeEntityPosition(spawnedped, true)
end
if data.invincible then
SetEntityInvincible(spawnedped, true)
end
if data.blockevents then
SetBlockingOfNonTemporaryEvents(spawnedped, true)
end
if data.animDict and data.anim then
RequestAnimDict(data.animDict)
while not HasAnimDictLoaded(data.animDict) do
Wait(0)
end
TaskPlayAnim(spawnedped, data.animDict, data.anim, 8.0, 0, -1, data.flag or 1, 0, 0, 0, 0)
end
if data.scenario then
SetPedCanPlayAmbientAnims(spawnedped, true)
TaskStartScenarioInPlace(spawnedped, data.scenario, 0, true)
end
if data.target then
if data.target.useModel then
AddTargetModel(data.model, {
options = data.target.options,
distance = data.target.distance
})
else
AddTargetEntity(spawnedped, {
options = data.target.options,
distance = data.target.distance
})
end
end
data.currentpednumber = spawnedped
end
local nextnumber = #Config.Peds + 1
if nextnumber <= 0 then nextnumber = 1 end
Config.Peds[nextnumber] = data
end
end
exports("SpawnPed", SpawnPed)
local function RemovePed(peds)
if type(peds) == 'table' then
for k, v in pairs(peds) do
DeletePed(v)
if Config.Peds[k] then Config.Peds[k].currentpednumber = 0 end
end
elseif type(peds) == 'number' then
DeletePed(peds)
end
end
exports("RemoveSpawnedPed", RemovePed)
-- Misc. Exports
exports("RemoveGlobalPed", function(labels) RemoveGlobalType(1, labels) end)
exports("RemoveGlobalVehicle", function(labels) RemoveGlobalType(2, labels) end)
exports("RemoveGlobalObject", function(labels) RemoveGlobalType(3, labels) end)
exports("IsTargetActive", function() return targetActive end)
exports("IsTargetSuccess", function() return success end)
exports("GetGlobalTypeData", function(type, label) return Types[type][label] end)
exports("GetZoneData", function(name) return Zones[name] end)
exports("GetTargetBoneData", function(bone) return Bones.Options[bone][label] end)
exports("GetTargetEntityData", function(entity, label) return Entities[entity][label] end)
exports("GetTargetModelData", function(model, label) return Models[model][label] end)
exports("GetGlobalPedData", function(label) return Types[1][label] end)
exports("GetGlobalVehicleData", function(label) return Types[2][label] end)
exports("GetGlobalObjectData", function(label) return Types[3][label] end)
exports("GetGlobalPlayerData", function(label) return Players[label] end)
exports("UpdateGlobalTypeData", function(type, label, data) Types[type][label] = data end)
exports("UpdateZoneData", function(name, data) Zones[name] = data end)
exports("UpdateTargetBoneData", function(bone, label, data) Bones.Options[bone][label] = data end)
exports("UpdateTargetEntityData", function(entity, label, data) Entities[entity][label] = data end)
exports("UpdateTargetModelData", function(model, label, data) Models[model][label] = data end)
exports("UpdateGlobalPedData", function(label, data) Types[1][label] = data end)
exports("UpdateGlobalVehicleData", function(label, data) Types[2][label] = data end)
exports("UpdateGlobalObjectData", function(label, data) Types[3][label] = data end)
exports("UpdateGlobalPlayerData", function(label, data) Players[label] = data end)
exports("GetPeds", function() return Config.Peds end)
exports("UpdatePedsData", function(index, data) Config.Peds[index] = data end)
exports("AllowTargeting", function(bool)
allowTarget = bool
if not allowTarget then
DisableTarget(true)
end
end)
-- NUI Callbacks
RegisterNUICallback('selectTarget', function(option, cb)
option = tonumber(option) or option
SetNuiFocus(false, false)
SetNuiFocusKeepInput(false)
Wait(100)
targetActive, success, hasFocus = false, false, false
if not next(sendData) then return end
local data = sendData[option]
if not data then return end
table_wipe(sendData)
CreateThread(function()
Wait(0)
if data.action then
data.action(data.entity)
elseif data.event then
if data.type == "client" then
TriggerEvent(data.event, data)
elseif data.type == "server" then
TriggerServerEvent(data.event, data)
elseif data.type == "command" then
ExecuteCommand(data.event)
elseif data.type == "qbcommand" then
TriggerServerEvent('QBCore:CallCommand', data.event, data)
else
TriggerEvent(data.event, data)
end
else
error("No trigger setup")
end
end)
cb('ok')
end)
RegisterNUICallback('closeTarget', function(_, cb)
SetNuiFocus(false, false)
SetNuiFocusKeepInput(false)
Wait(100)
targetActive, success, hasFocus = false, false, false
cb('ok')
end)
RegisterNUICallback('leftTarget', function(_, cb)
if Config.Toggle then
SetNuiFocus(false, false)
SetNuiFocusKeepInput(false)
Wait(100)
table_wipe(sendData)
success, hasFocus = false, false
else
DisableTarget(true)
end
cb('ok')
end)
-- Startup thread
CreateThread(function()
if Config.Toggle then
RegisterCommand('playerTarget', function()
if targetActive then
DisableTarget(true)
else
EnableTarget()
end
end, false)
RegisterKeyMapping("playerTarget", "Skift target", "keyboard", Config.OpenKey)
TriggerEvent('chat:removeSuggestion', '/playerTarget')
else
RegisterCommand('+playerTarget', EnableTarget, false)
RegisterCommand('-playerTarget', DisableTarget, false)
RegisterKeyMapping("+playerTarget", "Slå targetting til", "keyboard", Config.OpenKey)
TriggerEvent('chat:removeSuggestion', '/+playerTarget')
TriggerEvent('chat:removeSuggestion', '/-playerTarget')
end
if next(Config.CircleZones) then
for k, v in pairs(Config.CircleZones) do
AddCircleZone(v.name, v.coords, v.radius, {
name = v.name,
debugPoly = v.debugPoly,
}, {
options = v.options,
distance = v.distance
})
end
end
if next(Config.BoxZones) then
for k, v in pairs(Config.BoxZones) do
AddBoxZone(v.name, v.coords, v.length, v.width, {
name = v.name,
heading = v.heading,
debugPoly = v.debugPoly,
minZ = v.minZ,
maxZ = v.maxZ
}, {
options = v.options,
distance = v.distance
})
end
end
if next(Config.PolyZones) then
for k, v in pairs(Config.PolyZones) do
AddPolyZone(v.name, v.points, {
name = v.name,
debugPoly = v.debugPoly,
minZ = v.minZ,
maxZ = v.maxZ
}, {
options = v.options,
distance = v.distance
})
end
end
if next(Config.TargetBones) then
for k, v in pairs(Config.TargetBones) do
AddTargetBone(v.bones, {
options = v.options,
distance = v.distance
})
end
end
if next(Config.TargetModels) then
for k, v in pairs(Config.TargetModels) do
AddTargetModel(v.models, {
options = v.options,
distance = v.distance
})
end
end
if next(Config.GlobalPedOptions) then
AddGlobalPed(Config.GlobalPedOptions)
end
if next(Config.GlobalVehicleOptions) then
AddGlobalVehicle(Config.GlobalVehicleOptions)
end
if next(Config.GlobalObjectOptions) then
AddGlobalObject(Config.GlobalObjectOptions)
end
if next(Config.GlobalPlayerOptions) then
AddGlobalPlayer(Config.GlobalPlayerOptions)
end
end)
-- Events
-- This is to make sure the peds spawn on restart too instead of only when you load/log-in.
AddEventHandler('onResourceStart', function(resource)
if resource == currentResourceName then
SpawnPeds()
end
end)
-- This will delete the peds when the resource stops to make sure you don't have random peds walking
AddEventHandler('onResourceStop', function(resource)
if resource == currentResourceName then
DeletePeds()
end
end)
-- Debug Option
if Config.Debug then Load('debug') end