Exports

Jeder Export auf Client und Server, was er zurückgibt und wofür man ihn benutzt.

Client

Die Client-Seite fragt und schaut nach. Sie erlaubt nichts: Was OpenStation anstößt, prüft der Server genauso, als wäre jemand hingelaufen.

ExportGibt zurückBeschreibung
OpenStation(id)booleanBittet den Server, diese Station zu öffnen. true heißt nur, dass die Anfrage rausgegangen ist. Ob sie aufging, sagt das Event cs_revivestation:opened. false kommt sofort, wenn die ID unbekannt ist, schon eine Station offen ist, der Spieler tot oder nicht eingeloggt ist, oder die Station interact = false hat.
CloseStation()booleanSchließt, was dieses Script offen hat. false, wenn nichts offen war.
IsStationOpen()booleanOb die Liste auf dem Bildschirm ist. Lohnt sich, bevor du ein eigenes Menü darüber legst.
GetOpenStation()number / nilDie ID der offenen Station.
GetStations()tableAlle Stationen, die dieser Client kennt. Genug, um ein Menü zu bauen oder eigene Marker zu setzen.
GetStation(id)table / nilEine davon.
GetStationId(name)number / nilDie ID der Station, die in der Config name = '…' bekommen hat.
GetNearestStation(maxDistance)number, numberDie nächste Station, zu der der Spieler laufen könnte und wie weit sie weg ist. Ohne Angabe gilt Config.Interact. nil, wenn keine in Reichweite ist.
Client-Stations-Objekt
{
    id = 1, name = 'pillbox',
    label = 'CORECITY', accent = 'Revive',
    position = vector3(299.64, -582.20, 44.26),
    interact = true, radius = 10.0,
    ped = true, blip = true,
}
Beispiel: Station per Taste öffnen
local id = exports.cs_revivestation:GetNearestStation(3.0)
if id then exports.cs_revivestation:OpenStation(id) end

Server: lesen

Diese acht antworten, ohne etwas zu verändern. Sie sind die Grundlage für alles, was einem Spieler etwas anzeigen will, bevor er sich auf den Weg macht: ein Leitstellen- Bildschirm, ein Job-Computer, ein Menü, das sagt, wie viele Leute warten.

ExportGibt zurückBeschreibung
GetStations()tableAlle Stationen mit Rechten, Zustand und Preisfaktor.
GetStation(id)table / nilEine davon.
GetStationId(name)number / nilDie ID zum name aus der Config.
IsStationEnabled(id)boolean / nilOb sie eingeschaltet ist.
GetPriceMultiplier(id)number / nilDer geltende Faktor, 1.0, wenn er nie geändert wurde.
GetRevivePrice(id, target)number, numberWas diese Wiederbelebung an dieser Station jetzt kosten würde: der ganze Preis und die Sanitäter-Gebühr darin. Todesursache, Sanitäter im Dienst und Faktor sind eingerechnet. Das ist die Zahl, die man jemandem nennt, bevor er losläuft.
GetMedicsOnDuty(id)number / nilWie viele Sanitäter diese Station als im Dienst zählt: die Zahl, gegen die maxMedics misst und aus der die Gebühr gebaut wird.
GetDeadPlayers(id)table / nilWer in Reichweite der Station am Boden liegt, dieselbe Liste, die das Interface zeichnet.
IsPlayerDead(source)boolean / nilOb ein Spieler am Boden liegt, so wie dieses Script es beurteilt und damit so, wie die Station selbst es sieht. nil, wenn er nicht eingeloggt ist.
GetPlayerStation(source)number / nilWelche Station ein Spieler offen hat. Praktisch, wenn dein Script wissen muss, dass jemand gerade beschäftigt ist.
Server-Stations-Objekt
{
    id = 1, name = 'pillbox',
    label = 'CORECITY', accent = 'Revive',
    position = vector3(299.64, -582.20, 44.26),
    interact = true,
    runtime  = false,                      -- über CreateStation entstanden?

    jobs       = { ambulance = 2 },        -- nil, wenn ohne Jobbindung
    license    = 'medic',                  -- nil, wenn keine verlangt wird
    maxMedics  = 2,
    medicJobs  = { 'ambulance', 'police' },
    onDutyOnly = true,
    radius     = 10.0,

    price   = { base = 50, perMedic = 500, account = 'cash' },
    enabled = true,                        -- SetStationEnabled
    prices  = 1.0,                         -- SetPriceMultiplier
}

price ist der Block aus der Config, ohne Sanitäter-Gebühr und ohne Faktor. Was wirklich zu zahlen wäre, sagt GetRevivePrice.

Wer am Boden liegt (GetDeadPlayers)
{
    { source = 12, name = 'John Doe',  cause = 'Fire',   price = 1600 },
    { source = 31, name = 'Jane Roe',  cause = 'Pistol', price = 1150 },
}
Beispiel: Leitstellen-Anzeige
local station = exports.cs_revivestation:GetStationId('pillbox')
local warten  = exports.cs_revivestation:GetDeadPlayers(station)
local medics  = exports.cs_revivestation:GetMedicsOnDuty(station)

print(('%d Patient(en) an der Station, %d Sanitäter im Dienst'):format(#warten, medics))

Server: Stationen verändern

Hier hört das Nachschlagen auf. Diese fünf ändern etwas, das alle Clients sofort mitbekommen und jede davon schickt dabei die Leute hinaus, die gerade in die betroffene Station schauen.

ExportGibt zurückBeschreibung
CreateStation(station)number / nilEine Station, die nur existiert, solange der Server läuft. Nimmt denselben Block wie ein Eintrag in Config.Stations und erscheint sofort auf allen Clients. nil, wenn der Block keine Station werden kann: er braucht eine Position.
RemoveStation(id)booleanNimmt eine Station wieder weg, auf allen Clients, auch eine aus der Config. Wer sie offen hat, wird hinausgeschickt. Die ID wird nicht neu vergeben.
SetStationEnabled(id, bool)booleanSchaltet eine Station aus, ohne sie zu entfernen: Marker, Blip und Doktor bleiben stehen, wer öffnen will, hört, dass sie außer Betrieb ist. Alle, die sie offen haben, werden hinausgeschickt.
SetPriceMultiplier(id, factor)booleanWas jeder Preis an dieser Station wert ist, die Sanitäter-Gebühr eingeschlossen. 0.8 sind zwanzig Prozent Rabatt, 1.5 eine schlimme Nacht, 0 ist gratis. Einmal auf ganze Beträge gerundet, damit Interface, Meldung und Discord-Log dieselbe Zahl nennen.
RevivePlayer(target)booleanEine Wiederbelebung ohne Station und ohne Gebühr, auf demselben Weg, den Config.Revive nimmt. Für ein Admin-Menü, ein Defibrillator-Item, ein Job-Script. false, wenn der Spieler nicht auf dem Server ist, nicht am Boden liegt oder die Wiederbelebung selbst fehlschlug.
Beispiel: Feldlazarett für einen Einsatz
local id = exports.cs_revivestation:CreateStation({
    name     = 'fieldhospital',
    position = vector3(1234.0, -567.0, 63.0),
    label    = 'FIELD',
    accent   = 'Hospital',
    ped      = { model = 's_m_m_doctor_01', position = vector4(1234.0, -566.0, 62.0, 90.0) },
    access   = { jobs = { ambulance = 0 }, radius = 25.0 },
    price    = { base = 0 },
})

SetTimeout(3600000, function()   -- eine Stunde später wieder weg
    exports.cs_revivestation:RemoveStation(id)
end)
Beispiel: Stromausfall im Krankenhaus
local station = exports.cs_revivestation:GetStationId('pillbox')

exports.cs_revivestation:SetStationEnabled(station, false)

SetTimeout(300000, function()   -- fünf Minuten dunkel
    exports.cs_revivestation:SetStationEnabled(station, true)
end)
Beispiel: Nachtschicht ist teurer
-- 1.5 statt 1.0, solange niemand da ist
exports.cs_revivestation:SetPriceMultiplier(station, 1.5)
exports.cs_revivestation:SetPriceMultiplier(station, 1.0)   -- zurück auf normal

Server: Spieler

Der Weg in eine Station, die kein Ort ist. OpenStation ist der einzige Zugang zu einer Station mit interact = false und damit die Grundlage für Sanitäter-Tablets, Handy-Apps und Job-Terminals.

ExportGibt zurückBeschreibung
OpenStation(source, id)boolean, string, stringÖffnet einem Spieler eine Station, wo er auch steht. Job, Lizenz, das Sanitäter-Limit und dein canOpen-Hook werden vorher geprüft.
CloseStation(source)booleanSchließt, was dieser Spieler offen hat. false, wenn er nichts offen hatte.
CanPlayerUse(source, id)boolean, string, stringOb ein Spieler jetzt hineinkäme, ohne die Station zu öffnen. Für das Ausgrauen eines Eintrags in deinem Menü.

OpenStation und CanPlayerUse geben bei einer Absage einen Grund zurück und als drittes das, was dieser Grund braucht: den Namen der Lizenz, die Zahl der Sanitäter, oder den Satz, mit dem dein Hook abgelehnt hat.

GrundDrittesBedeutung
'unknown'Diese ID oder dieser Spieler existiert nicht.
'error'Der Spieler ist nicht eingeloggt oder das Framework antwortet nicht.
'unavailable'Die Station ist über SetStationEnabled aus.
'wrong_job'Falscher Job oder zu niedriger Grade.
'no_license'Name der LizenzDie verlangte Lizenz fehlt.
'too_many_medics'Zahl der SanitäterZu viele Sanitäter im Dienst, die Station bleibt zu.
'custom'sein SatzEin Hook von dir hat abgelehnt.
Beispiel: Sanitäter-Tablet
RegisterNetEvent('medictablet:open', function()
    local src     = source
    local station = exports.cs_revivestation:GetStationId('tablet')

    local ok, reason, extra = exports.cs_revivestation:OpenStation(src, station)
    if ok then return end

    if reason == 'too_many_medics' then
        return notify(src, ('Es sind %s Kollegen im Dienst.'):format(extra))
    end

    notify(src, extra or 'Das geht gerade nicht.')
end)
Beispiel: Menüeintrag ausgrauen
for _, station in ipairs(exports.cs_revivestation:GetStations()) do
    if station.interact == false then
        local allowed = exports.cs_revivestation:CanPlayerUse(src, station.id)
        addEntry(station.label, allowed)
    end
end

Eine Station, die der Server geöffnet hat, hat kein Terminal, an dem jemand stehen könnte. Die Erlaubnis gilt deshalb, bis das Interface wieder zugeht und der Spieler darf sich in der Zeit bewegen. Die Liste wird trotzdem um die Station herum gebaut: Ein Tablet zeigt, wer bei der Station liegt, nicht wer neben dem Tablet steht. Alles andere wird vor der Wiederbelebung erneut geprüft.

CreateStation liest den Block einmal. Änderst du deine Tabelle danach, ändert das nichts mehr. Und eine ID, die RemoveStation freigemacht hat, wird nicht neu vergeben: Was sie noch in der Hand hält, kann damit nie auf eine andere Station zeigen.

Frage offen geblieben?

Schreib uns im Discord. Mit Konsolen-Auszug, Framework und Script-Version ist die erste Antwort meistens schon die Lösung.

Zum Support