1
0
Fork 0
forked from Simnation/Main
This commit is contained in:
Nordi98 2025-07-20 17:07:46 +02:00
parent 5cb18574a7
commit 491ceff534
4 changed files with 186 additions and 152 deletions

View file

@ -1,7 +1,9 @@
local QBCore = exports['qb-core']:GetCoreObject() local QBCore = exports['qb-core']:GetCoreObject()
local isRobbing = false local isRobbing = false
local currentPoint = nil local currentZone = nil
local containerBlip = nil local containerBlip = nil
local inZone = false
local currentZoneId = nil
-- Debug function -- Debug function
local function Debug(msg) local function Debug(msg)
@ -10,7 +12,7 @@ local function Debug(msg)
end end
end end
-- Completely rewritten DrawText3D function -- Function to draw 3D text
function DrawText3D(x, y, z, text) function DrawText3D(x, y, z, text)
-- Set the text properties -- Set the text properties
SetTextScale(0.35, 0.35) SetTextScale(0.35, 0.35)
@ -27,22 +29,36 @@ function DrawText3D(x, y, z, text)
ClearDrawOrigin() ClearDrawOrigin()
end end
-- Function to find the nearest container point -- Function to check if a point is inside a polygon
local function GetNearestContainerPoint() 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 playerPed = PlayerPedId()
local playerCoords = GetEntityCoords(playerPed) local playerCoords = GetEntityCoords(playerPed)
local closestPoint = nil
local minDistance = 3.0 -- Maximum interaction distance
for _, point in pairs(Config.ContainerPoints) do for _, zone in pairs(Config.ContainerZones) do
local distance = #(playerCoords - point.coords) if IsPointInPolygon(playerCoords, zone.points) and
if distance < minDistance then playerCoords.z >= zone.minZ and playerCoords.z <= zone.maxZ then
minDistance = distance return zone
closestPoint = point
end end
end end
return closestPoint, minDistance return nil
end end
-- Function to create a blip at the robbery location -- Function to create a blip at the robbery location
@ -117,18 +133,18 @@ local function PlayRobberyAnimation(containerType)
end end
-- Function to start container robbery -- Function to start container robbery
local function StartContainerRobbery(point) local function StartContainerRobbery(zone)
if isRobbing then return end if isRobbing then return end
isRobbing = true isRobbing = true
currentPoint = point currentZone = zone
-- Get container type from point -- Get container type from zone
local containerType = Config.ContainerTypes[point.type] local containerType = Config.ContainerTypes[zone.type]
if not containerType then if not containerType then
QBCore.Functions.Notify("Invalid container type!", "error") QBCore.Functions.Notify("Invalid container type!", "error")
isRobbing = false isRobbing = false
currentPoint = nil currentZone = nil
return return
end end
@ -137,7 +153,7 @@ local function StartContainerRobbery(point)
if not hasTools then if not hasTools then
QBCore.Functions.Notify(Config.Notifications.noTools, "error") QBCore.Functions.Notify(Config.Notifications.noTools, "error")
isRobbing = false isRobbing = false
currentPoint = nil currentZone = nil
return return
end end
@ -146,7 +162,7 @@ local function StartContainerRobbery(point)
if not cooldownCheck.success then if not cooldownCheck.success then
QBCore.Functions.Notify(cooldownCheck.message, "error") QBCore.Functions.Notify(cooldownCheck.message, "error")
isRobbing = false isRobbing = false
currentPoint = nil currentZone = nil
return return
end end
@ -155,18 +171,15 @@ local function StartContainerRobbery(point)
if policeCount < Config.PoliceRequired then if policeCount < Config.PoliceRequired then
QBCore.Functions.Notify(Config.Notifications.notEnoughPolice, "error") QBCore.Functions.Notify(Config.Notifications.notEnoughPolice, "error")
isRobbing = false isRobbing = false
currentPoint = nil currentZone = nil
return return
end end
-- Position player for animation
SetEntityCoords(PlayerPedId(), point.coords.x, point.coords.y, point.coords.z)
SetEntityHeading(PlayerPedId(), point.heading)
-- Alert police if configured -- Alert police if configured
if containerType.policeAlert then if containerType.policeAlert then
local streetName = GetStreetNameFromHashKey(GetStreetNameAtCoord(point.coords.x, point.coords.y, point.coords.z)) local playerCoords = GetEntityCoords(PlayerPedId())
TriggerServerEvent('container_heist:server:alertPolice', point.coords, streetName, containerType.label) local streetName = GetStreetNameFromHashKey(GetStreetNameAtCoord(playerCoords.x, playerCoords.y, playerCoords.z))
TriggerServerEvent('container_heist:server:alertPolice', playerCoords, streetName, containerType.label)
end end
-- Start robbery progress bar -- Start robbery progress bar
@ -179,31 +192,31 @@ local function StartContainerRobbery(point)
disableCombat = true, disableCombat = true,
}, {}, {}, {}, function() -- Done }, {}, {}, {}, function() -- Done
-- Success -- Success
TriggerServerEvent('container_heist:server:finishRobbery', point.id, point.type) TriggerServerEvent('container_heist:server:finishRobbery', zone.id, zone.type)
QBCore.Functions.Notify(Config.Notifications.success, "success") QBCore.Functions.Notify(Config.Notifications.success, "success")
isRobbing = false isRobbing = false
currentPoint = nil currentZone = nil
end, function() -- Cancel end, function() -- Cancel
-- Cancelled -- Cancelled
QBCore.Functions.Notify(Config.Notifications.failed, "error") QBCore.Functions.Notify(Config.Notifications.failed, "error")
isRobbing = false isRobbing = false
currentPoint = nil currentZone = nil
end) end)
end) end)
end, point.id) end, zone.id)
end) end)
end end
-- Command to start container robbery -- Register usable item
RegisterCommand('robcontainer', function() RegisterNetEvent('container_heist:client:useFlexItem', function()
local point, distance = GetNearestContainerPoint() local zone = GetCurrentZone()
if point then if zone then
StartContainerRobbery(point) StartContainerRobbery(zone)
else else
QBCore.Functions.Notify("No container nearby!", "error") QBCore.Functions.Notify(Config.Notifications.notInZone, "error")
end end
end, false) end)
-- Command to toggle debug mode -- Command to toggle debug mode
RegisterCommand('containerdebug', function() RegisterCommand('containerdebug', function()
@ -216,52 +229,87 @@ RegisterCommand('containerdebug', function()
end end
end, false) end, false)
-- Main thread for checking nearby container points and drawing text -- Main thread for checking if player is in a zone
CreateThread(function() CreateThread(function()
while true do while true do
local sleep = 1000 local sleep = 1000
local playerPed = PlayerPedId() local zone = GetCurrentZone()
local playerCoords = GetEntityCoords(playerPed)
for _, point in pairs(Config.ContainerPoints) do if zone then
local distance = #(playerCoords - point.coords) if not inZone or currentZoneId ~= zone.id then
inZone = true
if distance < 10.0 then currentZoneId = zone.id
sleep = 0 QBCore.Functions.Notify("You entered " .. zone.label .. ". Use your flex tool to break in.", "primary")
-- Draw marker at the container point
DrawMarker(1, point.coords.x, point.coords.y, point.coords.z - 1.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
1.0, 1.0, 0.2, 0, 255, 0, 100, false, true, 2, false, nil, nil, false)
-- Draw 3D text above the marker when close enough
if distance < 3.0 then
DrawText3D(point.coords.x, point.coords.y, point.coords.z + 0.5, point.label .. " [E]")
-- Check for interaction
if IsControlJustReleased(0, 38) and distance < 1.5 then -- E key
StartContainerRobbery(point)
end
end
end end
end sleep = 500
else
-- Debug mode - show all container points if inZone then
if Config.Debug then inZone = false
for _, point in pairs(Config.ContainerPoints) do currentZoneId = nil
DrawMarker(1, point.coords.x, point.coords.y, point.coords.z - 1.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
1.0, 1.0, 0.2, 255, 0, 0, 100, false, true, 2, false, nil, nil, false)
DrawText3D(point.coords.x, point.coords.y, point.coords.z + 1.0,
point.id .. " (" .. point.type .. ")")
end end
sleep = 0
end end
Wait(sleep) Wait(sleep)
end end
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 .. ")")
end
else
Wait(1000)
end
end
end)
-- Event to show police alert -- Event to show police alert
RegisterNetEvent('container_heist:client:policeAlert', function(coords, streetName, containerLabel) RegisterNetEvent('container_heist:client:policeAlert', function(coords, streetName, containerLabel)
local playerJob = QBCore.Functions.GetPlayerData().job.name local playerJob = QBCore.Functions.GetPlayerData().job.name

View file

@ -36,6 +36,7 @@ Config.Notifications = {
notEnoughPolice = "Not enough police in the city!", notEnoughPolice = "Not enough police in the city!",
policeMessage = "Container robbery in progress at %s", policeMessage = "Container robbery in progress at %s",
alreadyRobbed = "This container has already been robbed recently!", alreadyRobbed = "This container has already been robbed recently!",
notInZone = "You need to be in a container area to use this tool!",
} }
-- Blip Settings -- Blip Settings
@ -129,71 +130,67 @@ Config.ContainerTypes = {
}, },
} }
-- Container Points (specific locations for container robberies) -- Container Zones (defined by 4 points)
Config.ContainerPoints = { Config.ContainerZones = {
-- Port area shipping containers -- Port area shipping containers
{ {
id = "port_container_1", id = "port_containers",
type = "shipping", -- References the container type above for rewards type = "shipping", -- References the container type above for rewards
coords = vector3(896.4, -2967.91, 5.9), label = "Port Containers",
heading = 90.0, points = {
label = "Break into Container" vector3(896.4, -2967.91, 5.9), -- Point 1
}, vector3(896.4, -2957.91, 5.9), -- Point 2
{ vector3(886.4, -2957.91, 5.9), -- Point 3
id = "port_container_2", vector3(886.4, -2967.91, 5.9) -- Point 4
type = "shipping", },
coords = vector3(990.23, -3050.34, 5.90), minZ = 4.0,
heading = 90.0, maxZ = 15.0,
label = "Break into Container"
}, },
-- Weapons containers -- Weapons containers
{ {
id = "weapons_container_1", id = "weapons_containers",
type = "weapons", type = "weapons",
coords = vector3(905.45, -3200.67, 5.90), label = "Weapons Containers",
heading = 0.0, points = {
label = "Break into Weapons Container" vector3(905.45, -3200.67, 5.90), -- Point 1
}, vector3(905.45, -3190.67, 5.90), -- Point 2
{ vector3(895.45, -3190.67, 5.90), -- Point 3
id = "weapons_container_2", vector3(895.45, -3200.67, 5.90) -- Point 4
type = "weapons", },
coords = vector3(910.34, -3195.23, 5.90), minZ = 4.0,
heading = 270.0, maxZ = 15.0,
label = "Break into Weapons Container"
}, },
-- Cargo trailers -- Cargo trailers
{ {
id = "cargo_trailer_1", id = "cargo_trailers",
type = "cargo", type = "cargo",
coords = vector3(825.34, -3125.45, 5.90), label = "Cargo Trailers",
heading = 270.0, points = {
label = "Break into Cargo Trailer" vector3(825.34, -3125.45, 5.90), -- Point 1
}, vector3(825.34, -3115.45, 5.90), -- Point 2
{ vector3(815.34, -3115.45, 5.90), -- Point 3
id = "cargo_trailer_2", vector3(815.34, -3125.45, 5.90) -- Point 4
type = "cargo", },
coords = vector3(830.56, -3130.78, 5.90), minZ = 4.0,
heading = 180.0, maxZ = 15.0,
label = "Break into Cargo Trailer"
}, },
-- Food trailers -- Food trailers
{ {
id = "food_trailer_1", id = "food_trailers",
type = "food", type = "food",
coords = vector3(765.23, -3165.34, 5.90), label = "Food Trailers",
heading = 180.0, points = {
label = "Break into Food Trailer" vector3(765.23, -3165.34, 5.90), -- Point 1
}, vector3(765.23, -3155.34, 5.90), -- Point 2
{ vector3(755.23, -3155.34, 5.90), -- Point 3
id = "food_trailer_2", vector3(755.23, -3165.34, 5.90) -- Point 4
type = "food", },
coords = vector3(770.45, -3170.56, 5.90), minZ = 4.0,
heading = 90.0, maxZ = 15.0,
label = "Break into Food Trailer"
}, },
-- Add more points as needed -- Add more zones as needed
} }

