feat: Flasche und Maske als Kleidung, Patronen tauschen, HUD-Anmeldung
- Tauchgeraet bereit = Taucherflasche (rigItem, Slot 31) mit Patrone UND Maske (maskItem, Slot 29) angezogen; Server getWorn statt verifyGear, geprueft bei jeder Inventaraenderung und nach jedem Umziehen. Props, diving_gear und der Anzieh-Balken entfallen. - Die fuenf Flaschen sind Patronen: benutzen = in die getragene Flasche einsetzen, die alte kommt mit Restluft zurueck (patroneTauschen). - Faeden mit Laufnummer, damit ein Tausch sie nicht verdoppelt. - exports.ox_inventory -> exports.d4rk_inventory, Meldungen ueber lib.notify (meldung_shared) und d4rk_bridge:Notify. - Konsole beim HUD angemeldet (client/hud.lua), 366 x 165 bei 1080p gemessen; ohne HUD bleibt die CSS-Position. - Nachfuellen (diving_fill) stillgelegt: kommt spaeter ueber Shop/Crafting. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
930ff6381f
commit
e64a1bd3d0
9 files changed
+401
-214
No files matched your search
+121
-27
@@ -26,7 +26,7 @@ end
|
||||
local function getTankSlot(source, slotId)
|
||||
if type(slotId) ~= 'number' then return end
|
||||
|
||||
local slot = exports.ox_inventory:GetSlot(source, slotId)
|
||||
local slot = exports.d4rk_inventory:GetSlot(source, slotId)
|
||||
|
||||
if not slot then return end
|
||||
|
||||
@@ -37,6 +37,19 @@ local function getTankSlot(source, slotId)
|
||||
return slot, tankConfig
|
||||
end
|
||||
|
||||
--- Die getragene Taucherflasche (Kleidung, shared.rigSlot) und die Patrone darin.
|
||||
--- @return table? slot nil = keine Flasche angezogen
|
||||
--- @return table? tankConfig nil = keine (gueltige) Patrone eingesetzt
|
||||
local function getRig(source)
|
||||
local slot = exports.d4rk_inventory:GetSlot(source, shared.rigSlot)
|
||||
|
||||
if not slot or slot.name ~= shared.rigItem then return nil end
|
||||
|
||||
local patrone = slot.metadata and slot.metadata.patrone
|
||||
|
||||
return slot, patrone and shared.tankByName[patrone] or nil
|
||||
end
|
||||
|
||||
--- Schreibt die Restluft in die Metadata.
|
||||
--- SetMetadata *ersetzt* die Metadata-Tabelle komplett (modules/inventory/server.lua),
|
||||
--- deshalb wird der bestehende Inhalt kopiert statt nur oxygen gesetzt.
|
||||
@@ -55,7 +68,7 @@ local function writeTank(source, slot, tankConfig, oxygen)
|
||||
-- Items, sonst würde ox_inventory die leere Flasche löschen (items/server.lua).
|
||||
metadata.durability = math.floor(oxygen / tankConfig.capacity * 100)
|
||||
|
||||
exports.ox_inventory:SetMetadata(source, slot.slot, metadata)
|
||||
exports.d4rk_inventory:SetMetadata(source, slot.slot, metadata)
|
||||
|
||||
return oxygen
|
||||
end
|
||||
@@ -64,7 +77,7 @@ end
|
||||
--- @param source number
|
||||
--- @return table[]
|
||||
local function getTankList(source)
|
||||
local found = exports.ox_inventory:Search(source, 'slots', shared.tankNames)
|
||||
local found = exports.d4rk_inventory:Search(source, 'slots', shared.tankNames)
|
||||
local tanks = {}
|
||||
|
||||
for i = 1, #shared.tankNames do
|
||||
@@ -79,7 +92,7 @@ local function getTankList(source)
|
||||
tanks[#tanks + 1] = {
|
||||
slot = slot.slot,
|
||||
name = name,
|
||||
label = (exports.ox_inventory:Items(name) or {}).label or name,
|
||||
label = (exports.d4rk_inventory:Items(name) or {}).label or name,
|
||||
oxygen = readOxygen(slot, tankConfig),
|
||||
capacity = tankConfig.capacity,
|
||||
pressure = tankConfig.pressure,
|
||||
@@ -99,9 +112,11 @@ local function syncTank(source, slotId, oxygen)
|
||||
|
||||
if not oxygen then return end
|
||||
|
||||
local slot, tankConfig = getTankSlot(source, slotId)
|
||||
-- Seit 28.09.2026 steckt die Luft in der GETRAGENEN Flasche (Kleidung);
|
||||
-- slotId bleibt im Aufruf, zaehlt aber nicht mehr.
|
||||
local slot, tankConfig = getRig(source)
|
||||
|
||||
if not slot then return end
|
||||
if not slot or not tankConfig then return end
|
||||
|
||||
local current = readOxygen(slot, tankConfig)
|
||||
local now = os.time()
|
||||
@@ -118,28 +133,102 @@ end
|
||||
|
||||
lib.callback.register('d4rk_divegear:server:getTanks', getTankList)
|
||||
|
||||
--- 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)
|
||||
--[[
|
||||
WAS TRAEGT ER? - 28.09.2026, ersetzt verifyGear.
|
||||
|
||||
if slot and slot.name == name then
|
||||
return { gear = (gearCount or 0) > 0, tank = slotId }
|
||||
end
|
||||
Flasche (rigSlot) UND Maske (maskSlot) angezogen, und in der Flasche eine
|
||||
Patrone. Die Antwort nennt den Grund, wenn etwas fehlt - der Client fragt
|
||||
bei jeder Inventaraenderung, und "keine Maske" ist etwas anderes als "keine
|
||||
Patrone".
|
||||
]]
|
||||
lib.callback.register('d4rk_divegear:server:getWorn', function(source)
|
||||
local rig, tankConfig = getRig(source)
|
||||
|
||||
-- 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)
|
||||
if not rig then return { ok = false, grund = 'keine_flasche' } end
|
||||
|
||||
local maske = exports.d4rk_inventory:GetSlot(source, shared.maskSlot)
|
||||
|
||||
if not maske or maske.name ~= shared.maskItem then return { ok = false, grund = 'keine_maske' } end
|
||||
if not tankConfig then return { ok = false, grund = 'keine_patrone' } end
|
||||
|
||||
local patrone = rig.metadata.patrone
|
||||
|
||||
return {
|
||||
gear = (gearCount or 0) > 0,
|
||||
tank = found and found[1] and found[1].slot or nil
|
||||
ok = true,
|
||||
tank = {
|
||||
slot = rig.slot,
|
||||
name = patrone,
|
||||
label = (exports.d4rk_inventory:Items(patrone) or {}).label or patrone,
|
||||
oxygen = readOxygen(rig, tankConfig),
|
||||
capacity = tankConfig.capacity,
|
||||
pressure = tankConfig.pressure,
|
||||
maxDepth = tankConfig.maxDepth,
|
||||
gas = tankConfig.gas,
|
||||
},
|
||||
}
|
||||
end)
|
||||
|
||||
--[[
|
||||
PATRONE TAUSCHEN - 28.09.2026. Die benutzte Patrone wandert in die
|
||||
getragene Flasche, die alte kommt mit ihrer Restluft als Item zurueck.
|
||||
|
||||
REIHENFOLGE: erst pruefen, ob die alte Patrone ueberhaupt Platz hat, dann
|
||||
die neue nehmen, dann die alte geben - scheitert das Geben, bekommt der
|
||||
Spieler die neue zurueck. Zuletzt die Flasche beschreiben (Metadata
|
||||
KOPIEREN, SetMetadata ersetzt die ganze Tabelle - ENTSCHEIDUNGEN.md).
|
||||
]]
|
||||
lib.callback.register('d4rk_divegear:server:patroneTauschen', function(source, cartSlot)
|
||||
cartSlot = math.tointeger(tonumber(cartSlot))
|
||||
|
||||
if not cartSlot or cartSlot == shared.rigSlot then return false, 'ungueltig' end
|
||||
|
||||
local cart, cartConfig = getTankSlot(source, cartSlot)
|
||||
|
||||
if not cart then return false, 'keine_patrone_im_slot' end
|
||||
|
||||
local rig, altConfig = getRig(source)
|
||||
|
||||
if not rig then return false, 'keine_flasche' end
|
||||
|
||||
local altName = rig.metadata and rig.metadata.patrone
|
||||
local altLuft = altConfig and readOxygen(rig, altConfig) or nil
|
||||
|
||||
if altConfig and not exports.d4rk_inventory:CanCarryItem(source, altName, 1) then
|
||||
return false, 'kein_platz'
|
||||
end
|
||||
|
||||
local neuLuft = readOxygen(cart, cartConfig)
|
||||
|
||||
if not exports.d4rk_inventory:RemoveItem(source, cart.name, 1, nil, cartSlot) then
|
||||
return false, 'fehler'
|
||||
end
|
||||
|
||||
if altConfig then
|
||||
local meta = {
|
||||
oxygen = math.floor(altLuft),
|
||||
durability = math.floor(altLuft / altConfig.capacity * 100),
|
||||
}
|
||||
|
||||
if not exports.d4rk_inventory:AddItem(source, altName, 1, meta) then
|
||||
exports.d4rk_inventory:AddItem(source, cart.name, 1, cart.metadata)
|
||||
return false, 'kein_platz'
|
||||
end
|
||||
end
|
||||
|
||||
local meta = {}
|
||||
|
||||
for key, value in pairs(rig.metadata or {}) do meta[key] = value end
|
||||
|
||||
meta.patrone = cart.name
|
||||
meta.oxygen = math.floor(neuLuft)
|
||||
meta.durability = math.floor(neuLuft / cartConfig.capacity * 100)
|
||||
|
||||
exports.d4rk_inventory:SetMetadata(source, rig.slot, meta)
|
||||
lastSync[source] = os.time()
|
||||
|
||||
return true
|
||||
end)
|
||||
|
||||
lib.callback.register('d4rk_divegear:server:syncTank', function(source, slotId, oxygen)
|
||||
return syncTank(source, slotId, oxygen)
|
||||
end)
|
||||
@@ -154,15 +243,20 @@ AddEventHandler('playerDropped', function()
|
||||
lastSync[source] = nil
|
||||
end)
|
||||
|
||||
exports.qbx_core:CreateUseableItem(shared.gearItem, function(source)
|
||||
TriggerClientEvent('d4rk_divegear:client:useGear', source)
|
||||
end)
|
||||
-- Eine Patrone benutzen = sie in die getragene Flasche einsetzen (28.09.2026).
|
||||
-- d4rk_inventory ruft den Rueckruf mit den Itemdaten samt Slot
|
||||
-- (modules/bridge/qbx/server.lua: cb(source, data)).
|
||||
for i = 1, #shared.tankNames do
|
||||
exports.qbx_core:CreateUseableItem(shared.tankNames[i], function(source, data)
|
||||
TriggerClientEvent('d4rk_divegear:client:patroneEinsetzen', source, data and data.slot)
|
||||
end)
|
||||
end
|
||||
|
||||
exports.qbx_core:CreateUseableItem(shared.fillItem, function(source)
|
||||
local tanks = getTankList(source)
|
||||
|
||||
if #tanks == 0 then
|
||||
exports.qbx_core:Notify(source, locale('error.no_tank'), 'error')
|
||||
exports.d4rk_bridge:Notify(source, locale('error.no_tank'), 'error')
|
||||
return
|
||||
end
|
||||
|
||||
@@ -175,12 +269,12 @@ exports.qbx_core:CreateUseableItem(shared.fillItem, 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, shared.fillItem, 1) then return end
|
||||
if not exports.d4rk_inventory:RemoveItem(source, shared.fillItem, 1) then return end
|
||||
|
||||
writeTank(source, slot, tankConfig, tankConfig.capacity)
|
||||
lastSync[source] = os.time()
|
||||
|
||||
-- Erst melden wenn das Item tatsächlich weg und die Flasche voll ist.
|
||||
exports.qbx_core:Notify(source, locale('success.tube_filled'), 'success')
|
||||
exports.d4rk_bridge:Notify(source, locale('success.tube_filled'), 'success')
|
||||
TriggerClientEvent('d4rk_divegear:client:tankRefilled', source, slot.slot, tankConfig.capacity)
|
||||
end)
|
||||
Reference in new issue
Block a user