From 2a1f7bf95cca15d2e2ba5b7639cf8cd1ff6ad3cd Mon Sep 17 00:00:00 2001 From: Nordi98 Date: Sun, 20 Jul 2025 18:04:26 +0200 Subject: [PATCH] ed --- .../nordi_containerheist/client/main.lua | 98 ++++- .../[crime]/nordi_containerheist/config.lua | 356 ++---------------- 2 files changed, 109 insertions(+), 345 deletions(-) diff --git a/resources/[jobs]/[crime]/nordi_containerheist/client/main.lua b/resources/[jobs]/[crime]/nordi_containerheist/client/main.lua index ad164ca1d..ff6071d9a 100644 --- a/resources/[jobs]/[crime]/nordi_containerheist/client/main.lua +++ b/resources/[jobs]/[crime]/nordi_containerheist/client/main.lua @@ -21,6 +21,40 @@ local function GetModelNameFromHash(hash) return "Unknown" end +-- Function to check if player is at the correct position (rear for trailers, door for containers) +local function IsPlayerAtCorrectPosition(entity, containerType) + local playerPos = GetEntityCoords(PlayerPedId()) + local entityPos = GetEntityCoords(entity) + local entityHeading = GetEntityHeading(entity) + local entityForwardVector = GetEntityForwardVector(entity) + + -- Get vector from entity to player + local toPlayerVector = vector3( + playerPos.x - entityPos.x, + playerPos.y - entityPos.y, + 0.0 + ) + + -- Normalize the vector + local length = math.sqrt(toPlayerVector.x^2 + toPlayerVector.y^2) + if length > 0 then + toPlayerVector = vector3(toPlayerVector.x / length, toPlayerVector.y / length, 0.0) + else + return false + end + + -- Calculate dot product with forward vector + local forwardDot = toPlayerVector.x * entityForwardVector.x + toPlayerVector.y * entityForwardVector.y + + if string.match(containerType.type, "trailer") then + -- For trailers, player should be at the rear (negative dot product) + return forwardDot < -0.7 -- Threshold to ensure player is behind the trailer + else + -- For containers, player should be at the door (positive dot product) + return forwardDot > 0.7 -- Threshold to ensure player is in front of the container + end +end + -- Function to check if player is near a valid container local function IsNearValidContainer() local playerPed = PlayerPedId() @@ -40,10 +74,19 @@ local function IsNearValidContainer() 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 + -- Check if player is at the door for containers + if IsPlayerAtCorrectPosition(object, containerType) then + foundEntity = object + foundType = containerType + closestDistance = distance + break + else + lib.notify({ + title = Config.Notifications.title, + description = "You need to stand at the door of the container!", + type = 'error' + }) + end end end end @@ -61,10 +104,19 @@ local function IsNearValidContainer() 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 + -- Check if player is at the rear for trailers + if IsPlayerAtCorrectPosition(vehicle, containerType) then + foundEntity = vehicle + foundType = containerType + closestDistance = distance + break + else + lib.notify({ + title = Config.Notifications.title, + description = "You need to stand at the rear of the trailer!", + type = 'error' + }) + end end end end @@ -191,14 +243,31 @@ local function StartContainerRobbery(container, containerType) return end + -- Get container dimensions + local containerModel = GetEntityModel(container) + local min, max = GetModelDimensions(containerModel) + local containerLength = max.y - min.y + -- 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) + local offsetCoords + local playerHeading + + -- Check if this is a trailer type + if string.match(containerType.type, "trailer") then + -- For trailers, position at the rear + offsetCoords = GetOffsetFromEntityInWorldCoords(container, 0.0, -(containerLength/2 + 1.0), 0.0) + playerHeading = containerHeading + 180.0 -- Face the rear of the trailer + else + -- For containers, position at the door (front) + offsetCoords = GetOffsetFromEntityInWorldCoords(container, 0.0, containerLength/2 + 1.0, 0.0) + playerHeading = containerHeading -- Face the front of the container + end -- Set player position and heading SetEntityCoords(PlayerPedId(), offsetCoords.x, offsetCoords.y, offsetCoords.z) - SetEntityHeading(PlayerPedId(), containerHeading + containerType.heading) + SetEntityHeading(PlayerPedId(), playerHeading) -- Alert police if configured if containerType.policeAlert then @@ -271,6 +340,9 @@ local function ScanAndAddContainersToTarget() icon = "fas fa-angle-double-right", label = "Break into " .. containerType.label, containerType = containerType, + canInteract = function(entity) + return IsPlayerAtCorrectPosition(entity, containerType) + end } }, distance = 3.0 @@ -306,6 +378,9 @@ local function ScanAndAddContainersToTarget() icon = "fas fa-angle-double-right", label = "Break into " .. containerType.label, containerType = containerType, + canInteract = function(entity) + return IsPlayerAtCorrectPosition(entity, containerType) + end } }, distance = 3.0 @@ -469,6 +544,9 @@ CreateThread(function() icon = "fas fa-angle-double-right", label = "Break into " .. containerType.label, containerType = containerType, + canInteract = function(entity) + return IsPlayerAtCorrectPosition(entity, containerType) + end } }, distance = 3.0 diff --git a/resources/[jobs]/[crime]/nordi_containerheist/config.lua b/resources/[jobs]/[crime]/nordi_containerheist/config.lua index 6a9a01c40..962c6b4e8 100644 --- a/resources/[jobs]/[crime]/nordi_containerheist/config.lua +++ b/resources/[jobs]/[crime]/nordi_containerheist/config.lua @@ -35,6 +35,8 @@ Config.Notifications = { notEnoughPolice = "Not enough police in the city!", policeMessage = "Container robbery in progress at %s", alreadyRobbed = "This container has already been robbed recently!", + containerPosition = "You need to stand at the door of the container!", + trailerPosition = "You need to stand at the rear of the trailer!", } -- Blip Settings @@ -421,343 +423,27 @@ Config.ContainerTypes = { }, -- Trailer models - { - model = "trailers", - type = "trailer", - label = "Cargo Trailer", - offset = vector3(0.0, -5.0, 0.0), - heading = 180.0, - animation = { - dict = "amb@world_human_welding@male@base", - name = "base", - flag = 1, - duration = 45000, - }, - rewards = { - {item = "electronics", label = "Electronics", min = 3, max = 8, chance = 40}, - {item = "plastic", label = "Plastic", min = 10, max = 20, chance = 60}, - {item = "aluminum", label = "Aluminum", min = 10, max = 20, chance = 50}, - {item = "copper", label = "Copper", min = 5, max = 15, chance = 30}, - {item = "cash", label = "Cash", min = 3000, max = 10000, chance = 25}, - }, - policeAlert = true, +{ + model = "trailers", + type = "trailer", + label = "Cargo Trailer", + offset = vector3(0.0, 0.0, 0.0), -- Changed to use dynamic positioning in the function + heading = 0.0, -- Changed to use dynamic heading in the function + animation = { + dict = "amb@world_human_welding@male@base", + name = "base", + flag = 1, + duration = 45000, }, - { - model = "trailers2", - type = "trailer", - label = "Box Trailer", - offset = vector3(0.0, -5.0, 0.0), - heading = 180.0, - animation = { - dict = "amb@world_human_welding@male@base", - name = "base", - flag = 1, - duration = 40000, - }, - rewards = { - {item = "food", label = "Food", min = 5, max = 15, chance = 70}, - {item = "water", label = "Water", min = 5, max = 15, chance = 70}, - {item = "firstaid", label = "First Aid Kit", min = 1, max = 3, chance = 30}, - {item = "cash", label = "Cash", min = 500, max = 3000, chance = 20}, - }, - policeAlert = false, - }, - { - model = "trailers3", - type = "trailer", - label = "Transport Trailer", - offset = vector3(0.0, -5.0, 0.0), - heading = 180.0, - animation = { - dict = "amb@world_human_welding@male@base", - name = "base", - flag = 1, - duration = 40000, - }, - rewards = { - {item = "phone", label = "Phone", min = 1, max = 3, chance = 30}, - {item = "rolex", label = "Rolex Watch", min = 1, max = 2, chance = 20}, - {item = "goldchain", label = "Gold Chain", min = 1, max = 3, chance = 25}, - {item = "diamond", label = "Diamond", min = 1, max = 1, chance = 5}, - {item = "laptop", label = "Laptop", min = 1, max = 1, chance = 15}, - {item = "cash", label = "Cash", min = 1000, max = 5000, chance = 40}, - }, - policeAlert = true, - }, - { - model = "trailers4", - type = "trailer", - label = "Car Trailer", - offset = vector3(0.0, -5.0, 0.0), - heading = 180.0, - animation = { - dict = "amb@world_human_welding@male@base", - name = "base", - flag = 1, - duration = 40000, - }, - rewards = { - {item = "carparts", label = "Car Parts", min = 3, max = 8, chance = 60}, - {item = "toolbox", label = "Toolbox", min = 1, max = 2, chance = 40}, - {item = "cash", label = "Cash", min = 1000, max = 3000, chance = 30}, - }, - policeAlert = true, - }, - { - model = "trailerlogs", - type = "trailer", - label = "Logging Trailer", - offset = vector3(0.0, -5.0, 0.0), - heading = 180.0, - animation = { - dict = "amb@world_human_welding@male@base", - name = "base", - flag = 1, - duration = 40000, - }, - rewards = { - {item = "wood", label = "Wood", min = 10, max = 20, chance = 80}, - {item = "cash", label = "Cash", min = 500, max = 2000, chance = 20}, - }, - policeAlert = false, - }, - { - model = "tanker", - type = "trailer", - label = "Fuel Tanker", - offset = vector3(0.0, -5.0, 0.0), - heading = 180.0, - animation = { - dict = "amb@world_human_welding@male@base", - name = "base", - flag = 1, - duration = 50000, - }, - rewards = { - {item = "petrol", label = "Petrol", min = 10, max = 20, chance = 70}, - {item = "cash", label = "Cash", min = 2000, max = 5000, chance = 30}, - }, - policeAlert = true, - }, - { - model = "tanker2", - type = "trailer", - label = "Chemical Tanker", - offset = vector3(0.0, -5.0, 0.0), - heading = 180.0, - animation = { - dict = "amb@world_human_welding@male@base", - name = "base", - flag = 1, - duration = 50000, - }, - rewards = { - {item = "chemicals", label = "Chemicals", min = 5, max = 15, chance = 60}, - {item = "cash", label = "Cash", min = 3000, max = 8000, chance = 40}, - }, - policeAlert = true, - }, - { - model = "docktrailer", - type = "trailer", - label = "Dock Trailer", - offset = vector3(0.0, -5.0, 0.0), - heading = 180.0, - animation = { - dict = "amb@world_human_welding@male@base", - name = "base", - flag = 1, - duration = 40000, - }, - rewards = { - {item = "electronics", label = "Electronics", min = 3, max = 8, chance = 40}, - {item = "plastic", label = "Plastic", min = 10, max = 20, chance = 60}, - {item = "aluminum", label = "Aluminum", min = 10, max = 20, chance = 50}, - {item = "copper", label = "Copper", min = 5, max = 15, chance = 30}, - {item = "cash", label = "Cash", min = 3000, max = 10000, chance = 25}, - }, - policeAlert = true, - }, - { - model = "tr2", - type = "trailer", - label = "Car Carrier Trailer", - offset = vector3(0.0, -5.0, 0.0), - heading = 180.0, - animation = { - dict = "amb@world_human_welding@male@base", - name = "base", - flag = 1, - duration = 40000, - }, - rewards = { - {item = "carparts", label = "Car Parts", min = 3, max = 8, chance = 60}, - {item = "toolbox", label = "Toolbox", min = 1, max = 2, chance = 40}, - {item = "cash", label = "Cash", min = 1000, max = 3000, chance = 30}, - }, - policeAlert = true, - }, - { - model = "tr3", - type = "trailer", - label = "Large Trailer", - offset = vector3(0.0, -5.0, 0.0), - heading = 180.0, - animation = { - dict = "amb@world_human_welding@male@base", - name = "base", - flag = 1, - duration = 40000, - }, - rewards = { - {item = "electronics", label = "Electronics", min = 3, max = 8, chance = 40}, - {item = "plastic", label = "Plastic", min = 10, max = 20, chance = 60}, - {item = "aluminum", label = "Aluminum", min = 10, max = 20, chance = 50}, - {item = "copper", label = "Copper", min = 5, max = 15, chance = 30}, - {item = "cash", label = "Cash", min = 3000, max = 10000, chance = 25}, - }, - policeAlert = true, - }, - { - model = "tr4", - type = "trailer", - label = "Training Trailer", - offset = vector3(0.0, -5.0, 0.0), - heading = 180.0, - animation = { - dict = "amb@world_human_welding@male@base", - name = "base", - flag = 1, - duration = 40000, - }, - rewards = { - {item = "electronics", label = "Electronics", min = 3, max = 8, chance = 40}, - {item = "plastic", label = "Plastic", min = 10, max = 20, chance = 60}, - {item = "aluminum", label = "Aluminum", min = 10, max = 20, chance = 50}, - {item = "copper", label = "Copper", min = 5, max = 15, chance = 30}, - {item = "cash", label = "Cash", min = 3000, max = 10000, chance = 25}, - }, - policeAlert = true, - }, - { - model = "tvtrailer", - type = "trailer", - label = "TV Trailer", - offset = vector3(0.0, -5.0, 0.0), - heading = 180.0, - animation = { - dict = "amb@world_human_welding@male@base", - name = "base", - flag = 1, - duration = 40000, - }, - rewards = { - {item = "electronics", label = "Electronics", min = 5, max = 10, chance = 70}, - {item = "wires", label = "Wires", min = 5, max = 15, chance = 60}, - {item = "cash", label = "Cash", min = 2000, max = 6000, chance = 30}, - }, - policeAlert = true, - }, - { - model = "armytanker", - type = "trailer", - label = "Military Tanker", - offset = vector3(0.0, -5.0, 0.0), - heading = 180.0, - animation = { - dict = "amb@world_human_welding@male@base", - name = "base", - flag = 1, - duration = 50000, - }, - rewards = { - {item = "weapon_pistol", label = "Pistol", min = 1, max = 1, chance = 15}, - {item = "pistol_ammo", label = "Pistol Ammo", min = 10, max = 30, chance = 30}, - {item = "armor", label = "Body Armor", min = 1, max = 3, chance = 25}, - {item = "cash", label = "Cash", min = 5000, max = 15000, chance = 20}, - }, - policeAlert = true, - }, - { - model = "armytrailer", - type = "trailer", - label = "Military Trailer", - offset = vector3(0.0, -5.0, 0.0), - heading = 180.0, - animation = { - dict = "amb@world_human_welding@male@base", - name = "base", - flag = 1, - duration = 50000, - }, - rewards = { - {item = "weapon_pistol", label = "Pistol", min = 1, max = 1, chance = 15}, - {item = "pistol_ammo", label = "Pistol Ammo", min = 10, max = 30, chance = 30}, - {item = "armor", label = "Body Armor", min = 1, max = 3, chance = 25}, - {item = "cash", label = "Cash", min = 5000, max = 15000, chance = 20}, - }, - policeAlert = true, - }, - { - model = "freighttrailer", - type = "trailer", - label = "Freight Trailer", - offset = vector3(0.0, -5.0, 0.0), - heading = 180.0, - animation = { - dict = "amb@world_human_welding@male@base", - name = "base", - flag = 1, - duration = 45000, - }, - rewards = { - {item = "electronics", label = "Electronics", min = 3, max = 8, chance = 40}, - {item = "plastic", label = "Plastic", min = 10, max = 20, chance = 60}, - {item = "aluminum", label = "Aluminum", min = 10, max = 20, chance = 50}, - {item = "copper", label = "Copper", min = 5, max = 15, chance = 30}, - {item = "cash", label = "Cash", min = 3000, max = 10000, chance = 25}, - }, - policeAlert = true, - }, - { - model = "graintrailer", - type = "trailer", - label = "Grain Trailer", - offset = vector3(0.0, -5.0, 0.0), - heading = 180.0, - animation = { - dict = "amb@world_human_welding@male@base", - name = "base", - flag = 1, - duration = 40000, - }, - rewards = { - {item = "grain", label = "Grain", min = 10, max = 20, chance = 80}, - {item = "cash", label = "Cash", min = 500, max = 2000, chance = 20}, - }, - policeAlert = false, - }, - { - model = "proptrailer", - type = "trailer", - label = "Prop Trailer", - offset = vector3(0.0, -5.0, 0.0), - heading = 180.0, - animation = { - dict = "amb@world_human_welding@male@base", - name = "base", - flag = 1, - duration = 40000, - }, - rewards = { - {item = "electronics", label = "Electronics", min = 3, max = 8, chance = 40}, - {item = "plastic", label = "Plastic", min = 10, max = 20, chance = 60}, - {item = "aluminum", label = "Aluminum", min = 10, max = 20, chance = 50}, - {item = "copper", label = "Copper", min = 5, max = 15, chance = 30}, - {item = "cash", label = "Cash", min = 3000, max = 10000, chance = 25}, - }, - policeAlert = true, + rewards = { + {item = "electronics", label = "Electronics", min = 3, max = 8, chance = 40}, + {item = "plastic", label = "Plastic", min = 10, max = 20, chance = 60}, + {item = "aluminum", label = "Aluminum", min = 10, max = 20, chance = 50}, + {item = "copper", label = "Copper", min = 5, max = 15, chance = 30}, + {item = "cash", label = "Cash", min = 3000, max = 10000, chance = 25}, }, + policeAlert = true, +}, }