diff --git a/resources/[inventory]/nordi_coffeemachine/client.lua b/resources/[inventory]/nordi_coffeemachine/client.lua index f0d51a14b..b1e3de6fc 100644 --- a/resources/[inventory]/nordi_coffeemachine/client.lua +++ b/resources/[inventory]/nordi_coffeemachine/client.lua @@ -5,6 +5,44 @@ local function Debug(msg) print("^2[Coffee Debug] ^7" .. msg) end +-- Cache system for item checks +local itemCheckCache = {} +local lastCheckTime = {} +local checkCooldown = 1000 -- 1 second cooldown between checks for the same item + +-- Function to check if player has an item +local function HasItem(itemName, amount, callback) + -- Check cache first (to avoid spamming the server) + local cacheKey = itemName .. "_" .. amount + local currentTime = GetGameTimer() + if itemCheckCache[cacheKey] ~= nil and lastCheckTime[cacheKey] and + (currentTime - lastCheckTime[cacheKey]) < checkCooldown then + callback(itemCheckCache[cacheKey]) + return + end + + -- Create a unique event name for this check + local uniqueEventName = 'coffee-script:itemCheckResult:' .. math.random(100000, 999999) + + -- Register the event handler + local eventHandler = RegisterNetEvent(uniqueEventName) + AddEventHandler(uniqueEventName, function(hasItem) + itemCheckCache[cacheKey] = hasItem + lastCheckTime[cacheKey] = GetGameTimer() + callback(hasItem) + end) + + -- Request the check from server with our unique event name + TriggerServerEvent('coffee-script:checkItem', itemName, amount, uniqueEventName) + + -- Set a timeout to prevent hanging if something goes wrong + SetTimeout(1000, function() + if not lastCheckTime[cacheKey] or (currentTime - lastCheckTime[cacheKey]) >= checkCooldown then + callback(false) + end + end) +end + CreateThread(function() Debug("Script starting...") for _, prop in pairs(Config.CoffeeProps) do @@ -31,22 +69,34 @@ AddEventHandler('nordi_coffeemachine:client:OpenMenu', function() OpenCoffeeMenu() end) -function CheckIngredients(requirements) +function CheckIngredients(requirements, callback) local hasItems = true local missingItems = {} + local checkedItems = 0 + local totalItems = #requirements - for _, requirement in ipairs(requirements) do - local hasItem = QBCore.Functions.HasItem(requirement.item, requirement.amount) - if not hasItem then - hasItems = false - table.insert(missingItems, { - item = requirement.item, - required = requirement.amount - }) - end + if totalItems == 0 then + callback(true, {}) + return end - return hasItems, missingItems + for _, requirement in ipairs(requirements) do + HasItem(requirement.item, requirement.amount, function(hasItem) + checkedItems = checkedItems + 1 + + if not hasItem then + hasItems = false + table.insert(missingItems, { + item = requirement.item, + required = requirement.amount + }) + end + + if checkedItems == totalItems then + callback(hasItems, missingItems) + end + end) + end end function ShowMissingIngredientsWarning(missingItems) @@ -62,33 +112,55 @@ end function OpenCoffeeMenu() Debug("Building menu options...") local options = {} + local coffeeChecked = 0 + local totalCoffees = #Config.CoffeeOptions for _, coffee in ipairs(Config.CoffeeOptions) do - local hasIngredients, missing = CheckIngredients(coffee.requires) - local description = coffee.description .. "\n\nBenötigt:" - - for _, req in ipairs(coffee.requires) do - local itemLabel = QBCore.Shared.Items[req.item].label - local hasItem = QBCore.Functions.HasItem(req.item, req.amount) - local status = hasItem and "~g~✓" or "~r~✗" - description = description .. "\n- " .. req.amount .. "x " .. itemLabel .. " " .. status - end - - table.insert(options, { - title = coffee.label, - description = description, - icon = coffee.icon, - onSelect = function() - local canMake, missingItems = CheckIngredients(coffee.requires) - if canMake then - PrepareCoffee(coffee) - else - ShowMissingIngredientsWarning(missingItems) - end + CheckIngredients(coffee.requires, function(hasIngredients, missingItems) + coffeeChecked = coffeeChecked + 1 + + local description = coffee.description .. "\n\nBenötigt:" + + for _, req in ipairs(coffee.requires) do + local itemLabel = QBCore.Shared.Items[req.item].label + local hasItem = not table.find(missingItems, function(item) return item.item == req.item end) + local status = hasItem and "~g~✓" or "~r~✗" + description = description .. "\n- " .. req.amount .. "x " .. itemLabel .. " " .. status end - }) + + table.insert(options, { + title = coffee.label, + description = description, + icon = coffee.icon, + onSelect = function() + CheckIngredients(coffee.requires, function(canMake, missingItems) + if canMake then + PrepareCoffee(coffee) + else + ShowMissingIngredientsWarning(missingItems) + end + end) + end + }) + + if coffeeChecked == totalCoffees then + ShowCoffeeMenu(options) + end + end) end +end +-- Helper function to find in table +function table.find(t, cb) + for _, v in ipairs(t) do + if cb(v) then + return true + end + end + return false +end + +function ShowCoffeeMenu(options) Debug("Showing menu...") lib.registerContext({ id = 'coffee_menu', @@ -133,11 +205,3 @@ RegisterNetEvent('coffee-script:debug') AddEventHandler('coffee-script:debug', function(msg) Debug(msg) end) - - - - - - - - diff --git a/resources/[inventory]/nordi_coffeemachine/server.lua b/resources/[inventory]/nordi_coffeemachine/server.lua index a4287274d..afedcf709 100644 --- a/resources/[inventory]/nordi_coffeemachine/server.lua +++ b/resources/[inventory]/nordi_coffeemachine/server.lua @@ -5,6 +5,31 @@ local function Debug(msg) print("^2[Coffee Debug] ^7" .. msg) end +-- Function to check if player has an item +local function HasItem(source, itemName, amount) + local items = exports["tgiann-inventory"]:GetPlayerItems(source) + if not items then return false end + + local count = 0 + for _, item in pairs(items) do + if item.name == itemName then + count = count + item.count + if count >= amount then + return true + end + end + end + + return false +end + +-- Event for client to check if player has an item +RegisterNetEvent('coffee-script:checkItem', function(itemName, amount, callbackEvent) + local src = source + local hasItem = HasItem(src, itemName, amount) + TriggerClientEvent(callbackEvent, src, hasItem) +end) + RegisterNetEvent('coffee-script:giveCoffee') AddEventHandler('coffee-script:giveCoffee', function(itemName, requirements) Debug("Give coffee event triggered") @@ -26,7 +51,7 @@ AddEventHandler('coffee-script:giveCoffee', function(itemName, requirements) -- Überprüfe nochmal die Zutaten local hasAllItems = true for _, requirement in ipairs(requirements) do - if not Player.Functions.HasItem(requirement.item, requirement.amount) then + if not HasItem(src, requirement.item, requirement.amount) then hasAllItems = false break end @@ -36,12 +61,12 @@ AddEventHandler('coffee-script:giveCoffee', function(itemName, requirements) Debug("Player has all required items") -- Entferne die benötigten Items for _, requirement in ipairs(requirements) do - Player.Functions.RemoveItem(requirement.item, requirement.amount) + exports["tgiann-inventory"]:RemoveItem(src, requirement.item, requirement.amount) TriggerClientEvent('inventory:client:ItemBox', src, QBCore.Shared.Items[requirement.item], "remove") end -- Gebe das fertige Getränk - Player.Functions.AddItem(itemName, 1) + exports["tgiann-inventory"]:AddItem(src, itemName, 1) TriggerClientEvent('inventory:client:ItemBox', src, QBCore.Shared.Items[itemName], "add") TriggerClientEvent('QBCore:Notify', src, "Du hast einen " .. QBCore.Shared.Items[itemName].label .. " zubereitet!", "success") else @@ -54,4 +79,3 @@ AddEventHandler('coffee-script:giveCoffee', function(itemName, requirements) end end end) -