diff --git a/resources/[inventory]/nordi_trashcan/client.lua b/resources/[inventory]/nordi_trashcan/client.lua new file mode 100644 index 000000000..f0678826c --- /dev/null +++ b/resources/[inventory]/nordi_trashcan/client.lua @@ -0,0 +1,61 @@ +local QBCore = exports['qb-core']:GetCoreObject() + +-- Variable to store the current entity being interacted with +local currentEntity = nil + +-- Add QB-Target to all matching props in the world +Citizen.CreateThread(function() + -- Add target to trash can props + exports['qb-target']:AddTargetModel(Config.TrashCanModels, { + options = { + { + type = "client", + event = "trash:openInventory", + icon = "fas fa-dumpster", + label = "Mülltonne öffnen", + action = function(entity) + currentEntity = entity + TriggerEvent('trash:openInventory') + end, + canInteract = function() + return true + end, + } + }, + distance = 2.0 + }) + + print("^2[TRASH-SYSTEM]^7 Added QB-Target to " .. #Config.TrashCanModels .. " trash can models") +end) + +-- Function to get container ID from entity +function GetContainerIDFromEntity(entity) + if not entity or not DoesEntityExist(entity) then return nil end + + local model = GetEntityModel(entity) + local entityCoords = GetEntityCoords(entity) + return "trashcan" .. "_" .. model .. "_" .. math.floor(entityCoords.x) .. "_" .. math.floor(entityCoords.y) .. "_" .. math.floor(entityCoords.z) +end + +-- Open container inventory +RegisterNetEvent('trash:openInventory', function() + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) + + if not currentEntity or not DoesEntityExist(currentEntity) then + lib.notify(Config.Notifications.noTrashCanFound) + return + end + + -- Get container ID + local containerID = GetContainerIDFromEntity(currentEntity) + if not containerID then return end + + -- Open inventory with this unique ID + TriggerServerEvent('trash:server:openInventory', containerID) +end) + +-- Notification when trash is emptied (can be triggered by server) +RegisterNetEvent('trash:client:notifyEmptied', function() + lib.notify(Config.Notifications.trashCanEmptied) +end) diff --git a/resources/[inventory]/nordi_trashcan/config.lua b/resources/[inventory]/nordi_trashcan/config.lua new file mode 100644 index 000000000..06d2b3726 --- /dev/null +++ b/resources/[inventory]/nordi_trashcan/config.lua @@ -0,0 +1,61 @@ +Config = {} + +-- Main settings +Config.EmptyInterval = 2880 -- 2 days in minutes (48 hours * 60 minutes) +Config.CheckFrequency = 30 -- How often to check for trash cans to empty (in minutes) + +-- Trash can models that can be interacted with +Config.TrashCanModels = { + 'p_secret_weapon_02', + 'prop_bin_08a', + 'prop_bin_01a', + 'prop_bin_03a', + 'prop_bin_04a', + 'prop_bin_07a', + 'prop_bin_07d', + 'prop_cs_bin_01', + 'prop_cs_bin_01_skinned', + 'prop_cs_bin_02', + 'prop_cs_bin_03', + -- Add more trash can models as needed +} + +-- Inventory settings +Config.TrashCanInventory = { + maxweight = 50000, -- 50kg max + slots = 20, -- 20 Slots + label = 'Mülltonne' +} + +-- Notification settings +Config.Notifications = { + noTrashCanFound = { + title = 'Mülltonne', + description = 'Keine Mülltonne gefunden!', + type = 'error' + }, + trashCanEmptied = { + title = 'Mülltonne', + description = 'Die Müllabfuhr hat die Mülltonne geleert!', + type = 'info', + duration = 5000 + }, + manualEmptySuccess = { + title = 'System', + description = 'Alle Mülltonnen wurden geleert', + type = 'success' + }, + noPermission = { + title = 'System', + description = 'Du hast keine Berechtigung für diesen Befehl', + type = 'error' + } +} + +-- Logging settings +Config.Logs = { + enabled = true, + webhookName = 'trash', -- Name of the webhook in qb-log + emptyTitle = 'Trash Can Emptied', + emptyColor = 'blue' +} diff --git a/resources/[inventory]/nordi_trashcan/fxmanifest.lua b/resources/[inventory]/nordi_trashcan/fxmanifest.lua new file mode 100644 index 000000000..1a0e39b25 --- /dev/null +++ b/resources/[inventory]/nordi_trashcan/fxmanifest.lua @@ -0,0 +1,27 @@ +fx_version 'cerulean' +game 'gta5' +lua54 'yes' + +author 'YourName' +description 'Mülltonnensystem mit automatischer Leerung alle 2 Tage' +version '1.0.0' + +shared_scripts { + 'config.lua', + '@ox_lib/init.lua' +} + +client_scripts { + 'client.lua' +} + +server_scripts { + 'server.lua' +} + +dependencies { + 'qb-core', + 'qb-target', + 'ox_lib', + 'tgiann-inventory' +} diff --git a/resources/[inventory]/nordi_trashcan/server.lua b/resources/[inventory]/nordi_trashcan/server.lua new file mode 100644 index 000000000..2713cbded --- /dev/null +++ b/resources/[inventory]/nordi_trashcan/server.lua @@ -0,0 +1,144 @@ +local QBCore = exports['qb-core']:GetCoreObject() + +-- Table to track all trash cans in the world +local trashCans = {} + +-- Initialize the script +Citizen.CreateThread(function() + print("^2[TRASH-SYSTEM]^7 Initializing trash can emptying system...") + -- Load existing trash cans from database if needed + InitializeTrashCans() + + -- Start the emptying cycle + StartEmptyingCycle() +end) + +-- Initialize trash cans +function InitializeTrashCans() + -- You could load from database here if you want persistence between server restarts + -- For now, we'll just initialize an empty table + trashCans = {} + print("^2[TRASH-SYSTEM]^7 Trash cans initialized") +end + +-- Register a new trash can when it's first used +RegisterNetEvent('trash:server:registerTrashCan', function(containerID) + if not trashCans[containerID] then + trashCans[containerID] = { + lastEmptied = os.time(), + nextEmptyTime = os.time() + (Config.EmptyInterval * 60) + } + print("^2[TRASH-SYSTEM]^7 New trash can registered: " .. containerID) + end +end) + +-- Container inventory open +RegisterNetEvent('trash:server:openInventory', function(containerID) + local src = source + local Player = QBCore.Functions.GetPlayer(src) + + if not Player then return end + + -- Register this trash can if it's new + TriggerEvent('trash:server:registerTrashCan', containerID) + + -- Open the inventory + exports["tgiann-inventory"]:OpenInventory(src, "stash", containerID, { + maxweight = Config.TrashCanInventory.maxweight, + slots = Config.TrashCanInventory.slots, + label = Config.TrashCanInventory.label + }) +end) + +-- Start the emptying cycle +function StartEmptyingCycle() + Citizen.CreateThread(function() + while true do + -- Check based on configured frequency + Citizen.Wait(Config.CheckFrequency * 60 * 1000) + EmptyTrashCans() + end + end) + print("^2[TRASH-SYSTEM]^7 Trash emptying cycle started - will check every " .. Config.CheckFrequency .. " minutes") +end + +-- Empty trash cans that are due +function EmptyTrashCans() + local currentTime = os.time() + local emptiedCount = 0 + + for containerID, data in pairs(trashCans) do + if currentTime >= data.nextEmptyTime then + -- Empty this trash can + EmptyTrashCan(containerID) + + -- Update the timing + trashCans[containerID] = { + lastEmptied = currentTime, + nextEmptyTime = currentTime + (Config.EmptyInterval * 60) + } + + emptiedCount = emptiedCount + 1 + end + end + + if emptiedCount > 0 then + print("^2[TRASH-SYSTEM]^7 Emptied " .. emptiedCount .. " trash cans") + end +end + +-- Empty a specific trash can +function EmptyTrashCan(containerID) + -- Get all items in the container + local items = exports["tgiann-inventory"]:GetSecondaryInventoryItems("stash", containerID) + + if not items or next(items) == nil then + return -- No items to remove + end + + local disposedItems = {} + local totalItems = 0 + + -- Dispose all items + for slot, item in pairs(items) do + if item and item.amount and item.amount > 0 then + local success = exports["tgiann-inventory"]:RemoveItemFromSecondaryInventory("stash", containerID, item.name, item.amount, slot) + if success then + table.insert(disposedItems, {name = item.name, amount = item.amount}) + totalItems = totalItems + item.amount + end + end + end + + if #disposedItems > 0 then + -- Log the emptying + print("^3[TRASH-SYSTEM]^7 Automatically emptied trash can " .. containerID .. " (" .. totalItems .. " items)") + + -- Discord Webhook with item list if enabled + if Config.Logs.enabled then + local itemList = "" + for _, item in pairs(disposedItems) do + itemList = itemList .. '• ' .. item.amount .. 'x ' .. item.name .. '\n' + end + + TriggerEvent('qb-log:server:CreateLog', Config.Logs.webhookName, + Config.Logs.emptyTitle, + Config.Logs.emptyColor, + '**Trash Can:** ' .. containerID .. + '\n**Action:** Automatic emptying' .. + '\n**Total Items:** ' .. totalItems .. + '\n**Items:**\n' .. itemList) + end + end +end + +-- Command to manually trigger trash emptying (admin only) +QBCore.Commands.Add('emptytrash', 'Empty all trash cans (Admin Only)', {}, false, function(source, args) + local Player = QBCore.Functions.GetPlayer(source) + if Player.PlayerData.permission == "admin" or Player.PlayerData.permission == "god" then + EmptyTrashCans() + TriggerClientEvent('ox_lib:notify', source, Config.Notifications.manualEmptySuccess) + else + TriggerClientEvent('ox_lib:notify', source, Config.Notifications.noPermission) + end +end, 'admin')