From f720b42a0036b47fbefed0f177d0de99885c4422 Mon Sep 17 00:00:00 2001 From: Nordi98 Date: Wed, 6 Aug 2025 14:18:00 +0200 Subject: [PATCH] ed --- .../[carscripts]/sn_vehicleKey/client.lua | 182 +++++++++++++++++- .../[carscripts]/sn_vehicleKey/config.lua | 13 ++ .../[carscripts]/sn_vehicleKey/server.lua | 66 ++++++- 3 files changed, 258 insertions(+), 3 deletions(-) diff --git a/resources/[carscripts]/sn_vehicleKey/client.lua b/resources/[carscripts]/sn_vehicleKey/client.lua index 917015bf8..fc7302505 100644 --- a/resources/[carscripts]/sn_vehicleKey/client.lua +++ b/resources/[carscripts]/sn_vehicleKey/client.lua @@ -1,4 +1,3 @@ - -- error when both menus are enabled if (Config.useContextMenu and Config.useNativeUI) then print("^1[ERROR] You can use only one menu or no menu at all. You cannot use both menus." @@ -159,6 +158,56 @@ if (Config.useContextMenu) then local item = ownKeyMenu:AddItem(model .. " " .. key.plate) item.rightText = Text("x" .. key.count) end + + -- Fahrzeugübergabe-Menü hinzufügen + local transferVehMenu, transferVehMenuItem = menuPool:AddSubmenu(playerMenu, "Fahrzeug übergeben") + for i, vehicle in ipairs(vehicleData) do + local plate = vehicle[1] + local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicle[2])) + if (model == "NULL") then + model = GetDisplayNameFromVehicleModel(vehicle[2]) + end + + local item = transferVehMenu:AddItem(model .. " " .. plate) + item.closeMenuOnClick = true + item.OnClick = function() + local nearbyPlayers = GetNearbyPlayersWithNames(5.0) + + if #nearbyPlayers == 0 then + Notification("Keine Spieler in der Nähe gefunden") + return + end + + -- Spielerauswahl-Menü erstellen + local playerOptions = {} + for _, player in ipairs(nearbyPlayers) do + table.insert(playerOptions, { + title = player.name, + description = "Entfernung: " .. math.floor(player.distance * 10) / 10 .. "m", + serverPlayerId = player.serverId + }) + end + + lib.registerMenu({ + id = 'transfer_vehicle_menu', + title = 'Fahrzeug übergeben', + position = 'top-right', + options = playerOptions, + onSelect = function(selected) + local targetPlayer = playerOptions[selected].serverPlayerId + local success = CB:Trigger("VKC:transferVehicleOwnership", plate, targetPlayer) + + if success then + Notification("Du hast dein " .. model .. " an " .. playerOptions[selected].title .. " übergeben") + else + Notification("Übergabe fehlgeschlagen") + end + end + }) + + lib.showMenu('transfer_vehicle_menu') + end + end playerMenu:SetPosition(screenPosition) playerMenu:Visible(true) @@ -363,6 +412,38 @@ function GenerateKeymakerMenuNativeUI() menuPoolNativeUI:RefreshIndex() end +-- Funktion zum Abrufen von Spielern in der Nähe mit Namen +function GetNearbyPlayersWithNames(maxDistance) + local players = {} + local playerPed = PlayerPedId() + local playerCoords = GetEntityCoords(playerPed) + + for _, id in ipairs(GetActivePlayers()) do + if id ~= PlayerId() then + local targetPed = GetPlayerPed(id) + local targetCoords = GetEntityCoords(targetPed) + local distance = #(playerCoords - targetCoords) + + if distance <= maxDistance then + local playerName = GetPlayerName(id) + table.insert(players, { + id = id, + serverId = GetPlayerServerId(id), + name = playerName, + distance = distance + }) + end + end + end + + -- Nach Entfernung sortieren + table.sort(players, function(a, b) + return a.distance < b.distance + end) + + return players +end + function GenerateKeyInventoryNativeUI() keyInvMenuNativeUI:Clear() @@ -388,6 +469,89 @@ function GenerateKeyInventoryNativeUI() submenuShowMasterKeys:AddItem(vehItem) end + -- Fahrzeugübergabe-Untermenü hinzufügen + local submenuTransferVehicle = menuPoolNativeUI:AddSubMenu(keyInvMenuNativeUI, "Fahrzeug übergeben", "Übertrage ein Fahrzeug an einen Spieler in der Nähe") + submenuTransferVehicle.ParentItem:RightLabel(">") + submenuTransferVehicle.Subtitle.Text._Text = "~b~Fahrzeug übergeben" + for i, vehicle in ipairs(vehicleData) do + local plate = vehicle[1] + local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicle[2])) + if (model == "NULL") then + model = GetDisplayNameFromVehicleModel(vehicle[2]) + end + + local vehItem = NativeUI.CreateItem(model .. " " .. plate, "Wähle dieses Fahrzeug zum Übergeben") + submenuTransferVehicle:AddItem(vehItem) + end + + submenuTransferVehicle.OnItemSelect = function(menu, item, index) + local selectedVehicle = vehicleData[index] + local plate = selectedVehicle[1] + local model = GetLabelText(GetDisplayNameFromVehicleModel(selectedVehicle[2])) + if (model == "NULL") then + model = GetDisplayNameFromVehicleModel(selectedVehicle[2]) + end + + -- Menü schließen und Spielerauswahl anzeigen + menuPoolNativeUI:CloseAllMenus() + menuOpen = false + + -- Spieler in der Nähe abrufen + local nearbyPlayers = GetNearbyPlayersWithNames(5.0) + + if #nearbyPlayers == 0 then + lib.notify({ + title = "Fahrzeug übergeben", + description = "Keine Spieler in der Nähe gefunden", + position = "top", + type = "error", + icon = "car" + }) + return + end + + -- Spielerauswahl-Menü erstellen + local playerOptions = {} + for _, player in ipairs(nearbyPlayers) do + table.insert(playerOptions, { + title = player.name, + description = "Entfernung: " .. math.floor(player.distance * 10) / 10 .. "m", + serverPlayerId = player.serverId + }) + end + + lib.registerMenu({ + id = 'transfer_vehicle_menu', + title = 'Fahrzeug übergeben', + position = 'top-right', + options = playerOptions, + onSelect = function(selected) + local targetPlayer = playerOptions[selected].serverPlayerId + local success = CB:Trigger("VKC:transferVehicleOwnership", plate, targetPlayer) + + if success then + lib.notify({ + title = "Fahrzeug übergeben", + description = "Du hast dein " .. model .. " an " .. playerOptions[selected].title .. " übergeben", + position = "top", + type = "success", + icon = "car" + }) + else + lib.notify({ + title = "Fahrzeug übergeben", + description = "Übergabe fehlgeschlagen", + position = "top", + type = "error", + icon = "car" + }) + end + end + }) + + lib.showMenu('transfer_vehicle_menu') + end + local submenuShowKeys = menuPoolNativeUI:AddSubMenu(keyInvMenuNativeUI, Config.Strings.NUI.keysTitle, Config.Strings.NUI.keysDesc) submenuShowKeys.ParentItem:RightLabel(">") submenuShowKeys.Subtitle.Text._Text = "~b~" .. Config.Strings.NUI.keysTitle @@ -431,7 +595,7 @@ function GenerateKeyInventoryNativeUI() if (submenuShowKeys:Visible() or submenuKey:Visible()) then local oldCount = submenuKey.ParentItem.Label.Text._Text:gsub("x", "") oldCount = oldCount:gsub(" >", "") - submenuKey.ParentItem:RightLabel("x" .. tostring(tonumber(oldCount) + 1) .. " >") + submenuKey.ParentItem:RightLabel("x" .. tostring(tonumber(oldCount) - 1) .. " >") end else Notification(string.format(Config.Strings.removeFailed, key.plate)) @@ -562,6 +726,8 @@ function ToggleLockOnVehicle(vehicle, lock) SetVehicleLights(vehicle, 2) Citizen.Wait(150) SetVehicleLights(vehicle, 0) + Citizen.Wait + SetVehicleLights(vehicle, 0) Citizen.Wait(150) SetVehicleLights(vehicle, 2) Citizen.Wait(150) @@ -607,6 +773,18 @@ AddEventHandler("VKC:giveKeyNotif", function(plate) Notification(string.format(Config.Strings.giveSuccessPly, plate)) end) +-- Ereignis für Fahrzeugübergabe-Benachrichtigung +RegisterNetEvent("VKC:vehicleTransferNotif") +AddEventHandler("VKC:vehicleTransferNotif", function(plate, model) + lib.notify({ + title = "Fahrzeug erhalten", + description = "Du hast ein " .. model .. " mit dem Kennzeichen " .. plate .. " erhalten", + position = "top", + type = "success", + icon = "car" + }) +end) + function IsVehicleOwner(vehicle) diff --git a/resources/[carscripts]/sn_vehicleKey/config.lua b/resources/[carscripts]/sn_vehicleKey/config.lua index 8b6d51906..6746abaa0 100644 --- a/resources/[carscripts]/sn_vehicleKey/config.lua +++ b/resources/[carscripts]/sn_vehicleKey/config.lua @@ -87,6 +87,7 @@ Config.Strings = { deleteKeys = "~r~Du hast für dein ~g~%s ~r~Das Schloss ausgetasucht, und somit sind jetzt alle Schlüssel nicht mehr Gültig.", + -- NativeUI NUI = { -- keymaker menu @@ -118,6 +119,14 @@ Config.Strings = { giveKeyDesc = "~g~Ersatzschlüssel Geben", removeKeyTitle = "~r~Schlüssel Entfernen", removeKeyDesc = "~r~Schlüssel Entfernen", + transferVehicleTitle = "~g~Fahrzeug übergeben", + transferVehicleDesc = "~g~Übertrage ein Fahrzeug an einen Spieler in der Nähe", + transferVehicleSuccess = "~g~Fahrzeug erfolgreich übergeben an %s", + transferVehicleFailed = "~r~Fahrzeugübergabe fehlgeschlagen", + transferVehicleReceived = "~g~Du hast ein Fahrzeug erhalten", + noPlayersNearby = "~r~Keine Spieler in der Nähe", + + }, -- ContextMenu @@ -132,5 +141,9 @@ Config.Strings = { -- other player giveKey = "~r~Gebe ein Schlüssel, an der Person", + + transferVehicleTitle = "Fahrzeug übergeben", + } } + diff --git a/resources/[carscripts]/sn_vehicleKey/server.lua b/resources/[carscripts]/sn_vehicleKey/server.lua index 39a28439a..b7fa1a81e 100644 --- a/resources/[carscripts]/sn_vehicleKey/server.lua +++ b/resources/[carscripts]/sn_vehicleKey/server.lua @@ -436,4 +436,68 @@ AddEventHandler('VKC:delvehkey', function(plate, owner) else MySQL.query("DELETE FROM vehicle_keys WHERE plate = ?", {plate}) end -end) \ No newline at end of file +end) + +-- Fahrzeugbesitz an einen anderen Spieler übertragen +CB:Register("VKC:transferVehicleOwnership", function(source, plate, targetPlayerId) + local src = source + + if (plate == nil or targetPlayerId == nil) then + print("^1[ERROR] \"plate\" or \"targetPlayerId\" was nil while transferring vehicle ownership for id " .. tostring(src)) + return false + end + + local Player = QBCore.Functions.GetPlayer(src) + local TargetPlayer = QBCore.Functions.GetPlayer(targetPlayerId) + + if (not Player or not TargetPlayer) then + print("^1[ERROR] Player or target player not found while transferring vehicle ownership") + return false + end + + local trimmedPlate = plate:gsub("^%s*(.-)%s*$", "%1"):upper() + + -- Überprüfen, ob der Spieler das Fahrzeug besitzt + local isOwner = IsVehicleOwner(src, trimmedPlate) + if not isOwner then + return false + end + + -- Fahrzeugmodell für die Benachrichtigung abrufen + local vehicleModel = nil + local results = MySQL.Sync.fetchAll("SELECT vehicle FROM player_vehicles WHERE plate = @plate AND citizenid = @owner", { + ["@plate"] = trimmedPlate, + ["@owner"] = Player.PlayerData.citizenid + }) + + if #results > 0 then + vehicleModel = results[1].vehicle + end + + -- Besitz in der Datenbank übertragen + local success = MySQL.Sync.execute("UPDATE player_vehicles SET citizenid = @newOwner WHERE plate = @plate AND citizenid = @oldOwner", { + ["@newOwner"] = TargetPlayer.PlayerData.citizenid, + ["@plate"] = trimmedPlate, + ["@oldOwner"] = Player.PlayerData.citizenid + }) + + if success > 0 then + -- Alle Schlüssel auf den neuen Besitzer übertragen + MySQL.Sync.execute("DELETE FROM vehicle_keys WHERE plate = @plate", { + ["@plate"] = trimmedPlate + }) + + -- Einen Schlüssel dem neuen Besitzer geben + MySQL.Sync.execute("INSERT INTO vehicle_keys (owner, plate, count) VALUES (@owner, @plate, 1)", { + ["@owner"] = TargetPlayer.PlayerData.citizenid, + ["@plate"] = trimmedPlate + }) + + -- Den Zielspieler benachrichtigen + TriggerClientEvent("VKC:vehicleTransferNotif", targetPlayerId, trimmedPlate, vehicleModel) + + return true + end + + return false +end)