Inventory management component API for items, slots, and storage
The Inventory component manages character inventories, item storage, weights, and item operations. It’s one of the most complex and frequently used components in Mythic Framework.
-- Get all item counts for a characterlocal counts = Inventory.Items:GetCounts(char:GetData('SID'), 1)for itemName, count in pairs(counts) do print(itemName, ':', count)end
-- Delete inventoryInventory:Delete(char.SID)-- Delete on character deletionAddEventHandler('mythic-characters:server:CharacterDeleted', function(source, characterId) Inventory:Delete(characterId)end)
-- Add single itemlocal success, slot = Inventory:AddItem(char.SID, 'water', 1)if success then print('Added water to slot', slot)else print('Failed to add item (inventory full or no space)')end-- Add multiple itemsInventory:AddItem(char.SID, 'sandwich', 5)-- Add with metadataInventory:AddItem(char.SID, 'weapon_pistol', 1, { serial = 'ABC123456', durability = 100, ammo = 12})-- Add to specific slotInventory:AddItem(char.SID, 'phone', 1, { number = char.Phone}, 1) -- Always in slot 1-- Add item with validationfunction GiveItemToPlayer(source, itemName, count) local player = Fetch:Source(source) if not player then return false, 'Player not found' end local char = player:GetData('Character') if not char then return false, 'No character' end -- Check if item exists local itemData = Items:Get(itemName) if not itemData then return false, 'Invalid item' end -- Add item local stateId = char:GetData('SID') local success, slot = Inventory:AddItem(stateId, itemName, count) if success then -- Notify player TriggerClientEvent('mythic-notifications:client:Send', source, { message = 'Received ' .. count .. 'x ' .. itemData.label, type = 'success' }) return true, slot else TriggerClientEvent('mythic-notifications:client:Send', source, { message = 'Inventory full', type = 'error' }) return false, 'Inventory full' endend
true if inventory has the item in sufficient quantity
Examples:
-- Check if has itemlocal stateId = char:GetData('SID')if Inventory.Items:Has(stateId, 1, 'water', 1) then print('Has water')else print('No water')end-- Require item for actionfunction CanCraftItem(stateId, recipe) for _, ingredient in ipairs(recipe.ingredients) do if not Inventory.Items:Has(stateId, 1, ingredient.item, ingredient.count) then return false, 'Missing ' .. ingredient.item end end return trueend-- Consume items for craftingfunction CraftItem(source, recipeId) local player = Fetch:Source(source) if not player then return false end local char = player:GetData('Character') if not char then return false end local stateId = char:GetData('SID') local recipe = Recipes[recipeId] -- Check has ingredients local canCraft, error = CanCraftItem(stateId, recipe) if not canCraft then return false, error end -- Remove ingredients for _, ingredient in ipairs(recipe.ingredients) do Inventory.Items:Remove(stateId, 1, ingredient.item, ingredient.count) end -- Give crafted item Inventory:AddItem(stateId, recipe.result, 1) return trueend
-- Get item in slotlocal item = Inventory:GetItemInSlot(char.SID, 1)if item then print('Slot 1 contains:', item.label) print('Count:', item.count) print('Weight:', item.weight)else print('Slot 1 is empty')end-- Use item callbackCallbacks:RegisterServerCallback('inventory:useItem', function(source, data, cb) local player = Fetch:Source(source) if not player then return cb(false, 'Player not found') end local char = player:GetData('Character') if not char then return cb(false, 'No character') end local stateId = char:GetData('SID') local item = Inventory:GetItemInSlot(stateId, data.slot) if not item then return cb(false, 'No item in slot') end -- Use item local success = Items:Use(source, item) cb(success)end)
-- Get current weightlocal weight = Inventory:GetWeight(char.SID)print('Current weight:', weight, 'kg')-- Check before adding itemfunction CanAddItem(characterId, itemName, count) local currentWeight = Inventory:GetWeight(characterId) local itemData = Items:Get(itemName) local additionalWeight = itemData.weight * count if currentWeight + additionalWeight > inventory.maxWeight then return false, 'Too heavy' end -- Check slot availability local emptySlots = Inventory:GetEmptySlots(characterId) if #emptySlots == 0 and not CanStack(characterId, itemName) then return false, 'No empty slots' end return trueend
-- Get empty slotslocal emptySlots = Inventory:GetEmptySlots(char.SID)print('Empty slots:', #emptySlots)for _, slot in ipairs(emptySlots) do print('Slot', slot, 'is empty')end-- Check if fullif #emptySlots == 0 then print('Inventory is full')end
local success, slot = Inventory:AddItem(char.SID, 'water', 1)if success then print('Item added to slot', slot) -- Notify player TriggerClientEvent('notify', source, 'Item added')else print('Failed to add item') TriggerClientEvent('notify', source, 'Inventory full')end
Check Weight Before Adding
function SafeAddItem(characterId, itemName, count) local canAdd, error = CanAddItem(characterId, itemName, count) if not canAdd then return false, error end return Inventory:AddItem(characterId, itemName, count)end
Use Metadata for Unique Items
-- Weapons with serial numbersInventory:AddItem(char.SID, 'weapon_pistol', 1, { serial = GenerateSerial(), durability = 100, ammo = 12, attachments = { 'flashlight', 'suppressor' }})-- Phones with numbersInventory:AddItem(char.SID, 'phone', 1, { number = char.Phone, contacts = {}, messages = {}})-- ID cardsInventory:AddItem(char.SID, 'id_card', 1, { name = char.First .. ' ' .. char.Last, dob = char.DOB, photo = 'url_to_photo'})
-- After inventory changes, update clientfunction UpdateInventoryUI(source) local player = Fetch:Source(source) if not player then return end local char = player:GetData('Character') if not char then return end local stateId = char:GetData('SID') -- The inventory UI is automatically synced by the Inventory componentend-- Call after add/removelocal stateId = char:GetData('SID')Inventory:AddItem(stateId, 'water', 1)UpdateInventoryUI(source)
Performance Tip: Inventory operations update the database. For bulk operations (giving many items at once), consider batching updates or using transactions where possible.