forked from Simnation/Main
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 QBCore = exports['qb-core']:GetCoreObject()
|
||||||
local currentVehicle = nil
|
local currentVehicle = nil
|
||||||
|
local anchoredBoats = {} -- Speichert verankerte Boote
|
||||||
|
|
||||||
-- Boot-Klassen für spezielle Behandlung
|
-- Boot-Klassen für spezielle Behandlung
|
||||||
local boatClasses = {
|
local boatClasses = {
|
||||||
[14] = true, -- Boats
|
[14] = true, -- Boats
|
||||||
[15] = true, -- Helicopters (falls gewünscht)
|
|
||||||
[16] = true -- Planes (falls gewünscht)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Sitz-Namen für bessere Anzeige
|
-- Sitz-Namen für bessere Anzeige
|
||||||
|
@ -29,6 +28,84 @@ local function isBoat(vehicle)
|
||||||
return boatClasses[vehicleClass] or false
|
return boatClasses[vehicleClass] or false
|
||||||
end
|
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
|
-- Funktion um verfügbare Sitze zu bekommen
|
||||||
local function getAvailableSeats(vehicle)
|
local function getAvailableSeats(vehicle)
|
||||||
local seats = {}
|
local seats = {}
|
||||||
|
@ -140,6 +217,11 @@ local function teleportToSeat(vehicle, seatIndex)
|
||||||
local seatName = seatNames[seatIndex] or "Sitz " .. (seatIndex + 1)
|
local seatName = seatNames[seatIndex] or "Sitz " .. (seatIndex + 1)
|
||||||
if isBoat(vehicle) then
|
if isBoat(vehicle) then
|
||||||
QBCore.Functions.Notify('Willkommen an Bord! (' .. seatName .. ')', 'success')
|
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
|
else
|
||||||
QBCore.Functions.Notify('Du bist eingestiegen (' .. seatName .. ')', 'success')
|
QBCore.Functions.Notify('Du bist eingestiegen (' .. seatName .. ')', 'success')
|
||||||
end
|
end
|
||||||
|
@ -198,6 +280,11 @@ local function switchSeat(vehicle, newSeatIndex)
|
||||||
|
|
||||||
local seatName = seatNames[newSeatIndex] or "Sitz " .. (newSeatIndex + 1)
|
local seatName = seatNames[newSeatIndex] or "Sitz " .. (newSeatIndex + 1)
|
||||||
QBCore.Functions.Notify('Gewechselt zu: ' .. seatName, 'success')
|
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
|
end
|
||||||
|
|
||||||
-- Hauptmenü für Sitzauswahl
|
-- Hauptmenü für Sitzauswahl
|
||||||
|
@ -207,6 +294,7 @@ local function showSeatMenu(vehicle)
|
||||||
local availableSeats = getAvailableSeats(vehicle)
|
local availableSeats = getAvailableSeats(vehicle)
|
||||||
local occupiedSeats = getOccupiedSeats(vehicle)
|
local occupiedSeats = getOccupiedSeats(vehicle)
|
||||||
local isVehicleBoat = isBoat(vehicle)
|
local isVehicleBoat = isBoat(vehicle)
|
||||||
|
local isAnchored = isBoatAnchored(vehicle)
|
||||||
local options = {}
|
local options = {}
|
||||||
|
|
||||||
-- Header
|
-- Header
|
||||||
|
@ -216,13 +304,35 @@ local function showSeatMenu(vehicle)
|
||||||
vehicleLabel = vehicleName
|
vehicleLabel = vehicleName
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Boot-spezifische Anzeige
|
-- Boot-spezifische Anzeige mit Anker-Status
|
||||||
if isVehicleBoat then
|
if isVehicleBoat then
|
||||||
vehicleLabel = "⛵ " .. vehicleLabel
|
vehicleLabel = (isAnchored and "⚓ " or "⛵ ") .. vehicleLabel
|
||||||
else
|
else
|
||||||
vehicleLabel = "🚗 " .. vehicleLabel
|
vehicleLabel = "🚗 " .. vehicleLabel
|
||||||
end
|
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
|
-- Verfügbare Sitze
|
||||||
if #availableSeats > 0 then
|
if #availableSeats > 0 then
|
||||||
local headerText = isVehicleBoat and '🟢 Verfügbare Plätze' or '🟢 Verfügbare Sitze'
|
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 engineHealth = math.floor(GetVehicleEngineHealth(vehicle) / 10)
|
||||||
local bodyHealth = math.floor(GetVehicleBodyHealth(vehicle) / 10)
|
local bodyHealth = math.floor(GetVehicleBodyHealth(vehicle) / 10)
|
||||||
local isVehicleBoat = isBoat(vehicle)
|
local isVehicleBoat = isBoat(vehicle)
|
||||||
|
local isAnchored = isBoatAnchored(vehicle)
|
||||||
|
|
||||||
local options = {
|
local options = {
|
||||||
{
|
{
|
||||||
|
@ -338,22 +449,34 @@ function showVehicleInfo(vehicle)
|
||||||
description = 'Maximale Anzahl Personen',
|
description = 'Maximale Anzahl Personen',
|
||||||
icon = 'fas fa-users',
|
icon = 'fas fa-users',
|
||||||
disabled = true
|
disabled = true
|
||||||
},
|
}
|
||||||
{
|
}
|
||||||
|
|
||||||
|
-- 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 .. '%',
|
title = (isVehicleBoat and 'Motor: ' or 'Motor: ') .. engineHealth .. '%',
|
||||||
description = 'Zustand des Motors',
|
description = 'Zustand des Motors',
|
||||||
icon = 'fas fa-cog',
|
icon = 'fas fa-cog',
|
||||||
disabled = true
|
disabled = true
|
||||||
},
|
})
|
||||||
{
|
|
||||||
|
table.insert(options, {
|
||||||
title = (isVehicleBoat and 'Rumpf: ' or 'Karosserie: ') .. bodyHealth .. '%',
|
title = (isVehicleBoat and 'Rumpf: ' or 'Karosserie: ') .. bodyHealth .. '%',
|
||||||
description = isVehicleBoat and 'Zustand des Rumpfes' or 'Zustand der Karosserie',
|
description = isVehicleBoat and 'Zustand des Rumpfes' or 'Zustand der Karosserie',
|
||||||
icon = isVehicleBoat and 'fas fa-ship' or 'fas fa-car-crash',
|
icon = isVehicleBoat and 'fas fa-ship' or 'fas fa-car-crash',
|
||||||
disabled = true
|
disabled = true
|
||||||
}
|
})
|
||||||
}
|
|
||||||
|
|
||||||
-- Kraftstoff nur für Nicht-Boote (Boote haben oft keinen Kraftstoff-Wert)
|
-- Kraftstoff nur für Nicht-Boote
|
||||||
if not isVehicleBoat then
|
if not isVehicleBoat then
|
||||||
local fuelLevel = math.floor(GetVehicleFuelLevel(vehicle))
|
local fuelLevel = math.floor(GetVehicleFuelLevel(vehicle))
|
||||||
table.insert(options, {
|
table.insert(options, {
|
||||||
|
@ -407,14 +530,23 @@ RegisterNetEvent('vehicle:openSeatMenu', function(data)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Cleanup
|
-- Cleanup verankerte Boote bei Resource Stop
|
||||||
AddEventHandler('onResourceStop', function(resourceName)
|
AddEventHandler('onResourceStop', function(resourceName)
|
||||||
if GetCurrentResourceName() == resourceName then
|
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
|
currentVehicle = nil
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Keybind für schnellen Zugriff (Optional)
|
-- Keybind für schnellen Zugriff
|
||||||
RegisterCommand('seats', function()
|
RegisterCommand('seats', function()
|
||||||
local playerPed = PlayerPedId()
|
local playerPed = PlayerPedId()
|
||||||
local vehicle = GetVehiclePedIsIn(playerPed, false)
|
local vehicle = GetVehiclePedIsIn(playerPed, false)
|
||||||
|
@ -422,7 +554,6 @@ RegisterCommand('seats', function()
|
||||||
if vehicle ~= 0 then
|
if vehicle ~= 0 then
|
||||||
showSeatMenu(vehicle)
|
showSeatMenu(vehicle)
|
||||||
else
|
else
|
||||||
-- Suche nach nahegelegenem Fahrzeug
|
|
||||||
local coords = GetEntityCoords(playerPed)
|
local coords = GetEntityCoords(playerPed)
|
||||||
local closestVehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71)
|
local closestVehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71)
|
||||||
|
|
||||||
|
@ -434,5 +565,23 @@ RegisterCommand('seats', function()
|
||||||
end
|
end
|
||||||
end, false)
|
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('seats', 'Sitzplatz Menü öffnen', 'keyboard', 'F6')
|
||||||
|
RegisterKeyMapping('anchor', 'Anker werfen/lichten', 'keyboard', 'H')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue