local QBCore = exports['qb-core']:GetCoreObject() local vendingMachines = {} local robberyInProgress = {} -- Load vending machines from database CreateThread(function() Wait(1000) local result = MySQL.Sync.fetchAll('SELECT * FROM vending_machines') if result then for i = 1, #result do local data = result[i] vendingMachines[data.id] = { id = data.id, owner = data.owner, coords = json.decode(data.coords), prop = data.prop, money = data.money, items = json.decode(data.items) or {}, prices = json.decode(data.prices) or {}, stash = 'vending_' .. data.id } end print('[Vending] Loaded ' .. #result .. ' vending machines') end end) -- Register vending machine (when player buys it) RegisterNetEvent('vending:server:registerMachine', function(coords, prop) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end print('[Vending] Player ' .. src .. ' trying to register machine at coords:', coords.x, coords.y, coords.z) -- Check if there's already a machine at these coords for id, machine in pairs(vendingMachines) do local dist = #(vector3(coords.x, coords.y, coords.z) - vector3(machine.coords.x, machine.coords.y, machine.coords.z)) if dist < 2.0 then TriggerClientEvent('QBCore:Notify', src, 'Hier ist bereits ein Automat registriert!', 'error') return end end -- Check if player has enough money if Player.PlayerData.money.cash < Config.VendingMachinePrice then TriggerClientEvent('QBCore:Notify', src, 'Du benötigst $' .. Config.VendingMachinePrice .. ' um diesen Automaten zu kaufen!', 'error') return end -- Remove money Player.Functions.RemoveMoney('cash', Config.VendingMachinePrice) -- Create machine in database local machineId = MySQL.insert.await('INSERT INTO vending_machines (owner, coords, prop, money, items, prices) VALUES (?, ?, ?, ?, ?, ?)', { Player.PlayerData.citizenid, json.encode(coords), prop, 0, json.encode({}), json.encode({}) }) -- Add to memory vendingMachines[machineId] = { id = machineId, owner = Player.PlayerData.citizenid, coords = coords, prop = prop, money = 0, items = {}, prices = {}, stash = 'vending_' .. machineId } print('[Vending] Machine registered with ID:', machineId) TriggerClientEvent('QBCore:Notify', src, 'Verkaufsautomat erfolgreich gekauft für $' .. Config.VendingMachinePrice .. '!', 'success') TriggerClientEvent('vending:client:refreshTargets', -1) end) -- Open management menu RegisterNetEvent('vending:server:openManagement', function(coords) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end local machineId = getMachineIdByCoords(coords) if not machineId then return end local machine = vendingMachines[machineId] if machine.owner ~= Player.PlayerData.citizenid then TriggerClientEvent('QBCore:Notify', src, 'Das ist nicht dein Verkaufsautomat!', 'error') return end TriggerClientEvent('vending:client:openManagement', src, machine) end) -- Open stash (simplified version) RegisterNetEvent('vending:server:openStash', function(coords) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end local machineId = getMachineIdByCoords(coords) if not machineId then return end local machine = vendingMachines[machineId] if machine.owner ~= Player.PlayerData.citizenid then TriggerClientEvent('QBCore:Notify', src, 'Das ist nicht dein Verkaufsautomat!', 'error') return end -- Try different inventory systems if GetResourceState('tgiann-inventory') == 'started' then -- tgiann-inventory TriggerEvent('tgiann-inventory:server:openStash', src, machine.stash, { maxweight = Config.MaxWeight, slots = Config.MaxSlots, label = 'Vending Machine #' .. machine.id }) elseif GetResourceState('qb-inventory') == 'started' then -- qb-inventory TriggerEvent('inventory:server:OpenInventory', 'stash', machine.stash, { maxweight = Config.MaxWeight, slots = Config.MaxSlots, }) TriggerClientEvent('inventory:client:SetCurrentStash', src, machine.stash) elseif GetResourceState('ps-inventory') == 'started' then -- ps-inventory exports['ps-inventory']:OpenInventory(src, machine.stash, { maxweight = Config.MaxWeight, slots = Config.MaxSlots, }) else TriggerClientEvent('QBCore:Notify', src, 'Kein unterstütztes Inventory-System gefunden!', 'error') end end) -- Set item price RegisterNetEvent('vending:server:setItemPrice', function(coords, itemName, price) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end local machineId = getMachineIdByCoords(coords) if not machineId then return end local machine = vendingMachines[machineId] if machine.owner ~= Player.PlayerData.citizenid then TriggerClientEvent('QBCore:Notify', src, 'Das ist nicht dein Verkaufsautomat!', 'error') return end -- Update price machine.prices[itemName] = price MySQL.update('UPDATE vending_machines SET prices = ? WHERE id = ?', {json.encode(machine.prices), machineId}) local itemLabel = QBCore.Shared.Items[itemName] and QBCore.Shared.Items[itemName].label or itemName TriggerClientEvent('QBCore:Notify', src, 'Preis für ' .. itemLabel .. ' auf $' .. price .. ' gesetzt!', 'success') end) -- Withdraw money RegisterNetEvent('vending:server:withdrawMoney', function(coords, amount) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end local machineId = getMachineIdByCoords(coords) if not machineId then return end local machine = vendingMachines[machineId] if machine.owner ~= Player.PlayerData.citizenid then TriggerClientEvent('QBCore:Notify', src, 'Das ist nicht dein Verkaufsautomat!', 'error') return end if machine.money < amount then TriggerClientEvent('QBCore:Notify', src, 'Nicht genug Geld im Automaten!', 'error') return end -- Update machine money machine.money = machine.money - amount MySQL.update('UPDATE vending_machines SET money = ? WHERE id = ?', {machine.money, machineId}) -- Give money to player Player.Functions.AddMoney('cash', amount) TriggerClientEvent('QBCore:Notify', src, 'Du hast $' .. amount .. ' abgehoben!', 'success') end) -- Buy item from vending machine (simplified) RegisterNetEvent('vending:server:buyItem', function(coords, itemName) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end local machineId = getMachineIdByCoords(coords) if not machineId then return end local machine = vendingMachines[machineId] local price = machine.prices[itemName] or Config.DefaultPrice -- Check if player has enough money if Player.PlayerData.money.cash < price then TriggerClientEvent('QBCore:Notify', src, 'Du hast nicht genug Geld!', 'error') return end -- For now, just simulate the purchase (you can add inventory checks later) -- Remove money from player Player.Functions.RemoveMoney('cash', price) -- Add money to machine machine.money = machine.money + price MySQL.update('UPDATE vending_machines SET money = ? WHERE id = ?', {machine.money, machineId}) -- Add item to player Player.Functions.AddItem(itemName, 1) TriggerClientEvent('QBCore:Notify', src, 'Artikel gekauft für $' .. price .. '!', 'success') end) -- Helper function to get machine ID by coordinates function getMachineIdByCoords(coords) for id, machine in pairs(vendingMachines) do local dist = #(vector3(coords.x, coords.y, coords.z) - vector3(machine.coords.x, machine.coords.y, machine.coords.z)) if dist < 2.0 then return id end end return nil end -- Get machine data by coordinates QBCore.Functions.CreateCallback('vending:server:getMachineByCoords', function(source, cb, coords) local machineId = getMachineIdByCoords(coords) if machineId then cb(vendingMachines[machineId]) else cb(nil) end end) -- Get stash items for vending machine menu (simplified) QBCore.Functions.CreateCallback('vending:server:getStashItems', function(source, cb, coords) local machineId = getMachineIdByCoords(coords) if not machineId then cb({}) return end local machine = vendingMachines[machineId] -- Return some dummy items for testing local items = { {name = 'water_bottle', amount = 10, price = machine.prices['water_bottle'] or Config.DefaultPrice}, {name = 'sandwich', amount = 5, price = machine.prices['sandwich'] or Config.DefaultPrice}, {name = 'coffee', amount = 8, price = machine.prices['coffee'] or Config.DefaultPrice} } cb(items) end) -- Check if player owns machine QBCore.Functions.CreateCallback('vending:server:isOwner', function(source, cb, coords) local Player = QBCore.Functions.GetPlayer(source) if not Player then cb(false) return end local machineId = getMachineIdByCoords(coords) if not machineId then cb(false) return end local machine = vendingMachines[machineId] cb(machine.owner == Player.PlayerData.citizenid) end) -- Check if machine exists at coords QBCore.Functions.CreateCallback('vending:server:machineExists', function(source, cb, coords) local machineId = getMachineIdByCoords(coords) cb(machineId ~= nil) end) -- Debug command RegisterCommand('vendingdebug', function(source, args) if source == 0 then -- Server console print('[Vending] Loaded machines:') for id, machine in pairs(vendingMachines) do print('ID:', id, 'Owner:', machine.owner, 'Money:', machine.money) end end end, true)