diff --git a/resources/[carscripts]/nordi_seats/client.lua b/resources/[carscripts]/nordi_seats/client.lua new file mode 100644 index 000000000..9d43be7cf --- /dev/null +++ b/resources/[carscripts]/nordi_seats/client.lua @@ -0,0 +1,363 @@ +local QBCore = exports['qb-core']:GetCoreObject() +local currentVehicle = nil + +-- Sitz-Namen für bessere Anzeige +local seatNames = { + [-1] = "Fahrer", + [0] = "Beifahrer", + [1] = "Hinten Links", + [2] = "Hinten Rechts", + [3] = "Hinten Mitte", + [4] = "Extra 1", + [5] = "Extra 2", + [6] = "Extra 3", + [7] = "Extra 4", + [8] = "Extra 5", + [9] = "Extra 6" +} + +-- Funktion um verfügbare Sitze zu bekommen +local function getAvailableSeats(vehicle) + local seats = {} + local maxSeats = GetVehicleMaxNumberOfPassengers(vehicle) + + -- Fahrersitz (-1) + if IsVehicleSeatFree(vehicle, -1) then + table.insert(seats, { + index = -1, + name = seatNames[-1], + icon = "fas fa-steering-wheel" + }) + end + + -- Passagiersitze (0 bis maxSeats-1) + for i = 0, maxSeats - 1 do + if IsVehicleSeatFree(vehicle, i) then + table.insert(seats, { + index = i, + name = seatNames[i] or "Sitz " .. (i + 1), + icon = "fas fa-user" + }) + end + end + + return seats +end + +-- Funktion um belegte Sitze zu bekommen +local function getOccupiedSeats(vehicle) + local occupiedSeats = {} + local maxSeats = GetVehicleMaxNumberOfPassengers(vehicle) + + -- Fahrersitz prüfen + if not IsVehicleSeatFree(vehicle, -1) then + local ped = GetPedInVehicleSeat(vehicle, -1) + local playerName = "Unbekannt" + + if IsPedAPlayer(ped) then + local playerId = NetworkGetPlayerIndexFromPed(ped) + if playerId ~= -1 then + playerName = GetPlayerName(playerId) + end + else + playerName = "NPC" + end + + table.insert(occupiedSeats, { + index = -1, + name = seatNames[-1], + occupant = playerName, + icon = "fas fa-steering-wheel" + }) + end + + -- Passagiersitze prüfen + for i = 0, maxSeats - 1 do + if not IsVehicleSeatFree(vehicle, i) then + local ped = GetPedInVehicleSeat(vehicle, i) + local playerName = "Unbekannt" + + if IsPedAPlayer(ped) then + local playerId = NetworkGetPlayerIndexFromPed(ped) + if playerId ~= -1 then + playerName = GetPlayerName(playerId) + end + else + playerName = "NPC" + end + + table.insert(occupiedSeats, { + index = i, + name = seatNames[i] or "Sitz " .. (i + 1), + occupant = playerName, + icon = "fas fa-user" + }) + end + end + + return occupiedSeats +end + +-- Funktion zum Einsteigen +local function enterVehicleSeat(vehicle, seatIndex) + local playerPed = PlayerPedId() + + if IsPedInAnyVehicle(playerPed, false) then + QBCore.Functions.Notify('Du bist bereits in einem Fahrzeug!', 'error') + return + end + + if not IsVehicleSeatFree(vehicle, seatIndex) then + QBCore.Functions.Notify('Dieser Sitz ist bereits belegt!', 'error') + return + end + + -- Prüfe ob Fahrzeug abgeschlossen ist + if GetVehicleDoorLockStatus(vehicle) == 2 then + QBCore.Functions.Notify('Das Fahrzeug ist abgeschlossen!', 'error') + return + end + + TaskEnterVehicle(playerPed, vehicle, 10000, seatIndex, 1.0, 1, 0) + currentVehicle = vehicle + + local seatName = seatNames[seatIndex] or "Sitz " .. (seatIndex + 1) + QBCore.Functions.Notify('Steige in das Fahrzeug ein (' .. seatName .. ')...', 'primary') +end + +-- Funktion zum Sitzwechsel +local function switchSeat(vehicle, newSeatIndex) + local playerPed = PlayerPedId() + + if not IsPedInVehicle(playerPed, vehicle, false) then + QBCore.Functions.Notify('Du bist nicht in diesem Fahrzeug!', 'error') + return + end + + if not IsVehicleSeatFree(vehicle, newSeatIndex) then + QBCore.Functions.Notify('Dieser Sitz ist bereits belegt!', 'error') + return + end + + TaskShuffleToNextVehicleSeat(playerPed, vehicle) + Wait(100) + + -- Setze auf gewünschten Sitz + SetPedIntoVehicle(playerPed, vehicle, newSeatIndex) + + local seatName = seatNames[newSeatIndex] or "Sitz " .. (newSeatIndex + 1) + QBCore.Functions.Notify('Gewechselt zu: ' .. seatName, 'success') +end + +-- Hauptmenü für Sitzauswahl +local function showSeatMenu(vehicle) + local playerPed = PlayerPedId() + local isInVehicle = IsPedInVehicle(playerPed, vehicle, false) + local availableSeats = getAvailableSeats(vehicle) + local occupiedSeats = getOccupiedSeats(vehicle) + local options = {} + + -- Header + local vehicleName = GetDisplayNameFromVehicleModel(GetEntityModel(vehicle)) + local vehicleLabel = GetLabelText(vehicleName) + if vehicleLabel == "NULL" then + vehicleLabel = vehicleName + end + + -- Verfügbare Sitze + if #availableSeats > 0 then + table.insert(options, { + title = '🟢 Verfügbare Sitze', + description = 'Freie Sitzplätze', + disabled = true + }) + + for _, seat in pairs(availableSeats) do + table.insert(options, { + title = seat.name, + description = isInVehicle and 'Zu diesem Sitz wechseln' or 'In das Fahrzeug einsteigen', + icon = seat.icon, + onSelect = function() + if isInVehicle then + switchSeat(vehicle, seat.index) + else + enterVehicleSeat(vehicle, seat.index) + end + end + }) + end + end + + -- Belegte Sitze anzeigen + if #occupiedSeats > 0 then + table.insert(options, { + title = '🔴 Belegte Sitze', + description = 'Bereits besetzte Sitzplätze', + disabled = true + }) + + for _, seat in pairs(occupiedSeats) do + table.insert(options, { + title = seat.name, + description = 'Besetzt von: ' .. seat.occupant, + icon = seat.icon, + disabled = true + }) + end + end + + -- Aussteigen Option (nur wenn im Fahrzeug) + if isInVehicle then + table.insert(options, { + title = '🚪 Aussteigen', + description = 'Das Fahrzeug verlassen', + icon = 'fas fa-door-open', + onSelect = function() + TaskLeaveVehicle(playerPed, vehicle, 0) + QBCore.Functions.Notify('Du steigst aus dem Fahrzeug aus...', 'primary') + end + }) + end + + -- Fahrzeuginfo + table.insert(options, { + title = '📋 Fahrzeuginfo', + description = 'Informationen über das Fahrzeug', + icon = 'fas fa-info-circle', + onSelect = function() + showVehicleInfo(vehicle) + end + }) + + if #options == 0 then + QBCore.Functions.Notify('Keine verfügbaren Aktionen!', 'error') + return + end + + lib.registerContext({ + id = 'vehicle_seat_menu', + title = '🚗 ' .. vehicleLabel, + options = options + }) + + lib.showContext('vehicle_seat_menu') +end + +-- Fahrzeuginfo anzeigen +function showVehicleInfo(vehicle) + local vehicleProps = QBCore.Functions.GetVehicleProperties(vehicle) + local vehicleName = GetDisplayNameFromVehicleModel(GetEntityModel(vehicle)) + local vehicleLabel = GetLabelText(vehicleName) + if vehicleLabel == "NULL" then + vehicleLabel = vehicleName + end + + local maxSeats = GetVehicleMaxNumberOfPassengers(vehicle) + 1 -- +1 für Fahrer + local engineHealth = math.floor(GetVehicleEngineHealth(vehicle) / 10) + local bodyHealth = math.floor(GetVehicleBodyHealth(vehicle) / 10) + local fuelLevel = math.floor(GetVehicleFuelLevel(vehicle)) + + local options = { + { + title = 'Fahrzeug: ' .. vehicleLabel, + description = 'Kennzeichen: ' .. (vehicleProps.plate or 'Unbekannt'), + icon = 'fas fa-car', + disabled = true + }, + { + title = 'Sitzplätze: ' .. maxSeats, + description = 'Maximale Anzahl Personen', + icon = 'fas fa-users', + disabled = true + }, + { + title = 'Motor: ' .. engineHealth .. '%', + description = 'Zustand des Motors', + icon = 'fas fa-cog', + disabled = true + }, + { + title = 'Karosserie: ' .. bodyHealth .. '%', + description = 'Zustand der Karosserie', + icon = 'fas fa-car-crash', + disabled = true + }, + { + title = 'Kraftstoff: ' .. fuelLevel .. '%', + description = 'Aktueller Tankstand', + icon = 'fas fa-gas-pump', + disabled = true + }, + { + title = '← Zurück', + description = 'Zurück zum Sitzmenü', + icon = 'fas fa-arrow-left', + onSelect = function() + showSeatMenu(vehicle) + end + } + } + + lib.registerContext({ + id = 'vehicle_info_menu', + title = '📋 Fahrzeuginfo', + options = options + }) + + lib.showContext('vehicle_info_menu') +end + +-- QB-Target Setup +CreateThread(function() + exports['qb-target']:AddGlobalVehicle({ + options = { + { + type = "client", + event = "vehicle:openSeatMenu", + icon = "fas fa-car", + label = "Sitzplatz wählen", + } + }, + distance = 3.0 + }) +end) + +-- Event Handler +RegisterNetEvent('vehicle:openSeatMenu', function(data) + local vehicle = data.entity + if DoesEntityExist(vehicle) and IsEntityAVehicle(vehicle) then + showSeatMenu(vehicle) + else + QBCore.Functions.Notify('Kein gültiges Fahrzeug gefunden!', 'error') + end +end) + +-- Cleanup +AddEventHandler('onResourceStop', function(resourceName) + if GetCurrentResourceName() == resourceName then + currentVehicle = nil + end +end) + +-- Keybind für schnellen Zugriff (Optional) +RegisterCommand('seats', function() + local playerPed = PlayerPedId() + local vehicle = GetVehiclePedIsIn(playerPed, false) + + if vehicle ~= 0 then + showSeatMenu(vehicle) + else + -- Suche nach nahegelegenem Fahrzeug + local coords = GetEntityCoords(playerPed) + local closestVehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + + if DoesEntityExist(closestVehicle) then + showSeatMenu(closestVehicle) + else + QBCore.Functions.Notify('Kein Fahrzeug in der Nähe!', 'error') + end + end +end, false) + +-- Keybind registrieren +RegisterKeyMapping('seats', 'Sitzplatz Menü öffnen', 'keyboard', 'F6') diff --git a/resources/[carscripts]/nordi_seats/fxmanifest.lua b/resources/[carscripts]/nordi_seats/fxmanifest.lua new file mode 100644 index 000000000..7dc5ef60c --- /dev/null +++ b/resources/[carscripts]/nordi_seats/fxmanifest.lua @@ -0,0 +1,22 @@ +fx_version 'cerulean' +game 'gta5' + +author 'Dein Name' +description 'Fahrzeug Sitz-Auswahl Script für QBCore' +version '1.0.0' + +shared_scripts { + '@ox_lib/init.lua' +} + +client_scripts { + 'client/main.lua' +} + +dependencies { + 'qb-core', + 'qb-target', + 'ox_lib' +} + +lua54 'yes' diff --git a/resources/[inventory]/cs_shops/ui/image/weapon_carbine.png b/resources/[inventory]/cs_shops/ui/image/weapon_carbine.png deleted file mode 100644 index 2633a89ce..000000000 Binary files a/resources/[inventory]/cs_shops/ui/image/weapon_carbine.png and /dev/null differ diff --git a/resources/[inventory]/cs_shops/ui/image/weapon_carbinerifle.png b/resources/[inventory]/cs_shops/ui/image/weapon_carbinerifle.png index a3685004a..2633a89ce 100644 Binary files a/resources/[inventory]/cs_shops/ui/image/weapon_carbinerifle.png and b/resources/[inventory]/cs_shops/ui/image/weapon_carbinerifle.png differ diff --git a/resources/[inventory]/inventory_images/images/weapon_carbine.png b/resources/[inventory]/inventory_images/images/weapon_carbine.png deleted file mode 100644 index 2633a89ce..000000000 Binary files a/resources/[inventory]/inventory_images/images/weapon_carbine.png and /dev/null differ diff --git a/resources/[inventory]/inventory_images/images/weapon_carbinerifle.png b/resources/[inventory]/inventory_images/images/weapon_carbinerifle.png index a3685004a..2633a89ce 100644 Binary files a/resources/[inventory]/inventory_images/images/weapon_carbinerifle.png and b/resources/[inventory]/inventory_images/images/weapon_carbinerifle.png differ