aether-framework/resources/[aether]/aether-character/client/aussehen.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

133 lines
5.8 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- =====================================================================
-- Aether Character — Aussehen auf den GTA-Ped uebertragen
--
-- WICHTIG: Der Charakter-Ersteller arbeitet mit einer stilisierten
-- SVG-Vorschau und eigenen Werten (Paletten-Index, Slider 0–100).
-- GTA kennt diese Werte nicht — die folgenden Tabellen sind daher eine
-- *Annaeherung*. Sie sind bewusst als einfache Zuordnungstabellen
-- gebaut, damit du die Werte jederzeit nachjustieren kannst.
-- =====================================================================
AetherAussehen = {}
-- ---------------------------------------------------------------------
-- Zuordnungstabellen (Index aus dem Ersteller -> GTA-Wert)
-- ---------------------------------------------------------------------
-- Hautton-Index -> Elternteil-Haut fuer SetPedHeadBlendData (0–45)
-- Niedrige Werte = hellere Haut, hohe Werte = dunklere Haut
local HAUT_ZU_ELTERN = { [0]=0, [1]=1, [2]=2, [3]=3, [4]=4, [5]=5, [6]=6, [7]=7 }
-- Frisur-Index -> Drawable der Komponente 2 (Haare), je Geschlecht
local FRISUR = {
maennlich = { [0]=1, [1]=2, [2]=6, [3]=4, [4]=10, [5]=0 }, -- Kurz/Mittel/Undercut/Lang/Zopf/Glatze
weiblich = { [0]=1, [1]=3, [2]=12, [3]=8, [4]=9, [5]=0 },
}
-- Haarfarben-Index -> GTA-Haarfarbe (0–63)
local HAARFARBE = { [0]=0, [1]=2, [2]=5, [3]=8, [4]=10, [5]=12, [6]=6, [7]=17, [8]=18, [9]=63 }
-- Augenfarben-Index -> GTA-Augenfarbe (0–31)
local AUGENFARBE = { [0]=1, [1]=2, [2]=0, [3]=3, [4]=5, [5]=4 }
-- Bart-Index -> Overlay-Drawable (Overlay 1 = Bart); -1 bedeutet rasiert
local BART = { [0]=-1, [1]=10, [2]=2, [3]=5 }
-- Augenbrauen-Index (0/1/2) -> Overlay-Drawable (Overlay 2)
local AUGENBRAUEN = { [0]=4, [1]=1, [2]=6 }
-- Kleidungsfarben-Index -> Textur-Variante der jeweiligen Komponente
local KLEID_TEXTUR = { [0]=0, [1]=1, [2]=2, [3]=3, [4]=4, [5]=5, [6]=6, [7]=7, [8]=8, [9]=9 }
-- ---------------------------------------------------------------------
-- Hilfsfunktionen
-- ---------------------------------------------------------------------
--- Rechnet einen Slider (0–100) in einen GTA-Gesichtswert (-1.0 bis 1.0) um
--- @param wert number Sliderwert 0–100
--- @return number Gesichtswert
local function SliderZuGesicht(wert)
return ((tonumber(wert) or 50) - 50) / 50.0
end
--- Liefert den Schluessel fuer die geschlechtsabhaengigen Tabellen
--- @param geschlecht string 'männlich' | 'weiblich' | 'divers'
--- @return string
local function GeschlechtSchluessel(geschlecht)
return (geschlecht == 'weiblich') and 'weiblich' or 'maennlich'
end
-- ---------------------------------------------------------------------
-- Anwendung
-- ---------------------------------------------------------------------
--- Liefert den passenden Ped-Modellnamen zum Geschlecht
--- @param geschlecht string
--- @return string Modellname
function AetherAussehen.HoleModell(geschlecht)
if geschlecht == 'weiblich' then return 'mp_f_freemode_01' end
return 'mp_m_freemode_01'
end
--- Uebertraegt ein Aussehen-Objekt des Erstellers auf einen Ped
--- @param ped number Ped-Handle
--- @param aussehen table Aussehen aus dem Charakter-Ersteller
function AetherAussehen.Anwenden(ped, aussehen)
if not aussehen or not DoesEntityExist(ped) then return end
local schluessel = GeschlechtSchluessel(aussehen.geschlecht)
local hautEltern = HAUT_ZU_ELTERN[aussehen.skin or 1] or 1
-- Grundgesicht: Eltern und Hautton mischen
SetPedHeadBlendData(ped,
0, 0, 0, -- Gesichtsform (Vater, Mutter, Mischung)
hautEltern, hautEltern, 0,
0.5, 1.0, 0.0, -- Gewichtung Form / Haut / Drittwert
false)
-- Gesichtszuege aus den Slidern (GTA-Index -> Sliderwert)
SetPedFaceFeature(ped, 0, SliderZuGesicht(aussehen.nase)) -- Nasenbreite
SetPedFaceFeature(ped, 6, SliderZuGesicht(aussehen.lippen)) -- Lippendicke
SetPedFaceFeature(ped, 7, SliderZuGesicht(aussehen.kiefer)) -- Kieferbreite
SetPedFaceFeature(ped, 11, SliderZuGesicht(aussehen.gesichtBreite)) -- Wangenbreite
-- Haare
local frisur = (FRISUR[schluessel] or FRISUR.maennlich)[aussehen.hairStyle or 0] or 0
SetPedComponentVariation(ped, 2, frisur, 0, 0)
local haarfarbe = HAARFARBE[aussehen.hairColor or 0] or 0
SetPedHairColor(ped, haarfarbe, haarfarbe)
-- Augenfarbe (Native ohne offiziellen Namen)
local augenfarbe = AUGENFARBE[aussehen.augen or 0] or 0
Citizen.InvokeNative(0x50B56988B170AFDF, ped, augenfarbe)
-- Augenbrauen (Overlay 2)
local braue = AUGENBRAUEN[math.floor((aussehen.augenbraue or 50) / 50)] or 1
SetPedHeadOverlay(ped, 2, braue, 1.0)
SetPedHeadOverlayColor(ped, 2, 1, haarfarbe, haarfarbe)
-- Bart (Overlay 1) — nur bei nicht-weiblichen Peds sinnvoll
local bart = BART[aussehen.bart or 0] or -1
if bart >= 0 then
SetPedHeadOverlay(ped, 1, bart, 1.0)
SetPedHeadOverlayColor(ped, 1, 1, haarfarbe, haarfarbe)
else
SetPedHeadOverlay(ped, 1, 255, 0.0) -- 255 = kein Overlay
end
-- Kleidung: Farbe wird als Texturvariante der Komponente gesetzt
local oberteil = KLEID_TEXTUR[aussehen.top or 0] or 0
local hose = KLEID_TEXTUR[aussehen.hose or 0] or 0
local schuhe = KLEID_TEXTUR[aussehen.schuhe or 0] or 0
SetPedComponentVariation(ped, 11, 1, oberteil, 0) -- Oberkoerper (Jacke/Shirt)
SetPedComponentVariation(ped, 8, 1, 0, 0) -- Unterhemd
SetPedComponentVariation(ped, 3, 1, 0, 0) -- Arme
SetPedComponentVariation(ped, 4, 1, hose, 0) -- Beine
SetPedComponentVariation(ped, 6, 1, schuhe, 0) -- Schuhe
-- Koerperbau als Fettigkeits-/Muskel-Overlay (Overlay 10 = Sommersprossen frei,
-- daher nutzen wir Overlay 0 nicht; Statur ueber Gesichtszug 19 annaehern)
SetPedFaceFeature(ped, 19, SliderZuGesicht(aussehen.koerper))
end