1
0
Fork 0
forked from Simnation/Main
This commit is contained in:
Nordi98 2025-07-20 17:36:21 +02:00
parent 0116d75418
commit c00df8dec6
3 changed files with 60 additions and 461 deletions

View file

@ -1,7 +1,5 @@
local QBCore = exports['qb-core']:GetCoreObject()
local isRobbing = false
local currentZone = nil
local containerBlip = nil
local inZone = false
local currentZoneId = nil
@ -12,23 +10,6 @@ local function Debug(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
@ -61,196 +42,47 @@ local function GetCurrentZone()
return nil
end
-- Function to create a blip at the robbery location
local function CreateRobberyBlip(coords)
if containerBlip then
RemoveBlip(containerBlip)
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)
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
local zone = GetCurrentZone()
if zone then
QBCore.Functions.Notify("You are in zone: " .. zone.id, "success")
print("In zone: " .. zone.id)
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
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
end, false)
-- Function to play container robbery animation
local function PlayRobberyAnimation(containerType)
local playerPed = PlayerPedId()
local animDict = containerType.animation.dict
local animName = containerType.animation.name
-- Command to start robbery (for testing)
RegisterCommand('robcontainer', function()
local zone = GetCurrentZone()
RequestAnimDict(animDict)
while not HasAnimDictLoaded(animDict) do
Wait(10)
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
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
end, false)
-- 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
-- Register usable item event handler
RegisterNetEvent('container_heist:client:useFlexItem', function()
Debug("useFlexItem event triggered")
print("useFlexItem event triggered")
local zone = GetCurrentZone()
if zone then
Debug("Player is in zone: " .. zone.id)
StartContainerRobbery(zone)
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)
-- 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
@ -262,14 +94,14 @@ CreateThread(function()
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)
print("Entered zone: " .. zone.id)
end
sleep = 500
else
if inZone then
inZone = false
currentZoneId = nil
Debug("Left zone")
print("Left zone")
end
end
@ -280,8 +112,6 @@ end)
-- Debug thread for visualizing zones
CreateThread(function()
while true do
Wait(0)
if Config.Debug then
local playerPed = PlayerPedId()
local playerCoords = GetEntityCoords(playerPed)
@ -299,21 +129,7 @@ CreateThread(function()
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
)
}
end
-- Calculate center of zone for label
local centerX, centerY = 0, 0
@ -326,52 +142,35 @@ CreateThread(function()
-- Draw zone label
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
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"
-- 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
-- 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)
end
-- Print message when resource starts
AddEventHandler('onClientResourceStart', function(resourceName)
if (GetCurrentResourceName() == resourceName) then
Debug("Client script started successfully")
print("^2[Container Heist]^7: Client script started successfully")
end
end)

View file

@ -8,7 +8,6 @@ Config.PoliceRequired = 1 -- Minimum police required
Config.PoliceJobs = {
"police", -- Regular police
"marshal", -- Marshal service
"sheriff" -- Sheriff department
}
-- Required Items

View file

@ -1,7 +1,4 @@
local QBCore = exports['qb-core']:GetCoreObject()
local zoneCooldowns = {}
local playerCooldowns = {}
local globalCooldowns = {}
-- Debug function
local function Debug(msg)
@ -10,226 +7,30 @@ local function Debug(msg)
end
end
-- Register usable item - FIXED VERSION
QBCore.Functions.CreateUseableItem(Config.RequiredItems.flex.name, function(source, item)
local src = source
Debug("Player " .. src .. " used item: " .. Config.RequiredItems.flex.name)
TriggerClientEvent('container_heist:client:useFlexItem', src)
-- Register usable item
QBCore.Functions.CreateUseableItem(Config.RequiredItems.flex.name, function(source)
print("Player " .. source .. " used item: " .. Config.RequiredItems.flex.name)
TriggerClientEvent('container_heist:client:useFlexItem', source)
end)
-- Check if player has required items
QBCore.Functions.CreateCallback('container_heist:server:checkRequiredItems', function(source, cb)
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)
-- Test robbery event
RegisterNetEvent('container_heist:server:testRobbery', function(zoneId, zoneType)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
local citizenId = Player.PlayerData.citizenid
local currentTime = os.time()
print("Player " .. src .. " started robbery in zone: " .. zoneId .. " of type: " .. zoneType)
TriggerClientEvent('QBCore:Notify', src, "Robbery started in zone: " .. zoneId, "success")
-- Set cooldowns
playerCooldowns[citizenId] = currentTime
zoneCooldowns[zoneId] = currentTime
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
-- Give a test reward
exports['tgiann-inventory']:AddItem(src, "cash", 1000)
TriggerClientEvent('QBCore:Notify', src, "You found $1000!", "success")
end)
-- Print message when resource starts
AddEventHandler('onResourceStart', function(resourceName)
if (GetCurrentResourceName() == resourceName) then
print('^2[Container Heist]^7: Script started successfully')
print('^2[Container Heist]^7: Registered usable item: ' .. Config.RequiredItems.flex.name)
print("^2[Container Heist]^7: Server script started successfully")
print("^2[Container Heist]^7: Registered usable item: " .. Config.RequiredItems.flex.name)
end
end)