2025-07-29 07:30:32 +02:00
local QBCore = exports [ ' qb-core ' ] : GetCoreObject ( )
2025-07-29 09:48:16 +02:00
-- Function to initialize targets
function InitializeTargets ( )
-- Remove existing targets first to avoid duplicates
exports [ ' qb-target ' ] : RemoveTargetModel ( Config.VendingProps )
Wait ( 100 )
2025-07-29 07:30:32 +02:00
2025-07-29 09:48:16 +02:00
-- Add targets
2025-07-29 07:30:32 +02:00
exports [ ' qb-target ' ] : AddTargetModel ( Config.VendingProps , {
options = {
{
type = " client " ,
event = " vending:client:buyMachine " ,
icon = " fas fa-dollar-sign " ,
2025-07-29 08:25:12 +02:00
label = " Automaten kaufen ($ " .. Config.VendingMachinePrice .. " ) " ,
2025-07-29 09:02:52 +02:00
canInteract = function ( entity )
2025-07-29 08:25:12 +02:00
return not isRegisteredMachine ( entity )
end
2025-07-29 07:30:32 +02:00
} ,
{
type = " client " ,
event = " vending:client:openBuyMenu " ,
icon = " fas fa-shopping-cart " ,
2025-07-29 08:25:12 +02:00
label = " Kaufen " ,
2025-07-29 09:02:52 +02:00
canInteract = function ( entity )
2025-07-29 08:25:12 +02:00
return isRegisteredMachine ( entity )
end
2025-07-29 07:30:32 +02:00
} ,
{
type = " client " ,
event = " vending:client:openOwnerMenu " ,
icon = " fas fa-cog " ,
2025-07-29 08:25:12 +02:00
label = " Verwalten " ,
2025-07-29 09:02:52 +02:00
canInteract = function ( entity )
return canManageMachine ( entity )
2025-07-29 08:25:12 +02:00
end
} ,
{
type = " client " ,
event = " vending:client:startRobbery " ,
icon = " fas fa-mask " ,
label = " Aufbrechen " ,
2025-07-29 09:02:52 +02:00
canInteract = function ( entity )
return isRegisteredMachine ( entity ) and not canManageMachine ( entity )
2025-07-29 08:25:12 +02:00
end
2025-07-29 07:30:32 +02:00
}
} ,
distance = 2.0
} )
2025-07-29 09:48:16 +02:00
print ( " ^2[VENDING]^7 Added targets to " .. # Config.VendingProps .. " vending machine props " )
end
-- Add targets to all vending machine props with multiple attempts (Option 1)
CreateThread ( function ( )
-- First attempt
Wait ( 2000 )
InitializeTargets ( )
-- Second attempt after a delay
Wait ( 5000 )
InitializeTargets ( )
-- Third attempt after server is fully loaded
Wait ( 10000 )
InitializeTargets ( )
2025-07-29 08:18:21 +02:00
end )
2025-07-29 07:30:32 +02:00
2025-07-29 09:48:16 +02:00
-- Event-based initialization (Option 2)
RegisterNetEvent ( ' QBCore:Client:OnPlayerLoaded ' , function ( )
Wait ( 1000 )
InitializeTargets ( )
end )
RegisterNetEvent ( ' QBCore:Client:OnPlayerUnload ' , function ( )
-- Nothing to do here, but good to have for completeness
end )
-- Listen for resource start/stop events
AddEventHandler ( ' onResourceStart ' , function ( resourceName )
if resourceName == ' qb-target ' or resourceName == GetCurrentResourceName ( ) then
Wait ( 1000 )
InitializeTargets ( )
end
end )
-- Command to manually refresh targets
RegisterCommand ( ' refreshvendingtargets ' , function ( )
InitializeTargets ( )
QBCore.Functions . Notify ( ' Vending machine targets refreshed ' , ' success ' )
end , false )
2025-07-29 08:25:12 +02:00
-- Check if machine is registered
function isRegisteredMachine ( entity )
2025-07-29 10:11:01 +02:00
local entityId = NetworkGetNetworkIdFromEntity ( entity )
2025-07-29 08:25:12 +02:00
local isRegistered = false
QBCore.Functions . TriggerCallback ( ' vending:server:machineExists ' , function ( exists )
isRegistered = exists
2025-07-29 10:11:01 +02:00
end , entityId )
2025-07-29 08:25:12 +02:00
-- Wait for callback (not ideal but works for canInteract)
local timeout = 0
while isRegistered == false and timeout < 100 do
Wait ( 10 )
timeout = timeout + 1
end
return isRegistered
end
2025-07-29 09:02:52 +02:00
-- Check if player can manage machine
function canManageMachine ( entity )
2025-07-29 10:11:01 +02:00
local entityId = NetworkGetNetworkIdFromEntity ( entity )
2025-07-29 09:02:52 +02:00
local canManage = false
2025-07-29 08:25:12 +02:00
2025-07-29 09:02:52 +02:00
QBCore.Functions . TriggerCallback ( ' vending:server:canManage ' , function ( result )
canManage = result
2025-07-29 10:11:01 +02:00
end , entityId )
2025-07-29 08:25:12 +02:00
-- Wait for callback
local timeout = 0
2025-07-29 09:02:52 +02:00
while canManage == false and timeout < 100 do
2025-07-29 08:25:12 +02:00
Wait ( 10 )
timeout = timeout + 1
end
2025-07-29 09:02:52 +02:00
return canManage
2025-07-29 08:25:12 +02:00
end
2025-07-29 07:30:32 +02:00
-- Buy vending machine
RegisterNetEvent ( ' vending:client:buyMachine ' , function ( data )
local entity = data.entity
local coords = GetEntityCoords ( entity )
local model = GetEntityModel ( entity )
2025-07-29 10:11:01 +02:00
local entityId = NetworkGetNetworkIdFromEntity ( entity )
2025-07-29 07:30:32 +02:00
local prop = nil
2025-07-29 10:11:01 +02:00
print ( " [VENDING] Buying machine: Entity ID: " .. entityId )
2025-07-29 07:30:32 +02:00
-- Find prop name
for i = 1 , # Config.VendingProps do
if GetHashKey ( Config.VendingProps [ i ] ) == model then
prop = Config.VendingProps [ i ]
break
end
end
2025-07-29 08:25:12 +02:00
if not prop then return end
2025-07-29 07:30:32 +02:00
lib.registerContext ( {
id = ' vending_buy_confirm ' ,
title = ' Verkaufsautomat kaufen ' ,
options = {
{
title = ' Bestätigen ' ,
description = ' Automaten für $ ' .. Config.VendingMachinePrice .. ' kaufen ' ,
icon = ' fas fa-check ' ,
onSelect = function ( )
2025-07-29 10:11:01 +02:00
TriggerServerEvent ( ' vending:server:registerMachine ' , coords , prop , entityId )
2025-07-29 07:30:32 +02:00
end
} ,
{
title = ' Abbrechen ' ,
description = ' Kauf abbrechen ' ,
icon = ' fas fa-times '
}
}
} )
lib.showContext ( ' vending_buy_confirm ' )
end )
2025-07-29 09:02:52 +02:00
-- Open buy menu with quantity selection
2025-07-29 07:30:32 +02:00
RegisterNetEvent ( ' vending:client:openBuyMenu ' , function ( data )
local entity = data.entity
2025-07-29 10:11:01 +02:00
local entityId = NetworkGetNetworkIdFromEntity ( entity )
print ( " [VENDING] Opening buy menu: Entity ID: " .. entityId )
2025-07-29 07:30:32 +02:00
QBCore.Functions . TriggerCallback ( ' vending:server:getStashItems ' , function ( items )
if # items == 0 then
QBCore.Functions . Notify ( ' Dieser Automat ist leer! ' , ' error ' )
return
end
local options = { }
for i = 1 , # items do
local item = items [ i ]
if item.amount > 0 then
2025-07-29 07:51:42 +02:00
local itemLabel = QBCore.Shared . Items [ item.name ] and QBCore.Shared . Items [ item.name ] . label or item.name
2025-07-29 07:30:32 +02:00
table.insert ( options , {
2025-07-29 07:51:42 +02:00
title = itemLabel ,
2025-07-29 07:30:32 +02:00
description = ' Preis: $ ' .. item.price .. ' | Verfügbar: ' .. item.amount ,
2025-07-29 08:25:12 +02:00
icon = ' fas fa-shopping-cart ' ,
2025-07-29 07:30:32 +02:00
onSelect = function ( )
2025-07-29 10:11:01 +02:00
openQuantityDialog ( entityId , item.name , item.price , item.amount , itemLabel )
2025-07-29 07:30:32 +02:00
end
} )
end
end
2025-07-29 08:25:12 +02:00
if # options == 0 then
QBCore.Functions . Notify ( ' Keine Artikel verfügbar! ' , ' error ' )
return
end
2025-07-29 07:30:32 +02:00
lib.registerContext ( {
id = ' vending_buy_menu ' ,
title = ' Verkaufsautomat ' ,
options = options
} )
lib.showContext ( ' vending_buy_menu ' )
2025-07-29 10:11:01 +02:00
end , entityId )
2025-07-29 07:30:32 +02:00
end )
2025-07-29 09:02:52 +02:00
-- Open quantity dialog for buying items
2025-07-29 10:11:01 +02:00
function openQuantityDialog ( entityId , itemName , price , maxAmount , itemLabel )
2025-07-29 09:02:52 +02:00
local input = lib.inputDialog ( ' Menge auswählen ' , {
{
type = ' number ' ,
label = itemLabel .. ' - $ ' .. price .. ' pro Stück ' ,
description = ' Wie viele möchtest du kaufen? (Max: ' .. maxAmount .. ' ) ' ,
required = true ,
min = 1 ,
max = maxAmount ,
default = 1
}
} )
if input and input [ 1 ] then
local amount = tonumber ( input [ 1 ] )
if amount > 0 and amount <= maxAmount then
2025-07-29 10:11:01 +02:00
TriggerServerEvent ( ' vending:server:buyItem ' , itemName , amount , entityId )
2025-07-29 09:02:52 +02:00
else
QBCore.Functions . Notify ( ' Ungültige Menge! ' , ' error ' )
end
end
end
2025-07-29 07:30:32 +02:00
-- Open owner menu
RegisterNetEvent ( ' vending:client:openOwnerMenu ' , function ( data )
local entity = data.entity
2025-07-29 10:11:01 +02:00
local entityId = NetworkGetNetworkIdFromEntity ( entity )
print ( " [VENDING] Opening owner menu: Entity ID: " .. entityId )
2025-07-29 07:30:32 +02:00
2025-07-29 10:11:01 +02:00
QBCore.Functions . TriggerCallback ( ' vending:server:getMachineByEntity ' , function ( machine )
2025-07-29 08:25:12 +02:00
if not machine then
QBCore.Functions . Notify ( ' Automat nicht gefunden! ' , ' error ' )
return
end
2025-07-29 10:11:01 +02:00
print ( " [VENDING] Machine data received: ID: " .. machine.id .. " , isOwner: " .. tostring ( machine.isOwner ) )
2025-07-29 09:02:52 +02:00
local options = {
{
title = ' Inventar verwalten ' ,
description = ' Items hinzufügen/entfernen ' ,
icon = ' fas fa-box ' ,
onSelect = function ( )
2025-07-29 10:11:01 +02:00
TriggerServerEvent ( ' vending:server:openStash ' , entityId )
2025-07-29 09:02:52 +02:00
end
} ,
{
title = ' Preise festlegen ' ,
description = ' Verkaufspreise für Items setzen ' ,
icon = ' fas fa-tags ' ,
onSelect = function ( )
2025-07-29 10:11:01 +02:00
openPriceMenu ( entityId )
2025-07-29 09:02:52 +02:00
end
} ,
{
title = ' Geld abheben ' ,
description = ' Verfügbar: $ ' .. machine.money ,
icon = ' fas fa-money-bill ' ,
onSelect = function ( )
2025-07-29 10:11:01 +02:00
openWithdrawMenu ( entityId , machine.money )
2025-07-29 09:02:52 +02:00
end
} ,
{
title = ' Statistiken ' ,
description = ' Verkaufsstatistiken anzeigen ' ,
icon = ' fas fa-chart-bar ' ,
onSelect = function ( )
openStatsMenu ( machine )
end
}
}
-- Add manager options only for owner
if machine.isOwner then
2025-07-29 10:11:01 +02:00
print ( " [VENDING] Adding manager options for owner " )
2025-07-29 09:02:52 +02:00
table.insert ( options , {
title = ' Verwalter ' ,
description = ' Verwalter hinzufügen/entfernen ' ,
icon = ' fas fa-users-cog ' ,
onSelect = function ( )
2025-07-29 10:11:01 +02:00
openManagersMenu ( entityId )
2025-07-29 09:02:52 +02:00
end
} )
2025-07-29 09:20:46 +02:00
-- Add sell option only for owner
table.insert ( options , {
title = ' Automaten verkaufen ' ,
description = ' Verkaufe den Automaten für ' .. math.floor ( Config.VendingMachinePrice * Config.SellBackPercentage / 100 ) .. ' $ ' ,
icon = ' fas fa-dollar-sign ' ,
onSelect = function ( )
2025-07-29 10:11:01 +02:00
sellVendingMachine ( entityId , machine.id )
2025-07-29 09:20:46 +02:00
end
} )
2025-07-29 10:11:01 +02:00
else
print ( " [VENDING] Not adding manager options - not owner " )
2025-07-29 09:02:52 +02:00
end
2025-07-29 08:25:12 +02:00
lib.registerContext ( {
id = ' vending_owner_menu ' ,
title = ' Verkaufsautomat Verwaltung ' ,
2025-07-29 09:02:52 +02:00
options = options
2025-07-29 08:25:12 +02:00
} )
lib.showContext ( ' vending_owner_menu ' )
2025-07-29 10:11:01 +02:00
end , entityId )
2025-07-29 08:25:12 +02:00
end )
2025-07-29 09:20:46 +02:00
-- Funktion zum Verkaufen des Automaten
2025-07-29 10:11:01 +02:00
function sellVendingMachine ( entityId , machineId )
2025-07-29 09:20:46 +02:00
local input = lib.inputDialog ( ' Automaten verkaufen ' , {
{
type = ' checkbox ' ,
label = ' Bestätigen ' ,
description = ' Du erhältst ' .. math.floor ( Config.VendingMachinePrice * Config.SellBackPercentage / 100 ) .. ' $ zurück. Diese Aktion kann nicht rückgängig gemacht werden! ' ,
required = true
}
} )
if input and input [ 1 ] then
2025-07-29 10:11:01 +02:00
TriggerServerEvent ( ' vending:server:sellMachine ' , machineId , entityId )
2025-07-29 09:20:46 +02:00
end
end
2025-07-29 08:25:12 +02:00
-- Open price menu
2025-07-29 10:11:01 +02:00
function openPriceMenu ( entityId )
2025-07-29 08:25:12 +02:00
QBCore.Functions . TriggerCallback ( ' vending:server:getStashItems ' , function ( items )
if # items == 0 then
QBCore.Functions . Notify ( ' Keine Items im Automaten! ' , ' error ' )
return
end
local options = { }
for i = 1 , # items do
local item = items [ i ]
local itemLabel = QBCore.Shared . Items [ item.name ] and QBCore.Shared . Items [ item.name ] . label or item.name
table.insert ( options , {
title = itemLabel ,
description = ' Aktueller Preis: $ ' .. item.price ,
icon = ' fas fa-tag ' ,
onSelect = function ( )
2025-07-29 10:11:01 +02:00
setPriceForItem ( entityId , item.name , itemLabel )
2025-07-29 08:25:12 +02:00
end
} )
end
lib.registerContext ( {
id = ' vending_price_menu ' ,
title = ' Preise festlegen ' ,
menu = ' vending_owner_menu ' ,
options = options
} )
lib.showContext ( ' vending_price_menu ' )
2025-07-29 10:11:01 +02:00
end , entityId )
2025-07-29 08:25:12 +02:00
end
-- Set price for specific item
2025-07-29 10:11:01 +02:00
function setPriceForItem ( entityId , itemName , itemLabel )
2025-07-29 08:25:12 +02:00
local input = lib.inputDialog ( ' Preis festlegen ' , {
{
type = ' number ' ,
label = ' Preis für ' .. itemLabel ,
description = ' Neuen Verkaufspreis eingeben ' ,
required = true ,
min = 1 ,
max = 10000
}
} )
if input and input [ 1 ] then
2025-07-29 10:11:01 +02:00
TriggerServerEvent ( ' vending:server:setItemPrice ' , itemName , tonumber ( input [ 1 ] ) , entityId )
2025-07-29 08:25:12 +02:00
end
end
-- Open withdraw menu
2025-07-29 10:11:01 +02:00
function openWithdrawMenu ( entityId , availableMoney )
2025-07-29 08:25:12 +02:00
if availableMoney <= 0 then
QBCore.Functions . Notify ( ' Kein Geld im Automaten! ' , ' error ' )
return
end
local input = lib.inputDialog ( ' Geld abheben ' , {
{
type = ' number ' ,
label = ' Betrag (Verfügbar: $ ' .. availableMoney .. ' ) ' ,
description = ' Wie viel möchtest du abheben? ' ,
required = true ,
min = 1 ,
max = availableMoney
}
} )
if input and input [ 1 ] then
2025-07-29 10:11:01 +02:00
TriggerServerEvent ( ' vending:server:withdrawMoney ' , tonumber ( input [ 1 ] ) , entityId )
2025-07-29 08:25:12 +02:00
end
end
-- Open stats menu
function openStatsMenu ( machine )
2025-07-29 07:30:32 +02:00
lib.registerContext ( {
2025-07-29 08:25:12 +02:00
id = ' vending_stats_menu ' ,
title = ' Verkaufsstatistiken ' ,
menu = ' vending_owner_menu ' ,
2025-07-29 07:30:32 +02:00
options = {
{
2025-07-29 08:25:12 +02:00
title = ' Gesamteinnahmen ' ,
description = ' $ ' .. machine.money ,
icon = ' fas fa-dollar-sign '
} ,
{
title = ' Automat ID ' ,
description = ' # ' .. machine.id ,
icon = ' fas fa-hashtag '
} ,
{
title = ' Standort ' ,
description = ' X: ' .. math.floor ( machine.coords . x ) .. ' Y: ' .. math.floor ( machine.coords . y ) ,
icon = ' fas fa-map-marker-alt '
}
}
} )
lib.showContext ( ' vending_stats_menu ' )
end
2025-07-29 09:02:52 +02:00
-- Open managers menu
2025-07-29 10:11:01 +02:00
function openManagersMenu ( entityId )
2025-07-29 09:02:52 +02:00
-- Get current managers
QBCore.Functions . TriggerCallback ( ' vending:server:getManagers ' , function ( managers )
local options = {
{
title = ' Verwalter hinzufügen ' ,
description = ' Neuen Verwalter hinzufügen ' ,
icon = ' fas fa-user-plus ' ,
onSelect = function ( )
2025-07-29 10:11:01 +02:00
openAddManagerMenu ( entityId )
2025-07-29 09:02:52 +02:00
end
}
}
-- Add existing managers with remove option
if # managers > 0 then
for i = 1 , # managers do
local manager = managers [ i ]
table.insert ( options , {
title = manager.name ,
description = manager.online and ' Online ' or ' Offline ' ,
icon = manager.online and ' fas fa-circle text-success ' or ' fas fa-circle text-danger ' ,
onSelect = function ( )
lib.registerContext ( {
id = ' manager_options ' ,
title = ' Verwalter: ' .. manager.name ,
menu = ' managers_menu ' ,
options = {
{
title = ' Entfernen ' ,
description = ' Verwalter entfernen ' ,
icon = ' fas fa-user-minus ' ,
onSelect = function ( )
2025-07-29 10:11:01 +02:00
TriggerServerEvent ( ' vending:server:removeManager ' , manager.citizenid , entityId )
2025-07-29 09:02:52 +02:00
Wait ( 500 )
2025-07-29 10:11:01 +02:00
openManagersMenu ( entityId ) -- Refresh the menu
2025-07-29 09:02:52 +02:00
end
}
}
} )
lib.showContext ( ' manager_options ' )
end
} )
end
else
table.insert ( options , {
title = ' Keine Verwalter ' ,
description = ' Es sind keine Verwalter vorhanden ' ,
icon = ' fas fa-info-circle ' ,
disabled = true
} )
end
lib.registerContext ( {
id = ' managers_menu ' ,
title = ' Verwalter verwalten ' ,
menu = ' vending_owner_menu ' ,
options = options
} )
lib.showContext ( ' managers_menu ' )
2025-07-29 10:11:01 +02:00
end , entityId )
2025-07-29 09:02:52 +02:00
end
-- Open add manager menu
2025-07-29 10:11:01 +02:00
function openAddManagerMenu ( entityId )
2025-07-29 09:02:52 +02:00
QBCore.Functions . TriggerCallback ( ' vending:server:getOnlinePlayers ' , function ( players )
if # players == 0 then
QBCore.Functions . Notify ( ' Keine Spieler online! ' , ' error ' )
return
end
local options = { }
for i = 1 , # players do
local player = players [ i ]
table.insert ( options , {
title = player.name ,
description = ' ID: ' .. player.id ,
icon = ' fas fa-user ' ,
onSelect = function ( )
2025-07-29 10:11:01 +02:00
TriggerServerEvent ( ' vending:server:addManager ' , player.id , entityId )
2025-07-29 09:02:52 +02:00
Wait ( 500 )
2025-07-29 10:11:01 +02:00
openManagersMenu ( entityId ) -- Refresh the menu
2025-07-29 09:02:52 +02:00
end
} )
end
lib.registerContext ( {
id = ' add_manager_menu ' ,
title = ' Verwalter hinzufügen ' ,
menu = ' managers_menu ' ,
options = options
} )
lib.showContext ( ' add_manager_menu ' )
end )
end
-- Robbery menu
2025-07-29 08:25:12 +02:00
RegisterNetEvent ( ' vending:client:startRobbery ' , function ( data )
local entity = data.entity
2025-07-29 10:11:01 +02:00
local entityId = NetworkGetNetworkIdFromEntity ( entity )
2025-07-29 08:25:12 +02:00
lib.registerContext ( {
id = ' vending_robbery_confirm ' ,
title = ' Verkaufsautomat aufbrechen ' ,
options = {
{
title = ' Aufbrechen ' ,
description = ' Versuche den Automaten aufzubrechen ' ,
icon = ' fas fa-mask ' ,
onSelect = function ( )
2025-07-29 10:11:01 +02:00
TriggerServerEvent ( ' vending:server:startRobbery ' , entityId )
2025-07-29 08:25:12 +02:00
end
} ,
{
title = ' Abbrechen ' ,
description = ' Aufbruch abbrechen ' ,
icon = ' fas fa-times '
}
}
} )
lib.showContext ( ' vending_robbery_confirm ' )
end )
-- Start robbery animation and progress
2025-07-29 10:11:01 +02:00
RegisterNetEvent ( ' vending:client:startRobbery ' , function ( entityId )
2025-07-29 08:25:12 +02:00
local playerPed = PlayerPedId ( )
local robberyTime = 10000 -- 10 seconds
-- Animation
RequestAnimDict ( ' anim@heists@fleeca_bank@drilling ' )
while not HasAnimDictLoaded ( ' anim@heists@fleeca_bank@drilling ' ) do
Wait ( 100 )
end
TaskPlayAnim ( playerPed , ' anim@heists@fleeca_bank@drilling ' , ' drill_straight_idle ' , 8.0 , - 8.0 , - 1 , 1 , 0 , false , false , false )
-- Progress bar
if lib.progressBar then
local success = lib.progressBar ( {
duration = robberyTime ,
label = ' Automat aufbrechen... ' ,
useWhileDead = false ,
canCancel = true ,
disable = {
car = true ,
move = true ,
combat = true
}
} )
ClearPedTasks ( playerPed )
2025-07-29 10:11:01 +02:00
TriggerServerEvent ( ' vending:server:completeRobbery ' , entityId , success )
2025-07-29 08:25:12 +02:00
else
-- Fallback without progress bar
Wait ( robberyTime )
ClearPedTasks ( playerPed )
2025-07-29 10:11:01 +02:00
TriggerServerEvent ( ' vending:server:completeRobbery ' , entityId , true )
2025-07-29 08:25:12 +02:00
end
end )
-- Police alert
RegisterNetEvent ( ' vending:client:policeAlert ' , function ( coords , streetName )
local alert = {
title = " Verkaufsautomat Aufbruch " ,
coords = coords ,
description = " Ein Verkaufsautomat wird aufgebrochen in " .. streetName
}
-- Add blip
local blip = AddBlipForCoord ( coords.x , coords.y , coords.z )
SetBlipSprite ( blip , 161 )
SetBlipColour ( blip , 1 )
SetBlipScale ( blip , 1.0 )
SetBlipAsShortRange ( blip , false )
BeginTextCommandSetBlipName ( " STRING " )
AddTextComponentString ( " Verkaufsautomat Aufbruch " )
EndTextCommandSetBlipName ( blip )
-- Remove blip after 5 minutes
SetTimeout ( 300000 , function ( )
RemoveBlip ( blip )
end )
QBCore.Functions . Notify ( ' Verkaufsautomat Aufbruch gemeldet: ' .. streetName , ' error ' , 8000 )
end )
-- Refresh targets (called when new machine is registered)
RegisterNetEvent ( ' vending:client:refreshTargets ' , function ( )
2025-07-29 09:48:16 +02:00
InitializeTargets ( )
2025-07-29 08:25:12 +02:00
end )
-- Management menu (alternative opening method)
RegisterNetEvent ( ' vending:client:openManagement ' , function ( machine )
lib.registerContext ( {
id = ' vending_management ' ,
title = ' Verkaufsautomat # ' .. machine.id ,
options = {
{
title = ' Inventar öffnen ' ,
description = ' Items hinzufügen oder entfernen ' ,
2025-07-29 07:30:32 +02:00
icon = ' fas fa-box ' ,
onSelect = function ( )
2025-07-29 10:11:01 +02:00
TriggerServerEvent ( ' vending:server:openStash ' , machine.entityId )
2025-07-29 07:30:32 +02:00
end
} ,
{
2025-07-29 08:25:12 +02:00
title = ' Einnahmen: $ ' .. machine.money ,
description = ' Geld abheben ' ,
2025-07-29 07:30:32 +02:00
icon = ' fas fa-money-bill ' ,
onSelect = function ( )
2025-07-29 10:11:01 +02:00
openWithdrawMenu ( machine.entityId , machine.money )
2025-07-29 07:30:32 +02:00
end
}
}
} )
2025-07-29 08:25:12 +02:00
lib.showContext ( ' vending_management ' )
2025-07-29 07:30:32 +02:00
end )
2025-07-29 09:39:15 +02:00
-- Debug command to check props
RegisterCommand ( ' checkvendingprops ' , function ( )
local playerPed = PlayerPedId ( )
local playerCoords = GetEntityCoords ( playerPed )
local foundProps = 0
for _ , propName in ipairs ( Config.VendingProps ) do
local hash = GetHashKey ( propName )
local objects = GetGamePool ( ' CObject ' )
print ( " Checking for prop: " .. propName .. " (Hash: " .. hash .. " ) " )
for _ , obj in ipairs ( objects ) do
if GetEntityModel ( obj ) == hash then
local objCoords = GetEntityCoords ( obj )
local dist = # ( playerCoords - objCoords )
if dist < 30.0 then
foundProps = foundProps + 1
2025-07-29 10:11:01 +02:00
local entityId = NetworkGetNetworkIdFromEntity ( obj )
print ( " Found " .. propName .. " at distance: " .. dist .. " | Entity ID: " .. entityId )
2025-07-29 09:39:15 +02:00
-- Add a temporary blip
local blip = AddBlipForEntity ( obj )
SetBlipSprite ( blip , 1 )
SetBlipColour ( blip , 2 )
SetBlipScale ( blip , 0.8 )
BeginTextCommandSetBlipName ( " STRING " )
2025-07-29 10:11:01 +02:00
AddTextComponentString ( propName .. " | ID: " .. entityId )
2025-07-29 09:39:15 +02:00
EndTextCommandSetBlipName ( blip )
-- Remove blip after 10 seconds
SetTimeout ( 10000 , function ( )
RemoveBlip ( blip )
end )
end
end
end
end
QBCore.Functions . Notify ( ' Found ' .. foundProps .. ' vending machines nearby ' , ' primary ' )
end , false )
2025-07-29 09:41:19 +02:00
2025-07-29 09:48:16 +02:00
-- Debug commands
RegisterCommand ( ' vendingdebug ' , function ( )
local playerPed = PlayerPedId ( )
local coords = GetEntityCoords ( playerPed )
2025-07-29 10:11:01 +02:00
local entity = nil
local entityId = 0
2025-07-29 09:41:19 +02:00
2025-07-29 10:11:01 +02:00
-- Try to find the closest vending machine
local minDist = 3.0
local objects = GetGamePool ( ' CObject ' )
for _ , obj in ipairs ( objects ) do
local model = GetEntityModel ( obj )
for _ , propName in ipairs ( Config.VendingProps ) do
if model == GetHashKey ( propName ) then
local objCoords = GetEntityCoords ( obj )
local dist = # ( coords - objCoords )
if dist < minDist then
minDist = dist
entity = obj
entityId = NetworkGetNetworkIdFromEntity ( obj )
end
end
2025-07-29 09:48:16 +02:00
end
2025-07-29 10:11:01 +02:00
end
if entity then
QBCore.Functions . TriggerCallback ( ' vending:server:getMachineByEntity ' , function ( machine )
if machine then
print ( ' Machine found: ' , json.encode ( machine ) )
QBCore.Functions . Notify ( ' Machine # ' .. machine.id .. ' | Entity ID: ' .. entityId .. ' | Owner: ' .. machine.owner , ' primary ' )
else
print ( ' No machine found with entity ID: ' , entityId )
QBCore.Functions . Notify ( ' No machine found with entity ID: ' .. entityId , ' error ' )
end
end , entityId )
else
QBCore.Functions . Notify ( ' No vending machine found nearby ' , ' error ' )
end
2025-07-29 09:41:19 +02:00
end , false )