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.
Inventory object with items, slots, and weight infoInventory Structure:
Copy
{ owner = 1, -- Character SID type = "main", -- Inventory type maxSlots = 50, -- Maximum slot count maxWeight = 100, -- Maximum weight items = { -- Items indexed by slot [1] = { name = "water", label = "Water Bottle", count = 5, weight = 0.5, metadata = {} }, [2] = { ... }, -- ... }}
Examples:
Copy
-- Get inventorylocal inventory = COMPONENTS.Inventory:Get(char.SID)if inventory then print('Inventory slots:', inventory.maxSlots) print('Total items:', #inventory.items)end-- Check if inventory existsfunction HasInventory(characterId) return COMPONENTS.Inventory:Get(characterId) ~= nilend-- Get inventory in callbackCOMPONENTS.Callbacks:RegisterServerCallback('inventory:getInventory', 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 inventory = COMPONENTS.Inventory:Get(char:GetData('SID')) cb(true, inventory)end)
-- Delete inventoryCOMPONENTS.Inventory:Delete(char.SID)-- Delete on character deletionAddEventHandler('mythic-characters:server:CharacterDeleted', function(source, characterId) COMPONENTS.Inventory:Delete(characterId)end)
-- Add single itemlocal success, slot = COMPONENTS.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 itemsCOMPONENTS.Inventory:AddItem(char.SID, 'sandwich', 5)-- Add with metadataCOMPONENTS.Inventory:AddItem(char.SID, 'weapon_pistol', 1, { serial = 'ABC123456', durability = 100, ammo = 12})-- Add to specific slotCOMPONENTS.Inventory: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 = COMPONENTS.Items:Get(itemName) if not itemData then return false, 'Invalid item' end -- Add item local stateId = char:GetData('SID') local success, slot = COMPONENTS.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
-- Remove single itemlocal success = COMPONENTS.Inventory:RemoveItem(char.SID, 5, 1)if success then print('Item removed')else print('Failed to remove (slot empty or insufficient quantity)')end-- Remove all items from slotCOMPONENTS.Inventory:RemoveItem(char.SID, 3, 999) -- Removes up to 999-- Remove item by name (find first slot)function RemoveItemByName(characterId, itemName, count) local inventory = COMPONENTS.Inventory:Get(characterId) for slot, item in pairs(inventory.items) do if item.name == itemName then return COMPONENTS.Inventory:RemoveItem(characterId, slot, count) end end return falseend
-- Check if has itemif COMPONENTS.Inventory:HasItem(char.SID, 'water', 1) then print('Has water')else print('No water')end-- Check quantitylocal hasItem, totalCount = COMPONENTS.Inventory:HasItem(char.SID, 'lockpick', 1)print('Has', totalCount, 'lockpicks')-- Require item for actionfunction CanCraftItem(characterId, recipe) for _, ingredient in ipairs(recipe.ingredients) do if not COMPONENTS.Inventory:HasItem(characterId, 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, 'Player not found' end local char = player:GetData('Character') if not char then return false, 'No character' 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 RemoveItemByName(stateId, ingredient.item, ingredient.count) end -- Give crafted item COMPONENTS.Inventory:AddItem(stateId, recipe.result, 1) return trueend
-- Get item in slotlocal item = COMPONENTS.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 callbackCOMPONENTS.Callbacks: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 = COMPONENTS.Inventory:GetItemInSlot(stateId, data.slot) if not item then return cb(false, 'No item in slot') end -- Use item local success = COMPONENTS.Items:Use(source, item) cb(success)end)
-- Get current weightlocal weight = COMPONENTS.Inventory:GetWeight(char.SID)print('Current weight:', weight, 'kg')-- Check if can carry morelocal inventory = COMPONENTS.Inventory:Get(char.SID)local weight = COMPONENTS.Inventory:GetWeight(char.SID)if weight >= inventory.maxWeight then print('Inventory is full (by weight)')end-- Check before adding itemfunction CanAddItem(characterId, itemName, count) local inventory = COMPONENTS.Inventory:Get(characterId) local currentWeight = COMPONENTS.Inventory:GetWeight(characterId) local itemData = COMPONENTS.Items:Get(itemName) local additionalWeight = itemData.weight * count if currentWeight + additionalWeight > inventory.maxWeight then return false, 'Too heavy' end -- Check slot availability local emptySlots = COMPONENTS.Inventory:GetEmptySlots(characterId) if #emptySlots == 0 and not CanStack(characterId, itemName) then return false, 'No empty slots' end return trueend
-- Get empty slotslocal emptySlots = COMPONENTS.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
-- Find itemlocal slot, item = COMPONENTS.Inventory:FindItem(char.SID, 'lockpick')if slot then print('Found lockpick in slot', slot) print('Count:', item.count)else print('No lockpick found')end-- Use first available itemfunction UseFirstOfType(source, itemName) 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 local stateId = char:GetData('SID') local slot, item = COMPONENTS.Inventory:FindItem(stateId, itemName) if not slot then return false, 'Item not found' end -- Use the item COMPONENTS.Items:Use(source, item) -- Remove one COMPONENTS.Inventory:RemoveItem(stateId, slot, 1) return trueend
-- Find all instances of an itemlocal results = COMPONENTS.Inventory:FindAllItems(char.SID, 'water')print('Found water in', #results, 'slots')for _, result in ipairs(results) do print('Slot', result.slot, ':', result.item.count, 'water')end-- Count total across all slotslocal total = 0local results = COMPONENTS.Inventory:FindAllItems(char.SID, 'lockpick')for _, result in ipairs(results) do total = total + result.item.countendprint('Total lockpicks:', total)
local success, slot = COMPONENTS.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
Copy
function SafeAddItem(characterId, itemName, count) local canAdd, error = CanAddItem(characterId, itemName, count) if not canAdd then return false, error end return COMPONENTS.Inventory:AddItem(characterId, itemName, count)end
Use Metadata for Unique Items
Copy
-- Weapons with serial numbersCOMPONENTS.Inventory:AddItem(char.SID, 'weapon_pistol', 1, { serial = GenerateSerial(), durability = 100, ammo = 12, attachments = { 'flashlight', 'suppressor' }})-- Phones with numbersCOMPONENTS.Inventory:AddItem(char.SID, 'phone', 1, { number = char.Phone, contacts = {}, messages = {}})-- ID cardsCOMPONENTS.Inventory: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') local inventory = COMPONENTS.Inventory:Get(stateId) TriggerClientEvent('mythic-inventory:client:SetInventory', source, inventory)end-- Call after add/removelocal stateId = char:GetData('SID')COMPONENTS.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.