1
0
Fork 0
forked from Simnation/Main
Main/resources/[jobs]/[crime]/nordi_containerheist/client/main.lua
2025-07-20 17:27:40 +02:00

377 lines
12 KiB
Lua

local QBCore = exports['qb-core']:GetCoreObject()
local isRobbing = false
local currentZone = nil
local containerBlip = nil
local inZone = false
local currentZoneId = nil
-- Debug function
local function Debug(msg)
if Config.Debug then
print("[Container Heist] " .. msg)
end
end
-- Function to draw 3D text
function DrawText3D(x, y, z, text)
-- Set the text properties
SetTextScale(0.35, 0.35)
SetTextFont(4)
SetTextProportional(1)
SetTextColour(255, 255, 255, 215)
SetTextEntry("STRING")
SetTextCentre(1)
AddTextComponentString(text)
SetDrawOrigin(x, y, z, 0)
DrawText(0.0, 0.0)
local factor = (string.len(text)) / 370
DrawRect(0.0, 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75)
ClearDrawOrigin()
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
end
j = i
end
return inside
end
-- Function to check if player is in any container zone
local function GetCurrentZone()
local playerPed = PlayerPedId()
local playerCoords = GetEntityCoords(playerPed)
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
-- 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(zone)
if isRobbing then return end
isRobbing = true
currentZone = zone
-- Get container type from zone
local containerType = Config.ContainerTypes[zone.type]
if not containerType then
QBCore.Functions.Notify("Invalid container type!", "error")
isRobbing = false
currentZone = nil
return
end
-- Check if player has required tools
QBCore.Functions.TriggerCallback('container_heist:server:checkRequiredItems', function(hasTools)
if not hasTools then
QBCore.Functions.Notify(Config.Notifications.noTools, "error")
isRobbing = false
currentZone = nil
return
end
-- Check cooldowns
QBCore.Functions.TriggerCallback('container_heist:server:checkCooldown', function(cooldownCheck)
if not cooldownCheck.success then
QBCore.Functions.Notify(cooldownCheck.message, "error")
isRobbing = false
currentZone = nil
return
end
-- Check police count
QBCore.Functions.TriggerCallback('container_heist:server:getPoliceCount', function(policeCount)
if policeCount < Config.PoliceRequired then
QBCore.Functions.Notify(Config.Notifications.notEnoughPolice, "error")
isRobbing = false
currentZone = nil
return
end
-- Alert police if configured
if containerType.policeAlert then
local playerCoords = GetEntityCoords(PlayerPedId())
local streetName = GetStreetNameFromHashKey(GetStreetNameAtCoord(playerCoords.x, playerCoords.y, playerCoords.z))
TriggerServerEvent('container_heist:server:alertPolice', playerCoords, streetName, containerType.label)
end
-- Start robbery progress bar
PlayRobberyAnimation(containerType)
QBCore.Functions.Progressbar("container_robbery", 'Breaking into ' .. containerType.label, containerType.animation.duration, false, true, {
disableMovement = true,
disableCarMovement = true,
disableMouse = false,
disableCombat = true,
}, {}, {}, {}, function() -- Done
-- Success
TriggerServerEvent('container_heist:server:finishRobbery', zone.id, zone.type)
QBCore.Functions.Notify(Config.Notifications.success, "success")
isRobbing = false
currentZone = nil
end, function() -- Cancel
-- Cancelled
QBCore.Functions.Notify(Config.Notifications.failed, "error")
isRobbing = false
currentZone = nil
end)
end)
end, zone.id)
end)
end
-- Register usable item event handler - FIXED VERSION
RegisterNetEvent('container_heist:client:useFlexItem', function()
Debug("useFlexItem event triggered")
local zone = GetCurrentZone()
if zone then
Debug("Player is in zone: " .. zone.id)
StartContainerRobbery(zone)
else
QBCore.Functions.Notify(Config.Notifications.notInZone, "error")
end
end)
-- Alternative method to handle item use
RegisterNetEvent('inventory:client:UseItem', function(item)
if item.name == Config.RequiredItems.flex.name then
Debug("Used item via inventory:client:UseItem: " .. item.name)
TriggerEvent('container_heist:client:useFlexItem')
end
end)
-- Command to test the robbery (for debugging)
RegisterCommand('testcontainerrob', function()
local zone = GetCurrentZone()
if zone then
Debug("Testing robbery in zone: " .. zone.id)
StartContainerRobbery(zone)
else
QBCore.Functions.Notify(Config.Notifications.notInZone, "error")
end
end, false)
-- Command to toggle debug mode
RegisterCommand('containerdebug', function()
Config.Debug = not Config.Debug
if Config.Debug then
QBCore.Functions.Notify("Container Debug mode enabled", "primary")
else
QBCore.Functions.Notify("Container Debug mode disabled", "primary")
end
end, false)
-- 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")
Debug("Entered zone: " .. zone.id)
end
sleep = 500
else
if inZone then
inZone = false
currentZoneId = nil
Debug("Left zone")
end
end
Wait(sleep)
end
end)
-- Debug thread for visualizing zones
CreateThread(function()
while true do
Wait(0)
if Config.Debug then
local playerPed = PlayerPedId()
local playerCoords = GetEntityCoords(playerPed)
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
)
-- Draw line at max height
DrawLine(
point1.x, point1.y, zone.maxZ,
point2.x, point2.y, zone.maxZ,
255, 0, 0, 255
)
-- Connect min and max height
DrawLine(
point1.x, point1.y, zone.minZ,
point1.x, point1.y, zone.maxZ,
255, 0, 0, 255
)
}
-- 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
DrawText3D(centerX, centerY, centerZ, zone.id .. " (" .. zone.type .. ")")
}
else
Wait(1000)
end
end
end)
-- Event to show police alert
RegisterNetEvent('container_heist:client:policeAlert', function(coords, streetName, containerLabel)
local playerJob = QBCore.Functions.GetPlayerData().job.name
local alertTitle = Config.Notifications.policeTitle
-- Customize alert based on job
if playerJob == "marshal" then
alertTitle = "MARSHAL SERVICE ALERT"
elseif playerJob == "sheriff" then
alertTitle = "SHERIFF DEPARTMENT ALERT"
end
-- Create alert for police officers
QBCore.Functions.Notify(alertTitle .. ": " .. string.format(Config.Notifications.policeMessage, streetName), "police", 10000)
-- 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 then
StopAnimTask(PlayerPedId(), "amb@world_human_welding@male@base", "base", 1.0)
end
end
end)
-- Print message when resource starts
AddEventHandler('onClientResourceStart', function(resourceName)
if (GetCurrentResourceName() == resourceName) then
Debug("Client script started successfully")
end
end)