From a49e6d0f6abe9e2c51c1186fe5333051c9b27ec3 Mon Sep 17 00:00:00 2001 From: D4rkst3r Date: Tue, 11 Aug 2026 10:08:00 +0200 Subject: [PATCH] fix: weggegebene Ausruestung beendet den Tauchgang Gleiche Bug-Klasse wie bei der Flasche, nur hatte mein Fix davor ausschliesslich die Flasche geprueft: wer diving_gear im Tauchgang weggab, blieb ausgeruestet und atmete weiter. Die Besitzpruefung deckt jetzt beides ab. verifyTank heisst verifyGear und gibt { gear, tank } zurueck - fehlt eines von beidem, kommt die Ausruestung ab, mit der passenden Meldung. Umsortieren im Inventar bindet weiterhin nur auf den neuen Slot um. Die Item-Namen stehen jetzt als gearItem/fillItem in config/shared.lua, statt verteilt als Zeichenketten im Server-Code. Co-Authored-By: Claude Opus 5 --- README.md | 1 + client/main.lua | 20 ++++++++++++++------ config/shared.lua | 5 +++++ locales/de.json | 1 + locales/en.json | 1 + server/main.lua | 26 ++++++++++++++++---------- 6 files changed, 38 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index a553fd8..dcd842a 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,7 @@ FiveM* umlegbar. | Option | Default | Bedeutung | |---|---|---| +| `gearItem` / `fillItem` | `diving_gear` / `diving_fill` | Item-Namen für Ausrüstung und Füll-Kartusche | | `tanks` | 5 Flaschen | `name`, `capacity` (Sekunden), `pressure` (bar), `maxDepth` (Meter), `gas` (Label fürs Menü) | | `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 | diff --git a/client/main.lua b/client/main.lua index df3d29c..c5ac1ed 100644 --- a/client/main.lua +++ b/client/main.lua @@ -741,27 +741,35 @@ lib.onCache('ped', function(ped) end end) ---- Die Flasche kann während des Tauchgangs das Inventar verlassen - weggegeben, ---- abgelegt, vom Admin entfernt. Ohne diese Prüfung hielt der Client nur eine ---- Slot-Nummer, die niemand mehr gegenprüfte, und man konnte unbegrenzt +--- Ausrüstung und Flasche können während des Tauchgangs das Inventar verlassen - +--- weggegeben, abgelegt, vom Admin entfernt. Ohne diese Prüfung hielt der Client +--- nur eine Slot-Nummer, die niemand mehr gegenprüfte, und man konnte unbegrenzt --- weitertauchen. ox_inventory feuert bei jeder Änderung, also einmal nachfragen. AddEventHandler('ox_inventory:updateInventory', function() if not currentGear.enabled or not activeTank then return end CreateThread(function() local expected = activeTank - local slot = lib.callback.await('d4rk_divegear:server:verifyTank', false, expected.slot, expected.name) + local result = lib.callback.await('d4rk_divegear:server:verifyGear', false, expected.slot, expected.name) -- Während des Callbacks kann die Ausrüstung schon abgelegt worden sein. if not currentGear.enabled or activeTank ~= expected then return end - if not slot then + if not result then return end + + if not result.gear then + exports.qbx_core:Notify(locale('error.gear_gone'), 'error') + removeGear(true) + return + end + + if not result.tank then exports.qbx_core:Notify(locale('error.tank_gone'), 'error') removeGear(true) return end - activeTank.slot = slot + activeTank.slot = result.tank end) end) diff --git a/config/shared.lua b/config/shared.lua index ca593be..00e682c 100644 --- a/config/shared.lua +++ b/config/shared.lua @@ -26,6 +26,11 @@ local config = { { name = 'diving_tank_trimix', capacity = 900, pressure = 300, maxDepth = 100.0, gas = 'Trimix' }, -- 15 Minuten, tieftauglich }, + --- Item, das die Ausrüstung an- und auszieht, und das Füll-Item. Stehen hier, + --- weil sowohl der Useable-Item-Handler als auch die Besitzprüfung sie brauchen. + gearItem = 'diving_gear', + fillItem = 'diving_fill', + --- 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 diff --git a/locales/de.json b/locales/de.json index f90bd9a..ce2fa74 100644 --- a/locales/de.json +++ b/locales/de.json @@ -9,6 +9,7 @@ "out_of_air": "Deine Luft ist alle! Sofort auftauchen!", "no_lamp_on_outfit": "Deine Tauchausrüstung hat keine Lampe.", "crush_depth": "Lebensgefahr! Ab %d m zerdrückt dich der Wasserdruck.", + "gear_gone": "Deine Tauchausrüstung ist weg!", "tank_gone": "Deine Tauchflasche ist weg!" }, "success": { diff --git a/locales/en.json b/locales/en.json index 24f385f..9e9460d 100644 --- a/locales/en.json +++ b/locales/en.json @@ -9,6 +9,7 @@ "out_of_air": "You're out of air! Surface now!", "no_lamp_on_outfit": "Your diving suit doesn't have a lamp.", "crush_depth": "Danger! Below %d m the water pressure will crush you.", + "gear_gone": "Your diving gear is gone!", "tank_gone": "Your air tank is gone!" }, "success": { diff --git a/server/main.lua b/server/main.lua index 2ccceca..167dfd4 100644 --- a/server/main.lua +++ b/server/main.lua @@ -118,20 +118,26 @@ end lib.callback.register('d4rk_divegear:server:getTanks', getTankList) ---- Prüft, ob der Spieler die getragene Flasche überhaupt noch hat. ---- Ohne das konnte man die Flasche im Tauchgang weggeben und trotzdem ---- weiteratmen - der Client hielt nur eine Slot-Nummer, die niemand mehr prüfte. ---- @return number? slot aktueller Slot, nil wenn die Flasche weg ist -lib.callback.register('d4rk_divegear:server:verifyTank', function(source, slotId, name) +--- Prüft, ob der Spieler Ausrüstung und Flasche überhaupt noch besitzt. +--- Ohne das konnte man beides im Tauchgang weggeben und trotzdem weiteratmen - +--- der Client hielt nur eine Slot-Nummer, die niemand mehr gegenprüfte. +--- @return { gear: boolean, tank: number? } +lib.callback.register('d4rk_divegear:server:verifyGear', function(source, slotId, name) + local gearCount = exports.ox_inventory:Search(source, 'count', shared.gearItem) local slot = getTankSlot(source, slotId) - if slot and slot.name == name then return slotId end + if slot and slot.name == name then + return { gear = (gearCount or 0) > 0, tank = slotId } + end -- Nur umsortiert? Dann dieselbe Flaschensorte woanders im Inventar suchen, -- sonst kostet jedes Verschieben im Inventar die Ausrüstung. local found = shared.tankByName[name] and exports.ox_inventory:Search(source, 'slots', name) - return found and found[1] and found[1].slot or nil + return { + gear = (gearCount or 0) > 0, + tank = found and found[1] and found[1].slot or nil + } end) lib.callback.register('d4rk_divegear:server:syncTank', function(source, slotId, oxygen) @@ -148,11 +154,11 @@ AddEventHandler('playerDropped', function() lastSync[source] = nil end) -exports.qbx_core:CreateUseableItem('diving_gear', function(source) +exports.qbx_core:CreateUseableItem(shared.gearItem, function(source) TriggerClientEvent('d4rk_divegear:client:useGear', source) end) -exports.qbx_core:CreateUseableItem('diving_fill', function(source) +exports.qbx_core:CreateUseableItem(shared.fillItem, function(source) local tanks = getTankList(source) if #tanks == 0 then @@ -169,7 +175,7 @@ exports.qbx_core:CreateUseableItem('diving_fill', function(source) if not slot then return end -- Nach dem Progressbar nochmal prüfen: das Item kann in der Zwischenzeit weg sein. - if not exports.ox_inventory:RemoveItem(source, 'diving_fill', 1) then return end + if not exports.ox_inventory:RemoveItem(source, shared.fillItem, 1) then return end writeTank(source, slot, tankConfig, tankConfig.capacity) lastSync[source] = os.time()