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 <noreply@anthropic.com>
This commit is contained in:
@@ -141,6 +141,7 @@ FiveM* umlegbar.
|
|||||||
|
|
||||||
| Option | Default | Bedeutung |
|
| 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ü) |
|
| `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 |
|
| `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 |
|
| `syncIntervalSeconds` | `15` | Wie oft die Restluft an den Server gemeldet wird. Bei einem Crash gehen maximal so viele Sekunden verloren |
|
||||||
|
|||||||
+14
-6
@@ -741,27 +741,35 @@ lib.onCache('ped', function(ped)
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--- Die Flasche kann während des Tauchgangs das Inventar verlassen - weggegeben,
|
--- Ausrüstung und Flasche können während des Tauchgangs das Inventar verlassen -
|
||||||
--- abgelegt, vom Admin entfernt. Ohne diese Prüfung hielt der Client nur eine
|
--- weggegeben, abgelegt, vom Admin entfernt. Ohne diese Prüfung hielt der Client
|
||||||
--- Slot-Nummer, die niemand mehr gegenprüfte, und man konnte unbegrenzt
|
--- nur eine Slot-Nummer, die niemand mehr gegenprüfte, und man konnte unbegrenzt
|
||||||
--- weitertauchen. ox_inventory feuert bei jeder Änderung, also einmal nachfragen.
|
--- weitertauchen. ox_inventory feuert bei jeder Änderung, also einmal nachfragen.
|
||||||
AddEventHandler('ox_inventory:updateInventory', function()
|
AddEventHandler('ox_inventory:updateInventory', function()
|
||||||
if not currentGear.enabled or not activeTank then return end
|
if not currentGear.enabled or not activeTank then return end
|
||||||
|
|
||||||
CreateThread(function()
|
CreateThread(function()
|
||||||
local expected = activeTank
|
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.
|
-- Während des Callbacks kann die Ausrüstung schon abgelegt worden sein.
|
||||||
if not currentGear.enabled or activeTank ~= expected then return end
|
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')
|
exports.qbx_core:Notify(locale('error.tank_gone'), 'error')
|
||||||
removeGear(true)
|
removeGear(true)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
activeTank.slot = slot
|
activeTank.slot = result.tank
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ local config = {
|
|||||||
{ name = 'diving_tank_trimix', capacity = 900, pressure = 300, maxDepth = 100.0, gas = 'Trimix' }, -- 15 Minuten, tieftauglich
|
{ 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
|
--- 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
|
--- 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
|
--- oxygen gesetzt. Auf false muss jede neue Flasche erst mit einer Kartusche
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"out_of_air": "Deine Luft ist alle! Sofort auftauchen!",
|
"out_of_air": "Deine Luft ist alle! Sofort auftauchen!",
|
||||||
"no_lamp_on_outfit": "Deine Tauchausrüstung hat keine Lampe.",
|
"no_lamp_on_outfit": "Deine Tauchausrüstung hat keine Lampe.",
|
||||||
"crush_depth": "Lebensgefahr! Ab %d m zerdrückt dich der Wasserdruck.",
|
"crush_depth": "Lebensgefahr! Ab %d m zerdrückt dich der Wasserdruck.",
|
||||||
|
"gear_gone": "Deine Tauchausrüstung ist weg!",
|
||||||
"tank_gone": "Deine Tauchflasche ist weg!"
|
"tank_gone": "Deine Tauchflasche ist weg!"
|
||||||
},
|
},
|
||||||
"success": {
|
"success": {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"out_of_air": "You're out of air! Surface now!",
|
"out_of_air": "You're out of air! Surface now!",
|
||||||
"no_lamp_on_outfit": "Your diving suit doesn't have a lamp.",
|
"no_lamp_on_outfit": "Your diving suit doesn't have a lamp.",
|
||||||
"crush_depth": "Danger! Below %d m the water pressure will crush you.",
|
"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!"
|
"tank_gone": "Your air tank is gone!"
|
||||||
},
|
},
|
||||||
"success": {
|
"success": {
|
||||||
|
|||||||
+16
-10
@@ -118,20 +118,26 @@ end
|
|||||||
|
|
||||||
lib.callback.register('d4rk_divegear:server:getTanks', getTankList)
|
lib.callback.register('d4rk_divegear:server:getTanks', getTankList)
|
||||||
|
|
||||||
--- Prüft, ob der Spieler die getragene Flasche überhaupt noch hat.
|
--- Prüft, ob der Spieler Ausrüstung und Flasche überhaupt noch besitzt.
|
||||||
--- Ohne das konnte man die Flasche im Tauchgang weggeben und trotzdem
|
--- Ohne das konnte man beides im Tauchgang weggeben und trotzdem weiteratmen -
|
||||||
--- weiteratmen - der Client hielt nur eine Slot-Nummer, die niemand mehr prüfte.
|
--- der Client hielt nur eine Slot-Nummer, die niemand mehr gegenprüfte.
|
||||||
--- @return number? slot aktueller Slot, nil wenn die Flasche weg ist
|
--- @return { gear: boolean, tank: number? }
|
||||||
lib.callback.register('d4rk_divegear:server:verifyTank', function(source, slotId, name)
|
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)
|
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,
|
-- Nur umsortiert? Dann dieselbe Flaschensorte woanders im Inventar suchen,
|
||||||
-- sonst kostet jedes Verschieben im Inventar die Ausrüstung.
|
-- sonst kostet jedes Verschieben im Inventar die Ausrüstung.
|
||||||
local found = shared.tankByName[name] and exports.ox_inventory:Search(source, 'slots', name)
|
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)
|
end)
|
||||||
|
|
||||||
lib.callback.register('d4rk_divegear:server:syncTank', function(source, slotId, oxygen)
|
lib.callback.register('d4rk_divegear:server:syncTank', function(source, slotId, oxygen)
|
||||||
@@ -148,11 +154,11 @@ AddEventHandler('playerDropped', function()
|
|||||||
lastSync[source] = nil
|
lastSync[source] = nil
|
||||||
end)
|
end)
|
||||||
|
|
||||||
exports.qbx_core:CreateUseableItem('diving_gear', function(source)
|
exports.qbx_core:CreateUseableItem(shared.gearItem, function(source)
|
||||||
TriggerClientEvent('d4rk_divegear:client:useGear', source)
|
TriggerClientEvent('d4rk_divegear:client:useGear', source)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
exports.qbx_core:CreateUseableItem('diving_fill', function(source)
|
exports.qbx_core:CreateUseableItem(shared.fillItem, function(source)
|
||||||
local tanks = getTankList(source)
|
local tanks = getTankList(source)
|
||||||
|
|
||||||
if #tanks == 0 then
|
if #tanks == 0 then
|
||||||
@@ -169,7 +175,7 @@ exports.qbx_core:CreateUseableItem('diving_fill', function(source)
|
|||||||
if not slot then return end
|
if not slot then return end
|
||||||
|
|
||||||
-- Nach dem Progressbar nochmal prüfen: das Item kann in der Zwischenzeit weg sein.
|
-- 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)
|
writeTank(source, slot, tankConfig, tankConfig.capacity)
|
||||||
lastSync[source] = os.time()
|
lastSync[source] = os.time()
|
||||||
|
|||||||
Reference in New Issue
Block a user