View file

@ -6,21 +6,5 @@ author 'Your Name'
version '1.0.0' version '1.0.0'
shared_scripts { shared_scripts {
'@ox_lib/init.lua',
'config.lua' 'config.lua'
} }
client_scripts {
'client.lua'
}
server_scripts {
'server.lua'
}
lua54 'yes'
dependencies {
'ox_lib',
'qb-core'
}

View file

@ -1,5 +1,5 @@
local QBCore = exports['qb-core']:GetCoreObject() local QBCore = exports['qb-core']:GetCoreObject()
local pointCooldowns = {} local zoneCooldowns = {}
local playerCooldowns = {} local playerCooldowns = {}
local globalCooldowns = {} local globalCooldowns = {}
@ -10,6 +10,11 @@ local function Debug(msg)
end end
end end
-- Register usable item
QBCore.Functions.CreateUseableItem(Config.RequiredItems.flex.name, function(source)
TriggerClientEvent('container_heist:client:useFlexItem', source)
end)
-- Check if player has required items -- Check if player has required items
QBCore.Functions.CreateCallback('container_heist:server:checkRequiredItems', function(source, cb) QBCore.Functions.CreateCallback('container_heist:server:checkRequiredItems', function(source, cb)
local src = source local src = source
@ -22,7 +27,7 @@ QBCore.Functions.CreateCallback('container_heist:server:checkRequiredItems', fun
end) end)
-- Check cooldowns -- Check cooldowns
QBCore.Functions.CreateCallback('container_heist:server:checkCooldown', function(source, cb, pointId) QBCore.Functions.CreateCallback('container_heist:server:checkCooldown', function(source, cb, zoneId)
local src = source local src = source
local Player = QBCore.Functions.GetPlayer(src) local Player = QBCore.Functions.GetPlayer(src)
if not Player then return cb({success = false, message = "Player not found"}) end if not Player then return cb({success = false, message = "Player not found"}) end
@ -36,27 +41,27 @@ QBCore.Functions.CreateCallback('container_heist:server:checkCooldown', function
return cb({success = false, message = "You need to wait " .. timeLeft .. " more minutes before attempting another heist!"}) return cb({success = false, message = "You need to wait " .. timeLeft .. " more minutes before attempting another heist!"})
end end
-- Check point cooldown -- Check zone cooldown
if pointCooldowns[pointId] and (currentTime - pointCooldowns[pointId]) < (Config.CooldownTime * 60) then if zoneCooldowns[zoneId] and (currentTime - zoneCooldowns[zoneId]) < (Config.CooldownTime * 60) then
return cb({success = false, message = Config.Notifications.alreadyRobbed}) return cb({success = false, message = Config.Notifications.alreadyRobbed})
end end
-- Find point type -- Find zone type
local pointType = nil local zoneType = nil
for _, point in pairs(Config.ContainerPoints) do for _, zone in pairs(Config.ContainerZones) do
if point.id == pointId then if zone.id == zoneId then
pointType = point.type zoneType = zone.type
break break
end end
end end
if not pointType then if not zoneType then
return cb({success = false, message = "Invalid point!"}) return cb({success = false, message = "Invalid zone!"})
end end
-- Check global cooldown for container type -- Check global cooldown for container type
if globalCooldowns[pointType] and (currentTime - globalCooldowns[pointType]) < (Config.GlobalCooldown * 60) then if globalCooldowns[zoneType] and (currentTime - globalCooldowns[zoneType]) < (Config.GlobalCooldown * 60) then
local timeLeft = math.ceil(((globalCooldowns[pointType] + (Config.GlobalCooldown * 60)) - currentTime) / 60) local timeLeft = math.ceil(((globalCooldowns[zoneType] + (Config.GlobalCooldown * 60)) - currentTime) / 60)
return cb({success = false, message = Config.Notifications.globalCooldown .. " (" .. timeLeft .. " minutes left)"}) return cb({success = false, message = Config.Notifications.globalCooldown .. " (" .. timeLeft .. " minutes left)"})
end end
@ -104,7 +109,7 @@ RegisterNetEvent('container_heist:server:alertPolice', function(coords, streetNa
end) end)
-- Finish robbery and give rewards -- Finish robbery and give rewards
RegisterNetEvent('container_heist:server:finishRobbery', function(pointId, containerTypeName) 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
@ -114,7 +119,7 @@ RegisterNetEvent('container_heist:server:finishRobbery', function(pointId, conta
-- Set cooldowns -- Set cooldowns
playerCooldowns[citizenId] = currentTime playerCooldowns[citizenId] = currentTime
pointCooldowns[pointId] = currentTime zoneCooldowns[zoneId] = currentTime
globalCooldowns[containerTypeName] = currentTime globalCooldowns[containerTypeName] = currentTime
-- Get container type -- Get container type
@ -194,10 +199,10 @@ CreateThread(function()
end end
end end
-- Clean up point cooldowns -- Clean up zone cooldowns
for pointId, cooldownTime in pairs(pointCooldowns) do for zoneId, cooldownTime in pairs(zoneCooldowns) do
if (currentTime - cooldownTime) > (Config.CooldownTime * 60) then if (currentTime - cooldownTime) > (Config.CooldownTime * 60) then
pointCooldowns[pointId] = nil zoneCooldowns[zoneId] = nil
end end
end end