forked from Simnation/Main
ed
This commit is contained in:
parent
8ee1bc193d
commit
6fbb9c5ea6
2 changed files with 183 additions and 5 deletions
|
@ -50,6 +50,52 @@ local function isBoat(vehicle)
|
||||||
return boatClasses[vehicleClass] or false
|
return boatClasses[vehicleClass] or false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Lade verankerte Boote vom Server
|
||||||
|
local function loadAnchoredBoats()
|
||||||
|
QBCore.Functions.TriggerCallback('nordi_seats:server:getAnchoredBoats', function(serverAnchors)
|
||||||
|
if serverAnchors then
|
||||||
|
for plate, anchorData in pairs(serverAnchors) do
|
||||||
|
-- Finde Fahrzeug mit dieser Kennzeichen
|
||||||
|
local vehicles = GetGamePool('CVehicle')
|
||||||
|
for _, vehicle in pairs(vehicles) do
|
||||||
|
if DoesEntityExist(vehicle) then
|
||||||
|
local vehicleProps = QBCore.Functions.GetVehicleProperties(vehicle)
|
||||||
|
if vehicleProps.plate == plate and isBoat(vehicle) then
|
||||||
|
-- Setze Boot an gespeicherte Position
|
||||||
|
SetEntityCoords(vehicle, anchorData.coords.x, anchorData.coords.y, anchorData.coords.z)
|
||||||
|
SetEntityHeading(vehicle, anchorData.heading)
|
||||||
|
FreezeEntityPosition(vehicle, true)
|
||||||
|
SetEntityInvincible(vehicle, true)
|
||||||
|
|
||||||
|
local vehicleNetId = NetworkGetNetworkIdFromEntity(vehicle)
|
||||||
|
anchoredBoats[vehicleNetId] = anchorData
|
||||||
|
|
||||||
|
print("^2[Anker]^7 Boot mit Kennzeichen " .. plate .. " wurde verankert geladen.")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Speichere Anker auf Server
|
||||||
|
local function saveAnchorToServer(vehicle, anchorData)
|
||||||
|
local vehicleProps = QBCore.Functions.GetVehicleProperties(vehicle)
|
||||||
|
if vehicleProps.plate then
|
||||||
|
TriggerServerEvent('nordi_seats:server:saveAnchor', vehicleProps.plate, anchorData)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Entferne Anker vom Server
|
||||||
|
local function removeAnchorFromServer(vehicle)
|
||||||
|
local vehicleProps = QBCore.Functions.GetVehicleProperties(vehicle)
|
||||||
|
if vehicleProps.plate then
|
||||||
|
TriggerServerEvent('nordi_seats:server:removeAnchor', vehicleProps.plate)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Anker setzen/entfernen
|
-- Anker setzen/entfernen
|
||||||
local function toggleAnchor(vehicle)
|
local function toggleAnchor(vehicle)
|
||||||
if not isBoat(vehicle) then
|
if not isBoat(vehicle) then
|
||||||
|
@ -65,6 +111,9 @@ local function toggleAnchor(vehicle)
|
||||||
SetEntityInvincible(vehicle, false)
|
SetEntityInvincible(vehicle, false)
|
||||||
anchoredBoats[vehicleNetId] = nil
|
anchoredBoats[vehicleNetId] = nil
|
||||||
|
|
||||||
|
-- Entferne vom Server
|
||||||
|
removeAnchorFromServer(vehicle)
|
||||||
|
|
||||||
QBCore.Functions.Notify('⚓ Anker gelichtet! Das Boot kann wieder bewegt werden.', 'success')
|
QBCore.Functions.Notify('⚓ Anker gelichtet! Das Boot kann wieder bewegt werden.', 'success')
|
||||||
|
|
||||||
-- Effekt: Kurzes Wackeln beim Anker lichten
|
-- Effekt: Kurzes Wackeln beim Anker lichten
|
||||||
|
@ -85,17 +134,22 @@ local function toggleAnchor(vehicle)
|
||||||
FreezeEntityPosition(vehicle, true)
|
FreezeEntityPosition(vehicle, true)
|
||||||
SetEntityInvincible(vehicle, true)
|
SetEntityInvincible(vehicle, true)
|
||||||
|
|
||||||
anchoredBoats[vehicleNetId] = {
|
local anchorData = {
|
||||||
coords = coords,
|
coords = coords,
|
||||||
heading = heading,
|
heading = heading,
|
||||||
time = GetGameTimer()
|
time = GetGameTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
anchoredBoats[vehicleNetId] = anchorData
|
||||||
|
|
||||||
|
-- Speichere auf Server
|
||||||
|
saveAnchorToServer(vehicle, anchorData)
|
||||||
|
|
||||||
QBCore.Functions.Notify('⚓ Anker geworfen! Das Boot ist jetzt verankert.', 'success')
|
QBCore.Functions.Notify('⚓ Anker geworfen! Das Boot ist jetzt verankert.', 'success')
|
||||||
|
|
||||||
-- Anker-Wurf Effekt
|
-- Anker-Wurf Effekt
|
||||||
CreateThread(function()
|
CreateThread(function()
|
||||||
-- Spiele Anker-Sound (falls vorhanden)
|
-- Spiele Anker-Sound
|
||||||
PlaySoundFromEntity(-1, "CHECKPOINT_PERFECT", vehicle, "HUD_MINI_GAME_SOUNDSET", 0, 0)
|
PlaySoundFromEntity(-1, "CHECKPOINT_PERFECT", vehicle, "HUD_MINI_GAME_SOUNDSET", 0, 0)
|
||||||
|
|
||||||
-- Kleine Wellen-Animation
|
-- Kleine Wellen-Animation
|
||||||
|
@ -103,7 +157,6 @@ local function toggleAnchor(vehicle)
|
||||||
local coords = GetEntityCoords(vehicle)
|
local coords = GetEntityCoords(vehicle)
|
||||||
local waterHeight = GetWaterHeight(coords.x, coords.y, coords.z)
|
local waterHeight = GetWaterHeight(coords.x, coords.y, coords.z)
|
||||||
if waterHeight then
|
if waterHeight then
|
||||||
-- Erstelle Wasser-Effekt um das Boot
|
|
||||||
local effect = "ent_sht_water"
|
local effect = "ent_sht_water"
|
||||||
RequestNamedPtfxAsset(effect)
|
RequestNamedPtfxAsset(effect)
|
||||||
while not HasNamedPtfxAssetLoaded(effect) do
|
while not HasNamedPtfxAssetLoaded(effect) do
|
||||||
|
@ -129,6 +182,51 @@ local function isBoatAnchored(vehicle)
|
||||||
return anchoredBoats[vehicleNetId] ~= nil
|
return anchoredBoats[vehicleNetId] ~= nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Überwache gespawnte Fahrzeuge für Anker-Wiederherstellung
|
||||||
|
CreateThread(function()
|
||||||
|
local checkedVehicles = {}
|
||||||
|
|
||||||
|
while true do
|
||||||
|
local vehicles = GetGamePool('CVehicle')
|
||||||
|
|
||||||
|
for _, vehicle in pairs(vehicles) do
|
||||||
|
if DoesEntityExist(vehicle) and not checkedVehicles[vehicle] then
|
||||||
|
checkedVehicles[vehicle] = true
|
||||||
|
|
||||||
|
if isBoat(vehicle) then
|
||||||
|
-- Prüfe ob dieses Boot einen gespeicherten Anker hat
|
||||||
|
local vehicleProps = QBCore.Functions.GetVehicleProperties(vehicle)
|
||||||
|
if vehicleProps.plate then
|
||||||
|
QBCore.Functions.TriggerCallback('nordi_seats:server:getAnchorByPlate', function(anchorData)
|
||||||
|
if anchorData then
|
||||||
|
-- Setze Boot an gespeicherte Position
|
||||||
|
SetEntityCoords(vehicle, anchorData.coords.x, anchorData.coords.y, anchorData.coords.z)
|
||||||
|
SetEntityHeading(vehicle, anchorData.heading)
|
||||||
|
FreezeEntityPosition(vehicle, true)
|
||||||
|
SetEntityInvincible(vehicle, true)
|
||||||
|
|
||||||
|
local vehicleNetId = NetworkGetNetworkIdFromEntity(vehicle)
|
||||||
|
anchoredBoats[vehicleNetId] = anchorData
|
||||||
|
|
||||||
|
print("^2[Anker]^7 Boot " .. vehicleProps.plate .. " automatisch verankert.")
|
||||||
|
end
|
||||||
|
end, vehicleProps.plate)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Cleanup nicht mehr existierende Fahrzeuge
|
||||||
|
for vehicle, _ in pairs(checkedVehicles) do
|
||||||
|
if not DoesEntityExist(vehicle) then
|
||||||
|
checkedVehicles[vehicle] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Wait(5000) -- Prüfe alle 5 Sekunden
|
||||||
|
end
|
||||||
|
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 = {}
|
||||||
|
@ -553,10 +651,16 @@ RegisterNetEvent('vehicle:openSeatMenu', function(data)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
-- Lade Anker beim Start
|
||||||
|
CreateThread(function()
|
||||||
|
Wait(2000) -- Warte bis QBCore geladen ist
|
||||||
|
loadAnchoredBoats()
|
||||||
|
end)
|
||||||
|
|
||||||
-- Cleanup verankerte Boote bei Resource Stop
|
-- 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
|
-- Alle verankerten Boote wieder freigeben (aber nicht vom Server löschen)
|
||||||
for vehicleNetId, _ in pairs(anchoredBoats) do
|
for vehicleNetId, _ in pairs(anchoredBoats) do
|
||||||
local vehicle = NetworkGetEntityFromNetworkId(vehicleNetId)
|
local vehicle = NetworkGetEntityFromNetworkId(vehicleNetId)
|
||||||
if DoesEntityExist(vehicle) then
|
if DoesEntityExist(vehicle) then
|
||||||
|
@ -606,5 +710,5 @@ RegisterCommand('anchor', function()
|
||||||
end, false)
|
end, false)
|
||||||
|
|
||||||
-- Keybinds registrieren
|
-- Keybinds registrieren
|
||||||
RegisterKeyMapping('seats', 'Sitzplatz Menü öffnen', 'keyboard', 'F6')
|
RegisterKeyMapping('seats', 'Sitzplatz Menü öffnen', 'keyboard', 'F1')
|
||||||
RegisterKeyMapping('anchor', 'Anker werfen/lichten', 'keyboard', 'H')
|
RegisterKeyMapping('anchor', 'Anker werfen/lichten', 'keyboard', 'H')
|
||||||
|
|
74
resources/[carscripts]/nordi_seats/server/main.lua
Normal file
74
resources/[carscripts]/nordi_seats/server/main.lua
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
local QBCore = exports['qb-core']:GetCoreObject()
|
||||||
|
local anchoredBoats = {} -- Gespeicherte Anker {plate = anchorData}
|
||||||
|
|
||||||
|
-- Lade Anker aus Datenbank
|
||||||
|
local function loadAnchorsFromDB()
|
||||||
|
local result = MySQL.query.await('SELECT * FROM anchored_boats')
|
||||||
|
if result then
|
||||||
|
for _, row in pairs(result) do
|
||||||
|
anchoredBoats[row.plate] = {
|
||||||
|
coords = json.decode(row.coords),
|
||||||
|
heading = row.heading,
|
||||||
|
time = row.timestamp
|
||||||
|
}
|
||||||
|
end
|
||||||
|
print("^2[Anker]^7 " .. #result .. " verankerte Boote aus der Datenbank geladen.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Speichere Anker in Datenbank
|
||||||
|
local function saveAnchorToDB(plate, anchorData)
|
||||||
|
MySQL.insert('INSERT INTO anchored_boats (plate, coords, heading, timestamp) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE coords = VALUES(coords), heading = VALUES(heading), timestamp = VALUES(timestamp)', {
|
||||||
|
plate,
|
||||||
|
json.encode(anchorData.coords),
|
||||||
|
anchorData.heading,
|
||||||
|
anchorData.time or os.time()
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Entferne Anker aus Datenbank
|
||||||
|
local function removeAnchorFromDB(plate)
|
||||||
|
MySQL.execute('DELETE FROM anchored_boats WHERE plate = ?', {plate})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Events
|
||||||
|
RegisterNetEvent('nordi_seats:server:saveAnchor', function(plate, anchorData)
|
||||||
|
local src = source
|
||||||
|
if not plate or not anchorData then return end
|
||||||
|
|
||||||
|
anchoredBoats[plate] = anchorData
|
||||||
|
saveAnchorToDB(plate, anchorData)
|
||||||
|
|
||||||
|
print("^2[Anker]^7 Boot " .. plate .. " wurde verankert (Spieler: " .. src .. ")")
|
||||||
|
end)
|
||||||
|
|
||||||
|
RegisterNetEvent('nordi_seats:server:removeAnchor', function(plate)
|
||||||
|
local src = source
|
||||||
|
if not plate then return end
|
||||||
|
|
||||||
|
anchoredBoats[plate] = nil
|
||||||
|
removeAnchorFromDB(plate)
|
||||||
|
|
||||||
|
print("^2[Anker]^7 Boot " .. plate .. " Anker wurde gelichtet (Spieler: " .. src .. ")")
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Callbacks
|
||||||
|
QBCore.Functions.CreateCallback('nordi_seats:server:getAnchoredBoats', function(source, cb)
|
||||||
|
cb(anchoredBoats)
|
||||||
|
end)
|
||||||
|
|
||||||
|
QBCore.Functions.CreateCallback('nordi_seats:server:getAnchorByPlate', function(source, cb, plate)
|
||||||
|
cb(anchoredBoats[plate])
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Lade Anker beim Start
|
||||||
|
CreateThread(function()
|
||||||
|
loadAnchorsFromDB()
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Cleanup bei Resource Stop
|
||||||
|
AddEventHandler('onResourceStop', function(resourceName)
|
||||||
|
if GetCurrentResourceName() == resourceName then
|
||||||
|
print("^3[Anker]^7 Resource gestoppt. Anker bleiben in der Datenbank gespeichert.")
|
||||||
|
end
|
||||||
|
end)
|
Loading…
Add table
Add a link
Reference in a new issue