ed
This commit is contained in:
		
							parent
							
								
									0b8ab3c19a
								
							
						
					
					
						commit
						b846de7b20
					
				
					 1 changed files with 170 additions and 21 deletions
				
			
		|  | @ -1,11 +1,10 @@ | |||
| local QBCore = exports['qb-core']:GetCoreObject() | ||||
| local currentVehicle = nil | ||||
| local anchoredBoats = {} -- Speichert verankerte Boote | ||||
|  | ||||
| -- Boot-Klassen für spezielle Behandlung | ||||
| local boatClasses = { | ||||
|     [14] = true, -- Boats | ||||
|     [15] = true, -- Helicopters (falls gewünscht) | ||||
|     [16] = true  -- Planes (falls gewünscht) | ||||
| } | ||||
|  | ||||
| -- Sitz-Namen für bessere Anzeige | ||||
|  | @ -29,6 +28,84 @@ local function isBoat(vehicle) | |||
|     return boatClasses[vehicleClass] or false | ||||
| end | ||||
|  | ||||
| -- Anker setzen/entfernen | ||||
| local function toggleAnchor(vehicle) | ||||
|     if not isBoat(vehicle) then | ||||
|         QBCore.Functions.Notify('Nur Boote können verankert werden!', 'error') | ||||
|         return | ||||
|     end | ||||
|      | ||||
|     local vehicleNetId = NetworkGetNetworkIdFromEntity(vehicle) | ||||
|      | ||||
|     if anchoredBoats[vehicleNetId] then | ||||
|         -- Anker lichten | ||||
|         FreezeEntityPosition(vehicle, false) | ||||
|         SetEntityInvincible(vehicle, false) | ||||
|         anchoredBoats[vehicleNetId] = nil | ||||
|          | ||||
|         QBCore.Functions.Notify('⚓ Anker gelichtet! Das Boot kann wieder bewegt werden.', 'success') | ||||
|          | ||||
|         -- Effekt: Kurzes Wackeln beim Anker lichten | ||||
|         CreateThread(function() | ||||
|             local originalCoords = GetEntityCoords(vehicle) | ||||
|             for i = 1, 10 do | ||||
|                 local offset = math.random(-10, 10) / 100 | ||||
|                 SetEntityCoords(vehicle, originalCoords.x + offset, originalCoords.y + offset, originalCoords.z) | ||||
|                 Wait(50) | ||||
|             end | ||||
|             SetEntityCoords(vehicle, originalCoords.x, originalCoords.y, originalCoords.z) | ||||
|         end) | ||||
|     else | ||||
|         -- Anker werfen | ||||
|         local coords = GetEntityCoords(vehicle) | ||||
|         local heading = GetEntityHeading(vehicle) | ||||
|          | ||||
|         FreezeEntityPosition(vehicle, true) | ||||
|         SetEntityInvincible(vehicle, true) | ||||
|          | ||||
|         anchoredBoats[vehicleNetId] = { | ||||
|             coords = coords, | ||||
|             heading = heading, | ||||
|             time = GetGameTimer() | ||||
|         } | ||||
|          | ||||
|         QBCore.Functions.Notify('⚓ Anker geworfen! Das Boot ist jetzt verankert.', 'success') | ||||
|          | ||||
|         -- Anker-Wurf Effekt | ||||
|         CreateThread(function() | ||||
|             -- Spiele Anker-Sound (falls vorhanden) | ||||
|             PlaySoundFromEntity(-1, "CHECKPOINT_PERFECT", vehicle, "HUD_MINI_GAME_SOUNDSET", 0, 0) | ||||
|              | ||||
|             -- Kleine Wellen-Animation | ||||
|             for i = 1, 5 do | ||||
|                 local waterHeight = GetWaterHeight(coords.x, coords.y, coords.z) | ||||
|                 if waterHeight then | ||||
|                     -- Erstelle Wasser-Effekt um das Boot | ||||
|                     local effect = "ent_sht_water" | ||||
|                     RequestNamedPtfxAsset(effect) | ||||
|                     while not HasNamedPtfxAssetLoaded(effect) do | ||||
|                         Wait(1) | ||||
|                     end | ||||
|                      | ||||
|                     for j = 1, 3 do | ||||
|                         local offsetX = math.random(-200, 200) / 100 | ||||
|                         local offsetY = math.random(-200, 200) / 100 | ||||
|                         UsePartikelFxAssetNextCall(effect) | ||||
|                         StartParticleFxNonLoopedAtCoord("ent_sht_water", coords.x + offsetX, coords.y + offsetY, waterHeight, 0.0, 0.0, 0.0, 0.5, false, false, false) | ||||
|                     end | ||||
|                 end | ||||
|                 Wait(200) | ||||
|             end | ||||
|         end) | ||||
|     end | ||||
| end | ||||
|  | ||||
| -- Prüfe ob Boot verankert ist | ||||
| local function isBoatAnchored(vehicle) | ||||
|     local vehicleNetId = NetworkGetNetworkIdFromEntity(vehicle) | ||||
|     return anchoredBoats[vehicleNetId] ~= nil | ||||
| end | ||||
|  | ||||
| -- Funktion um verfügbare Sitze zu bekommen | ||||
| local function getAvailableSeats(vehicle) | ||||
|     local seats = {} | ||||
|  | @ -140,6 +217,11 @@ local function teleportToSeat(vehicle, seatIndex) | |||
|     local seatName = seatNames[seatIndex] or "Sitz " .. (seatIndex + 1) | ||||
|     if isBoat(vehicle) then | ||||
|         QBCore.Functions.Notify('Willkommen an Bord! (' .. seatName .. ')', 'success') | ||||
|          | ||||
|         -- Zeige Anker-Status wenn Kapitän | ||||
|         if seatIndex == -1 and isBoatAnchored(vehicle) then | ||||
|             QBCore.Functions.Notify('⚓ Das Boot ist verankert. Nutze das Menü um den Anker zu lichten.', 'primary') | ||||
|         end | ||||
|     else | ||||
|         QBCore.Functions.Notify('Du bist eingestiegen (' .. seatName .. ')', 'success') | ||||
|     end | ||||
|  | @ -198,6 +280,11 @@ local function switchSeat(vehicle, newSeatIndex) | |||
|      | ||||
|     local seatName = seatNames[newSeatIndex] or "Sitz " .. (newSeatIndex + 1) | ||||
|     QBCore.Functions.Notify('Gewechselt zu: ' .. seatName, 'success') | ||||
|      | ||||
|     -- Zeige Anker-Status wenn zum Kapitän gewechselt | ||||
|     if isBoat(vehicle) and newSeatIndex == -1 and isBoatAnchored(vehicle) then | ||||
|         QBCore.Functions.Notify('⚓ Das Boot ist verankert. Nutze das Menü um den Anker zu lichten.', 'primary') | ||||
|     end | ||||
| end | ||||
|  | ||||
| -- Hauptmenü für Sitzauswahl | ||||
|  | @ -207,6 +294,7 @@ local function showSeatMenu(vehicle) | |||
|     local availableSeats = getAvailableSeats(vehicle) | ||||
|     local occupiedSeats = getOccupiedSeats(vehicle) | ||||
|     local isVehicleBoat = isBoat(vehicle) | ||||
|     local isAnchored = isBoatAnchored(vehicle) | ||||
|     local options = {} | ||||
|      | ||||
|     -- Header | ||||
|  | @ -216,13 +304,35 @@ local function showSeatMenu(vehicle) | |||
|         vehicleLabel = vehicleName | ||||
|     end | ||||
|      | ||||
|     -- Boot-spezifische Anzeige | ||||
|     -- Boot-spezifische Anzeige mit Anker-Status | ||||
|     if isVehicleBoat then | ||||
|         vehicleLabel = "⛵ " .. vehicleLabel | ||||
|         vehicleLabel = (isAnchored and "⚓ " or "⛵ ") .. vehicleLabel | ||||
|     else | ||||
|         vehicleLabel = "🚗 " .. vehicleLabel | ||||
|     end | ||||
|      | ||||
|     -- Anker-Kontrolle (nur für Boote und nur wenn im Boot) | ||||
|     if isVehicleBoat and isInVehicle then | ||||
|         local currentSeat = GetPedVehicleSeat(playerPed) | ||||
|         -- Nur Kapitän kann Anker bedienen | ||||
|         if currentSeat == -1 then | ||||
|             table.insert(options, { | ||||
|                 title = isAnchored and '⚓ Anker lichten' or '⚓ Anker werfen', | ||||
|                 description = isAnchored and 'Boot wieder beweglich machen' or 'Boot an aktueller Position verankern', | ||||
|                 icon = 'fas fa-anchor', | ||||
|                 onSelect = function() | ||||
|                     toggleAnchor(vehicle) | ||||
|                 end | ||||
|             }) | ||||
|              | ||||
|             -- Trennlinie | ||||
|             table.insert(options, { | ||||
|                 title = '─────────────────', | ||||
|                 disabled = true | ||||
|             }) | ||||
|         end | ||||
|     end | ||||
|      | ||||
|     -- Verfügbare Sitze | ||||
|     if #availableSeats > 0 then | ||||
|         local headerText = isVehicleBoat and '🟢 Verfügbare Plätze' or '🟢 Verfügbare Sitze' | ||||
|  | @ -325,6 +435,7 @@ function showVehicleInfo(vehicle) | |||
|     local engineHealth = math.floor(GetVehicleEngineHealth(vehicle) / 10) | ||||
|     local bodyHealth = math.floor(GetVehicleBodyHealth(vehicle) / 10) | ||||
|     local isVehicleBoat = isBoat(vehicle) | ||||
|     local isAnchored = isBoatAnchored(vehicle) | ||||
|      | ||||
|     local options = { | ||||
|         { | ||||
|  | @ -338,22 +449,34 @@ function showVehicleInfo(vehicle) | |||
|             description = 'Maximale Anzahl Personen', | ||||
|             icon = 'fas fa-users', | ||||
|             disabled = true | ||||
|         }, | ||||
|         { | ||||
|             title = (isVehicleBoat and 'Motor: ' or 'Motor: ') .. engineHealth .. '%', | ||||
|             description = 'Zustand des Motors', | ||||
|             icon = 'fas fa-cog', | ||||
|             disabled = true | ||||
|         }, | ||||
|         { | ||||
|             title = (isVehicleBoat and 'Rumpf: ' or 'Karosserie: ') .. bodyHealth .. '%', | ||||
|             description = isVehicleBoat and 'Zustand des Rumpfes' or 'Zustand der Karosserie', | ||||
|             icon = isVehicleBoat and 'fas fa-ship' or 'fas fa-car-crash', | ||||
|             disabled = true | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     -- Kraftstoff nur für Nicht-Boote (Boote haben oft keinen Kraftstoff-Wert) | ||||
|     -- Anker-Status für Boote | ||||
|     if isVehicleBoat then | ||||
|         table.insert(options, { | ||||
|             title = 'Anker-Status: ' .. (isAnchored and 'Verankert ⚓' or 'Gelichtet ⛵'), | ||||
|             description = isAnchored and 'Das Boot ist an der aktuellen Position verankert' or 'Das Boot kann frei bewegt werden', | ||||
|             icon = 'fas fa-anchor', | ||||
|             disabled = true | ||||
|         }) | ||||
|     end | ||||
|      | ||||
|     table.insert(options, { | ||||
|         title = (isVehicleBoat and 'Motor: ' or 'Motor: ') .. engineHealth .. '%', | ||||
|         description = 'Zustand des Motors', | ||||
|         icon = 'fas fa-cog', | ||||
|         disabled = true | ||||
|     }) | ||||
|      | ||||
|     table.insert(options, { | ||||
|         title = (isVehicleBoat and 'Rumpf: ' or 'Karosserie: ') .. bodyHealth .. '%', | ||||
|         description = isVehicleBoat and 'Zustand des Rumpfes' or 'Zustand der Karosserie', | ||||
|         icon = isVehicleBoat and 'fas fa-ship' or 'fas fa-car-crash', | ||||
|         disabled = true | ||||
|     }) | ||||
|      | ||||
|     -- Kraftstoff nur für Nicht-Boote | ||||
|     if not isVehicleBoat then | ||||
|         local fuelLevel = math.floor(GetVehicleFuelLevel(vehicle)) | ||||
|         table.insert(options, { | ||||
|  | @ -407,14 +530,23 @@ RegisterNetEvent('vehicle:openSeatMenu', function(data) | |||
|     end | ||||
| end) | ||||
|  | ||||
| -- Cleanup | ||||
| -- Cleanup verankerte Boote bei Resource Stop | ||||
| AddEventHandler('onResourceStop', function(resourceName) | ||||
|     if GetCurrentResourceName() == resourceName then | ||||
|         -- Alle verankerten Boote wieder freigeben | ||||
|         for vehicleNetId, _ in pairs(anchoredBoats) do | ||||
|             local vehicle = NetworkGetEntityFromNetworkId(vehicleNetId) | ||||
|             if DoesEntityExist(vehicle) then | ||||
|                 FreezeEntityPosition(vehicle, false) | ||||
|                 SetEntityInvincible(vehicle, false) | ||||
|             end | ||||
|         end | ||||
|         anchoredBoats = {} | ||||
|         currentVehicle = nil | ||||
|     end | ||||
| end) | ||||
|  | ||||
| -- Keybind für schnellen Zugriff (Optional) | ||||
| -- Keybind für schnellen Zugriff | ||||
| RegisterCommand('seats', function() | ||||
|     local playerPed = PlayerPedId() | ||||
|     local vehicle = GetVehiclePedIsIn(playerPed, false) | ||||
|  | @ -422,7 +554,6 @@ RegisterCommand('seats', function() | |||
|     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) | ||||
|          | ||||
|  | @ -434,5 +565,23 @@ RegisterCommand('seats', function() | |||
|     end | ||||
| end, false) | ||||
|  | ||||
| -- Keybind registrieren | ||||
| -- Schneller Anker-Befehl für Kapitäne | ||||
| RegisterCommand('anchor', function() | ||||
|     local playerPed = PlayerPedId() | ||||
|     local vehicle = GetVehiclePedIsIn(playerPed, false) | ||||
|      | ||||
|     if vehicle ~= 0 and isBoat(vehicle) then | ||||
|         local seat = GetPedVehicleSeat(playerPed) | ||||
|         if seat == -1 then -- Nur Kapitän | ||||
|             toggleAnchor(vehicle) | ||||
|         else | ||||
|             QBCore.Functions.Notify('Nur der Kapitän kann den Anker bedienen!', 'error') | ||||
|         end | ||||
|     else | ||||
|         QBCore.Functions.Notify('Du musst Kapitän eines Bootes sein!', 'error') | ||||
|     end | ||||
| end, false) | ||||
|  | ||||
| -- Keybinds registrieren | ||||
| RegisterKeyMapping('seats', 'Sitzplatz Menü öffnen', 'keyboard', 'F6') | ||||
| RegisterKeyMapping('anchor', 'Anker werfen/lichten', 'keyboard', 'H') | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Nordi98
						Nordi98