ed
This commit is contained in:
parent
c00df8dec6
commit
4676cbfc6d
4 changed files with 1386 additions and 250 deletions
|
|
@ -1,7 +1,8 @@
|
|||
local QBCore = exports['qb-core']:GetCoreObject()
|
||||
local isRobbing = false
|
||||
local inZone = false
|
||||
local currentZoneId = nil
|
||||
local currentContainer = nil
|
||||
local containerBlip = nil
|
||||
local addedEntities = {}
|
||||
|
||||
-- Debug function
|
||||
local function Debug(msg)
|
||||
|
|
@ -10,167 +11,544 @@ local function Debug(msg)
|
|||
end
|
||||
end
|
||||
|
||||
-- Function to check if a point is inside a polygon
|
||||
local function IsPointInPolygon(point, polygon)
|
||||
local x, y = point.x, point.y
|
||||
local inside = false
|
||||
local j = #polygon
|
||||
|
||||
for i = 1, #polygon do
|
||||
if (polygon[i].y > y) ~= (polygon[j].y > y) and
|
||||
x < (polygon[j].x - polygon[i].x) * (y - polygon[i].y) / (polygon[j].y - polygon[i].y) + polygon[i].x then
|
||||
inside = not inside
|
||||
-- Function to get model name from hash
|
||||
local function GetModelNameFromHash(hash)
|
||||
for _, containerType in pairs(Config.ContainerTypes) do
|
||||
if GetHashKey(containerType.model) == hash then
|
||||
return containerType.model
|
||||
end
|
||||
j = i
|
||||
end
|
||||
|
||||
return inside
|
||||
return "Unknown"
|
||||
end
|
||||
|
||||
-- Function to check if player is in any container zone
|
||||
local function GetCurrentZone()
|
||||
-- Function to check if player is near a valid container
|
||||
local function IsNearValidContainer()
|
||||
local playerPed = PlayerPedId()
|
||||
local playerCoords = GetEntityCoords(playerPed)
|
||||
local foundEntity = nil
|
||||
local foundType = nil
|
||||
local closestDistance = 999.0
|
||||
|
||||
for _, zone in pairs(Config.ContainerZones) do
|
||||
if IsPointInPolygon(playerCoords, zone.points) and
|
||||
playerCoords.z >= zone.minZ and playerCoords.z <= zone.maxZ then
|
||||
return zone
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Simple command to test if the script is working
|
||||
RegisterCommand('containertest', function()
|
||||
local playerCoords = GetEntityCoords(PlayerPedId())
|
||||
print("Player coords: " .. playerCoords.x .. ", " .. playerCoords.y .. ", " .. playerCoords.z)
|
||||
|
||||
local zone = GetCurrentZone()
|
||||
if zone then
|
||||
QBCore.Functions.Notify("You are in zone: " .. zone.id, "success")
|
||||
print("In zone: " .. zone.id)
|
||||
else
|
||||
QBCore.Functions.Notify("You are not in any container zone", "error")
|
||||
print("Not in any zone")
|
||||
end
|
||||
end, false)
|
||||
|
||||
-- Command to start robbery (for testing)
|
||||
RegisterCommand('robcontainer', function()
|
||||
local zone = GetCurrentZone()
|
||||
|
||||
if zone then
|
||||
QBCore.Functions.Notify("Starting robbery in zone: " .. zone.id, "success")
|
||||
TriggerServerEvent('container_heist:server:testRobbery', zone.id, zone.type)
|
||||
else
|
||||
QBCore.Functions.Notify("You are not in any container zone", "error")
|
||||
end
|
||||
end, false)
|
||||
|
||||
-- Register usable item event handler
|
||||
RegisterNetEvent('container_heist:client:useFlexItem', function()
|
||||
print("useFlexItem event triggered")
|
||||
local zone = GetCurrentZone()
|
||||
|
||||
if zone then
|
||||
print("Player is in zone: " .. zone.id)
|
||||
QBCore.Functions.Notify("Starting robbery with flex tool in zone: " .. zone.id, "success")
|
||||
TriggerServerEvent('container_heist:server:testRobbery', zone.id, zone.type)
|
||||
else
|
||||
QBCore.Functions.Notify(Config.Notifications.notInZone, "error")
|
||||
end
|
||||
end)
|
||||
|
||||
-- Main thread for checking if player is in a zone
|
||||
CreateThread(function()
|
||||
while true do
|
||||
local sleep = 1000
|
||||
local zone = GetCurrentZone()
|
||||
|
||||
if zone then
|
||||
if not inZone or currentZoneId ~= zone.id then
|
||||
inZone = true
|
||||
currentZoneId = zone.id
|
||||
QBCore.Functions.Notify("You entered " .. zone.label .. ". Use your flex tool to break in.", "primary")
|
||||
print("Entered zone: " .. zone.id)
|
||||
end
|
||||
sleep = 500
|
||||
else
|
||||
if inZone then
|
||||
inZone = false
|
||||
currentZoneId = nil
|
||||
print("Left zone")
|
||||
end
|
||||
end
|
||||
|
||||
Wait(sleep)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Debug thread for visualizing zones
|
||||
CreateThread(function()
|
||||
while true do
|
||||
if Config.Debug then
|
||||
local playerPed = PlayerPedId()
|
||||
local playerCoords = GetEntityCoords(playerPed)
|
||||
-- Check for containers in the area (objects)
|
||||
local objects = GetGamePool('CObject')
|
||||
for _, object in ipairs(objects) do
|
||||
if DoesEntityExist(object) and not IsEntityDead(object) then
|
||||
local model = GetEntityModel(object)
|
||||
local objectCoords = GetEntityCoords(object)
|
||||
local distance = #(playerCoords - objectCoords)
|
||||
|
||||
for _, zone in pairs(Config.ContainerZones) do
|
||||
-- Draw lines connecting the points to visualize the zone
|
||||
for i = 1, #zone.points do
|
||||
local j = i % #zone.points + 1
|
||||
local point1 = zone.points[i]
|
||||
local point2 = zone.points[j]
|
||||
|
||||
-- Draw line at ground level
|
||||
DrawLine(
|
||||
point1.x, point1.y, zone.minZ,
|
||||
point2.x, point2.y, zone.minZ,
|
||||
255, 0, 0, 255
|
||||
)
|
||||
if distance <= 5.0 and distance < closestDistance then
|
||||
for _, containerType in pairs(Config.ContainerTypes) do
|
||||
if model == GetHashKey(containerType.model) then
|
||||
foundEntity = object
|
||||
foundType = containerType
|
||||
closestDistance = distance
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- Calculate center of zone for label
|
||||
local centerX, centerY = 0, 0
|
||||
for _, point in ipairs(zone.points) do
|
||||
centerX = centerX + point.x
|
||||
centerY = centerY + point.y
|
||||
end
|
||||
centerX = centerX / #zone.points
|
||||
centerY = centerY / #zone.points
|
||||
|
||||
-- Draw zone label
|
||||
local centerZ = (zone.minZ + zone.maxZ) / 2
|
||||
DrawTextOnCoord(centerX, centerY, centerZ, zone.id .. " (" .. zone.type .. ")")
|
||||
end
|
||||
Wait(0)
|
||||
else
|
||||
Wait(1000)
|
||||
end
|
||||
end
|
||||
|
||||
-- Check for trailers in the area (vehicles)
|
||||
local vehicles = GetGamePool('CVehicle')
|
||||
for _, vehicle in ipairs(vehicles) do
|
||||
if DoesEntityExist(vehicle) and not IsEntityDead(vehicle) then
|
||||
local model = GetEntityModel(vehicle)
|
||||
local vehicleCoords = GetEntityCoords(vehicle)
|
||||
local distance = #(playerCoords - vehicleCoords)
|
||||
|
||||
if distance <= 5.0 and distance < closestDistance then
|
||||
for _, containerType in pairs(Config.ContainerTypes) do
|
||||
if model == GetHashKey(containerType.model) then
|
||||
foundEntity = vehicle
|
||||
foundType = containerType
|
||||
closestDistance = distance
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return foundEntity, foundType
|
||||
end
|
||||
|
||||
-- Function to create a blip at the robbery location
|
||||
local function CreateRobberyBlip(coords)
|
||||
if containerBlip then
|
||||
RemoveBlip(containerBlip)
|
||||
end
|
||||
|
||||
containerBlip = AddBlipForCoord(coords)
|
||||
|
||||
-- Set blip color based on job
|
||||
local playerJob = QBCore.Functions.GetPlayerData().job.name
|
||||
if playerJob == "marshal" then
|
||||
SetBlipColour(containerBlip, 38) -- Purple for Marshal
|
||||
elseif playerJob == "sheriff" then
|
||||
SetBlipColour(containerBlip, 16) -- Orange for Sheriff
|
||||
else
|
||||
SetBlipColour(containerBlip, Config.Blip.color) -- Default color for regular police
|
||||
end
|
||||
|
||||
SetBlipSprite(containerBlip, Config.Blip.sprite)
|
||||
SetBlipScale(containerBlip, Config.Blip.scale)
|
||||
SetBlipAsShortRange(containerBlip, true)
|
||||
BeginTextCommandSetBlipName("STRING")
|
||||
AddTextComponentString(Config.Blip.label)
|
||||
EndTextCommandSetBlipName(containerBlip)
|
||||
|
||||
if Config.Blip.flash then
|
||||
SetBlipFlashes(containerBlip, true)
|
||||
end
|
||||
|
||||
-- Remove blip after duration
|
||||
SetTimeout(Config.Blip.duration * 1000, function()
|
||||
if containerBlip then
|
||||
RemoveBlip(containerBlip)
|
||||
containerBlip = nil
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- Function to play container robbery animation
|
||||
local function PlayRobberyAnimation(containerType)
|
||||
local playerPed = PlayerPedId()
|
||||
local animDict = containerType.animation.dict
|
||||
local animName = containerType.animation.name
|
||||
|
||||
RequestAnimDict(animDict)
|
||||
while not HasAnimDictLoaded(animDict) do
|
||||
Wait(10)
|
||||
end
|
||||
|
||||
TaskPlayAnim(playerPed, animDict, animName, 8.0, -8.0, containerType.animation.duration, containerType.animation.flag, 0, false, false, false)
|
||||
|
||||
-- Add particle effects for welding
|
||||
local boneIndex = GetPedBoneIndex(playerPed, 28422)
|
||||
local particleDict = "core"
|
||||
local particleName = "ent_amb_welding"
|
||||
|
||||
RequestNamedPtfxAsset(particleDict)
|
||||
while not HasNamedPtfxAssetLoaded(particleDict) do
|
||||
Wait(10)
|
||||
end
|
||||
|
||||
UseParticleFxAssetNextCall(particleDict)
|
||||
local particleHandle = StartParticleFxLoopedOnPedBone(particleName, playerPed, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, boneIndex, 0.5, false, false, false)
|
||||
|
||||
-- Clean up after animation
|
||||
SetTimeout(containerType.animation.duration, function()
|
||||
StopParticleFxLooped(particleHandle, 0)
|
||||
StopAnimTask(playerPed, animDict, animName, 1.0)
|
||||
end)
|
||||
end
|
||||
|
||||
-- Function to start container robbery
|
||||
local function StartContainerRobbery(container, containerType)
|
||||
if isRobbing then return end
|
||||
|
||||
isRobbing = true
|
||||
currentContainer = container
|
||||
|
||||
-- Check if player has required tools
|
||||
local hasTools = lib.callback.await('container_heist:server:checkRequiredItems', false)
|
||||
if not hasTools then
|
||||
lib.notify({
|
||||
title = Config.Notifications.title,
|
||||
description = Config.Notifications.noTools,
|
||||
type = 'error'
|
||||
})
|
||||
isRobbing = false
|
||||
currentContainer = nil
|
||||
return
|
||||
end
|
||||
|
||||
-- Check cooldowns
|
||||
local cooldownCheck = lib.callback.await('container_heist:server:checkCooldown', false, NetworkGetNetworkIdFromEntity(container))
|
||||
if not cooldownCheck.success then
|
||||
lib.notify({
|
||||
title = Config.Notifications.title,
|
||||
description = cooldownCheck.message,
|
||||
type = 'error'
|
||||
})
|
||||
isRobbing = false
|
||||
currentContainer = nil
|
||||
return
|
||||
end
|
||||
|
||||
-- Check police count
|
||||
local policeCount = lib.callback.await('container_heist:server:getPoliceCount', false)
|
||||
if policeCount < Config.PoliceRequired then
|
||||
lib.notify({
|
||||
title = Config.Notifications.title,
|
||||
description = Config.Notifications.notEnoughPolice,
|
||||
type = 'error'
|
||||
})
|
||||
isRobbing = false
|
||||
currentContainer = nil
|
||||
return
|
||||
end
|
||||
|
||||
-- Position player for animation
|
||||
local containerCoords = GetEntityCoords(container)
|
||||
local containerHeading = GetEntityHeading(container)
|
||||
local offsetCoords = GetOffsetFromEntityInWorldCoords(container, containerType.offset.x, containerType.offset.y, containerType.offset.z)
|
||||
|
||||
-- Set player position and heading
|
||||
SetEntityCoords(PlayerPedId(), offsetCoords.x, offsetCoords.y, offsetCoords.z)
|
||||
SetEntityHeading(PlayerPedId(), containerHeading + containerType.heading)
|
||||
|
||||
-- Alert police if configured
|
||||
if containerType.policeAlert then
|
||||
local streetName = GetStreetNameFromHashKey(GetStreetNameAtCoord(containerCoords.x, containerCoords.y, containerCoords.z))
|
||||
TriggerServerEvent('container_heist:server:alertPolice', containerCoords, streetName, containerType.label)
|
||||
end
|
||||
|
||||
-- Start robbery progress bar
|
||||
PlayRobberyAnimation(containerType)
|
||||
|
||||
if lib.progressBar({
|
||||
duration = containerType.animation.duration,
|
||||
label = 'Breaking into ' .. containerType.label,
|
||||
useWhileDead = false,
|
||||
canCancel = true,
|
||||
disable = {
|
||||
car = true,
|
||||
move = true,
|
||||
combat = true,
|
||||
},
|
||||
anim = {
|
||||
dict = containerType.animation.dict,
|
||||
clip = containerType.animation.name,
|
||||
},
|
||||
}) then
|
||||
-- Success
|
||||
TriggerServerEvent('container_heist:server:finishRobbery', NetworkGetNetworkIdFromEntity(container), containerType.type)
|
||||
lib.notify({
|
||||
title = Config.Notifications.title,
|
||||
description = Config.Notifications.success,
|
||||
type = 'success'
|
||||
})
|
||||
else
|
||||
-- Cancelled
|
||||
lib.notify({
|
||||
title = Config.Notifications.title,
|
||||
description = Config.Notifications.failed,
|
||||
type = 'error'
|
||||
})
|
||||
end
|
||||
|
||||
isRobbing = false
|
||||
currentContainer = nil
|
||||
end
|
||||
|
||||
-- Function to scan and add all nearby containers to target system
|
||||
local function ScanAndAddContainersToTarget()
|
||||
local playerPed = PlayerPedId()
|
||||
local playerCoords = GetEntityCoords(playerPed)
|
||||
local count = 0
|
||||
|
||||
-- Check for containers in the area (objects)
|
||||
local objects = GetGamePool('CObject')
|
||||
for _, object in ipairs(objects) do
|
||||
if DoesEntityExist(object) and not IsEntityDead(object) then
|
||||
local objectCoords = GetEntityCoords(object)
|
||||
local distance = #(playerCoords - objectCoords)
|
||||
|
||||
if distance <= 50.0 then
|
||||
local model = GetEntityModel(object)
|
||||
|
||||
if not addedEntities[object] then
|
||||
for _, containerType in pairs(Config.ContainerTypes) do
|
||||
if model == GetHashKey(containerType.model) then
|
||||
exports['qb-target']:AddTargetEntity(object, {
|
||||
options = {
|
||||
{
|
||||
type = "client",
|
||||
event = "container_heist:client:startRobbery",
|
||||
icon = "fas fa-angle-double-right",
|
||||
label = "Break into " .. containerType.label,
|
||||
containerType = containerType,
|
||||
}
|
||||
},
|
||||
distance = 3.0
|
||||
})
|
||||
addedEntities[object] = true
|
||||
count = count + 1
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Check for trailers in the area (vehicles)
|
||||
local vehicles = GetGamePool('CVehicle')
|
||||
for _, vehicle in ipairs(vehicles) do
|
||||
if DoesEntityExist(vehicle) and not IsEntityDead(vehicle) then
|
||||
local vehicleCoords = GetEntityCoords(vehicle)
|
||||
local distance = #(playerCoords - vehicleCoords)
|
||||
|
||||
if distance <= 50.0 then
|
||||
local model = GetEntityModel(vehicle)
|
||||
|
||||
if not addedEntities[vehicle] then
|
||||
for _, containerType in pairs(Config.ContainerTypes) do
|
||||
if model == GetHashKey(containerType.model) then
|
||||
exports['qb-target']:AddTargetEntity(vehicle, {
|
||||
options = {
|
||||
{
|
||||
type = "client",
|
||||
event = "container_heist:client:startRobbery",
|
||||
icon = "fas fa-angle-double-right",
|
||||
label = "Break into " .. containerType.label,
|
||||
containerType = containerType,
|
||||
}
|
||||
},
|
||||
distance = 3.0
|
||||
})
|
||||
addedEntities[vehicle] = true
|
||||
count = count + 1
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return count
|
||||
end
|
||||
|
||||
-- Command to start container robbery
|
||||
RegisterCommand('robcontainer', function()
|
||||
local container, containerType = IsNearValidContainer()
|
||||
if container and containerType then
|
||||
StartContainerRobbery(container, containerType)
|
||||
else
|
||||
lib.notify({
|
||||
title = Config.Notifications.title,
|
||||
description = "No valid container nearby!",
|
||||
type = 'error'
|
||||
})
|
||||
end
|
||||
end, false)
|
||||
|
||||
-- Command to scan and add all nearby containers to target system
|
||||
RegisterCommand('scancontainers', function()
|
||||
local count = ScanAndAddContainersToTarget()
|
||||
lib.notify({
|
||||
title = "Container Scanner",
|
||||
description = "Added " .. count .. " containers/trailers to target system",
|
||||
type = 'success',
|
||||
position = 'top',
|
||||
duration = 3000
|
||||
})
|
||||
end, false)
|
||||
|
||||
-- Debug command to show all nearby containers and trailers
|
||||
RegisterCommand('containersdebug', function()
|
||||
if not Config.Debug then return end
|
||||
|
||||
local playerPed = PlayerPedId()
|
||||
local playerCoords = GetEntityCoords(playerPed)
|
||||
local foundContainers = 0
|
||||
|
||||
-- Check for containers in the area (objects)
|
||||
local objects = GetGamePool('CObject')
|
||||
for _, object in ipairs(objects) do
|
||||
if DoesEntityExist(object) and not IsEntityDead(object) then
|
||||
local objectCoords = GetEntityCoords(object)
|
||||
local distance = #(playerCoords - objectCoords)
|
||||
|
||||
if distance <= 20.0 then
|
||||
local model = GetEntityModel(object)
|
||||
local modelName = "Unknown"
|
||||
|
||||
for _, containerType in pairs(Config.ContainerTypes) do
|
||||
if model == GetHashKey(containerType.model) then
|
||||
modelName = containerType.model
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
print("Found container object: " .. modelName .. " (Hash: " .. model .. ") at distance: " .. distance)
|
||||
foundContainers = foundContainers + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Check for trailers in the area (vehicles)
|
||||
local vehicles = GetGamePool('CVehicle')
|
||||
for _, vehicle in ipairs(vehicles) do
|
||||
if DoesEntityExist(vehicle) and not IsEntityDead(vehicle) then
|
||||
local vehicleCoords = GetEntityCoords(vehicle)
|
||||
local distance = #(playerCoords - vehicleCoords)
|
||||
|
||||
if distance <= 20.0 then
|
||||
local model = GetEntityModel(vehicle)
|
||||
local modelName = "Unknown"
|
||||
|
||||
for _, containerType in pairs(Config.ContainerTypes) do
|
||||
if model == GetHashKey(containerType.model) then
|
||||
modelName = containerType.model
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
print("Found trailer vehicle: " .. modelName .. " (Hash: " .. model .. ") at distance: " .. distance)
|
||||
foundContainers = foundContainers + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
print("Total containers/trailers found: " .. foundContainers)
|
||||
end, false)
|
||||
|
||||
-- Command to identify the model of what you're looking at
|
||||
RegisterCommand('identifycontainer', function()
|
||||
local playerPed = PlayerPedId()
|
||||
local success, entity = GetEntityPlayerIsFreeAimingAt(PlayerId())
|
||||
|
||||
if success and DoesEntityExist(entity) then
|
||||
local model = GetEntityModel(entity)
|
||||
local modelName = GetModelNameFromHash(model)
|
||||
local entityType = GetEntityType(entity)
|
||||
local entityTypeStr = "Unknown"
|
||||
|
||||
if entityType == 1 then
|
||||
entityTypeStr = "Ped"
|
||||
elseif entityType == 2 then
|
||||
entityTypeStr = "Vehicle"
|
||||
elseif entityType == 3 then
|
||||
entityTypeStr = "Object"
|
||||
end
|
||||
|
||||
print("Entity Type: " .. entityTypeStr)
|
||||
print("Model Hash: " .. model)
|
||||
print("Model Name: " .. modelName)
|
||||
|
||||
-- Add visual indicator
|
||||
local coords = GetEntityCoords(entity)
|
||||
DrawMarker(0, coords.x, coords.y, coords.z + 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 255, 0, 0, 100, false, true, 2, false, nil, nil, false)
|
||||
|
||||
-- Show notification
|
||||
lib.notify({
|
||||
title = "Container Identification",
|
||||
description = "Type: " .. entityTypeStr .. "\nModel: " .. modelName .. "\nHash: " .. model,
|
||||
type = 'inform',
|
||||
position = 'top',
|
||||
duration = 5000
|
||||
})
|
||||
else
|
||||
lib.notify({
|
||||
title = "Container Identification",
|
||||
description = "No entity found. Aim at a container or trailer.",
|
||||
type = 'error',
|
||||
position = 'top',
|
||||
duration = 3000
|
||||
})
|
||||
end
|
||||
end, false)
|
||||
|
||||
-- Setup target interactions for containers
|
||||
CreateThread(function()
|
||||
-- Wait for target system to be ready
|
||||
Wait(1000)
|
||||
|
||||
-- Add target for all container types
|
||||
for _, containerType in pairs(Config.ContainerTypes) do
|
||||
exports['qb-target']:AddTargetModel(containerType.model, {
|
||||
options = {
|
||||
{
|
||||
type = "client",
|
||||
event = "container_heist:client:startRobbery",
|
||||
icon = "fas fa-angle-double-right",
|
||||
label = "Break into " .. containerType.label,
|
||||
containerType = containerType,
|
||||
}
|
||||
},
|
||||
distance = 3.0
|
||||
})
|
||||
end
|
||||
|
||||
-- Spawn containers at fixed locations if configured
|
||||
for _, location in pairs(Config.ContainerLocations) do
|
||||
if location.spawnContainer then
|
||||
local hash = GetHashKey(location.model)
|
||||
RequestModel(hash)
|
||||
while not HasModelLoaded(hash) do
|
||||
Wait(10)
|
||||
end
|
||||
|
||||
local container = CreateObject(hash, location.coords.x, location.coords.y, location.coords.z, true, false, false)
|
||||
SetEntityHeading(container, location.heading)
|
||||
FreezeEntityPosition(container, true)
|
||||
SetModelAsNoLongerNeeded(hash)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Function to draw text in 3D space
|
||||
function DrawTextOnCoord(x, y, z, text)
|
||||
local onScreen, _x, _y = World3dToScreen2d(x, y, z)
|
||||
if onScreen then
|
||||
SetTextScale(0.35, 0.35)
|
||||
SetTextFont(4)
|
||||
SetTextProportional(1)
|
||||
SetTextColour(255, 255, 255, 215)
|
||||
SetTextEntry("STRING")
|
||||
SetTextCentre(1)
|
||||
AddTextComponentString(text)
|
||||
DrawText(_x, _y)
|
||||
local factor = (string.len(text)) / 370
|
||||
DrawRect(_x, _y + 0.0125, 0.015 + factor, 0.03, 0, 0, 0, 75)
|
||||
end
|
||||
end
|
||||
|
||||
-- Print message when resource starts
|
||||
AddEventHandler('onClientResourceStart', function(resourceName)
|
||||
if (GetCurrentResourceName() == resourceName) then
|
||||
print("^2[Container Heist]^7: Client script started successfully")
|
||||
-- Automatically scan for containers periodically
|
||||
CreateThread(function()
|
||||
while true do
|
||||
ScanAndAddContainersToTarget()
|
||||
Wait(30000) -- Scan every 30 seconds
|
||||
end
|
||||
end)
|
||||
|
||||
-- Event handler for target interaction
|
||||
RegisterNetEvent('container_heist:client:startRobbery', function(data)
|
||||
local container, _ = IsNearValidContainer()
|
||||
if container then
|
||||
StartContainerRobbery(container, data.containerType)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Event to show police alert
|
||||
RegisterNetEvent('container_heist:client:policeAlert', function(coords, streetName, containerType)
|
||||
local playerJob = QBCore.Functions.GetPlayerData().job.name
|
||||
local alertTitle = Config.Notifications.policeTitle
|
||||
local alertIcon = 'fas fa-exclamation-triangle'
|
||||
|
||||
-- Customize alert based on job
|
||||
if playerJob == "marshal" then
|
||||
alertTitle = "MARSHAL SERVICE ALERT"
|
||||
alertIcon = 'fas fa-star' -- Marshal badge icon
|
||||
elseif playerJob == "sheriff" then
|
||||
alertTitle = "SHERIFF DEPARTMENT ALERT"
|
||||
alertIcon = 'fas fa-shield-alt' -- Sheriff badge icon
|
||||
end
|
||||
|
||||
-- Create alert for police officers
|
||||
lib.notify({
|
||||
title = alertTitle,
|
||||
description = string.format(Config.Notifications.policeMessage, streetName),
|
||||
type = 'inform',
|
||||
position = 'top',
|
||||
icon = alertIcon,
|
||||
iconColor = '#ff0000'
|
||||
})
|
||||
|
||||
-- Add blip to map
|
||||
CreateRobberyBlip(coords)
|
||||
|
||||
-- Play alert sound
|
||||
PlaySound(-1, "Lose_1st", "GTAO_FM_Events_Soundset", 0, 0, 1)
|
||||
end)
|
||||
|
||||
-- Clean up on resource stop
|
||||
AddEventHandler('onResourceStop', function(resourceName)
|
||||
if resourceName == GetCurrentResourceName() then
|
||||
if containerBlip then
|
||||
RemoveBlip(containerBlip)
|
||||
end
|
||||
|
||||
if isRobbing and currentContainer then
|
||||
StopAnimTask(PlayerPedId(), "amb@world_human_welding@male@base", "base", 1.0)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue