- aether-medical: Stationen/Belegung, Intensivstation, Blutbank, Fuhrpark, Nachrichten/Aushänge, Berichte und Textbausteine (server + NUI) - aether-admin: vollständiges Server-Admin-Panel als echtes FiveM-Resource, an aether-core gekoppelt (Rechte über aether_users.admin_group), mit WebRTC-Live-Kameras (Bildschirmfreigabe) und separatem Media-Server (SFU) - Prototypen admin/ vervollständigt - SQL-Schema aether_admin.sql - Docker-Compose mit MariaDB und idempotenter Auto-Migration (schema_migrations) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
152 lines
5.0 KiB
Lua
152 lines
5.0 KiB
Lua
-- =====================================================================
|
|
-- Aether Inventory — Clientlogik
|
|
-- Oeffnet die Oberflaeche und reicht Wuensche an den Server weiter.
|
|
-- Es wird bewusst nichts lokal entschieden.
|
|
-- =====================================================================
|
|
|
|
-- Ist das Inventar gerade offen?
|
|
local istOffen = false
|
|
-- Ist der Spieler im Spiel?
|
|
local istGeladen = false
|
|
|
|
-- Taste zum Oeffnen (I)
|
|
local TASTE_INVENTAR = 311
|
|
|
|
--- Schickt eine Nachricht an die Oberflaeche
|
|
--- @param nachricht table Daten
|
|
local function SendeAnNui(nachricht)
|
|
SendNuiMessage(json.encode(nachricht))
|
|
end
|
|
|
|
--- Schliesst das Inventar und gibt die Steuerung zurueck
|
|
local function Schliessen()
|
|
if not istOffen then return end
|
|
istOffen = false
|
|
SetNuiFocus(false, false)
|
|
SendeAnNui({ aktion = 'schliessen' })
|
|
|
|
-- HUD wieder einblenden, falls vorhanden
|
|
pcall(function() exports['aether-hud']:SetzeSichtbar(true) end)
|
|
end
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- Ereignisse vom Core und Server
|
|
-- ---------------------------------------------------------------------
|
|
AddEventHandler('aether:client:bereit', function()
|
|
istGeladen = true
|
|
end)
|
|
|
|
--- Server schickt den Zustand und moechte, dass wir oeffnen
|
|
RegisterNetEvent('aether:inventory:zeige', function(zustand)
|
|
istOffen = true
|
|
SetNuiFocus(true, true)
|
|
|
|
-- HUD ausblenden, solange das Inventar offen ist
|
|
pcall(function() exports['aether-hud']:SetzeSichtbar(false) end)
|
|
|
|
zustand.aktion = 'oeffnen'
|
|
zustand.items = Inventar.Items -- Registry zum Anzeigen mitschicken
|
|
zustand.equipSlots = Inventar.EQUIP_SLOTS
|
|
zustand.bereiche = Inventar.BEREICH
|
|
SendeAnNui(zustand)
|
|
end)
|
|
|
|
--- Zeigt eine Meldung oben links im Spiel (wenn die Oberflaeche zu ist)
|
|
--- @param text string Meldungstext
|
|
local function ZeigeSpielmeldung(text)
|
|
if not text or text == '' then return end
|
|
BeginTextCommandThefeedPost('STRING')
|
|
AddTextComponentSubstringPlayerName(text)
|
|
EndTextCommandThefeedPostTicker(false, true)
|
|
end
|
|
|
|
--- Server schickt einen aktualisierten Zustand (nach jeder Aktion)
|
|
RegisterNetEvent('aether:inventory:zustand', function(zustand)
|
|
if not istOffen then
|
|
-- Inventar zu (z. B. Aufheben per Taste E): kurz im Spiel melden
|
|
ZeigeSpielmeldung(zustand.hinweis)
|
|
return
|
|
end
|
|
zustand.aktion = 'zustand'
|
|
SendeAnNui(zustand)
|
|
end)
|
|
|
|
--- Kurze Rueckmeldung (z. B. Ablehnung einer Aktion)
|
|
RegisterNetEvent('aether:inventory:hinweis', function(text)
|
|
if istOffen then
|
|
SendeAnNui({ aktion = 'hinweis', text = text })
|
|
else
|
|
ZeigeSpielmeldung(text)
|
|
end
|
|
end)
|
|
|
|
--- Heilung durch ein benutztes Item
|
|
RegisterNetEvent('aether:inventory:heilen', function(menge)
|
|
local ped = PlayerPedId()
|
|
local leben = GetEntityHealth(ped)
|
|
SetEntityHealth(ped, math.min(200, leben + (menge or 0)))
|
|
end)
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- Oeffnen per Taste
|
|
-- ---------------------------------------------------------------------
|
|
CreateThread(function()
|
|
while true do
|
|
Wait(0)
|
|
if istGeladen and not istOffen and IsControlJustReleased(0, TASTE_INVENTAR) then
|
|
-- Nicht oeffnen, waehrend man tot ist oder schwimmt
|
|
local ped = PlayerPedId()
|
|
if not IsEntityDead(ped) then
|
|
TriggerServerEvent('aether:inventory:oeffnen')
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- NUI-Callbacks — jede Aktion geht ungeprueft an den Server,
|
|
-- der sie dann validiert.
|
|
-- ---------------------------------------------------------------------
|
|
RegisterNUICallback('schliessen', function(_, rueckgabe)
|
|
Schliessen()
|
|
rueckgabe({ ok = true })
|
|
end)
|
|
|
|
RegisterNUICallback('verschieben', function(daten, rueckgabe)
|
|
TriggerServerEvent('aether:inventory:verschieben', daten.von, daten.nach)
|
|
rueckgabe({ ok = true })
|
|
end)
|
|
|
|
RegisterNUICallback('splitten', function(daten, rueckgabe)
|
|
TriggerServerEvent('aether:inventory:splitten', daten.slot, daten.menge)
|
|
rueckgabe({ ok = true })
|
|
end)
|
|
|
|
RegisterNUICallback('fallenlassen', function(daten, rueckgabe)
|
|
TriggerServerEvent('aether:inventory:fallenlassen', daten.slot, daten.menge)
|
|
rueckgabe({ ok = true })
|
|
end)
|
|
|
|
RegisterNUICallback('aufheben', function(daten, rueckgabe)
|
|
TriggerServerEvent('aether:inventory:aufheben', daten.bodenId)
|
|
rueckgabe({ ok = true })
|
|
end)
|
|
|
|
RegisterNUICallback('geben', function(daten, rueckgabe)
|
|
TriggerServerEvent('aether:inventory:geben', daten.slot, daten.menge, daten.zielId)
|
|
rueckgabe({ ok = true })
|
|
end)
|
|
|
|
RegisterNUICallback('benutzen', function(daten, rueckgabe)
|
|
TriggerServerEvent('aether:inventory:benutzen', daten.slot)
|
|
rueckgabe({ ok = true })
|
|
end)
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- Aufraeumen
|
|
-- ---------------------------------------------------------------------
|
|
AddEventHandler('onResourceStop', function(ressource)
|
|
if ressource ~= GetCurrentResourceName() then return end
|
|
SetNuiFocus(false, false)
|
|
end)
|