fix(server): frisch gekaufte Flaschen sind nicht mehr leer
Lint / Lint Resource (push) Has been cancelled

Eine Flasche ohne gesetzte Metadata - aus dem Shop, per AddItem oder per
Admin-Befehl - wurde in getTankList als 0 gelesen. Anlegen scheiterte damit an
"Diese Tauchflasche ist leer!", man haette also erst eine Kartusche verbrauchen
muessen, um ueberhaupt tauchen zu koennen.

Dazu waren sich die beiden Codepfade uneinig: syncTank hat denselben Fall auf
capacity zurueckfallen lassen, also als voll behandelt.

Beide gehen jetzt ueber readOxygen(), gesteuert von shared.newTanksFull
(default true = neue Flasche ist voll).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-11 00:31:37 +02:00
co-authored by Claude Opus 5
parent c264872007
commit 3ab70d44ef
3 changed files with 27 additions and 3 deletions
+4
View File
@@ -109,6 +109,9 @@ auffüllbar zu bleiben.
## Bedienung
Die Flasche wird **nicht** separat angezogen. Sie muss nur im Inventar liegen —
beim Anlegen der Ausrüstung fragt das Script, welche angeschlossen werden soll.
| Aktion | Wie |
|---|---|
| Ausrüstung an-/ausziehen | `diving_gear` benutzen |
@@ -127,6 +130,7 @@ FiveM* umlegbar.
| Option | Default | Bedeutung |
|---|---|---|
| `tanks` | 4 Flaschen | `name`, `capacity` (Sekunden), `pressure` (bar) |
| `newTanksFull` | `true` | Flaschen ohne Metadata (Shop, `AddItem`, Admin-Befehl) gelten als voll. Auf `false` muss jede neue Flasche erst mit einer Kartusche befüllt werden |
| `syncIntervalSeconds` | `15` | Wie oft die Restluft an den Server gemeldet wird. Bei einem Crash gehen maximal so viele Sekunden verloren |
| `maxDrainPerSecond` | `5.0` | Obergrenze der serverseitigen Prüfung |
+6
View File
@@ -17,6 +17,12 @@ local config = {
{ name = 'diving_tank_xl', capacity = 1200, pressure = 300 }, -- 20 Minuten
},
--- Flaschen ohne Metadata als voll behandeln. Betrifft alles, was frisch aus
--- einem Shop, per AddItem oder aus einem Admin-Befehl kommt - da ist noch kein
--- oxygen gesetzt. Auf false muss jede neue Flasche erst mit einer Kartusche
--- befüllt werden, bevor man damit tauchen kann.
newTanksFull = true,
--- Wie oft der Client die Restluft an den Server meldet (Sekunden).
--- Bei einem Crash gehen maximal so viele Sekunden Luft verloren.
syncIntervalSeconds = 15,
+17 -3
View File
@@ -5,6 +5,21 @@ local shared = require 'config.shared'
--- niemand verbrauchen.
local lastSync = {}
--- Restluft eines Slots. Ohne gesetzte Metadata (frisch aus dem Shop, per AddItem
--- oder Admin-Befehl) entscheidet newTanksFull, ob die Flasche voll oder leer ist.
--- Muss überall dieselbe Antwort geben, sonst hält die eine Stelle die Flasche für
--- leer und die andere für voll.
--- @return number
local function readOxygen(slot, tankConfig)
local stored = tonumber(slot.metadata and slot.metadata.oxygen)
if not stored then
return shared.newTanksFull and tankConfig.capacity or 0
end
return math.max(0, math.min(stored, tankConfig.capacity))
end
--- @param source number
--- @param slotId number
--- @return table? slot, table? tankConfig
@@ -60,13 +75,12 @@ local function getTankList(source)
if slots then
for j = 1, #slots do
local slot = slots[j]
local oxygen = tonumber(slot.metadata and slot.metadata.oxygen) or 0
tanks[#tanks + 1] = {
slot = slot.slot,
name = name,
label = (exports.ox_inventory:Items(name) or {}).label or name,
oxygen = math.max(0, math.min(oxygen, tankConfig.capacity)),
oxygen = readOxygen(slot, tankConfig),
capacity = tankConfig.capacity,
pressure = tankConfig.pressure
}
@@ -87,7 +101,7 @@ local function syncTank(source, slotId, oxygen)
if not slot then return end
local current = tonumber(slot.metadata and slot.metadata.oxygen) or tankConfig.capacity
local current = readOxygen(slot, tankConfig)
local now = os.time()
local elapsed = lastSync[source] and (now - lastSync[source]) or shared.syncIntervalSeconds