Server Events
All inventory events fire on the server-side.Item Operations
Added, Removed, Moved, Swapped
Item Usage
Used, Equipped, Dropped
Inventory State
Created, Deleted, Updated
Validation
Pre-operation validation hooks
Item Operation Events
mythic-inventory:server:ItemAdded
Fired when an item is successfully added to an inventory.AddEventHandler('mythic-inventory:server:ItemAdded', function(characterId, itemName, count, slot, metadata)
-- Handler code
end)
number
Character SID who received the item
string
Item identifier (e.g., ‘water’, ‘weapon_pistol’)
number
Quantity added
number
Slot number where item was added
table
Item metadata (can be empty table)
-- Log item additions
AddEventHandler('mythic-inventory:server:ItemAdded', function(characterId, itemName, count, slot, metadata)
Logger:Info('Inventory', 'Item added', {
console = true,
file = true
}, {
character = characterId,
item = itemName,
count = count,
slot = slot
})
end)
-- Track weapon distribution
AddEventHandler('mythic-inventory:server:ItemAdded', function(characterId, itemName, count, slot, metadata)
if string.match(itemName, '^weapon_') then
-- Log weapon given
Database.Game:insertOne({
collection = 'weapon_logs',
document = {
character = characterId,
weapon = itemName,
serial = metadata.serial,
action = 'added',
timestamp = os.time()
}
})
-- Notify admins
Logger:Info('Weapons', 'Weapon distributed', {
console = true,
file = true,
discord = true
}, {
character = characterId,
weapon = itemName,
serial = metadata.serial
})
end
end)
-- Update client inventory UI
AddEventHandler('mythic-inventory:server:ItemAdded', function(characterId, itemName, count, slot, metadata)
local player = Fetch:SID(characterId)
if player then
local source = player:GetData('Source')
local inventory = Inventory.Items:GetCounts(characterId, 1)
TriggerClientEvent('mythic-inventory:client:SetInventory', source, inventory)
-- Show notification
local itemData = Items:Get(itemName)
TriggerClientEvent('mythic-notifications:client:Send', source, {
message = 'Received ' .. count .. 'x ' .. itemData.label,
type = 'success'
})
end
end)
-- Achievement tracking
AddEventHandler('mythic-inventory:server:ItemAdded', function(characterId, itemName, count, slot, metadata)
if itemName == 'rare_diamond' then
Achievements:Unlock(characterId, 'found_diamond')
end
end)
mythic-inventory:server:ItemRemoved
Fired when an item is removed from an inventory.AddEventHandler('mythic-inventory:server:ItemRemoved', function(characterId, itemName, count, slot)
-- Handler code
end)
number
Character SID
string
Item identifier
number
Quantity removed
number
Slot number item was removed from
-- Log item removals
AddEventHandler('mythic-inventory:server:ItemRemoved', function(characterId, itemName, count, slot)
Logger:Info('Inventory', 'Item removed', {
console = true,
file = true
}, {
character = characterId,
item = itemName,
count = count,
slot = slot
})
end)
-- Track consumable usage
AddEventHandler('mythic-inventory:server:ItemRemoved', function(characterId, itemName, count, slot)
local consumables = { 'water', 'sandwich', 'burger', 'cola' }
if table.contains(consumables, itemName) then
-- Update consumption stats
Characters:UpdateCharacter(characterId, {
['metadata.stats.consumed'] = (char.metadata.stats.consumed or 0) + count
})
end
end)
-- Notify on weapon removal
AddEventHandler('mythic-inventory:server:ItemRemoved', function(characterId, itemName, count, slot)
if string.match(itemName, '^weapon_') then
local player = Fetch:SID(characterId)
if player then
local source = player:GetData('Source')
TriggerClientEvent('mythic-weapons:client:RemoveWeapon', source, itemName)
end
end
end)
mythic-inventory:server:ItemUsed
Fired when a player uses an item.AddEventHandler('mythic-inventory:server:ItemUsed', function(source, characterId, itemName, slot, metadata)
-- Handler code
end)
number
Player server ID who used the item
number
Character SID
string
Item identifier
number
Slot the item was used from
table
Item metadata
-- Handle item usage
AddEventHandler('mythic-inventory:server:ItemUsed', function(source, characterId, itemName, slot, metadata)
if itemName == 'water' then
-- Restore thirst
Characters:UpdateCharacter(characterId, {
['metadata.needs.thirst'] = 100
})
-- Remove item
Inventory.Items:Remove(characterId, 1, itemName, 1)
-- Notify
TriggerClientEvent('mythic-notifications:client:Send', source, {
message = 'You drank water',
type = 'success'
})
elseif itemName == 'medkit' then
-- Heal player
TriggerClientEvent('mythic-medical:client:Heal', source, 100)
-- Remove item
Inventory.Items:Remove(characterId, 1, itemName, 1)
elseif itemName == 'lockpick' then
-- Start lockpicking minigame
TriggerClientEvent('mythic-lockpick:client:Start', source, function(success)
if not success then
-- Break lockpick on failure
Inventory.Items:Remove(characterId, 1, itemName, 1)
end
end)
end
end)
-- Log usage
AddEventHandler('mythic-inventory:server:ItemUsed', function(source, characterId, itemName, slot, metadata)
Logger:Info('Items', 'Item used', {
console = true,
file = true
}, {
player = source,
character = characterId,
item = itemName
})
end)
-- Track drug usage
AddEventHandler('mythic-inventory:server:ItemUsed', function(source, characterId, itemName, slot, metadata)
local drugs = { 'weed_joint', 'cocaine', 'meth' }
if table.contains(drugs, itemName) then
-- Track in character metadata
Characters:UpdateCharacter(characterId, {
['metadata.stats.drugsUsed'] = (char.metadata.stats.drugsUsed or 0) + 1
})
-- Police can detect
TriggerEvent('mythic-police:server:DrugActivityDetected', source, itemName)
end
end)
mythic-inventory:server:ItemMoved
Fired when an item is moved from one slot to another.AddEventHandler('mythic-inventory:server:ItemMoved', function(characterId, fromSlot, toSlot, itemName, count)
-- Handler code
end)
number
Character SID
number
Source slot number
number
Destination slot number
string
Item identifier
number
Quantity moved
-- Update client on move
AddEventHandler('mythic-inventory:server:ItemMoved', function(characterId, fromSlot, toSlot, itemName, count)
local player = Fetch:SID(characterId)
if player then
local source = player:GetData('Source')
local inventory = Inventory.Items:GetCounts(characterId, 1)
TriggerClientEvent('mythic-inventory:client:SetInventory', source, inventory)
end
end)
-- Log suspicious rapid movements (anti-cheat)
local moveTracking = {}
AddEventHandler('mythic-inventory:server:ItemMoved', function(characterId, fromSlot, toSlot, itemName, count)
moveTracking[characterId] = moveTracking[characterId] or { count = 0, lastMove = 0 }
local now = os.time()
if now - moveTracking[characterId].lastMove < 1 then
moveTracking[characterId].count = moveTracking[characterId].count + 1
if moveTracking[characterId].count > 10 then
-- Suspicious activity
Logger:Warn('AntiCheat', 'Rapid inventory movements', {
console = true,
file = true,
discord = true
}, {
character = characterId,
moves = moveTracking[characterId].count
})
end
else
moveTracking[characterId].count = 0
end
moveTracking[characterId].lastMove = now
end)
Item Transfer Events
mythic-inventory:server:ItemGiven
Fired when an item is given from one player to another.AddEventHandler('mythic-inventory:server:ItemGiven', function(fromCharacterId, toCharacterId, itemName, count)
-- Handler code
end)
number
Character SID of giver
number
Character SID of receiver
string
Item identifier
number
Quantity given
-- Log trades between players
AddEventHandler('mythic-inventory:server:ItemGiven', function(fromCharacterId, toCharacterId, itemName, count)
Logger:Info('Trading', 'Item given', {
console = true,
file = true
}, {
from = fromCharacterId,
to = toCharacterId,
item = itemName,
count = count
})
-- Insert trade log
Database.Game:insertOne({
collection = 'trades',
document = {
from = fromCharacterId,
to = toCharacterId,
item = itemName,
count = count,
timestamp = os.time()
}
})
end)
-- Prevent weapon trading
AddEventHandler('mythic-inventory:server:ItemGiven', function(fromCharacterId, toCharacterId, itemName, count)
if string.match(itemName, '^weapon_') then
local fromPlayer = Fetch:SID(fromCharacterId)
-- Block weapon trades
Logger:Warn('Trading', 'Attempted weapon trade', {
console = true,
file = true
}, {
from = fromCharacterId,
to = toCharacterId,
weapon = itemName
})
if fromPlayer then
local fromSource = fromPlayer:GetData('Source')
TriggerClientEvent('mythic-notifications:client:Send', fromSource, {
message = 'Weapons cannot be traded',
type = 'error'
})
end
-- Cancel the trade
return false
end
end)
-- Track drug distribution
AddEventHandler('mythic-inventory:server:ItemGiven', function(fromCharacterId, toCharacterId, itemName, count)
local drugs = { 'weed', 'cocaine', 'meth' }
if table.contains(drugs, itemName) then
-- Track dealer activity
Characters:UpdateCharacter(fromCharacterId, {
['metadata.stats.drugsDealt'] = (char.metadata.stats.drugsDealt or 0) + count
})
-- Police can track distribution networks
TriggerEvent('mythic-police:server:DrugDistributionDetected', fromCharacterId, toCharacterId, itemName, count)
end
end)
mythic-inventory:server:ItemDropped
Fired when a player drops an item on the ground.AddEventHandler('mythic-inventory:server:ItemDropped', function(source, characterId, itemName, count, coords)
-- Handler code
end)
number
Player server ID
number
Character SID
string
Item identifier
number
Quantity dropped
table
Drop location
{x, y, z}-- Create world item
AddEventHandler('mythic-inventory:server:ItemDropped', function(source, characterId, itemName, count, coords)
-- Create pickup in the world
local pickup = WorldItems:Create(itemName, count, coords)
-- Notify nearby players
TriggerClientEvent('mythic-inventory:client:ItemDropped', -1, {
item = itemName,
count = count,
coords = coords,
pickupId = pickup.id
})
-- Auto-delete after 5 minutes
SetTimeout(300000, function()
WorldItems:Delete(pickup.id)
end)
end)
-- Log weapon drops
AddEventHandler('mythic-inventory:server:ItemDropped', function(source, characterId, itemName, count, coords)
if string.match(itemName, '^weapon_') then
Logger:Info('Weapons', 'Weapon dropped', {
console = true,
file = true
}, {
character = characterId,
weapon = itemName,
location = coords
})
end
end)
-- Prevent dropping certain items
AddEventHandler('mythic-inventory:server:ItemDropped', function(source, characterId, itemName, count, coords)
local noDropItems = { 'id_card', 'driver_license', 'phone' }
if table.contains(noDropItems, itemName) then
TriggerClientEvent('mythic-notifications:client:Send', source, {
message = 'You cannot drop this item',
type = 'error'
})
-- Cancel drop
return false
end
end)
Inventory State Events
mythic-inventory:server:InventoryCreated
Fired when a new inventory is created.AddEventHandler('mythic-inventory:server:InventoryCreated', function(characterId, inventory)
-- Handler code
end)
AddEventHandler('mythic-inventory:server:InventoryCreated', function(characterId, inventory)
Logger:Info('Inventory', 'Inventory created', {
console = true,
file = true
}, {
character = characterId,
maxSlots = inventory.maxSlots,
maxWeight = inventory.maxWeight
})
end)
mythic-inventory:server:InventoryOpened
Fired when a player opens their inventory UI.AddEventHandler('mythic-inventory:server:InventoryOpened', function(source, characterId)
-- Handler code
end)
-- Send fresh inventory data
AddEventHandler('mythic-inventory:server:InventoryOpened', function(source, characterId)
local inventory = Inventory.Items:GetCounts(characterId, 1)
TriggerClientEvent('mythic-inventory:client:SetInventory', source, inventory)
end)
-- Track inventory usage
AddEventHandler('mythic-inventory:server:InventoryOpened', function(source, characterId)
Characters:UpdateCharacter(characterId, {
['metadata.stats.inventoryOpened'] = (char.metadata.stats.inventoryOpened or 0) + 1
})
end)
Client Events
mythic-inventory:client:UpdateInventory
Sent from server to update client inventory UI.AddEventHandler('mythic-inventory:client:UpdateInventory', function(inventory)
-- Handler code
end)
-- Update React UI
AddEventHandler('mythic-inventory:client:UpdateInventory', function(inventory)
SendNUIMessage({
type = 'SET_INVENTORY',
inventory = inventory
})
end)
mythic-inventory:client:ItemUsed
Sent to client when an item is used (for client-side effects).AddEventHandler('mythic-inventory:client:ItemUsed', function(itemName, metadata)
-- Handler code
end)
-- Play animations/effects
AddEventHandler('mythic-inventory:client:ItemUsed', function(itemName, metadata)
local ped = PlayerPedId()
if itemName == 'water' then
-- Play drinking animation
TaskStartScenarioInPlace(ped, 'WORLD_HUMAN_DRINKING', 0, true)
Wait(3000)
ClearPedTasks(ped)
elseif itemName == 'sandwich' then
-- Play eating animation
TaskStartScenarioInPlace(ped, 'WORLD_HUMAN_SEAT_WALL_EATING', 0, true)
Wait(5000)
ClearPedTasks(ped)
elseif itemName == 'phone' then
-- Open phone UI
TriggerEvent('mythic-phone:client:Open')
end
end)
Using Events for Custom Logic
Custom Item Effects
-- Server: Handle custom consumable
AddEventHandler('mythic-inventory:server:ItemUsed', function(source, characterId, itemName, slot, metadata)
if itemName == 'energy_drink' then
-- Restore energy
Characters:UpdateCharacter(characterId, {
['metadata.needs.energy'] = 100
})
-- Give temporary speed boost
TriggerClientEvent('mythic-effects:client:SpeedBoost', source, 30000) -- 30 seconds
-- Remove item
Inventory.Items:Remove(characterId, 1, itemName, 1)
-- Notify
TriggerClientEvent('mythic-notifications:client:Send', source, {
message = 'You feel energized!',
type = 'success'
})
end
end)
-- Client: Apply speed boost
AddEventHandler('mythic-effects:client:SpeedBoost', function(duration)
local ped = PlayerPedId()
SetPedMoveRateOverride(ped, 1.3) -- 30% faster
SetTimeout(duration, function()
SetPedMoveRateOverride(ped, 1.0) -- Back to normal
end)
end)
Inventory Logging System
-- Comprehensive inventory audit log
local function LogInventoryAction(action, characterId, details)
Database.Game:insertOne({
collection = 'inventory_logs',
document = {
action = action,
character = characterId,
details = details,
timestamp = os.time()
}
})
end
AddEventHandler('mythic-inventory:server:ItemAdded', function(characterId, itemName, count, slot, metadata)
LogInventoryAction('item_added', characterId, {
item = itemName,
count = count,
slot = slot
})
end)
AddEventHandler('mythic-inventory:server:ItemRemoved', function(characterId, itemName, count, slot)
LogInventoryAction('item_removed', characterId, {
item = itemName,
count = count,
slot = slot
})
end)
AddEventHandler('mythic-inventory:server:ItemGiven', function(fromCharacterId, toCharacterId, itemName, count)
LogInventoryAction('item_given', fromCharacterId, {
to = toCharacterId,
item = itemName,
count = count
})
end)
Anti-Cheat Integration
-- Track suspicious inventory operations
local suspiciousActivity = {}
AddEventHandler('mythic-inventory:server:ItemAdded', function(characterId, itemName, count, slot, metadata)
-- Flag large item additions
if count > 100 then
local player = Fetch:SID(characterId)
Logger:Warn('AntiCheat', 'Large item addition', {
console = true,
file = true,
discord = true
}, {
character = characterId,
item = itemName,
count = count
})
suspiciousActivity[characterId] = (suspiciousActivity[characterId] or 0) + 1
if suspiciousActivity[characterId] > 3 and player then
-- Automatic kick/ban
local source = player:GetData('Source')
Punishment:Ban(source, 'Inventory manipulation', 7) -- 7 day ban
end
end
end)
Best Practices
Validate Event Data
Validate Event Data
AddEventHandler('mythic-inventory:server:ItemUsed', function(source, characterId, itemName, slot, metadata)
-- Validate character
local player = Fetch:SID(characterId)
if not player then
return
end
local char = player:GetData('Character')
if not char then
return
end
-- Validate item exists
local item = Items:Get(itemName)
if not item then
Logger:Warn('Inventory', 'Invalid item used', {
console = true,
file = true
}, {
character = characterId,
item = itemName
})
return
end
-- Validate slot
local slotItem = Inventory:GetItemInSlot(characterId, slot)
if not slotItem or slotItem.name ~= itemName then
return
end
-- Process usage
end)
Update Client After Changes
Update Client After Changes
AddEventHandler('mythic-inventory:server:ItemAdded', function(characterId, itemName, count, slot, metadata)
local player = Fetch:SID(characterId)
if player then
local source = player:GetData('Source')
local inventory = Inventory.Items:GetCounts(characterId, 1)
TriggerClientEvent('mythic-inventory:client:UpdateInventory', source, inventory)
end
end)
Clean Up Tracking Data
Clean Up Tracking Data
local eventTracking = {}
AddEventHandler('playerDropped', function()
local player = Fetch:Source(source)
if player then
local char = player:GetData('Character')
if char then
eventTracking[char:GetData('SID')] = nil
end
end
end)
Next Steps
Inventory - Exports
Inventory management methods
Inventory - Item Definition
Item data structure
Characters Events
Character-related events
Event System
Understanding events
Event Order: Inventory events fire in a specific sequence. For example, when an item is used,
ItemUsed fires first, then if the item is consumed, ItemRemoved fires. Use this to your advantage when chaining logic.