aether-framework/resources/[aether]/aether-shop/client/main.lua
Jerrit Fritzsche e4b82dd685 Aether-Framework: Fachmodule, Admin-Panel und Docker-Datenbank
- 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>
2026-07-27 18:55:32 +02:00

150 lines
5.1 KiB
Lua

-- =====================================================================
-- Aether Shop — Clientlogik
-- Setzt Karten-Markierungen, erkennt Filialen und oeffnet die Oberflaeche.
-- Gekauft wird ausschliesslich ueber den Server.
-- =====================================================================
local istOffen = false
local istGeladen = false
-- Taste E zum Betreten
local TASTE_BENUTZEN = 38
--- Schickt eine Nachricht an die Oberflaeche
local function SendeAnNui(nachricht)
SendNuiMessage(json.encode(nachricht))
end
--- Zeigt eine Meldung oben links im Spiel
local function ZeigeSpielmeldung(text)
if not text or text == '' then return end
BeginTextCommandThefeedPost('STRING')
AddTextComponentSubstringPlayerName(text)
EndTextCommandThefeedPostTicker(false, true)
end
--- Schliesst den Laden
local function Schliessen()
if not istOffen then return end
istOffen = false
SetNuiFocus(false, false)
SendeAnNui({ aktion = 'schliessen' })
TriggerServerEvent('aether:shop:schliessen')
pcall(function() exports['aether-hud']:SetzeSichtbar(true) end)
end
-- ---------------------------------------------------------------------
-- Karten-Markierungen setzen
-- ---------------------------------------------------------------------
CreateThread(function()
for _, laden in pairs(Shop.Laeden) do
for _, standort in ipairs(laden.standorte) do
local blip = AddBlipForCoord(standort.x, standort.y, standort.z)
SetBlipSprite(blip, laden.blip.sprite)
SetBlipColour(blip, laden.blip.farbe)
SetBlipScale(blip, 0.7)
SetBlipAsShortRange(blip, true)
BeginTextCommandSetBlipName('STRING')
AddTextComponentString(laden.name)
EndTextCommandSetBlipName(blip)
end
end
end)
-- ---------------------------------------------------------------------
-- Ereignisse
-- ---------------------------------------------------------------------
AddEventHandler('aether:client:bereit', function()
istGeladen = true
end)
--- Server erlaubt das Oeffnen und schickt den Katalog
RegisterNetEvent('aether:shop:zeige', function(katalog, geld)
istOffen = true
SetNuiFocus(true, true)
pcall(function() exports['aether-hud']:SetzeSichtbar(false) end)
SendeAnNui({ aktion = 'oeffnen', katalog = katalog, geld = geld })
end)
--- Kauf erfolgreich: Beleg und aktualisierter Katalog
RegisterNetEvent('aether:shop:gekauft', function(ergebnis)
ergebnis.aktion = 'gekauft'
SendeAnNui(ergebnis)
end)
--- Ablehnung einer Aktion
RegisterNetEvent('aether:shop:fehler', function(text)
if istOffen then
SendeAnNui({ aktion = 'fehler', text = text })
else
ZeigeSpielmeldung(text)
end
end)
-- ---------------------------------------------------------------------
-- Filiale in der Naehe erkennen
-- ---------------------------------------------------------------------
CreateThread(function()
while true do
local pause = 800
if istGeladen and not istOffen then
local position = GetEntityCoords(PlayerPedId())
-- Naechstgelegene Filiale suchen
local trefferId, trefferLaden, trefferPos = nil, nil, nil
for ladenId, laden in pairs(Shop.Laeden) do
for _, standort in ipairs(laden.standorte) do
if #(position - standort) <= Shop.INTERAKTION_WEITE then
trefferId, trefferLaden, trefferPos = ladenId, laden, standort
break
end
end
if trefferId then break end
end
if trefferId then
pause = 0 -- fuer die Textanzeige jeden Frame laufen
SetTextFont(4)
SetTextScale(0.34, 0.34)
SetTextColour(255, 255, 255, 215)
SetTextCentre(true)
SetTextOutline()
SetTextEntry('STRING')
AddTextComponentString('[E] ' .. trefferLaden.name)
SetDrawOrigin(trefferPos.x, trefferPos.y, trefferPos.z + 0.9, 0)
DrawText(0.0, 0.0)
ClearDrawOrigin()
if IsControlJustReleased(0, TASTE_BENUTZEN) then
TriggerServerEvent('aether:shop:oeffnen', trefferId)
end
end
end
Wait(pause)
end
end)
-- ---------------------------------------------------------------------
-- NUI-Callbacks
-- ---------------------------------------------------------------------
RegisterNUICallback('schliessen', function(_, rueckgabe)
Schliessen()
rueckgabe({ ok = true })
end)
RegisterNUICallback('kaufen', function(daten, rueckgabe)
TriggerServerEvent('aether:shop:kaufen', daten.warenkorb or {}, daten.zahlung or 'bargeld')
rueckgabe({ ok = true })
end)
-- ---------------------------------------------------------------------
-- Aufraeumen
-- ---------------------------------------------------------------------
AddEventHandler('onResourceStop', function(ressource)
if ressource ~= GetCurrentResourceName() then return end
SetNuiFocus(false, false)
end)