mirror of
https://github.com/jimathy/jim_bridge.git
synced 2026-08-17 05:56:02 +01:00
552 lines
23 KiB
Lua
552 lines
23 KiB
Lua
--[[
|
|
Experimental GTA In-World Text Prompts Targets Module
|
|
-------------------------------------------------------
|
|
This module handles the creation, removal, and management of in-world text targets
|
|
for interacting with entities and zones using GTA text prompts. It supports multiple
|
|
targeting systems: OX Target, QB Target, or a fallback using DrawText3D.
|
|
|
|
Available functionalities:
|
|
• createEntityTarget - Creates a target for a specific entity.
|
|
• createBoxTarget - Creates a box-shaped zone target.
|
|
• createCircleTarget - Creates a circular zone target.
|
|
• createModelTarget - Creates a target for specified models.
|
|
• removeEntityTarget - Removes a target from an entity.
|
|
• removeZoneTarget - Removes a zone target.
|
|
|
|
Fallback: If no targeting system is detected (or if disabled via Config.System.DontUseTarget),
|
|
the module uses DrawText3D prompts. This is experimental and may not work as expected.
|
|
]]
|
|
|
|
-------------------------------------------------------------
|
|
-- Utility Data & Tables
|
|
-------------------------------------------------------------
|
|
|
|
-- Mapping of key codes to human-readable key names.
|
|
local Keys = {
|
|
[322] = "ESC", [288] = "F1", [289] = "F2", [170] = "F3", [166] = "F5",
|
|
[167] = "F6", [168] = "F7", [169] = "F8", [56] = "F9", [57] = "F10",
|
|
[243] = "~", [157] = "1", [158] = "2", [160] = "3", [164] = "4", [165] = "5",
|
|
[159] = "6", [161] = "7", [162] = "8", [163] = "9", [84] = "-", [83] = "=",
|
|
[177] = "BACKSPACE", [37] = "TAB",
|
|
[44] = "Q", [32] = "W", [38] = "E", [45] = "R", [245] = "T", [246] = "Y",
|
|
[303] = "U", [199] = "P",
|
|
[39] = "[", [40] = "]", [18] = "ENTER", [137] = "CAPS",
|
|
[34] = "A", [8] = "S", [9] = "D", [23] = "F", [47] = "G",
|
|
[74] = "H", [311] = "K", [182] = "L", [21] = "LEFTSHIFT",
|
|
[20] = "Z", [73] = "X", [26] = "C", [0] = "V", [29] = "B", [249] = "N",
|
|
[244] = "M", [82] = ",", [81] = "."
|
|
}
|
|
|
|
-- Tables for storing created targets for the fallback system and zone management.
|
|
local TextTargets = {} -- For fallback DrawText3D targets.
|
|
local targetEntities = {} -- For entity targets.
|
|
local boxTargets = {} -- For box-shaped zone targets.
|
|
local circleTargets = {} -- For circular zone targets.
|
|
|
|
-------------------------------------------------------------
|
|
-- Entity Target Creation
|
|
-------------------------------------------------------------
|
|
|
|
--- Creates a target for an entity with specified options and interaction distance.
|
|
--- Supports different targeting systems (OX Target, QB Target, or custom DrawText3D)
|
|
--- based on the server configuration.
|
|
---
|
|
--- @param entity number The entity ID for which the target is created.
|
|
--- @param opts table Array of option tables. Each option should include:
|
|
--- - icon (string): The icon to display.
|
|
--- - label (string): The text label for the option.
|
|
--- - item (string|nil): (Optional) An associated item.
|
|
--- - job (string|nil): (Optional) The job required to interact.
|
|
--- - gang (string|nil): (Optional) The gang required to interact.
|
|
--- - action (function|nil): (Optional) The function executed on selection.
|
|
--- @param dist number The interaction distance for the target.
|
|
---
|
|
--- @usage
|
|
--- ```lua
|
|
---createEntityTarget(entityId, {
|
|
--- {
|
|
--- action = function()
|
|
--- openStorage()
|
|
--- end,
|
|
--- icon = "fas fa-box",
|
|
--- job = "police",
|
|
--- label = "Open Storage",
|
|
--- },
|
|
---}, 2.0)
|
|
--- ```
|
|
function createEntityTarget(entity, opts, dist)
|
|
-- Store the target entity for later cleanup.
|
|
targetEntities[#targetEntities + 1] = entity
|
|
local entityCoords = GetEntityCoords(entity)
|
|
|
|
-- Fallback: Use DrawText3D if targeting systems are disabled or unavailable.
|
|
if Config.System.DontUseTarget or (not isStarted(OXTargetExport) and not isStarted(QBTargetExport)) then
|
|
debugPrint("^6Bridge^7: ^2Creating new ^3Entity^2 target with DrawText for entity ^7"..entity)
|
|
local existingTarget = nil
|
|
-- Check if a target already exists at similar coordinates.
|
|
for _, target in pairs(TextTargets) do
|
|
if #(target.coords - entityCoords) < 0.01 then
|
|
existingTarget = target
|
|
break
|
|
end
|
|
end
|
|
|
|
local keyTable = { 38, 29, 303, 45, 46, 47, 48 } -- Predefined key codes for options.
|
|
if existingTarget then
|
|
-- Append new options to the existing target.
|
|
for i = 1, #opts do
|
|
local key = keyTable[#existingTarget.options + i]
|
|
opts[i].key = key
|
|
existingTarget.buttontext[#existingTarget.buttontext + 1] = " ~b~[~w~"..Keys[key].."~b~] ~w~"..opts[i].label
|
|
existingTarget.options[#existingTarget.options + 1] = opts[i]
|
|
end
|
|
else
|
|
-- Create a new target entry.
|
|
local tempText = {}
|
|
for i = 1, #opts do
|
|
opts[i].key = keyTable[i]
|
|
tempText[#tempText + 1] = " ~b~[~w~"..Keys[opts[i].key].."~b~] ~w~"..opts[i].label
|
|
end
|
|
TextTargets[entity] = { coords = vec3(entityCoords.x, entityCoords.y, entityCoords.z), buttontext = tempText, options = opts, dist = dist }
|
|
end
|
|
elseif isStarted(OXTargetExport) then
|
|
debugPrint("^6Bridge^7: ^2Creating new ^3Entity ^2target with ^6"..OXTargetExport.." ^2for entity ^7"..entity)
|
|
local options = {}
|
|
for i = 1, #opts do
|
|
options[i] = {
|
|
icon = opts[i].icon,
|
|
label = opts[i].label,
|
|
item = opts[i].item or nil,
|
|
groups = opts[i].job or opts[i].gang,
|
|
onSelect = opts[i].action,
|
|
distance = dist,
|
|
canInteract = opts[i].canInteract or nil,
|
|
}
|
|
end
|
|
exports[OXTargetExport]:addLocalEntity(entity, options)
|
|
elseif isStarted(QBTargetExport) then
|
|
debugPrint("^6Bridge^7: ^2Creating new ^3Entity ^2target with ^6"..QBTargetExport.." ^2for entity ^7"..entity)
|
|
local options = { options = opts, distance = dist }
|
|
exports[QBTargetExport]:AddTargetEntity(entity, options)
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------
|
|
-- Box Zone Target Creation
|
|
-------------------------------------------------------------
|
|
|
|
--- Creates a box-shaped target zone with specified options and interaction distance.
|
|
--- Supports different targeting systems based on the server configuration.
|
|
---@param data table A table containing the box zone configuration.
|
|
--- - name (`string`): The name identifier for the zone.
|
|
--- - coords (`vector3`): The center coordinates of the box.
|
|
--- - width (`number`): The width of the box.
|
|
--- - height (`number`): The height of the box.
|
|
--- - options (`table`): A table with additional options:
|
|
--- - heading (`number`): The rotation angle of the box.
|
|
--- - debugPoly (`boolean`): Whether to enable debug mode for the zone.
|
|
---
|
|
---@param opts table A table of option configurations for the target.
|
|
--- - icon (`string`): The icon to display for the option.
|
|
--- - label (`string`): The label text for the option.
|
|
--- - item (`string|nil`): (Optional) The item associated with the option.
|
|
--- - job (`string|nil`): (Optional) The job required to interact with the option.
|
|
--- - gang (`string|nil`): (Optional) The gang required to interact with the option.
|
|
--- - onSelect (`function|nil`): (Optional) The function to execute when the option is selected.
|
|
---@param dist number The interaction distance for the target.
|
|
---
|
|
---@return string|table name identifier or target object of the created zone.
|
|
---
|
|
---@usage
|
|
---```lua
|
|
---createBoxTarget(
|
|
--- {
|
|
--- 'storageBox',
|
|
--- vector3(100.0, 200.0, 30.0),
|
|
--- 2.0,
|
|
--- 2.0,
|
|
--- {
|
|
--- name = 'storageBox',
|
|
--- heading = 100.0,
|
|
--- debugPoly = true,
|
|
--- minZ = 27.0,
|
|
--- maxZ = 32.0,
|
|
--- },
|
|
--- },
|
|
---{
|
|
--- {
|
|
--- action = function()
|
|
--- openStorage()
|
|
--- end,
|
|
--- icon = "fas fa-box",
|
|
--- job = "police",
|
|
--- label = "Open Storage",
|
|
--- },
|
|
---}, 2.0)
|
|
---```
|
|
function createBoxTarget(data, opts, dist)
|
|
if Config.System.DontUseTarget or (not isStarted(OXTargetExport) and not isStarted(QBTargetExport)) then
|
|
debugPrint("^6Bridge^7: ^2Creating new ^3Box^2 target with ^6DrawText ^2 for zone ^7"..data[1])
|
|
local existingTarget = nil
|
|
for _, target in pairs(TextTargets) do
|
|
if #(target.coords - data[2]) < 0.01 then
|
|
existingTarget = target
|
|
break
|
|
end
|
|
end
|
|
|
|
local keyTable = { 38, 29, 303, 45, 46, 47, 48 }
|
|
if existingTarget then
|
|
for i = 1, #opts do
|
|
local key = keyTable[#existingTarget.options + i]
|
|
opts[i].key = key
|
|
existingTarget.buttontext[#existingTarget.buttontext + 1] = " ~b~[~w~"..Keys[key].."~b~] ~w~"..opts[i].label
|
|
existingTarget.options[#existingTarget.options + 1] = opts[i]
|
|
end
|
|
else
|
|
local tempText = {}
|
|
for i = 1, #opts do
|
|
opts[i].key = keyTable[i]
|
|
tempText[#tempText + 1] = " ~b~[~w~"..Keys[opts[i].key].."~b~] ~w~"..opts[i].label
|
|
end
|
|
TextTargets[data[1]] = { coords = data[2], buttontext = tempText, options = opts, dist = dist }
|
|
end
|
|
return data[1]
|
|
elseif isStarted(OXTargetExport) then
|
|
debugPrint("^6Bridge^7: ^2Creating new ^3Box^2 target with ^6"..OXTargetExport.." ^2for zone ^7"..data[1])
|
|
local options = {}
|
|
for i = 1, #opts do
|
|
options[i] = {
|
|
icon = opts[i].icon,
|
|
label = opts[i].label,
|
|
item = opts[i].item or nil,
|
|
groups = opts[i].job or opts[i].gang,
|
|
onSelect = opts[i].onSelect or opts[i].action,
|
|
distance = dist,
|
|
canInteract = opts[i].canInteract or nil,
|
|
}
|
|
end
|
|
if not data[5].useZ then
|
|
local z = data[2].z + math.abs(data[5].maxZ - data[5].minZ) / 2
|
|
data[2] = vec3(data[2].x, data[2].y, z)
|
|
end
|
|
local target = exports[OXTargetExport]:addBoxZone({
|
|
coords = data[2],
|
|
size = vec3(data[4], data[3], (data[5].useZ or not data[5].maxZ) and data[2].z or math.abs(data[5].maxZ - data[5].minZ)),
|
|
rotation = data[5].heading,
|
|
debug = data[5].debugPoly,
|
|
options = options
|
|
})
|
|
boxTargets[#boxTargets + 1] = target
|
|
return target
|
|
elseif isStarted(QBTargetExport) then
|
|
debugPrint("^6Bridge^7: ^2Creating new ^3Box^2 target with ^6"..QBTargetExport.." ^2for zone ^7"..data[1])
|
|
local options = { options = opts, distance = dist }
|
|
local target = exports[QBTargetExport]:AddBoxZone(data[1], data[2], data[3], data[4], data[5], options)
|
|
boxTargets[#boxTargets + 1] = target
|
|
return data[1]
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------
|
|
-- Circle Zone Target Creation
|
|
-------------------------------------------------------------
|
|
|
|
--- Creates a circular target zone with specified options and interaction distance.
|
|
--- Supports different targeting systems based on server configuration.
|
|
---
|
|
---@param data table A table containing the circle zone configuration.
|
|
--- - name (`string`): The name identifier for the zone.
|
|
--- - coords (`vector3`): The center coordinates of the circle.
|
|
--- - radius (`number`): The radius of the circle.
|
|
--- - options (`table`): A table with additional options:
|
|
--- - debugPoly (`boolean`): Whether to enable debug mode for the zone.
|
|
---
|
|
---@param opts table A table of option configurations for the target.
|
|
--- - icon (`string`): The icon to display for the option.
|
|
--- - label (`string`): The label text for the option.
|
|
--- - item (`string|nil`): (Optional) The item associated with the option.
|
|
--- - job (`string|nil`): (Optional) The job required to interact with the option.
|
|
--- - gang (`string|nil`): (Optional) The gang required to interact with the option.
|
|
--- - onSelect (`function|nil`): (Optional) The function to execute when the option is selected.
|
|
---@param dist number The interaction distance for the target.
|
|
---
|
|
---@return string|table name identifier or target object of the created zone.
|
|
---
|
|
---@usage
|
|
--- ```lua
|
|
--- createCircleTarget({
|
|
--- name = 'centralPark',
|
|
--- coords = vector3(200.0, 300.0, 40.0),
|
|
--- radius = 50.0,
|
|
--- options = { debugPoly = false }
|
|
--- }, {
|
|
--- { icon = "fas fa-tree", label = "Relax", action = relaxAction }
|
|
--- }, 2.0)
|
|
--- ```
|
|
function createCircleTarget(data, opts, dist)
|
|
if Config.System.DontUseTarget then
|
|
debugPrint("^6Bridge^7: ^2Creating new ^3Circle ^2target with ^6DrawText ^2for zone ^7"..data[1])
|
|
local existingTarget = nil
|
|
for _, target in pairs(TextTargets) do
|
|
if #(target.coords - data[2]) < 0.01 then
|
|
existingTarget = target
|
|
break
|
|
end
|
|
end
|
|
|
|
local keyTable = { 38, 29, 303, 45, 46, 47, 48 }
|
|
if existingTarget then
|
|
for i = 1, #opts do
|
|
local key = keyTable[#existingTarget.options + i]
|
|
opts[i].key = key
|
|
existingTarget.buttontext[#existingTarget.buttontext + 1] = " ~b~[~w~"..Keys[key].."~b~] ~w~"..opts[i].label
|
|
existingTarget.options[#existingTarget.options + 1] = opts[i]
|
|
end
|
|
else
|
|
local tempText = {}
|
|
for i = 1, #opts do
|
|
opts[i].key = keyTable[i]
|
|
tempText[#tempText + 1] = " ~b~[~w~"..Keys[opts[i].key].."~b~] ~w~"..opts[i].label
|
|
end
|
|
TextTargets[data[1]] = { coords = data[2], buttontext = tempText, options = opts, dist = dist }
|
|
end
|
|
return data[1]
|
|
elseif isStarted(OXTargetExport) then
|
|
debugPrint("^6Bridge^7: ^2Creating new ^3Circle ^2target with ^6"..OXTargetExport.." ^2for zone ^7"..data[1])
|
|
local options = {}
|
|
for i = 1, #opts do
|
|
options[i] = {
|
|
icon = opts[i].icon,
|
|
label = opts[i].label,
|
|
item = opts[i].item or nil,
|
|
groups = opts[i].job or opts[i].gang,
|
|
onSelect = opts[i].onSelect or opts[i].action,
|
|
distance = dist,
|
|
canInteract = opts[i].canInteract or nil,
|
|
}
|
|
end
|
|
local target = exports[OXTargetExport]:addSphereZone({
|
|
coords = data[2],
|
|
radius = data[3],
|
|
debug = data[4].debugPoly,
|
|
options = options
|
|
})
|
|
circleTargets[#circleTargets + 1] = target
|
|
return target
|
|
elseif isStarted(QBTargetExport) then
|
|
debugPrint("^6Bridge^7: ^2Creating new ^3Circle ^2target with ^6"..QBTargetExport.." ^2for zone ^7"..data[1])
|
|
local options = { options = opts, distance = dist }
|
|
local target = exports[QBTargetExport]:AddCircleZone(data[1], data[2], data[3], data[4], options)
|
|
circleTargets[#circleTargets + 1] = target
|
|
return data[1]
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------
|
|
-- Model Target Creation
|
|
-------------------------------------------------------------
|
|
|
|
--- Creates a target for models with specified options and interaction distance.
|
|
--- Supports different targeting systems (OX Target, QB Target) based on server configuration.
|
|
---
|
|
--- @param models table Array of model identifiers.
|
|
--- @param opts table Array of option tables (same structure as in createEntityTarget).
|
|
--- @param dist number The interaction distance for the target.
|
|
---
|
|
--- @usage
|
|
--- ```lua
|
|
---createModelTarget(
|
|
---{ model1, model2 },
|
|
---{
|
|
--- {
|
|
--- action = function()
|
|
--- openStorage()
|
|
--- end,
|
|
--- icon = "fas fa-box",
|
|
--- job = "police",
|
|
--- label = "Open Storage",
|
|
--- },
|
|
---}, 2.0)
|
|
---```
|
|
function createModelTarget(models, opts, dist)
|
|
if Config.System.DontUseTarget or (not isStarted(OXTargetExport) and not isStarted(QBTargetExport)) then
|
|
-- Fallback for model targets is not implemented.
|
|
elseif isStarted(OXTargetExport) then
|
|
debugPrint("^6Bridge^7: ^2Creating new ^3Model^2 target with ^6"..OXTargetExport)
|
|
local options = {}
|
|
for i = 1, #opts do
|
|
options[i] = {
|
|
icon = opts[i].icon,
|
|
label = opts[i].label,
|
|
item = opts[i].item or nil,
|
|
groups = opts[i].job or opts[i].gang,
|
|
onSelect = opts[i].action,
|
|
distance = dist,
|
|
canInteract = opts[i].canInteract or nil,
|
|
}
|
|
end
|
|
exports[OXTargetExport]:addModel(models, options)
|
|
elseif isStarted(QBTargetExport) then
|
|
debugPrint("^6Bridge^7: ^2Creating new ^3Model^2 target with ^6"..QBTargetExport)
|
|
local options = { options = opts, distance = dist }
|
|
exports[QBTargetExport]:AddTargetModel(models, options)
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------
|
|
-- Target Removal Functions
|
|
-------------------------------------------------------------
|
|
|
|
--- Removes a previously created entity target.
|
|
---
|
|
--- @param entity number The entity ID whose target should be removed.
|
|
---
|
|
--- @usage
|
|
--- ```lua
|
|
--- removeEntityTarget(entityId)
|
|
--- ```
|
|
function removeEntityTarget(entity)
|
|
if isStarted(QBTargetExport) then
|
|
exports[QBTargetExport]:RemoveTargetEntity(entity)
|
|
end
|
|
if isStarted(OXTargetExport) then
|
|
exports[OXTargetExport]:removeLocalEntity(entity, nil)
|
|
end
|
|
if Config.System.DontUseTarget or (not isStarted(OXTargetExport) and not isStarted(QBTargetExport)) then
|
|
TextTargets[entity] = nil
|
|
end
|
|
end
|
|
|
|
--- Removes a previously created zone target.
|
|
---
|
|
--- @param target string|table The name identifier or target object of the zone to remove.
|
|
---
|
|
--- @usage
|
|
--- ```lua
|
|
--- removeZoneTarget('centralPark')
|
|
--- removeZoneTarget(targetObject)
|
|
--- ```
|
|
function removeZoneTarget(target)
|
|
if isStarted(QBTargetExport) then
|
|
exports[QBTargetExport]:RemoveZone(target)
|
|
end
|
|
if isStarted(OXTargetExport) then
|
|
exports[OXTargetExport]:removeZone(target, true)
|
|
end
|
|
if Config.System.DontUseTarget or (not isStarted(OXTargetExport) and not isStarted(QBTargetExport)) then
|
|
TextTargets[target] = nil
|
|
end
|
|
end
|
|
|
|
--- Removes a previously created model target.
|
|
---
|
|
--- @param model table The model ID whose target should be removed.
|
|
---
|
|
--- @usage
|
|
--- ```lua
|
|
--- removeModelTarget(model)
|
|
--- ```
|
|
function removeModelTarget(model)
|
|
if isStarted(QBTargetExport) then
|
|
exports[QBTargetExport]:RemoveTargetModel(model, "Test")
|
|
end
|
|
if isStarted(OXTargetExport) then
|
|
exports[OXTargetExport]:removeModel(model, nil)
|
|
end
|
|
if Config.System.DontUseTarget or (not isStarted(OXTargetExport) and not isStarted(QBTargetExport)) then
|
|
TextTargets[entity] = nil
|
|
end
|
|
end
|
|
-------------------------------------------------------------
|
|
-- Fallback: DrawText3D Targets (Experimental)
|
|
-------------------------------------------------------------
|
|
|
|
-- If no targeting system is detected and this is a client script, use DrawText3D for targets.
|
|
if (Config.System.DontUseTarget or (not isStarted(OXTargetExport) and not isStarted(QBTargetExport))) and not isServer() then
|
|
CreateThread(function()
|
|
while true do
|
|
local pedCoords = GetEntityCoords(PlayerPedId())
|
|
local camCoords = GetGameplayCamCoord()
|
|
local camRotation = GetGameplayCamRot(2) -- Camera rotation (degrees)
|
|
local camForwardVector = RotationToDirection(camRotation) -- Convert rotation to direction
|
|
|
|
local closestTarget = nil
|
|
local closestDist = math.huge
|
|
|
|
-- Create a shallow copy of TextTargets
|
|
local targetsCopy = {}
|
|
for k, target in pairs(TextTargets) do
|
|
targetsCopy[k] = target
|
|
end
|
|
|
|
-- Identify the closest target in front of the camera.
|
|
for _, target in pairs(targetsCopy) do
|
|
local dist = #(pedCoords - target.coords)
|
|
local vecToTarget = target.coords - camCoords
|
|
local vecToTargetNormalized = normalizeVector(vecToTarget)
|
|
local dot = camForwardVector.x * vecToTargetNormalized.x +
|
|
camForwardVector.y * vecToTargetNormalized.y +
|
|
camForwardVector.z * vecToTargetNormalized.z
|
|
local isFacingTarget = dot > 0.5 -- Threshold for facing target.
|
|
|
|
if dist <= target.dist and isFacingTarget then
|
|
if dist < closestDist then
|
|
closestDist = dist
|
|
closestTarget = target
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Render the DrawText3D targets and listen for key presses.
|
|
for _, target in pairs(targetsCopy) do
|
|
local isClosest = (target == closestTarget)
|
|
if #(pedCoords - target.coords) <= target.dist then
|
|
for i = 1, #target.options do
|
|
if IsControlJustPressed(0, target.options[i].key) and isClosest then
|
|
if target.options[i].onSelect then target.options[i].onSelect() end
|
|
if target.options[i].action then target.options[i].action() end
|
|
end
|
|
end
|
|
DrawText3D(vec3(target.coords.x, target.coords.y, target.coords.z + 0.7),
|
|
concatenateText(target.buttontext),
|
|
isClosest)
|
|
end
|
|
end
|
|
|
|
Wait(0)
|
|
end
|
|
end)
|
|
end
|
|
|
|
-------------------------------------------------------------
|
|
-- Cleanup on Resource Stop
|
|
-------------------------------------------------------------
|
|
|
|
-- When the current resource stops, remove all targets.
|
|
onResourceStop(function()
|
|
-- Remove entity targets.
|
|
for i = 1, #targetEntities do
|
|
if isStarted(OXTargetExport) then
|
|
exports[OXTargetExport]:removeLocalEntity(targetEntities[i], nil)
|
|
elseif isStarted(QBTargetExport) then
|
|
exports[QBTargetExport]:RemoveTargetEntity(targetEntities[i])
|
|
end
|
|
end
|
|
-- Remove box zone targets.
|
|
for i = 1, #boxTargets do
|
|
if isStarted(OXTargetExport) then
|
|
exports[OXTargetExport]:removeZone(boxTargets[i], true)
|
|
elseif isStarted(QBTargetExport) then
|
|
exports[QBTargetExport]:RemoveZone(boxTargets[i].name)
|
|
end
|
|
end
|
|
-- Remove circle zone targets.
|
|
for i = 1, #circleTargets do
|
|
if isStarted(OXTargetExport) then
|
|
exports[OXTargetExport]:removeZone(circleTargets[i], true)
|
|
elseif isStarted(QBTargetExport) then
|
|
exports[QBTargetExport]:RemoveZone(circleTargets[i].name)
|
|
end
|
|
end
|
|
end, true) |