-- ===================================================================== -- aether-medical — Dienstsystem -- -- Speichert ausschliesslich Statusinformationen. Es gibt keine -- automatische Dienstkleidung und keine automatische Fahrzeugausgabe. -- Auch die Funktion (RTW, Notarzt, OP, Leitstelle) wählt jeder selbst. -- ===================================================================== Dienst = {} -- Mitarbeiter im Dienst: [quelle] = mitarbeiter local imDienst = {} -- Wer hält die Leitstelle? (Server-ID oder nil) local leitstelle = nil local Core = exports['aether-core'] -- --------------------------------------------------------------------- -- Zugriff -- --------------------------------------------------------------------- --- Liefert die Daten eines Mitarbeiters im Dienst --- @param quelle number Server-ID --- @return table|nil function Dienst.Hole(quelle) return imDienst[quelle] end --- Liefert alle Mitarbeiter im Dienst --- @return table [quelle] = mitarbeiter function Dienst.AlleImDienst() return imDienst end --- Sucht die Server-ID zu einer Charakter-ID --- @param charakterId number Charakter --- @return number|nil function Dienst.QuelleVonCharakter(charakterId) for quelle, mitarbeiter in pairs(imDienst) do if mitarbeiter.charakterId == charakterId then return quelle end end return nil end --- Wer hält die Leitstelle? --- @return number|nil Server-ID function Dienst.Leitstelle() return leitstelle end -- --------------------------------------------------------------------- -- Personalakte laden -- --------------------------------------------------------------------- --- Lädt den Personaldatensatz und baut daraus den Mitarbeiter --- @param quelle number Server-ID --- @param charakterId number Charakter --- @return table|nil Mitarbeiter, string|nil Fehler function Dienst.LadeMitarbeiter(quelle, charakterId) local zeilen = MySQL.query.await( 'SELECT * FROM medical_personal WHERE `character` = ? AND aktiv = 1', { charakterId }) if not zeilen or not zeilen[1] then return nil, 'Du gehörst nicht zum Personal der Klinik.' end local personal = zeilen[1] local person = Core:HoleSpielerInfo(quelle) local rolle = Medizin.HoleRolle(personal.rolle) return { quelle = quelle, charakterId = charakterId, name = ((person and person.vorname or '') .. ' ' .. (person and person.nachname or '')), personalnummer = personal.personalnummer, rolle = personal.rolle, rolleName = rolle and rolle.name or personal.rolle, stufe = Medizin.Stufe(personal.rolle), station = personal.station, rechte = Rechte.Berechne(personal), status = 'verfuegbar', funktion = 'station', seit = os.time(), dienstId = nil, } end -- --------------------------------------------------------------------- -- Dienst antreten und beenden -- --------------------------------------------------------------------- --- Meldet einen Mitarbeiter zum Dienst an --- @param quelle number Server-ID --- @param funktion string|nil Gewählte Dienstfunktion --- @return table|nil Mitarbeiter, string|nil Fehler function Dienst.Antreten(quelle, funktion) if imDienst[quelle] then return imDienst[quelle] end local charakterId = Core:HoleCharakterId(quelle) if not charakterId then return nil, 'Kein Charakter geladen.' end local mitarbeiter, fehler = Dienst.LadeMitarbeiter(quelle, charakterId) if not mitarbeiter then return nil, fehler end if not Rechte.Hat(mitarbeiter, 'dienst.antreten') then return nil, 'Dir fehlt die Berechtigung, den Dienst anzutreten.' end -- Funktion prüfen; manche erfordern ein eigenes Recht local gewaehlt = Dienst.PruefeFunktion(mitarbeiter, funktion) mitarbeiter.funktion = gewaehlt -- Dienstzeit protokollieren mitarbeiter.dienstId = MySQL.insert.await( 'INSERT INTO medical_dienst (`character`, station, funktion) VALUES (?, ?, ?)', { charakterId, mitarbeiter.station, gewaehlt }) imDienst[quelle] = mitarbeiter Protokoll.Schreibe(mitarbeiter, 'dienst', 'Dienst angetreten', nil, { funktion = gewaehlt, station = mitarbeiter.station }) Kern.Loese('dienst.angetreten', quelle, mitarbeiter) Dienst.Verteile() return mitarbeiter end --- Prüft eine gewünschte Dienstfunktion und liefert eine zulässige zurück --- @param mitarbeiter table Mitarbeiter --- @param funktion string|nil Wunsch --- @return string Zulässige Funktion function Dienst.PruefeFunktion(mitarbeiter, funktion) for _, eintrag in ipairs(Medizin.Config.Dienstfunktionen) do if eintrag.id == funktion then if not eintrag.recht or Rechte.Hat(mitarbeiter, eintrag.recht) then return eintrag.id end break end end -- Im Zweifel der einfache Stationsdienst return 'station' end --- Meldet einen Mitarbeiter vom Dienst ab --- @param quelle number Server-ID function Dienst.Beenden(quelle) local mitarbeiter = imDienst[quelle] if not mitarbeiter then return end if mitarbeiter.dienstId then MySQL.update('UPDATE medical_dienst SET ende = NOW(), sekunden = ? WHERE id = ?', { os.time() - mitarbeiter.seit, mitarbeiter.dienstId }) end imDienst[quelle] = nil -- Leitstelle freigeben, wenn der Inhaber geht if leitstelle == quelle then leitstelle = nil end Protokoll.Schreibe(mitarbeiter, 'dienst', 'Dienst beendet') Kern.Loese('dienst.beendet', quelle, mitarbeiter) Dienst.Verteile() end --- Setzt den Status (verfügbar, am Patienten, Pause ...) --- @param quelle number Server-ID --- @param status string Statuskennung --- @return boolean function Dienst.SetzeStatus(quelle, status) local mitarbeiter = imDienst[quelle] if not mitarbeiter then return false end local gueltig = false for _, eintrag in ipairs(Medizin.Config.Dienststatus) do if eintrag.id == status then gueltig = true break end end if not gueltig then return false end mitarbeiter.status = status Kern.Loese('dienst.status', quelle, mitarbeiter, status) Dienst.Verteile() return true end --- Wechselt die Dienstfunktion im laufenden Dienst --- @param quelle number Server-ID --- @param funktion string Gewünschte Funktion --- @return boolean, string|nil function Dienst.SetzeFunktion(quelle, funktion) local mitarbeiter = imDienst[quelle] if not mitarbeiter then return false end local gewaehlt = Dienst.PruefeFunktion(mitarbeiter, funktion) if gewaehlt ~= funktion then return false, 'Dir fehlt die Berechtigung für diese Funktion.' end mitarbeiter.funktion = gewaehlt if mitarbeiter.dienstId then MySQL.update('UPDATE medical_dienst SET funktion = ? WHERE id = ?', { gewaehlt, mitarbeiter.dienstId }) end Protokoll.Schreibe(mitarbeiter, 'dienst', 'Dienstfunktion gewechselt', nil, { funktion = gewaehlt }) Kern.Loese('dienst.funktion', quelle, mitarbeiter, gewaehlt) Dienst.Verteile() return true end --- Übernimmt oder überträgt die Leitstelle --- @param quelle number Handelnder --- @param zielQuelle number|nil Ziel (nil = selbst übernehmen) --- @return boolean, string|nil function Dienst.SetzeLeitstelle(quelle, zielQuelle) local mitarbeiter = imDienst[quelle] if not mitarbeiter then return false end if not Rechte.Hat(mitarbeiter, 'dienst.leitstelle') then return false, 'Dir fehlt die Berechtigung für die Leitstelle.' end if zielQuelle and zielQuelle ~= quelle then -- Zuweisen an andere setzt voraus, dass man über ihnen steht local ziel = imDienst[zielQuelle] if not ziel then return false, 'Diese Person ist nicht im Dienst.' end if not Rechte.StehtUeber(mitarbeiter, ziel.rolle) then return false, 'Du kannst die Leitstelle nur an rangniedrigere Kollegen übertragen.' end leitstelle = zielQuelle Protokoll.Schreibe(mitarbeiter, 'dienst', 'Leitstelle übertragen', { typ = 'person', id = ziel.charakterId }) else leitstelle = quelle Protokoll.Schreibe(mitarbeiter, 'dienst', 'Leitstelle übernommen') end Kern.Loese('dienst.leitstelle', leitstelle) Dienst.Verteile() return true end -- --------------------------------------------------------------------- -- Verteilung an die Clients -- --------------------------------------------------------------------- --- Baut die Liste der Mitarbeiter im Dienst --- @return table function Dienst.BaueListe() local liste = {} for quelle, mitarbeiter in pairs(imDienst) do local position = GetEntityCoords(GetPlayerPed(quelle)) liste[#liste + 1] = { quelle = quelle, charakterId = mitarbeiter.charakterId, name = mitarbeiter.name, personalnummer = mitarbeiter.personalnummer, rolle = mitarbeiter.rolle, rolleName = mitarbeiter.rolleName, station = mitarbeiter.station, funktion = mitarbeiter.funktion, status = mitarbeiter.status, leitstelle = leitstelle == quelle, seit = mitarbeiter.seit, position = { x = position.x, y = position.y, z = position.z }, } end table.sort(liste, function(a, b) return a.personalnummer < b.personalnummer end) return liste end --- Schickt die Dienstliste an alle im Dienst function Dienst.Verteile() local liste = Dienst.BaueListe() for quelle in pairs(imDienst) do TriggerClientEvent('aether:medical:dienstliste', quelle, liste) end end -- Positionen regelmäßig auffrischen (für die Einsatzkarte) CreateThread(function() while true do Wait(5000) if next(imDienst) then Dienst.Verteile() end end end) -- Beim Verlassen sauber abmelden AddEventHandler('playerDropped', function() Dienst.Beenden(source) end)