-- ===================================================================== -- Aether Core — Clientlogik -- Meldet sich beim Server an, spawnt den Charakter und haelt die Daten aktuell. -- ===================================================================== Aether = Aether or {} -- Daten des eigenen Charakters (vom Server befuellt) Aether.SpielerDaten = nil -- Ist der Spieler fertig geladen und im Spiel? Aether.IstGeladen = false -- --------------------------------------------------------------------- -- Startvorgang -- --------------------------------------------------------------------- CreateThread(function() -- Warten, bis die Spielwelt bereit ist while not NetworkIsSessionStarted() do Wait(100) end -- Standard-Spawnverhalten von FiveM unterbinden. -- Abgesichert, falls spawnmanager nicht laeuft (dann uebernimmt der Core allein). local erfolg = pcall(function() exports.spawnmanager:setAutoSpawn(false) end) if not erfolg then Aether.Debug('spawnmanager nicht verfuegbar — Core spawnt eigenstaendig.') end -- Bildschirm schwarz halten, bis der Charakter geladen ist DoScreenFadeOut(0) SetEntityVisible(PlayerPedId(), false, false) Aether.Debug('Client bereit — fordere Spielerdaten an.') TriggerServerEvent('aether:server:spielerBereit') end) -- --------------------------------------------------------------------- -- Spieler wurde geladen: Ped setzen und spawnen -- --------------------------------------------------------------------- RegisterNetEvent('aether:client:spielerGeladen', function(daten) Aether.SpielerDaten = daten -- Passendes Standardmodell laden (bis der Charakter-Ersteller migriert ist) local modellName = Config.StandardPed[daten.geschlecht] or Config.StandardPed.m local modell = GetHashKey(modellName) RequestModel(modell) local versuche = 0 while not HasModelLoaded(modell) and versuche < 100 do Wait(50) versuche = versuche + 1 end if HasModelLoaded(modell) then SetPlayerModel(PlayerId(), modell) SetModelAsNoLongerNeeded(modell) else Aether.Fehler('Ped-Modell konnte nicht geladen werden: ' .. modellName) end -- Spieler an die gespeicherte Position setzen local ped = PlayerPedId() local pos = daten.position or Config.SpawnPunkt SetEntityCoordsNoOffset(ped, pos.x + 0.0, pos.y + 0.0, pos.z + 0.0, false, false, false) SetEntityHeading(ped, pos.heading or 0.0) -- Zustand wiederherstellen SetEntityHealth(ped, daten.leben or 200) FreezeEntityPosition(ped, false) SetEntityVisible(ped, true, false) -- Warten, bis die Umgebung geladen ist, dann Bild freigeben local wartezeit = 0 while not HasCollisionLoadedAroundEntity(ped) and wartezeit < 100 do Wait(50) wartezeit = wartezeit + 1 end ShutdownLoadingScreen() ShutdownLoadingScreenNui() DoScreenFadeIn(1000) Aether.IstGeladen = true Aether.Info(('Willkommen, %s %s!'):format(daten.vorname, daten.nachname)) -- Andere Ressourcen (HUD, Handy, Inventar) informieren. -- WICHTIG: anderer Name als das Netz-Event, sonst ruft sich dieser -- Handler endlos selbst auf. TriggerEvent('aether:client:bereit', daten) end) -- --------------------------------------------------------------------- -- Aktualisierungen vom Server -- --------------------------------------------------------------------- RegisterNetEvent('aether:client:geldAktualisiert', function(geld) if not Aether.SpielerDaten then return end Aether.SpielerDaten.bargeld = geld.bargeld Aether.SpielerDaten.konto = geld.konto Aether.SpielerDaten.schwarzgeld = geld.schwarzgeld -- Weiterreichen ans HUD TriggerEvent('aether:client:geldGeaendert', geld) end) RegisterNetEvent('aether:client:zustandAktualisiert', function(zustand) if not Aether.SpielerDaten then return end Aether.SpielerDaten.hunger = zustand.hunger Aether.SpielerDaten.durst = zustand.durst Aether.SpielerDaten.ausdauer = zustand.ausdauer -- Weiterreichen ans HUD TriggerEvent('aether:client:zustandGeaendert', zustand) end) --- Schaden durch Hunger/Durst zufuegen RegisterNetEvent('aether:client:erleideSchaden', function(menge) local ped = PlayerPedId() local leben = GetEntityHealth(ped) SetEntityHealth(ped, math.max(0, leben - (menge or 5))) end) -- --------------------------------------------------------------------- -- Position regelmaessig an den Server melden (fuer das Speichern) -- --------------------------------------------------------------------- CreateThread(function() while true do Wait(10000) -- alle 10 Sekunden if Aether.IstGeladen then local ped = PlayerPedId() local koordinaten = GetEntityCoords(ped) TriggerServerEvent('aether:server:aktualisierePosition', { x = Aether.Runde(koordinaten.x, 2), y = Aether.Runde(koordinaten.y, 2), z = Aether.Runde(koordinaten.z, 2), heading = Aether.Runde(GetEntityHeading(ped), 2), }) -- Lebenswert mitschicken, damit er beim Speichern stimmt TriggerServerEvent('aether:server:aktualisiereZustand', { leben = GetEntityHealth(ped), }) end end end) -- --------------------------------------------------------------------- -- Kein Charakter vorhanden (spaeter uebernimmt das aether-character) -- --------------------------------------------------------------------- RegisterNetEvent('aether:client:keinCharakter', function() Aether.Fehler('Kein Charakter vorhanden — Charaktererstellung ist noch nicht migriert.') end) -- ===================================================================== -- EXPORTS fuer andere Module -- Beispiel: local daten = exports['aether-core']:HoleSpielerDaten() -- ===================================================================== --- Liefert die Daten des eigenen Charakters exports('HoleSpielerDaten', function() return Aether.SpielerDaten end) --- Ist der Spieler fertig geladen? exports('IstGeladen', function() return Aether.IstGeladen end)