Inventar-System (cv_inventory)¶
React/NUI-Inventar mit Slots, Gewichtslimit, Waffenslots und optionalem Sekundär-Container (Camper-Lager, Truhe).
Architektur¶
cv_inventory
├─ NUI (React) – Slot-Grid, Drag & Drop, Waffenrad-Zuweisung
└─ Server (Lua)
├─ BuildInventoryPayload(charId) – Haupt-Inventar aufbauen
├─ BuildContainerInventoryPayload(id) – Container aufbauen
├─ GetActiveSecondaryContainer(source) – aktiver Sekundär-Container
└─ Events / Callbacks für Slot-Operationen
Inventar öffnen¶
Das Inventar wird über einen Tastendruck geöffnet (Standard: I). Der Client sendet cv_inventory:requestInventory an den Server, der das komplette Payload zurückschickt:
Server → Client: 'cv_inventory:updateInventory'
Payload:
{
slots – { [slotNr] = slotPayload }
weight – aktuelles Gewicht
maxWeight – maximales Gewicht
maxSlots – maximale Slot-Anzahl
weaponSlots – { [slotType] = weaponData }
weaponSlotsConfig
secondary? – { slots, weight, maxWeight, maxSlots, containerId, title }
}
Framework-Exports (verwendet intern)¶
Die eigentliche Inventar-Logik liegt im cv_framework und wird über Exports aufgerufen:
-- Inventar eines Charakters lesen
exports["cv_framework"]:GetCharacterInventory(charId) -- → item[]
-- Einzelnen Slot lesen
exports["cv_framework"]:GetSlotItem(charId, slot) -- → { item_name, quantity, slot, ... }
-- Item zu Inventar hinzufügen
cv.inventory.addItem(charId, itemName, quantity, metadata) -- → boolean
-- Item entfernen
cv.inventory.removeItem(charId, itemName, quantity) -- → boolean
-- Prüfen ob Item vorhanden
cv.inventory.hasItem(charId, itemName, quantity) -- → boolean
-- Platz prüfen (Gewicht + Slots)
cv.inventory.canAddItem(charId, itemName, quantity) -- → boolean, reason
-- Slot-Payload bauen (für NUI-Darstellung)
exports["cv_framework"]:BuildSlotPayload(itemName, { quantity, durability, metadata }, slot)
-- Gewichts-/Slot-Limit
exports["cv_framework"]:GetInventoryMaxWeight() -- → number
exports["cv_framework"]:GetInventoryDefaultSlotCount() -- → number
Container (Lager / Truhen)¶
Ein Sekundär-Container kann parallel zum Spieler-Inventar geöffnet werden:
-- Container-Inventar lesen
exports["cv_framework"]:GetContainerInventory(containerId) -- → item[]
-- Container konfigurieren (z.B. beim Erstellen)
exports["cv_framework"]:GetCustomInventoryConfig(containerId)
-- → { maxWeight, maxSlots, containerType, ... }
-- Items in Container
cv.inventory.addContainerItem(containerId, containerType, itemName, qty, metadata)
cv.inventory.removeContainerItem(containerId, itemName, qty)
cv.inventory.hasContainerItem(containerId, itemName, qty)
cv.inventory.canAddContainerItem(containerId, itemName, qty)
cv.inventory.getContainerSlotItem(containerId, slot)
Sekundär-Context setzen (Server-Event)¶
-- Aus anderer Ressource: Öffnet Container als zweites Inventar-Panel
TriggerClientEvent('cv_inventory:setSecondaryContext', source, {
type = 'custom', -- 'custom', 'vehicle_trunk', ...
containerId = 'mein-container-id',
title = 'WERKZEUGKISTE'
})
-- Context wieder entfernen
TriggerClientEvent('cv_inventory:clearSecondaryContext', source)
-- oder Server-Event:
TriggerServerEvent('cv_inventory:clearSecondaryContext')
Waffenslots¶
Waffen können in bis zu 3 dedizierten Slots (Holster) eingetragen werden:
-- Waffenslots eines Charakters lesen
exports["cv_framework"]:GetCharacterWeaponSlots(charId)
-- → { [slotType] = { itemName, ammo, durability, inventorySlot, metadata } }
-- Waffe einem Slot zuweisen
exports["cv_framework"]:AssignWeaponToSlot(source, slotType, inventorySlot)
-- Waffe aus Slot entfernen
exports["cv_framework"]:RemoveWeaponFromSlot(source, slotType, restoreToInventory)
-- Munition speichern
exports["cv_framework"]:SaveAllWeaponSlotAmmo(charId, source)
-- Status
exports["cv_framework"]:IsWeaponSlotsEnabled() -- → boolean
exports["cv_framework"]:GetWeaponSlotsConfig() -- → table
Munitions-Sync: Der Client sendet periodisch cv:server:SyncWeaponAmmo { [slotType] = ammo }. Der Server akzeptiert nur gleiche oder niedrigere Werte (verhindert Cheating).
Exports aus cv_inventory¶
-- Camper/Instanzlager direkt befüllen (aus anderen Ressourcen)
exports['cv_inventory']:StoreItemInPlayerInstanceInventory(playerSource, itemName, amount)
-- → boolean, errorMessage
-- Item aus Camper/Instanzlager nehmen
exports['cv_inventory']:TakeItemFromPlayerInstanceInventory(playerSource, itemName, amount)
-- → boolean, errorMessage
-- Waffenslots für Charakter deaktivieren (temporär, bis Relog)
exports['cv_inventory']:DisableWeaponSlots(charId)
exports['cv_inventory']:EnableWeaponSlots(charId)
exports['cv_inventory']:IsWeaponSlotsDisabled(charId) -- → boolean
-- Container-Payload für externe NUI bauen
exports['cv_inventory']:BuildContainerInventoryPayload(containerId)
Relevante Events¶
| Event | Richtung | Beschreibung |
|---|---|---|
cv_inventory:requestInventory |
Client → Server | Inventar laden |
cv_inventory:updateInventory |
Server → Client | Inventar-Payload senden |
cv_inventory:setSecondaryContext |
Client → Server | Sekundär-Container setzen |
cv_inventory:clearSecondaryContext |
Client → Server | Sekundär-Container entfernen |
cv:server:SwapSecondaryInventorySlots |
Client → Server | Slots im Container tauschen |
cv:server:MoveBetweenInventories |
Client → Server | Item zwischen Inventar und Container verschieben |
cv:server:AssignWeaponSlot |
Client → Server | Waffe einem Waffenslot zuweisen |
cv:server:RemoveWeaponSlot |
Client → Server | Waffe aus Waffenslot entfernen |
cv:server:SyncWeaponAmmo |
Client → Server | Munitionsstand synchronisieren |
cv:client:SyncWeaponWheel |
Server → Client | Waffenrad-Status senden |