Ersetzt die qbx.drawText2d-Anzeige (rohe Zahl plus Uhr-Emoji in der Ecke, jeden Frame neu gezeichnet) durch ein NUI-Overlay. - Luft als Ring mit mm:ss, Farbstufen aus config.warnAtSeconds abgeleitet, Pulsieren im kritischen Bereich - Tiefe in Metern ueber GetWaterHeight, geglaettet damit Wellengang die Zahl nicht zappeln laesst; Einfaerbung ab config.deepWarningDepth - Platz fuer den Lampen-Status, wird in Phase 5 befuellt - Sichtbar nur mit angelegter Ausruestung unter Wasser, mit Fade - Updates gedrosselt auf 4/s statt jeden Frame - Kein backdrop-filter (bekannter FiveM-Bug) Die geglaettete Tiefe speist auch den tiefenabhaengigen Verbrauch, der bisher bei jedem Tick neu und ungeglaettet gemessen wurde. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+69
-10
@@ -14,6 +14,20 @@ local activeTank = nil
|
||||
--- Bereits ausgelöste Warnschwellen des laufenden Tauchgangs.
|
||||
local warned = {}
|
||||
|
||||
--- Geglättete Tauchtiefe in Metern. Wird vom HUD-Thread gepflegt und sowohl für
|
||||
--- die Anzeige als auch für den tiefenabhängigen Verbrauch benutzt.
|
||||
local currentDepth = 0.0
|
||||
|
||||
--- Grenzen für die Farbstufen im HUD, aus config.warnAtSeconds abgeleitet.
|
||||
local warnThreshold, dangerThreshold = 0, 0
|
||||
|
||||
for i = 1, #config.warnAtSeconds do
|
||||
local threshold = config.warnAtSeconds[i]
|
||||
|
||||
if threshold > warnThreshold then warnThreshold = threshold end
|
||||
if dangerThreshold == 0 or threshold < dangerThreshold then dangerThreshold = threshold end
|
||||
end
|
||||
|
||||
local MASK_MODEL = `p_d_scuba_mask_s`
|
||||
local TANK_MODEL = `p_s_scuba_tank_s`
|
||||
local MASK_BONE = 12844
|
||||
@@ -37,10 +51,12 @@ local function getDepth()
|
||||
end
|
||||
|
||||
--- Verbrauchsfaktor. Tiefer tauchen kostet mehr Luft.
|
||||
--- Nutzt die geglättete Tiefe aus dem HUD-Thread, damit Wellengang den Verbrauch
|
||||
--- nicht im Sekundentakt springen lässt.
|
||||
local function getDecayFactor()
|
||||
if not config.depthDecayEnabled then return 1.0 end
|
||||
|
||||
return math.min(config.maxDecayFactor, 1.0 + getDepth() / config.depthDecayReference)
|
||||
return math.min(config.maxDecayFactor, 1.0 + currentDepth / config.depthDecayReference)
|
||||
end
|
||||
|
||||
--- @param ped number? default cache.ped - beim Model-Wechsel muss der neue Ped explizit rein
|
||||
@@ -236,18 +252,60 @@ local function takeOffSuit()
|
||||
end
|
||||
end
|
||||
|
||||
local function startOxygenLevelDrawTextThread()
|
||||
--- @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 level = 'ok'
|
||||
|
||||
if oxygen <= dangerThreshold then
|
||||
level = 'danger'
|
||||
elseif oxygen <= warnThreshold then
|
||||
level = 'warn'
|
||||
end
|
||||
|
||||
SendNUIMessage({
|
||||
action = 'state',
|
||||
visible = visible,
|
||||
oxygen = oxygen,
|
||||
capacity = capacity,
|
||||
depth = currentDepth,
|
||||
level = level,
|
||||
deep = currentDepth >= config.deepWarningDepth,
|
||||
hasLamp = false,
|
||||
lamp = false
|
||||
})
|
||||
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.
|
||||
local function startHudThread()
|
||||
CreateThread(function()
|
||||
local wasVisible = false
|
||||
|
||||
SendNUIMessage({
|
||||
action = 'labels',
|
||||
air = locale('hud.air'),
|
||||
depth = locale('hud.depth'),
|
||||
lamp = locale('hud.lamp')
|
||||
})
|
||||
|
||||
while currentGear.enabled do
|
||||
if IsPedSwimmingUnderWater(cache.ped) and activeTank then
|
||||
qbx.drawText2d({
|
||||
text = formatTime(activeTank.oxygen)..'⏱',
|
||||
coords = vec2(1.0, 1.42),
|
||||
scale = 0.45
|
||||
})
|
||||
currentDepth = currentDepth + (getDepth() - currentDepth) * 0.25
|
||||
|
||||
local visible = config.hudEnabled and activeTank ~= nil and IsPedSwimmingUnderWater(cache.ped)
|
||||
|
||||
if visible or wasVisible then
|
||||
sendHudState(visible)
|
||||
wasVisible = visible
|
||||
end
|
||||
Wait(0)
|
||||
|
||||
Wait(config.hudUpdateIntervalMs)
|
||||
end
|
||||
|
||||
currentDepth = 0.0
|
||||
sendHudState(false)
|
||||
end)
|
||||
end
|
||||
|
||||
@@ -370,7 +428,7 @@ local function putOnSuit()
|
||||
currentGear.enabled = true
|
||||
-- Initiate breathing suit audio
|
||||
startOxygenLevelDecrementerThread()
|
||||
startOxygenLevelDrawTextThread()
|
||||
startHudThread()
|
||||
startGearWatchdogThread()
|
||||
end
|
||||
end
|
||||
@@ -406,6 +464,7 @@ AddEventHandler('onResourceStop', function(resource)
|
||||
|
||||
syncTank(true)
|
||||
deleteGear()
|
||||
SendNUIMessage({ action = 'state', visible = false })
|
||||
SetEnableScuba(cache.ped, false)
|
||||
SetPedMaxTimeUnderwater(cache.ped, config.maxTimeUnderwater)
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user