diff --git a/PLAN.md b/PLAN.md index 13bfef8..e2ebb77 100644 --- a/PLAN.md +++ b/PLAN.md @@ -121,6 +121,15 @@ Tiefenanzeige und O2-Anzeige zusammen als ein NUI-Overlay — `qbx.drawText2d` - [x] Updates gedrosselt per `SendNUIMessage` (~4/s statt jeden Frame) - [x] Kein `backdrop-filter` (bekannter FiveM-Bug → schwarzer Hintergrund) - [x] `hudEnabled`, `hudUpdateIntervalMs` und `deepWarningDepth` in `config/client.lua` +- [x] **Nachgereicht:** Manometer in bar. `pressure * (Restluft / capacity)` — bei + konstantem Volumen ist der Druck proportional zur verbliebenen Gasmenge, die + lineare Abbildung ist also korrekt. Alle Flaschen starten bei 300 bar; dass + die große Flasche denselben Druck zeigt wie die kleine, ist gewollt (in echt + macht das Volumen die Laufzeit). Unter `reservePressure` wird rot eingefärbt +- [x] **Nachgereicht:** HUD ausblendbar für Unterwasser-Screenshots. Drei Wege, + weil `qbx_core` selbst keinen HUD-Toggle hat (es feuert nur `hud:client:*` + an eine separate HUD-Resource): `IsHudHidden()` folgen, eigene Taste, + und der Export `setHudVisible(bool)` - [ ] **Offen:** Position und Größe des HUD sind bisher nur in `nui/style.css` einstellbar, nicht in der Config @@ -234,7 +243,10 @@ Locale-JSONs und das HUD im Browser. tauschen oder das Vorzeichen drehen. 3. **Auto-Anziehen nach Relog** (siehe Phase 2) und **HUD-Position in der Config** (Phase 4) sind nicht umgesetzt. -4. **Balancing:** `maxDrainPerSecond = 5.0` muss über `maxDecayFactor = 4.0` liegen, +4. **`IsHudHidden()`** — ob die Native wirklich auf `DisplayHud(false)` anspringt, + ist ungetestet. Falls nicht, greifen weiterhin die eigene Taste und der Export; + `hudFollowGameHud` lässt sich dann abschalten. +5. **Balancing:** `maxDrainPerSecond = 5.0` muss über `maxDecayFactor = 4.0` liegen, sonst bekommen ehrliche Spieler in großer Tiefe vom Server Luft zurückgeschrieben. Wer den Tiefenfaktor hochdreht, muss beides nachziehen. diff --git a/README.md b/README.md index 8b61200..baea0ac 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,9 @@ Animationen nicht verschwindet. Füllstand ist als Balken direkt im Inventar-Slot sichtbar. - **Gesyncte Tauchlampe** — an der Ausrüstung, An/Aus per Taste (Standard `L`). Andere Spieler sehen den Lichtkegel. -- **NUI-HUD** — Restluft als Ring mit `mm:ss` und Tauchtiefe in Metern, mit - Warnstufen. Nur sichtbar mit angelegter Ausrüstung unter Wasser. +- **NUI-HUD** — Restluft als Ring mit `mm:ss`, Tauchtiefe in Metern und + Manometer in bar, mit Warnstufen. Nur sichtbar mit angelegter Ausrüstung + unter Wasser, und ausblendbar für Unterwasser-Screenshots. - **Tiefenabhängiger Verbrauch** — tiefer tauchen kostet mehr Luft. Abschaltbar. - **Ausrüstung bleibt** — bei Emotes, Ragdoll, Kleiderwechsel und aufräumenden Fremd-Scripts. @@ -39,6 +40,22 @@ Animationen nicht verschwindet. | Flasche wählen | Menü beim Anlegen (entfällt bei nur einer Flasche) | | Flasche auffüllen | `diving_fill` benutzen, nicht unter Wasser | | Lampe an/aus | `L` (in den FiveM-Tastenbelegungen umlegbar) | +| HUD ausblenden | Eigene Taste, standardmäßig unbelegt — in den FiveM-Tastenbelegungen unter "FiveM" setzen | + +### HUD ausblenden für Screenshots + +Drei Wege, damit es unabhängig von der eingesetzten HUD-Resource funktioniert: + +1. **Automatisch** — das Tauch-HUD verschwindet mit dem Spiel-HUD. Greift bei + allem, was `DisplayHud(false)` setzt (Screenshot-Scripts, HUD-Toggles, + Cinematic-Modes). Abschaltbar über `hudFollowGameHud`. +2. **Eigene Taste** — `hudToggleKey` in der Config, oder vom Spieler selbst belegt. +3. **Export** — für andere Resources: + +```lua +exports.d4rk_divegear:setHudVisible(false) +local shown = exports.d4rk_divegear:isHudVisible() +``` ## Konfiguration diff --git a/client/main.lua b/client/main.lua index 7c8c5d3..0ab6b98 100644 --- a/client/main.lua +++ b/client/main.lua @@ -289,10 +289,20 @@ local function takeOffSuit() end end +--- Manometer-Anzeige. Bei konstantem Volumen ist der Druck proportional zur +--- verbliebenen Gasmenge, deshalb reicht der lineare Anteil an der Füllung. +--- @return number bar +local function getPressure() + if not activeTank or activeTank.capacity <= 0 then return 0 end + + return (activeTank.pressure or 0) * (activeTank.oxygen / activeTank.capacity) +end + --- @param visible boolean local function sendHudState(visible) local oxygen = activeTank and activeTank.oxygen or 0.0 local capacity = activeTank and activeTank.capacity or 1 + local pressure = getPressure() local level = 'ok' if oxygen <= dangerThreshold then @@ -307,6 +317,8 @@ local function sendHudState(visible) oxygen = oxygen, capacity = capacity, depth = currentDepth, + pressure = pressure, + reserve = pressure > 0 and pressure <= config.reservePressure, level = level, deep = currentDepth >= config.deepWarningDepth, hasLamp = true, @@ -314,6 +326,25 @@ local function sendHudState(visible) }) end +--- Manuell ausgeblendet (eigene Taste oder Export)? Unabhängig davon, ob das +--- Spiel-HUD gerade sichtbar ist. +local hudHidden = false + +--- Blendet das Tauch-HUD aus oder wieder ein, z.B. für Unterwasser-Screenshots. +--- Als Export nutzbar, damit HUD- und Screenshot-Resources es mitnehmen können: +--- exports.d4rk_divegear:setHudVisible(false) +--- @param visible boolean +local function setHudVisible(visible) + hudHidden = not visible + + if hudHidden then + SendNUIMessage({ action = 'state', visible = false }) + end +end + +exports('setHudVisible', setHudVisible) +exports('isHudVisible', function() return not hudHidden end) + --- Pflegt die geglättete Tiefe und schiebt den Zustand ins NUI. --- Läuft auch über Wasser weiter, weil getDecayFactor die Tiefe braucht - nur die --- Anzeige wird ausgeblendet. @@ -325,13 +356,20 @@ local function startHudThread() action = 'labels', air = locale('hud.air'), depth = locale('hud.depth'), + pressure = locale('hud.pressure'), lamp = locale('hud.lamp') }) while currentGear.enabled do currentDepth = currentDepth + (getDepth() - currentDepth) * 0.25 - local visible = config.hudEnabled and activeTank ~= nil and IsPedSwimmingUnderWater(cache.ped) + local visible = config.hudEnabled + and not hudHidden + and activeTank ~= nil + and IsPedSwimmingUnderWater(cache.ped) + -- Folgt dem Spiel-HUD: alles was DisplayHud(false) setzt, blendet + -- damit auch das Tauch-HUD aus. + and not (config.hudFollowGameHud and IsHudHidden()) if visible or wasVisible then sendHudState(visible) @@ -478,6 +516,15 @@ RegisterNetEvent('d4rk_divegear:client:useGear', function() end end) +lib.addKeybind({ + name = 'divegear_hud', + description = locale('keybind.toggle_hud'), + defaultKey = config.hudToggleKey, + onPressed = function() + setHudVisible(hudHidden) + end +}) + lib.addKeybind({ name = 'divegear_lamp', description = locale('keybind.toggle_lamp'), diff --git a/config/client.lua b/config/client.lua index 6b5c309..b456bae 100644 --- a/config/client.lua +++ b/config/client.lua @@ -36,9 +36,23 @@ return { --- ruhige Anzeige ohne unnötigen NUI-Traffic. hudUpdateIntervalMs = 250, + --- Tauch-HUD mit ausblenden, sobald das Spiel-HUD ausgeblendet ist. + --- Greift bei allem, was DisplayHud(false) setzt - Screenshot-Scripts, + --- HUD-Toggles, Cinematic-Modes -, ohne dass wir die Resource kennen müssen. + hudFollowGameHud = true, + + --- Eigene Taste zum Aus-/Einblenden des Tauch-HUD. Leer = keine Vorbelegung, + --- der Spieler kann sie in den FiveM-Tastenbelegungen unter "FiveM" setzen. + --- Zusätzlich gibt es den Export setHudVisible(bool) für andere Resources. + hudToggleKey = '', + --- Ab dieser Tiefe wird die Tiefenanzeige eingefärbt (Meter). deepWarningDepth = 25.0, + --- Reservedruck in bar. Darunter wird die Druckanzeige eingefärbt - in der + --- Tauchpraxis die Schwelle, ab der man den Aufstieg einleitet. + reservePressure = 50, + --------------------------------------------------------------------------- -- Taschenlampe --------------------------------------------------------------------------- diff --git a/config/shared.lua b/config/shared.lua index fee32fd..aa1f1b8 100644 --- a/config/shared.lua +++ b/config/shared.lua @@ -2,13 +2,19 @@ -- damit lib.require die Datei auf beiden Seiten laden kann. local config = { - --- Tauchflaschen. capacity = Laufzeit in Sekunden bei normalem Verbrauch. + --- Tauchflaschen. + --- capacity = Laufzeit in Sekunden bei normalem Verbrauch. + --- pressure = Fülldruck in bar. Reine Anzeige: der angezeigte Druck ist + --- pressure * (Restluft / capacity). Bei konstantem Volumen ist der + --- Druck proportional zur verbliebenen Gasmenge, das passt also. + --- Dass alle Flaschen denselben Fülldruck haben ist gewollt - in echt + --- macht das Volumen die Laufzeit, nicht der Druck. --- Reihenfolge = Reihenfolge im Auswahlmenü. tanks = { - { name = 'diving_tank_small', capacity = 300 }, -- 5 Minuten - { name = 'diving_tank_medium', capacity = 600 }, -- 10 Minuten - { name = 'diving_tank_large', capacity = 900 }, -- 15 Minuten - { name = 'diving_tank_xl', capacity = 1200 }, -- 20 Minuten + { name = 'diving_tank_small', capacity = 300, pressure = 300 }, -- 5 Minuten + { name = 'diving_tank_medium', capacity = 600, pressure = 300 }, -- 10 Minuten + { name = 'diving_tank_large', capacity = 900, pressure = 300 }, -- 15 Minuten + { name = 'diving_tank_xl', capacity = 1200, pressure = 300 }, -- 20 Minuten }, --- Wie oft der Client die Restluft an den Server meldet (Sekunden). diff --git a/items_for_ox_inventory.lua b/items_for_ox_inventory.lua index 199c7c4..f4121c2 100644 --- a/items_for_ox_inventory.lua +++ b/items_for_ox_inventory.lua @@ -5,8 +5,9 @@ -- (modules/items/server.lua) - die leere Flasche würde also verschwinden statt -- auffüllbar zu bleiben. -- --- Die Laufzeiten stehen in config/shared.lua (capacity in Sekunden). Wer die dort --- ändert, sollte die Labels hier mitziehen. +-- Laufzeit (capacity, Sekunden) und Fülldruck (pressure, bar) stehen in +-- config/shared.lua. Wer die dort ändert, sollte Labels und Beschreibungen hier +-- mitziehen. ['diving_gear'] = { label = 'Tauchausrüstung', @@ -34,7 +35,7 @@ stack = false, close = true, consume = 0, - description = 'Kleine Tauchflasche. Reicht für etwa 5 Minuten.', + description = 'Kleine Tauchflasche, 300 bar. Reicht für etwa 5 Minuten.', client = { image = 'diving_tank_small.png' } }, @@ -44,7 +45,7 @@ stack = false, close = true, consume = 0, - description = 'Mittlere Tauchflasche. Reicht für etwa 10 Minuten.', + description = 'Mittlere Tauchflasche, 300 bar. Reicht für etwa 10 Minuten.', client = { image = 'diving_tank_medium.png' } }, @@ -54,7 +55,7 @@ stack = false, close = true, consume = 0, - description = 'Große Tauchflasche. Reicht für etwa 15 Minuten.', + description = 'Große Tauchflasche, 300 bar. Reicht für etwa 15 Minuten.', client = { image = 'diving_tank_large.png' } }, @@ -64,6 +65,6 @@ stack = false, close = true, consume = 0, - description = 'Doppelflasche für lange Tauchgänge. Reicht für etwa 20 Minuten.', + description = 'Doppelflasche, 300 bar. Reicht für etwa 20 Minuten.', client = { image = 'diving_tank_xl.png' } }, diff --git a/locales/de.json b/locales/de.json index 134e009..f1b8fc2 100644 --- a/locales/de.json +++ b/locales/de.json @@ -25,9 +25,11 @@ "hud": { "air": "Luft", "depth": "Tiefe", + "pressure": "Druck", "lamp": "Lampe" }, "keybind": { - "toggle_lamp": "Tauchlampe an/aus" + "toggle_lamp": "Tauchlampe an/aus", + "toggle_hud": "Tauch-HUD ein-/ausblenden" } } diff --git a/locales/en.json b/locales/en.json index 6b48969..34d1c34 100644 --- a/locales/en.json +++ b/locales/en.json @@ -25,9 +25,11 @@ "hud": { "air": "Air", "depth": "Depth", + "pressure": "Pressure", "lamp": "Lamp" }, "keybind": { - "toggle_lamp": "Toggle dive lamp" + "toggle_lamp": "Toggle dive lamp", + "toggle_hud": "Toggle dive HUD" } } diff --git a/nui/index.html b/nui/index.html index cdb012f..116194d 100644 --- a/nui/index.html +++ b/nui/index.html @@ -18,9 +18,16 @@