forked from Simnation/Main
ed
This commit is contained in:
parent
0116d75418
commit
c00df8dec6
3 changed files with 60 additions and 461 deletions
|
@ -1,7 +1,5 @@
|
||||||
local QBCore = exports['qb-core']:GetCoreObject()
|
local QBCore = exports['qb-core']:GetCoreObject()
|
||||||
local isRobbing = false
|
local isRobbing = false
|
||||||
local currentZone = nil
|
|
||||||
local containerBlip = nil
|
|
||||||
local inZone = false
|
local inZone = false
|
||||||
local currentZoneId = nil
|
local currentZoneId = nil
|
||||||
|
|
||||||
|
@ -12,23 +10,6 @@ local function Debug(msg)
|
||||||
end
|
end
|
||||||
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
|
-- Function to check if a point is inside a polygon
|
||||||
local function IsPointInPolygon(point, polygon)
|
local function IsPointInPolygon(point, polygon)
|
||||||
local x, y = point.x, point.y
|
local x, y = point.x, point.y
|
||||||
|
@ -61,196 +42,47 @@ local function GetCurrentZone()
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Function to create a blip at the robbery location
|
-- Simple command to test if the script is working
|
||||||
local function CreateRobberyBlip(coords)
|
RegisterCommand('containertest', function()
|
||||||
if containerBlip then
|
local playerCoords = GetEntityCoords(PlayerPedId())
|
||||||
RemoveBlip(containerBlip)
|
print("Player coords: " .. playerCoords.x .. ", " .. playerCoords.y .. ", " .. playerCoords.z)
|
||||||
end
|
|
||||||
|
|
||||||
containerBlip = AddBlipForCoord(coords)
|
local zone = GetCurrentZone()
|
||||||
|
if zone then
|
||||||
-- Set blip color based on job
|
QBCore.Functions.Notify("You are in zone: " .. zone.id, "success")
|
||||||
local playerJob = QBCore.Functions.GetPlayerData().job.name
|
print("In zone: " .. zone.id)
|
||||||
if playerJob == "marshal" then
|
|
||||||
SetBlipColour(containerBlip, 38) -- Purple for Marshal
|
|
||||||
elseif playerJob == "sheriff" then
|
|
||||||
SetBlipColour(containerBlip, 16) -- Orange for Sheriff
|
|
||||||
else
|
else
|
||||||
SetBlipColour(containerBlip, Config.Blip.color) -- Default color for regular police
|
QBCore.Functions.Notify("You are not in any container zone", "error")
|
||||||
|
print("Not in any zone")
|
||||||
end
|
end
|
||||||
|
end, false)
|
||||||
|
|
||||||
SetBlipSprite(containerBlip, Config.Blip.sprite)
|
-- Command to start robbery (for testing)
|
||||||
SetBlipScale(containerBlip, Config.Blip.scale)
|
RegisterCommand('robcontainer', function()
|
||||||
SetBlipAsShortRange(containerBlip, true)
|
local zone = GetCurrentZone()
|
||||||
BeginTextCommandSetBlipName("STRING")
|
|
||||||
AddTextComponentString(Config.Blip.label)
|
|
||||||
EndTextCommandSetBlipName(containerBlip)
|
|
||||||
|
|
||||||
if Config.Blip.flash then
|
if zone then
|
||||||
SetBlipFlashes(containerBlip, true)
|
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
|
||||||
|
end, false)
|
||||||
|
|
||||||
-- Remove blip after duration
|
-- Register usable item event handler
|
||||||
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()
|
RegisterNetEvent('container_heist:client:useFlexItem', function()
|
||||||
Debug("useFlexItem event triggered")
|
print("useFlexItem event triggered")
|
||||||
local zone = GetCurrentZone()
|
local zone = GetCurrentZone()
|
||||||
|
|
||||||
if zone then
|
if zone then
|
||||||
Debug("Player is in zone: " .. zone.id)
|
print("Player is in zone: " .. zone.id)
|
||||||
StartContainerRobbery(zone)
|
QBCore.Functions.Notify("Starting robbery with flex tool in zone: " .. zone.id, "success")
|
||||||
|
TriggerServerEvent('container_heist:server:testRobbery', zone.id, zone.type)
|
||||||
else
|
else
|
||||||
QBCore.Functions.Notify(Config.Notifications.notInZone, "error")
|
QBCore.Functions.Notify(Config.Notifications.notInZone, "error")
|
||||||
end
|
end
|
||||||
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
|
-- Main thread for checking if player is in a zone
|
||||||
CreateThread(function()
|
CreateThread(function()
|
||||||
while true do
|
while true do
|
||||||
|
@ -262,14 +94,14 @@ CreateThread(function()
|
||||||
inZone = true
|
inZone = true
|
||||||
currentZoneId = zone.id
|
currentZoneId = zone.id
|
||||||
QBCore.Functions.Notify("You entered " .. zone.label .. ". Use your flex tool to break in.", "primary")
|
QBCore.Functions.Notify("You entered " .. zone.label .. ". Use your flex tool to break in.", "primary")
|
||||||
Debug("Entered zone: " .. zone.id)
|
print("Entered zone: " .. zone.id)
|
||||||
end
|
end
|
||||||
sleep = 500
|
sleep = 500
|
||||||
else
|
else
|
||||||
if inZone then
|
if inZone then
|
||||||
inZone = false
|
inZone = false
|
||||||
currentZoneId = nil
|
currentZoneId = nil
|
||||||
Debug("Left zone")
|
print("Left zone")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -280,8 +112,6 @@ end)
|
||||||
-- Debug thread for visualizing zones
|
-- Debug thread for visualizing zones
|
||||||
CreateThread(function()
|
CreateThread(function()
|
||||||
while true do
|
while true do
|
||||||
Wait(0)
|
|
||||||
|
|
||||||
if Config.Debug then
|
if Config.Debug then
|
||||||
local playerPed = PlayerPedId()
|
local playerPed = PlayerPedId()
|
||||||
local playerCoords = GetEntityCoords(playerPed)
|
local playerCoords = GetEntityCoords(playerPed)
|
||||||
|
@ -299,21 +129,7 @@ CreateThread(function()
|
||||||
point2.x, point2.y, zone.minZ,
|
point2.x, point2.y, zone.minZ,
|
||||||
255, 0, 0, 255
|
255, 0, 0, 255
|
||||||
)
|
)
|
||||||
|
end
|
||||||
-- 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
|
-- Calculate center of zone for label
|
||||||
local centerX, centerY = 0, 0
|
local centerX, centerY = 0, 0
|
||||||
|
@ -326,52 +142,35 @@ CreateThread(function()
|
||||||
|
|
||||||
-- Draw zone label
|
-- Draw zone label
|
||||||
local centerZ = (zone.minZ + zone.maxZ) / 2
|
local centerZ = (zone.minZ + zone.maxZ) / 2
|
||||||
DrawText3D(centerX, centerY, centerZ, zone.id .. " (" .. zone.type .. ")")
|
DrawTextOnCoord(centerX, centerY, centerZ, zone.id .. " (" .. zone.type .. ")")
|
||||||
}
|
end
|
||||||
|
Wait(0)
|
||||||
else
|
else
|
||||||
Wait(1000)
|
Wait(1000)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Event to show police alert
|
-- Function to draw text in 3D space
|
||||||
RegisterNetEvent('container_heist:client:policeAlert', function(coords, streetName, containerLabel)
|
function DrawTextOnCoord(x, y, z, text)
|
||||||
local playerJob = QBCore.Functions.GetPlayerData().job.name
|
local onScreen, _x, _y = World3dToScreen2d(x, y, z)
|
||||||
local alertTitle = Config.Notifications.policeTitle
|
if onScreen then
|
||||||
|
SetTextScale(0.35, 0.35)
|
||||||
-- Customize alert based on job
|
SetTextFont(4)
|
||||||
if playerJob == "marshal" then
|
SetTextProportional(1)
|
||||||
alertTitle = "MARSHAL SERVICE ALERT"
|
SetTextColour(255, 255, 255, 215)
|
||||||
elseif playerJob == "sheriff" then
|
SetTextEntry("STRING")
|
||||||
alertTitle = "SHERIFF DEPARTMENT ALERT"
|
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
|
||||||
|
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
|
-- Print message when resource starts
|
||||||
AddEventHandler('onClientResourceStart', function(resourceName)
|
AddEventHandler('onClientResourceStart', function(resourceName)
|
||||||
if (GetCurrentResourceName() == resourceName) then
|
if (GetCurrentResourceName() == resourceName) then
|
||||||
Debug("Client script started successfully")
|
print("^2[Container Heist]^7: Client script started successfully")
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -8,7 +8,6 @@ Config.PoliceRequired = 1 -- Minimum police required
|
||||||
Config.PoliceJobs = {
|
Config.PoliceJobs = {
|
||||||
"police", -- Regular police
|
"police", -- Regular police
|
||||||
"marshal", -- Marshal service
|
"marshal", -- Marshal service
|
||||||
"sheriff" -- Sheriff department
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Required Items
|
-- Required Items
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
local QBCore = exports['qb-core']:GetCoreObject()
|
local QBCore = exports['qb-core']:GetCoreObject()
|
||||||
local zoneCooldowns = {}
|
|
||||||
local playerCooldowns = {}
|
|
||||||
local globalCooldowns = {}
|
|
||||||
|
|
||||||
-- Debug function
|
-- Debug function
|
||||||
local function Debug(msg)
|
local function Debug(msg)
|
||||||
|
@ -10,226 +7,30 @@ local function Debug(msg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Register usable item - FIXED VERSION
|
-- Register usable item
|
||||||
QBCore.Functions.CreateUseableItem(Config.RequiredItems.flex.name, function(source, item)
|
QBCore.Functions.CreateUseableItem(Config.RequiredItems.flex.name, function(source)
|
||||||
local src = source
|
print("Player " .. source .. " used item: " .. Config.RequiredItems.flex.name)
|
||||||
Debug("Player " .. src .. " used item: " .. Config.RequiredItems.flex.name)
|
TriggerClientEvent('container_heist:client:useFlexItem', source)
|
||||||
TriggerClientEvent('container_heist:client:useFlexItem', src)
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Check if player has required items
|
-- Test robbery event
|
||||||
QBCore.Functions.CreateCallback('container_heist:server:checkRequiredItems', function(source, cb)
|
RegisterNetEvent('container_heist:server:testRobbery', function(zoneId, zoneType)
|
||||||
local src = source
|
|
||||||
local Player = QBCore.Functions.GetPlayer(src)
|
|
||||||
if not Player then return cb(false) end
|
|
||||||
|
|
||||||
-- Check for required flex tool
|
|
||||||
local hasItem = exports['tgiann-inventory']:HasItem(src, Config.RequiredItems.flex.name, Config.RequiredItems.flex.amount)
|
|
||||||
Debug("Player " .. src .. " has required item: " .. tostring(hasItem))
|
|
||||||
cb(hasItem)
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Check cooldowns
|
|
||||||
QBCore.Functions.CreateCallback('container_heist:server:checkCooldown', function(source, cb, zoneId)
|
|
||||||
local src = source
|
|
||||||
local Player = QBCore.Functions.GetPlayer(src)
|
|
||||||
if not Player then return cb({success = false, message = "Player not found"}) end
|
|
||||||
|
|
||||||
local citizenId = Player.PlayerData.citizenid
|
|
||||||
local currentTime = os.time()
|
|
||||||
|
|
||||||
-- Check player cooldown
|
|
||||||
if playerCooldowns[citizenId] and (currentTime - playerCooldowns[citizenId]) < (Config.CooldownTime * 60) then
|
|
||||||
local timeLeft = math.ceil(((playerCooldowns[citizenId] + (Config.CooldownTime * 60)) - currentTime) / 60)
|
|
||||||
return cb({success = false, message = "You need to wait " .. timeLeft .. " more minutes before attempting another heist!"})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Check zone cooldown
|
|
||||||
if zoneCooldowns[zoneId] and (currentTime - zoneCooldowns[zoneId]) < (Config.CooldownTime * 60) then
|
|
||||||
return cb({success = false, message = Config.Notifications.alreadyRobbed})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Find zone type
|
|
||||||
local zoneType = nil
|
|
||||||
for _, zone in pairs(Config.ContainerZones) do
|
|
||||||
if zone.id == zoneId then
|
|
||||||
zoneType = zone.type
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not zoneType then
|
|
||||||
return cb({success = false, message = "Invalid zone!"})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Check global cooldown for container type
|
|
||||||
if globalCooldowns[zoneType] and (currentTime - globalCooldowns[zoneType]) < (Config.GlobalCooldown * 60) then
|
|
||||||
local timeLeft = math.ceil(((globalCooldowns[zoneType] + (Config.GlobalCooldown * 60)) - currentTime) / 60)
|
|
||||||
return cb({success = false, message = Config.Notifications.globalCooldown .. " (" .. timeLeft .. " minutes left)"})
|
|
||||||
end
|
|
||||||
|
|
||||||
cb({success = true})
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Get police count
|
|
||||||
QBCore.Functions.CreateCallback('container_heist:server:getPoliceCount', function(source, cb)
|
|
||||||
local policeCount = 0
|
|
||||||
local players = QBCore.Functions.GetPlayers()
|
|
||||||
|
|
||||||
for _, playerId in ipairs(players) do
|
|
||||||
local Player = QBCore.Functions.GetPlayer(playerId)
|
|
||||||
if Player then
|
|
||||||
-- Check if player's job is in the list of police jobs
|
|
||||||
for _, jobName in ipairs(Config.PoliceJobs) do
|
|
||||||
if Player.PlayerData.job.name == jobName and Player.PlayerData.job.onduty then
|
|
||||||
policeCount = policeCount + 1
|
|
||||||
break -- No need to check other job names for this player
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
cb(policeCount)
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Alert police
|
|
||||||
RegisterNetEvent('container_heist:server:alertPolice', function(coords, streetName, containerLabel)
|
|
||||||
local src = source
|
|
||||||
local players = QBCore.Functions.GetPlayers()
|
|
||||||
|
|
||||||
for _, playerId in ipairs(players) do
|
|
||||||
local Player = QBCore.Functions.GetPlayer(playerId)
|
|
||||||
if Player then
|
|
||||||
-- Check if player's job is in the list of police jobs
|
|
||||||
for _, jobName in ipairs(Config.PoliceJobs) do
|
|
||||||
if Player.PlayerData.job.name == jobName and Player.PlayerData.job.onduty then
|
|
||||||
TriggerClientEvent('container_heist:client:policeAlert', playerId, coords, streetName, containerLabel)
|
|
||||||
break -- No need to send multiple alerts to the same player
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Finish robbery and give rewards
|
|
||||||
RegisterNetEvent('container_heist:server:finishRobbery', function(zoneId, containerTypeName)
|
|
||||||
local src = source
|
local src = source
|
||||||
local Player = QBCore.Functions.GetPlayer(src)
|
local Player = QBCore.Functions.GetPlayer(src)
|
||||||
if not Player then return end
|
if not Player then return end
|
||||||
|
|
||||||
local citizenId = Player.PlayerData.citizenid
|
print("Player " .. src .. " started robbery in zone: " .. zoneId .. " of type: " .. zoneType)
|
||||||
local currentTime = os.time()
|
TriggerClientEvent('QBCore:Notify', src, "Robbery started in zone: " .. zoneId, "success")
|
||||||
|
|
||||||
-- Set cooldowns
|
-- Give a test reward
|
||||||
playerCooldowns[citizenId] = currentTime
|
exports['tgiann-inventory']:AddItem(src, "cash", 1000)
|
||||||
zoneCooldowns[zoneId] = currentTime
|
TriggerClientEvent('QBCore:Notify', src, "You found $1000!", "success")
|
||||||
globalCooldowns[containerTypeName] = currentTime
|
|
||||||
|
|
||||||
-- Get container type
|
|
||||||
local containerType = Config.ContainerTypes[containerTypeName]
|
|
||||||
if not containerType then
|
|
||||||
Debug("Container type not found: " .. containerTypeName)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Decrease durability of flex tool if configured
|
|
||||||
if Config.RequiredItems.flex.durability then
|
|
||||||
local itemData = exports['tgiann-inventory']:GetItemByName(src, Config.RequiredItems.flex.name)
|
|
||||||
if itemData and itemData.info then
|
|
||||||
local newDurability = math.max(0, (itemData.info.durabilityPercent or 100) - Config.RequiredItems.flex.durabilityDecrease)
|
|
||||||
exports['tgiann-inventory']:UpdateItemMetadata(src, Config.RequiredItems.flex.name, itemData.slot, {
|
|
||||||
durabilityPercent = newDurability,
|
|
||||||
serie = itemData.info.serie or "TOOL-" .. math.random(100000, 999999),
|
|
||||||
usedTotalAmmo = itemData.info.usedTotalAmmo or 0,
|
|
||||||
ammo = itemData.info.ammo or 0
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Remove item if durability reaches 0
|
|
||||||
if newDurability <= 0 and Config.RequiredItems.flex.remove then
|
|
||||||
exports['tgiann-inventory']:RemoveItem(src, Config.RequiredItems.flex.name, 1)
|
|
||||||
TriggerClientEvent('QBCore:Notify', src, "Your " .. Config.RequiredItems.flex.label .. " broke!", "error")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif Config.RequiredItems.flex.remove then
|
|
||||||
-- Remove item if configured
|
|
||||||
exports['tgiann-inventory']:RemoveItem(src, Config.RequiredItems.flex.name, Config.RequiredItems.flex.amount)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Give rewards based on chances
|
|
||||||
local rewardsGiven = 0
|
|
||||||
for _, reward in pairs(containerType.rewards) do
|
|
||||||
if math.random(1, 100) <= reward.chance then
|
|
||||||
local amount = math.random(reward.min, reward.max)
|
|
||||||
|
|
||||||
if reward.item == "cash" then
|
|
||||||
Player.Functions.AddMoney("cash", amount)
|
|
||||||
TriggerClientEvent('QBCore:Notify', src, "Found $" .. amount, "success")
|
|
||||||
else
|
|
||||||
-- Add item with proper metadata for weapons
|
|
||||||
if string.match(reward.item, "weapon_") then
|
|
||||||
exports['tgiann-inventory']:AddItem(src, reward.item, amount, nil, {
|
|
||||||
serie = "HEIST-" .. math.random(100000, 999999),
|
|
||||||
durabilityPercent = 100,
|
|
||||||
usedTotalAmmo = 0,
|
|
||||||
ammo = 0
|
|
||||||
})
|
|
||||||
else
|
|
||||||
exports['tgiann-inventory']:AddItem(src, reward.item, amount)
|
|
||||||
end
|
|
||||||
|
|
||||||
TriggerClientEvent('QBCore:Notify', src, "Found " .. amount .. "x " .. reward.label, "success")
|
|
||||||
end
|
|
||||||
|
|
||||||
rewardsGiven = rewardsGiven + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if rewardsGiven == 0 then
|
|
||||||
TriggerClientEvent('QBCore:Notify', src, "The container was empty!", "error")
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Clean up cooldowns periodically
|
|
||||||
CreateThread(function()
|
|
||||||
while true do
|
|
||||||
Wait(60000) -- Check every minute
|
|
||||||
local currentTime = os.time()
|
|
||||||
|
|
||||||
-- Clean up player cooldowns
|
|
||||||
for citizenId, cooldownTime in pairs(playerCooldowns) do
|
|
||||||
if (currentTime - cooldownTime) > (Config.CooldownTime * 60) then
|
|
||||||
playerCooldowns[citizenId] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Clean up zone cooldowns
|
|
||||||
for zoneId, cooldownTime in pairs(zoneCooldowns) do
|
|
||||||
if (currentTime - cooldownTime) > (Config.CooldownTime * 60) then
|
|
||||||
zoneCooldowns[zoneId] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Clean up global cooldowns
|
|
||||||
for containerType, cooldownTime in pairs(globalCooldowns) do
|
|
||||||
if (currentTime - cooldownTime) > (Config.GlobalCooldown * 60) then
|
|
||||||
globalCooldowns[containerType] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Alternative method to register usable item for tgiann-inventory
|
|
||||||
RegisterNetEvent('QBCore:Server:UseItem', function(source, item)
|
|
||||||
if item.name == Config.RequiredItems.flex.name then
|
|
||||||
Debug("Player " .. source .. " used item via QBCore:Server:UseItem: " .. item.name)
|
|
||||||
TriggerClientEvent('container_heist:client:useFlexItem', source)
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Print message when resource starts
|
-- Print message when resource starts
|
||||||
AddEventHandler('onResourceStart', function(resourceName)
|
AddEventHandler('onResourceStart', function(resourceName)
|
||||||
if (GetCurrentResourceName() == resourceName) then
|
if (GetCurrentResourceName() == resourceName) then
|
||||||
print('^2[Container Heist]^7: Script started successfully')
|
print("^2[Container Heist]^7: Server script started successfully")
|
||||||
print('^2[Container Heist]^7: Registered usable item: ' .. Config.RequiredItems.flex.name)
|
print("^2[Container Heist]^7: Registered usable item: " .. Config.RequiredItems.flex.name)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue