-- ===================================================================== -- aether-medical — Clientlogik -- -- Öffnet die Kliniksoftware und vermittelt zwischen Oberfläche und -- Server. Der Client führt nichts Medizinisches aus — er zeigt an, -- meldet Tatsachen (Fahrzeugtelemetrie) und setzt Wegpunkte. -- ===================================================================== local istOffen = false local istGeladen = false local imDienst = false local function SendeAnNui(nachricht) SendNuiMessage(json.encode(nachricht)) end local function ZeigeSpielmeldung(text) if not text or text == '' then return end BeginTextCommandThefeedPost('STRING') AddTextComponentSubstringPlayerName(text) EndTextCommandThefeedPostTicker(false, true) end local function Schliessen() if not istOffen then return end istOffen = false SetNuiFocus(false, false) SendeAnNui({ aktion = 'schliessen' }) pcall(function() exports['aether-hud']:SetzeSichtbar(true) end) end -- --------------------------------------------------------------------- -- Ereignisse vom Server -- --------------------------------------------------------------------- AddEventHandler('aether:client:bereit', function() istGeladen = true end) --- Oberfläche mit vollem Zustand anzeigen RegisterNetEvent('aether:medical:zeige', function(daten) istOffen = true imDienst = true SetNuiFocus(true, true) pcall(function() exports['aether-hud']:SetzeSichtbar(false) end) daten.aktion = 'oeffnen' SendeAnNui(daten) end) --- Anmeldebildschirm (noch nicht im Dienst) RegisterNetEvent('aether:medical:anmeldung', function(daten) istOffen = true SetNuiFocus(true, true) pcall(function() exports['aether-hud']:SetzeSichtbar(false) end) daten.aktion = 'anmeldung' SendeAnNui(daten) end) RegisterNetEvent('aether:medical:schliessen', function() imDienst = false Schliessen() ZeigeSpielmeldung('Dienst beendet.') end) --- Antwort auf einen Modul-Aufruf RegisterNetEvent('aether:medical:antwort', function(ruf, ergebnis, fehler) SendeAnNui({ aktion = 'antwort', ruf = ruf, ergebnis = ergebnis, fehler = fehler }) end) --- Dienstliste (wer ist im Dienst, für Dashboard und Leitstelle) RegisterNetEvent('aether:medical:dienstliste', function(liste) if istOffen then SendeAnNui({ aktion = 'dienstliste', mitarbeiter = liste }) end end) --- Hinweis / Erinnerung RegisterNetEvent('aether:medical:hinweis', function(hinweis) if istOffen then SendeAnNui({ aktion = 'hinweis', hinweis = hinweis }) else -- Auch ausserhalb der Oberfläche erreichbar, damit Fristen nicht untergehen local praefix = hinweis.prioritaet == 'kritisch' and '~r~' or hinweis.prioritaet == 'hoch' and '~o~' or '~b~' ZeigeSpielmeldung(praefix .. hinweis.titel .. '~s~' .. (hinweis.text and ('\n' .. hinweis.text) or '')) end end) RegisterNetEvent('aether:medical:fehler', function(text) if istOffen then SendeAnNui({ aktion = 'fehler', text = text }) else ZeigeSpielmeldung(text) end end) --- Es hat sich etwas an den Einsätzen geändert RegisterNetEvent('aether:medical:einsatzAenderung', function() if istOffen then SendeAnNui({ aktion = 'einsatzAenderung' }) end end) --- Die Leitstelle bittet um Übernahme eines Einsatzes RegisterNetEvent('aether:medical:einsatzZuweisung', function(daten) PlaySoundFrontend(-1, 'Event_Start_Text', 'GTAO_FM_Events_Soundset', true) if daten.position then SetNewWaypoint(daten.position.x, daten.position.y) end if istOffen then SendeAnNui({ aktion = 'einsatzZuweisung', daten = daten }) else ZeigeSpielmeldung(('~b~Zuweisung von %s~s~\n%s — %s') :format(daten.von, daten.nummer, daten.titel)) end end) -- --------------------------------------------------------------------- -- Fahrzeug-Telemetrie -- -- Meldet Tatsachen über das gefahrene Rettungsfahrzeug: Position, -- Tankstand, Zustand. Der Server verwirft die Meldung, wenn das -- Kennzeichen nicht zum Fuhrpark gehört. -- --------------------------------------------------------------------- CreateThread(function() while true do Wait(30000) -- alle 30 Sekunden genügt if imDienst then local ped = PlayerPedId() if IsPedInAnyVehicle(ped, false) then local fahrzeug = GetVehiclePedIsIn(ped, false) -- Nur melden, wenn man selbst am Steuer sitzt if GetPedInVehicleSeat(fahrzeug, -1) == ped then local position = GetEntityCoords(fahrzeug) TriggerServerEvent('aether:medical:fahrzeugMelden', { kennzeichen = GetVehicleNumberPlateText(fahrzeug), tank = GetVehicleFuelLevel(fahrzeug), zustand = GetVehicleBodyHealth(fahrzeug), x = position.x, y = position.y, z = position.z, }) end end end end end) -- --------------------------------------------------------------------- -- Terminals in der Klinik -- --------------------------------------------------------------------- CreateThread(function() for _, terminal in ipairs(Medizin.Config.Terminals) do local blip = AddBlipForCoord(terminal.pos.x, terminal.pos.y, terminal.pos.z) SetBlipSprite(blip, 61) SetBlipColour(blip, 2) SetBlipScale(blip, 0.8) SetBlipAsShortRange(blip, true) BeginTextCommandSetBlipName('STRING') AddTextComponentString('Klinik ' .. terminal.name) EndTextCommandSetBlipName(blip) end while true do local pause = 800 if istGeladen and not istOffen then local position = GetEntityCoords(PlayerPedId()) for _, terminal in ipairs(Medizin.Config.Terminals) do if #(position - terminal.pos) <= Medizin.Config.TerminalWeite then pause = 0 SetTextFont(4) SetTextScale(0.34, 0.34) SetTextColour(255, 255, 255, 215) SetTextCentre(true) SetTextOutline() SetTextEntry('STRING') AddTextComponentString('[E] Klinik-PC ' .. terminal.name) SetDrawOrigin(terminal.pos.x, terminal.pos.y, terminal.pos.z + 0.9, 0) DrawText(0.0, 0.0) ClearDrawOrigin() if IsControlJustReleased(0, 38) then TriggerServerEvent('aether:medical:oeffnen') end break end end end Wait(pause) end end) --- Tablet jederzeit öffnen, sobald man im Dienst ist RegisterCommand('kis', function() if istGeladen and not istOffen then TriggerServerEvent('aether:medical:oeffnen') end end, false) RegisterKeyMapping('kis', 'Klinik-Tablet öffnen', 'keyboard', 'F6') -- --------------------------------------------------------------------- -- NUI-Callbacks -- --------------------------------------------------------------------- RegisterNUICallback('schliessen', function(_, rueckgabe) Schliessen() rueckgabe({ ok = true }) end) --- Zentraler Modul-Aufruf: die Oberfläche fragt, der Server antwortet RegisterNUICallback('aufruf', function(daten, rueckgabe) TriggerServerEvent('aether:medical:aufruf', tostring(daten.modul or ''), tostring(daten.aktion or ''), daten.daten or {}, daten.ruf) rueckgabe({ ok = true }) end) RegisterNUICallback('dienstAntreten', function(daten, rueckgabe) TriggerServerEvent('aether:medical:dienstAntreten', tostring(daten.funktion or 'station')) rueckgabe({ ok = true }) end) RegisterNUICallback('dienstBeenden', function(_, rueckgabe) TriggerServerEvent('aether:medical:dienstBeenden') rueckgabe({ ok = true }) end) RegisterNUICallback('status', function(daten, rueckgabe) TriggerServerEvent('aether:medical:status', tostring(daten.status or '')) rueckgabe({ ok = true }) end) RegisterNUICallback('funktion', function(daten, rueckgabe) TriggerServerEvent('aether:medical:funktion', tostring(daten.funktion or '')) rueckgabe({ ok = true }) end) RegisterNUICallback('leitstelle', function(daten, rueckgabe) TriggerServerEvent('aether:medical:leitstelle', tonumber(daten.quelle)) rueckgabe({ ok = true }) end) --- Wegpunkt auf der Karte setzen (z. B. zu einem Einsatzort) RegisterNUICallback('wegpunkt', function(daten, rueckgabe) if daten.x and daten.y then SetNewWaypoint(daten.x + 0.0, daten.y + 0.0) ZeigeSpielmeldung('Wegpunkt gesetzt.') end rueckgabe({ ok = true }) end) -- --------------------------------------------------------------------- -- Aufräumen -- --------------------------------------------------------------------- AddEventHandler('onResourceStop', function(ressource) if ressource ~= GetCurrentResourceName() then return end SetNuiFocus(false, false) end)