Skip to content

Server-Side Hooks

Server-side hook system for the Lilia framework.


Overview

Server-side hooks in the Lilia framework handle server-side logic, data persistence, permissions, character management, and other server-specific functionality. They follow the Garry's Mod hook system and can be overridden or extended by addons and modules.


AddWarning(charID, warned, warnedSteamID, timestamp, message, warner, warnerSteamID, severity)

Records a warning entry for a character and lets modules react to the new warning.

Fired whenever a warning is issued via admin commands, anti-cheat triggers, or net requests.

Parameters:

number|string charID Character database identifier being warned.

string warned Display name of the warned player.

string warnedSteamID SteamID of the warned player.

number timestamp Unix timestamp when the warning was created.

string message Reason text for the warning.

string warner Name of the admin or system issuing the warning.

string warnerSteamID SteamID of the issuer.

string severity Severity label such as Low/Medium/High.

Returns:

string Final severity value chosen (if modified) or nil.

Example Usage:

    hook.Add("AddWarning", "LogWarning", function(charID, warned, warnedSteamID, timestamp, message, warner, warnerSteamID, severity)
        lia.log.add(warner, "warningIssued", warned, severity, message)
    end)

CollectDoorDataFields(extras)

Collect additional field definitions for door data.

When retrieving default door values and field definitions.

Parameters:

table extras Table to populate with additional field definitions in the format {fieldName = {default = value, ...}}.

Example Usage:

    hook.Add("CollectDoorDataFields", "ExampleCollectDoorDataFields", function(extras)
        extras.customField = {default = false, type = "boolean"}
    end)

CanItemBeTransfered(item, inventory, VendorInventoryMeasure, client)

Determines if an item move is allowed before completing a transfer between inventories.

Checked whenever an item is about to be moved to another inventory (including vendors).

Parameters:

Item item Item instance being transferred.

Inventory inventory Destination inventory.

boolean VendorInventoryMeasure True when the transfer originates from a vendor panel.

Player client Player requesting the transfer.

Returns:

boolean False to block the transfer; nil/true to allow.

Example Usage:

    hook.Add("CanItemBeTransfered", "LimitAmmoMoves", function(item, inventory, isVendor, client)
        if isVendor and item.isWeapon then return false end
    end)

CanPersistEntity(entity)

Decides if an entity should be recorded in the persistence system.

Invoked while scanning entities for persistence during map saves.

Parameters:

Entity entity The world entity being evaluated.

Returns:

boolean False to skip saving this entity; nil/true to include it.

Example Usage:

    hook.Add("CanPersistEntity", "IgnoreRagdolls", function(ent)
        if ent:IsRagdoll() then return false end
    end)

CanPlayerAccessDoor(client, door, access)

Lets modules override door access checks before built-in permissions are evaluated.

Queried whenever door access is validated in entity:checkDoorAccess.

Parameters:

Player client Player requesting access.

Entity door Door entity being checked.

number access Required access level (e.g., DOOR_OWNER, DOOR_TENANT, DOOR_GUEST).

Returns:

boolean True to grant access regardless of stored permissions; nil to fall back to defaults.

Example Usage:

    hook.Add("CanPlayerAccessDoor", "StaffOverrideDoor", function(client, door)
        if client:isStaffOnDuty() then return true end
    end)

CanPlayerAccessVendor(client, vendor)

Allows or denies a player opening/using a vendor entity.

Checked when a player attempts to access a vendor UI.

Parameters:

Player client Player interacting with the vendor.

Entity vendor Vendor entity being accessed.

Returns:

boolean False to block interaction; true/nil to allow.

Example Usage:

    hook.Add("CanPlayerAccessVendor", "FactionLockVendors", function(client, vendor)
        if not vendor:isFactionAllowed(client:Team()) then return false end
    end)

CanPlayerDropItem(client, item)

Controls whether a player may drop a specific item from their inventory.

Triggered before an item drop is performed.

Parameters:

Player client Player attempting to drop the item.

Item item Item instance being dropped.

Returns:

boolean False to block the drop; true/nil to permit.

Example Usage:

    hook.Add("CanPlayerDropItem", "NoQuestItemDrops", function(client, item)
        if item.isQuestItem then return false end
    end)

CanPlayerEarnSalary(client)

Checks whether a player is eligible to receive their periodic salary.

Evaluated each time salary is about to be granted.

Parameters:

Player client Player due to receive salary.

Returns:

boolean False to block salary payment; true/nil to allow.

Example Usage:

    hook.Add("CanPlayerEarnSalary", "JailedNoSalary", function(client)
        if client:isJailed() then return false end
    end)

CanPlayerEquipItem(client, item)

Decides if a player is allowed to equip a given item.

Checked before the equip logic for any item runs.

Parameters:

Player client Player equipping the item.

Item item Item instance being equipped.

Returns:

boolean False to prevent equipping; true/nil to allow.

Example Usage:

    hook.Add("CanPlayerEquipItem", "RestrictHeavyArmor", function(client, item)
        if item.weight and item.weight > 20 then return false end
    end)

CanPlayerHoldObject(client, entity)

Allows or blocks a player from picking up physics objects with their hands tool.

Checked before a player grabs an entity with lia_hands.

Parameters:

Player client Player attempting to hold the object.

Entity entity Target entity being picked up.

Returns:

boolean False to prevent picking up; true/nil to allow.

Example Usage:

    hook.Add("CanPlayerHoldObject", "NoHoldingDoors", function(client, ent)
        if ent:isDoor() then return false end
    end)

CanPlayerInteractItem(client, action, item, data)

Lets modules validate or modify player item interactions (use, drop, split, etc.).

Fired before an inventory action runs on an item.

Parameters:

Player client Player performing the action.

string action Interaction verb such as "drop", "combine", or a custom action ID.

Item item Item instance being interacted with.

table data Extra data supplied by the action (position, merge target, etc.).

Returns:

boolean, string False or false,reason to block; true/nil to allow.

Example Usage:

    hook.Add("CanPlayerInteractItem", "StopHotbarDrop", function(client, action, item)
        if action == "drop" and item.noDrop then return false, L("cannotDrop") end
    end)

CanPlayerLock(client, door)

Decides if a player may lock a door or vehicle using provided access rights.

Evaluated before lock attempts are processed.

Parameters:

Player client Player performing the lock.

Entity door Door or vehicle entity targeted.

Returns:

boolean False to prevent locking; true/nil to allow.

Example Usage:

    hook.Add("CanPlayerLock", "OnlyOwnersLock", function(client, door)
        if not door:checkDoorAccess(client, DOOR_OWNER) then return false end
    end)

CanPlayerSeeLogCategory(client, category)

Controls visibility of specific log categories to a player.

Checked before sending a log entry or opening the log viewer.

Parameters:

Player client Player requesting or receiving logs.

string category Category identifier of the log.

Returns:

boolean False to hide the category; true/nil to show.

Example Usage:

    hook.Add("CanPlayerSeeLogCategory", "HideAdminLogs", function(client, category)
        if category == "admin" and not client:isStaffOnDuty() then return false end
    end)

CanPlayerSpawnStorage(client, entity, info)

Determines whether a player is permitted to spawn a storage entity.

Invoked when a storage deploy action is requested.

Parameters:

Player client Player spawning the storage.

Entity entity Storage entity class about to be created.

table info Context info such as item data or position.

Returns:

boolean False to block spawning; true/nil to allow.

Example Usage:

    hook.Add("CanPlayerSpawnStorage", "LimitStoragePerPlayer", function(client, entity)
        if client:GetCount("lia_storage") >= 2 then return false end
    end)

CanPlayerSwitchChar(client, currentCharacter, newCharacter)

Validates whether a player may switch from their current character to another.

Checked when a player initiates a character switch.

Parameters:

Player client Player requesting the swap.

Character currentCharacter Active character.

Character newCharacter Target character to switch to.

Returns:

boolean False to deny the swap; true/nil to allow.

Example Usage:

    hook.Add("CanPlayerSwitchChar", "BlockDuringCombat", function(client)
        if client:isInCombat() then return false end
    end)

CanPlayerTakeItem(client, item)

Checks if a player may take an item out of a container or ground entity.

Fired before item pickup/move from a world/container inventory.

Parameters:

Player client Player attempting to take the item.

Item item Item instance being taken.

Returns:

boolean False to block taking; true/nil to allow.

Example Usage:

    hook.Add("CanPlayerTakeItem", "LockdownLooting", function(client, item)
        if lia.state.isLockdown() then return false end
    end)

CanPlayerTradeWithVendor(client, vendor, itemType, isSellingToVendor)

Approves or denies a vendor transaction before money/items exchange.

Invoked when a player tries to buy from or sell to a vendor.

Parameters:

Player client Player trading with the vendor.

Entity vendor Vendor entity.

string itemType UniqueID of the item being traded.

boolean isSellingToVendor True when the player sells an item to the vendor.

Returns:

boolean, string, any False,reason to cancel; true/nil to allow. Optional third param for formatted message data.

Example Usage:

    hook.Add("CanPlayerTradeWithVendor", "RestrictRareItems", function(client, vendor, itemType)
        if lia.item.list[itemType].rarity == "legendary" and not client:isVIP() then
            return false, L("vendorVIPOnly")
        end
    end)

CanPlayerUnequipItem(client, item)

Decides if a player may unequip an item currently worn/active.

Checked before unequip logic runs.

Parameters:

Player client Player requesting to unequip.

Item item Item being unequipped.

Returns:

boolean False to block; true/nil to allow.

Example Usage:

    hook.Add("CanPlayerUnequipItem", "PreventCombatUnequip", function(client, item)
        if client:isInCombat() then return false end
    end)

CanPlayerUnlock(client, door)

Decides if a player can unlock a door or vehicle.

Evaluated before unlock attempts are processed.

Parameters:

Player client Player performing the unlock.

Entity door Door or vehicle entity targeted.

Returns:

boolean False to block unlocking; true/nil to allow.

Example Usage:

    hook.Add("CanPlayerUnlock", "OnlyOwnersUnlock", function(client, door)
        if not door:checkDoorAccess(client, DOOR_OWNER) then return false end
    end)

CanPlayerUseChar(client, character)

Validates that a player can use/load a given character record.

Checked before spawning the character into the world.

Parameters:

Player client Player requesting to use the character.

Character character Character record being selected.

Returns:

boolean False to prevent selection; true/nil to allow.

Example Usage:

    hook.Add("CanPlayerUseChar", "BanSpecificChar", function(client, character)
        if character:getData("locked") then return false end
    end)

CanPlayerUseDoor(client, door)

Final gate before a player uses a door (open, interact).

Fired when a player attempts to use a door entity.

Parameters:

Player client Player using the door.

Entity door Door entity being used.

Returns:

boolean False to deny use; true/nil to allow.

Example Usage:

    hook.Add("CanPlayerUseDoor", "LockdownUse", function(client, door)
        if lia.state.isLockdown() then return false end
    end)

CanSaveData(ent, inventory)

Decides if an entity's data should be included when saving persistent map state.

During persistence save routines.

Parameters:

Entity ent Entity being evaluated for save.

Inventory inventory Inventory attached to the entity (if any).

Returns:

boolean False to skip saving; true/nil to save.

Example Usage:

    hook.Add("CanSaveData", "SkipTempProps", function(ent)
        if ent.tempSpawned then return false end
    end)

CreateSalaryTimers()

Called when salary timers need to be created or recreated.

During server initialization and when salary timers need to be reset.

Example Usage:

    hook.Add("CreateSalaryTimers", "ExampleCreateSalaryTimers", function(...)
        -- add custom server-side behavior
    end)

CharCleanUp(character)

Provides a cleanup hook when a character is fully removed from the server.

After character deletion/cleanup logic runs.

Parameters:

Character character Character object being cleaned up.

Example Usage:

    hook.Add("CharCleanUp", "RemoveCharTimers", function(character)
        timer.Remove("char_timer_" .. character:getID())
    end)

CharDeleted(client, character)

Notifies that a character has been removed from the database and game.

After a character is deleted by the player or admin.

Parameters:

Player client Player who owned the character (may be nil if offline).

Character character The character that was deleted.

Example Usage:

    hook.Add("CharDeleted", "LogDeletion", function(client, character)
        lia.log.add(client, "charDeleted", character:getName())
    end)

CharListExtraDetails(client, entry, stored)

Adds extra per-character info to the character selection list entry.

While building the char list shown to the client.

Parameters:

Player client Player viewing the list.

table entry Table of character info to be sent.

table stored Raw character data from storage.

Returns:

table Optionally return modified entry data.

Example Usage:

    hook.Add("CharListExtraDetails", "AddPlaytime", function(client, entry, stored)
        entry.playtime = stored.playtime or 0
        return entry
    end)

CharPostSave(character)

Runs after a character has been saved to persistence.

Immediately after character data write completes.

Parameters:

Character character Character that was saved.

Example Usage:

    hook.Add("CharPostSave", "QueueBackup", function(character)
        lia.backup.queue(character:getID())
    end)

CharPreSave(character)

Pre-save hook for characters to sync state into the database payload.

Right before character data is persisted.

Parameters:

Character character Character about to be saved.

Example Usage:

    hook.Add("CharPreSave", "StoreTempAmmo", function(character)
        local client = character:getPlayer()
        if IsValid(client) then character:setData("ammo", client:GetAmmo()) end
    end)

CheckFactionLimitReached(faction, character, client)

Allows factions to enforce population limits before creation/join.

Checked when a player attempts to create or switch to a faction.

Parameters:

table faction Faction definition table.

Character character Character requesting the faction.

Player client Player owning the character.

Returns:

boolean False to block joining; true/nil to allow.

Example Usage:

    hook.Add("CheckFactionLimitReached", "CapCombine", function(faction)
        if faction.uniqueID == "combine" and faction:onlineCount() >= 10 then return false end
    end)

DatabaseConnected()

Signals that the database connection is established and ready.

Once the SQL connection succeeds during initialization.

Example Usage:

    hook.Add("DatabaseConnected", "InitPlugins", function()
        lia.plugin.loadAll()
    end)

DiscordRelaySend(embed)

Allows modules to intercept and modify Discord relay embeds before sending.

Right before an embed is pushed to the Discord relay webhook.

Parameters:

table embed Table describing the Discord embed payload.

Returns:

table Optionally return a modified embed.

Example Usage:

    hook.Add("DiscordRelaySend", "AddFooter", function(embed)
        embed.footer = {text = "Lilia Relay"}
        return embed
    end)

DiscordRelayUnavailable()

Notifies the game that the Discord relay feature became unavailable.

Triggered when the relay HTTP endpoint cannot be reached or is disabled.

Example Usage:

    hook.Add("DiscordRelayUnavailable", "AlertStaff", function()
        lia.log.add(nil, "discordRelayDown")
    end)

DiscordRelayed(embed)

Fired after a Discord relay message has been successfully sent.

Immediately after the relay HTTP request completes.

Parameters:

table embed Embed table that was sent.

Example Usage:

    hook.Add("DiscordRelayed", "TrackRelayCount", function(embed)
        lia.metrics.bump("discordRelay")
    end)

DoorEnabledToggled(client, door, newState)

Signals that a door's enabled/disabled state has been toggled.

After admin tools enable or disable door ownership/usage.

Parameters:

Player client Player who toggled the state.

Entity door Door entity affected.

boolean newState True when enabled, false when disabled.

Example Usage:

    hook.Add("DoorEnabledToggled", "AnnounceToggle", function(client, door, state)
        lia.log.add(client, "doorEnabledToggle", tostring(state))
    end)

DoorHiddenToggled(client, entity, newState)

Signals that a door has been hidden or unhidden from ownership.

After the hidden flag is toggled for a door entity.

Parameters:

Player client Player performing the change.

Entity entity Door entity affected.

boolean newState True when hidden, false when shown.

Example Usage:

    hook.Add("DoorHiddenToggled", "MirrorToClients", function(_, door, state)
        net.Start("liaDoorHidden") net.WriteEntity(door) net.WriteBool(state) net.Broadcast()
    end)

DoorLockToggled(client, door, state)

Fired when a door lock state is toggled (locked/unlocked).

After lock/unlock succeeds via key or command.

Parameters:

Player client Player who toggled the lock.

Entity door Door entity.

boolean state True if now locked.

Example Usage:

    hook.Add("DoorLockToggled", "SoundDoorLock", function(_, door, state)
        door:EmitSound(state and "doors/door_latch3.wav" or "doors/door_latch1.wav")
    end)

DoorOwnableToggled(client, door, newState)

Signals that a door has been marked ownable or unownable.

After toggling door ownership availability.

Parameters:

Player client Player performing the toggle.

Entity door Door entity affected.

boolean newState True when ownable.

Example Usage:

    hook.Add("DoorOwnableToggled", "SyncOwnableState", function(_, door, state)
        net.Start("liaDoorOwnable") net.WriteEntity(door) net.WriteBool(state) net.Broadcast()
    end)

DoorPriceSet(client, door, price)

Fired when a door purchase price is changed.

After a player sets a new door price via management tools.

Parameters:

Player client Player setting the price.

Entity door Door entity.

number price New purchase price.

Example Usage:

    hook.Add("DoorPriceSet", "LogDoorPrice", function(client, door, price)
        lia.log.add(client, "doorPriceSet", price)
    end)

DoorTitleSet(client, door, name)

Fired when a door's title/name is changed.

After a player renames a door via the interface or command.

Parameters:

Player client Player setting the title.

Entity door Door entity.

string name New door title.

Example Usage:

    hook.Add("DoorTitleSet", "SaveDoorTitle", function(client, door, name)
        door:setNetVar("doorTitle", name)
    end)

FetchSpawns()

Requests the server spawn list; gives modules a chance to override or inject spawns.

When spawn points are being loaded or refreshed.

Returns:

table Custom spawn data table or nil to use defaults.

Example Usage:

    hook.Add("FetchSpawns", "UseCustomSpawns", function()
        return lia.spawns.getCustom()
    end)

GetAllCaseClaims()

Returns a list of all active support tickets claimed by staff.

When the ticket system needs to display open claims.

Returns:

table Array of ticket claim data.

Example Usage:

    hook.Add("GetAllCaseClaims", "MirrorTickets", function()
        return lia.ticket.getClaims()
    end)

GetBotModel(client, faction)

Provides the model to use for spawning a bot player given a faction.

During bot setup when choosing a model.

Parameters:

Player client Bot player entity.

table faction Faction data assigned to the bot.

Returns:

string Model path to use for the bot.

Example Usage:

    hook.Add("GetBotModel", "RandomCitizenModel", function(client, faction)
        if faction.uniqueID == "citizen" then return "models/Humans/Group01/male_07.mdl" end
    end)

GetDamageScale(hitgroup, dmgInfo, damageScale)

Lets modules adjust the final damage scale applied to a hitgroup.

During ScalePlayerDamage after base scaling has been calculated.

Parameters:

number hitgroup Hitgroup constant from the damage trace.

CTakeDamageInfo dmgInfo Damage info object.

number damageScale Current scale value about to be applied.

Returns:

number New scale value to apply or nil to keep current.

Example Usage:

    hook.Add("GetDamageScale", "HelmetProtection", function(hitgroup, dmgInfo, scale)
        if hitgroup == HITGROUP_HEAD and dmgInfo:IsBulletDamage() then return scale * 0.5 end
    end)

GetDefaultInventoryType(character)

Specifies which inventory type to create for a character by default.

During character creation and bot setup before inventories are instanced.

Parameters:

Character character Character being initialized (may be nil for bots).

Returns:

string Inventory type ID (e.g., "GridInv").

Example Usage:

    hook.Add("GetDefaultInventoryType", "UseListInventory", function(character)
        return "ListInv"
    end)

GetEntitySaveData(ent)

Provides custom data to persist for an entity.

While serializing entities for persistence saves.

Parameters:

Entity ent Entity being saved.

Returns:

table Data table to store or nil for none.

Example Usage:

    hook.Add("GetEntitySaveData", "SaveHealth", function(ent)
        return {health = ent:Health()}
    end)

GetOOCDelay(speaker)

Allows modules to set or modify the OOC chat cooldown for a speaker.

Each time an OOC message is about to be sent.

Parameters:

Player speaker Player sending the OOC message.

Returns:

number Cooldown in seconds, or nil to use config default.

Example Usage:

    hook.Add("GetOOCDelay", "VIPShorterCooldown", function(speaker)
        if speaker:isVIP() then return 5 end
    end)

GetPlayTime(client)

Override or calculate a player's tracked playtime value.

When playtime is requested for display or logic.

Parameters:

Player client Player whose playtime is queried.

Returns:

number Seconds of playtime.

Example Usage:

    hook.Add("GetPlayTime", "CustomPlaytime", function(client)
        return client:getChar():getData("customPlaytime", 0)
    end)

GetPlayerDeathSound(client, isFemale)

Supplies the death sound file to play for a player.

During PlayerDeath when death sounds are enabled.

Parameters:

Player client Player who died.

boolean isFemale Gender flag.

Returns:

string Sound path to emit.

Example Usage:

    hook.Add("GetPlayerDeathSound", "FactionDeathSounds", function(client)
        if client:Team() == FACTION_CP then return "npc/metropolice/pain1.wav" end
    end)

GetPlayerPainSound(paintype, isFemale, client)

Provides the pain sound to play for a hurt entity.

During damage processing when selecting pain sounds.

Parameters:

string paintype Pain type identifier ("hurt", etc.).

boolean isFemale Gender flag.

Entity client Entity that is hurt.

Returns:

string Sound path to emit, or nil to use default.

Example Usage:

    hook.Add("GetPlayerPainSound", "RobotPain", function(client, paintype)
        if client:IsPlayer() and client:IsCombine() then return "npc/combine_soldier/pain1.wav" end
    end)

GetPlayerRespawnLocation(client, character)

Selects where a player should respawn after death.

During respawn processing to determine the spawn location.

Parameters:

Player client Player respawning.

Character character Character data of the player.

Returns:

vector, angle Position and angle for the respawn; nil to use default.

Example Usage:

    hook.Add("GetPlayerRespawnLocation", "HospitalRespawn", function(client)
        return lia.spawns.getHospitalPos(), lia.spawns.getHospitalAng()
    end)

GetPlayerSpawnLocation(client, character)

Chooses the spawn location for a player when initially joining the server.

During first spawn/character load to position the player.

Parameters:

Player client Player spawning.

Character character Character data of the player.

Returns:

vector, angle Position and angle; nil to use map spawns.

Example Usage:

    hook.Add("GetPlayerSpawnLocation", "FactionSpawns", function(client, character)
        return lia.spawns.getFactionSpawn(character:getFaction())
    end)

GetPrestigePayBonus(client, char, pay, faction, class)

Allows adjusting the salary amount using a prestige bonus.

Each time salary is calculated for a character.

Parameters:

Player client Player receiving salary.

Character char Character data.

number pay Current salary amount.

table faction Faction definition.

table class Class definition (if any).

Returns:

number Modified pay amount or nil to keep.

Example Usage:

    hook.Add("GetPrestigePayBonus", "PrestigeScaling", function(client, char, pay)
        return pay + (char:getData("prestigeLevel", 0) * 50)
    end)

GetSalaryAmount(client, faction, class)

Provides the base salary amount for a player based on faction/class.

Whenever salary is being computed for payout.

Parameters:

Player client Player receiving salary.

table faction Faction definition.

table class Class definition (may be nil).

Returns:

number Salary amount.

Example Usage:

    hook.Add("GetSalaryAmount", "VIPSalary", function(client, faction, class)
        if client:isVIP() then return 500 end
    end)

GetTicketsByRequester(steamID)

Retrieves all ticket entries made by a specific requester SteamID.

During ticket queries filtered by requester.

Parameters:

string steamID SteamID64 or SteamID of the requester.

Returns:

table List of ticket rows.

Example Usage:

    hook.Add("GetTicketsByRequester", "MaskRequester", function(steamID)
        return lia.tickets.byRequester(steamID)
    end)

GetWarnings(charID)

Fetches all warnings stored for a character ID.

When viewing a character's warning history.

Parameters:

number|string charID Character database identifier.

Returns:

table Array of warning rows.

Example Usage:

    hook.Add("GetWarnings", "MirrorWarnings", function(charID)
        return lia.warn.get(charID)
    end)

GetWarningsByIssuer(steamID)

Retrieves warnings issued by a specific SteamID.

When filtering warnings by issuing admin.

Parameters:

string steamID SteamID of the issuer.

Returns:

table Array of warning rows.

Example Usage:

    hook.Add("GetWarningsByIssuer", "ListIssuerWarnings", function(steamID)
        return lia.warn.getByIssuer(steamID)
    end)

HandleItemTransferRequest(client, itemID, x, y, invID)

Handles the server-side logic when a client requests to move an item.

When the inventory UI sends a transfer request.

Parameters:

Player client Player requesting the transfer.

number|string itemID Item instance identifier.

number x Target X slot.

number y Target Y slot.

number|string invID Destination inventory ID.

Example Usage:

    hook.Add("HandleItemTransferRequest", "LogTransfers", function(client, itemID, x, y, invID)
        lia.log.add(client, "itemMove", itemID, invID, x, y)
    end)

InventoryDeleted(instance)

Notifies that an inventory has been removed or destroyed.

After an inventory instance is deleted.

Parameters:

Inventory instance Inventory object that was removed.

Example Usage:

    hook.Add("InventoryDeleted", "CleanupInvCache", function(instance)
        lia.inventory.cache[instance:getID()] = nil
    end)

ItemCombine(client, item, target)

Fired when a player combines an item with another (stacking or crafting).

After the combine action has been requested.

Parameters:

Player client Player performing the combine.

Item item Primary item.

Item target Target item being combined into.

Returns:

boolean False to block the combine; true/nil to allow.

Example Usage:

    hook.Add("ItemCombine", "BlockCertainCombines", function(client, item, target)
        if target.noCombine then return false end
    end)

ItemDeleted(instance)

Notifies that an item instance has been deleted from storage.

Immediately after an item is removed from persistence.

Parameters:

Item instance Item instance that was deleted.

Example Usage:

    hook.Add("ItemDeleted", "LogItemDelete", function(instance)
        lia.log.add(nil, "itemDeleted", instance.uniqueID)
    end)

ItemFunctionCalled(item, method, client, entity, results)

Called whenever an item method is executed so modules can react or modify results.

After an item function such as OnUse or custom actions is invoked.

Parameters:

Item item Item instance whose method was called.

string method Name of the method invoked.

Player client Player who triggered the call.

Entity entity Entity representation if applicable.

table results Return values from the method.

Example Usage:

    hook.Add("ItemFunctionCalled", "AuditItemUse", function(item, method, client)
        lia.log.add(client, "itemFunction", item.uniqueID, method)
    end)

ItemTransfered(context)

Fires after an item has been successfully transferred between inventories.

Right after a transfer completes.

Parameters:

table context Transfer context containing client, item, from, and to inventories.

Example Usage:

    hook.Add("ItemTransfered", "NotifyTransfer", function(context)
        lia.log.add(context.client, "itemTransferred", context.item.uniqueID)
    end)

KeyLock(client, door, time)

Allows overriding the key lock timing or behavior when using key items.

When a player uses a key to lock a door for a set duration.

Parameters:

Player client Player locking.

Entity door Door entity.

number time Duration of the lock action.

Example Usage:

    hook.Add("KeyLock", "InstantLock", function(client, door)
        door:Fire("lock")
        return false
    end)

KeyUnlock(client, door, time)

Allows overriding key-based unlock timing or behavior.

When a player uses a key to unlock a door for a duration.

Parameters:

Player client Player unlocking.

Entity door Door entity.

number time Duration for unlock action.

Example Usage:

    hook.Add("KeyUnlock", "InstantUnlock", function(client, door)
        door:Fire("unlock")
        return false
    end)

KickedFromChar(characterID, isCurrentChar)

Fired when a character is kicked from the session and forced to select another.

After the character kick is processed.

Parameters:

number characterID ID of the character kicked.

boolean isCurrentChar True if it was the active character at time of kick.

Example Usage:

    hook.Add("KickedFromChar", "LogCharKick", function(characterID, wasCurrent)
        lia.log.add(nil, "charKicked", characterID, wasCurrent)
    end)

LiliaTablesLoaded()

Indicates that all Lilia database tables have been created/loaded.

After tables are created during startup.

Example Usage:

    hook.Add("LiliaTablesLoaded", "SeedDefaults", function()
        lia.seed.run()
    end)

LoadData()

Allows modules to inject data when the gamemode performs a data load.

During server startup after initial load begins.

Example Usage:

    hook.Add("LoadData", "LoadCustomData", function()
        lia.data.loadCustom()
    end)

ModifyCharacterModel(arg1, character)

Lets modules change the model chosen for a character before it is set.

During character creation or model updates.

Parameters:

any arg1 Context value (varies by caller).

Character character Character being modified.

Returns:

string Model path override or nil to keep current.

Example Usage:

    hook.Add("ModifyCharacterModel", "ForceFactionModel", function(_, character)
        if character:getFaction() == FACTION_STAFF then return "models/player/police_fem.mdl" end
    end)

OnCharAttribBoosted(client, character, attribID, boostID, arg5)

Notifies when an attribute boost is applied to a character.

After lia.attrib has boosted an attribute.

Parameters:

Player client Player whose character was boosted.

Character character Character receiving the boost.

string|number attribID Attribute identifier.

string boostID Boost source identifier.

any arg5 Additional data supplied by the boost.

Example Usage:

    hook.Add("OnCharAttribBoosted", "LogBoost", function(client, character, attribID, boostID)
        lia.log.add(client, "attribBoosted", attribID, boostID)
    end)

OnCharAttribUpdated(client, character, key, arg4)

Notifies that a character attribute value has been updated.

After attribute points are changed.

Parameters:

Player client Player whose character changed.

Character character Character object.

string|number key Attribute identifier.

any arg4 Old value.

Example Usage:

    hook.Add("OnCharAttribUpdated", "SyncAttrib", function(client, character, key, oldValue)
        lia.log.add(client, "attribUpdated", key, oldValue, character:getAttrib(key))
    end)

OnCharCreated(client, character, originalData)

Signals that a new character has been created.

Immediately after character creation succeeds.

Parameters:

Player client Player who created the character.

Character character New character object.

table originalData Raw creation data submitted.

Example Usage:

    hook.Add("OnCharCreated", "WelcomeMessage", function(client, character)
        client:notifyLocalized("charCreated", character:getName())
    end)

OnCharDelete(client, id)

Invoked just before a character is deleted from persistence.

Right before deletion is executed.

Parameters:

Player client Player requesting deletion.

number id Character ID to delete.

Example Usage:

    hook.Add("OnCharDelete", "BackupChar", function(client, id)
        lia.backup.character(id)
    end)

OnCharDisconnect(client, character)

Called when a player disconnects while owning a character.

Immediately after the player leaves the server.

Parameters:

Player client Player who disconnected.

Character character Character they had active.

Example Usage:

    hook.Add("OnCharDisconnect", "SaveOnLeave", function(client, character)
        character:save()
    end)

OnCharFlagsGiven(ply, character, addedFlags)

Notifies that flags have been granted to a character.

After permanent or session flags are added.

Parameters:

Player ply Player whose character received flags.

Character character Character instance.

string addedFlags Flags added.

Example Usage:

    hook.Add("OnCharFlagsGiven", "LogFlagGrant", function(ply, character, addedFlags)
        lia.log.add(ply, "flagsGiven", addedFlags)
    end)

OnCharFlagsTaken(ply, character, removedFlags)

Notifies that flags have been removed from a character.

After flag removal occurs.

Parameters:

Player ply Player whose character lost flags.

Character character Character affected.

string removedFlags Flags removed.

Example Usage:

    hook.Add("OnCharFlagsTaken", "LogFlagRemoval", function(ply, character, removedFlags)
        lia.log.add(ply, "flagsTaken", removedFlags)
    end)

OnCharKick(character, client)

Runs when a character is kicked out of the game or forced to menu.

After kicking logic completes.

Parameters:

Character character Character that was kicked.

Player client Player owning the character (may be nil).

Example Usage:

    hook.Add("OnCharKick", "LogCharKick", function(character, client)
        lia.log.add(client, "charKicked", character:getName())
    end)

OnCharNetVarChanged(character, key, oldVar, value)

Fired when a character networked variable changes.

Whenever character:setNetVar updates a value.

Parameters:

Character character Character whose var changed.

string key Net var key.

any oldVar Previous value.

any value New value.

Example Usage:

    hook.Add("OnCharNetVarChanged", "TrackWantedState", function(character, key, old, value)
        if key == "wanted" then lia.log.add(nil, "wantedToggle", character:getName(), value) end
    end)

OnCharPermakilled(character, time)

Reports that a character has been permanently killed.

After perma-kill logic marks the character as dead.

Parameters:

Character character Character that was permakilled.

number time Timestamp of the perma-kill.

Example Usage:

    hook.Add("OnCharPermakilled", "AnnouncePerma", function(character)
        lia.chat.send(nil, "event", L("permakilled", character:getName()))
    end)

OnCharRecognized(client, arg2)

Notifies when a recognition check is performed between characters.

When determining if one character recognizes another.

Parameters:

Player client Player performing the recognition.

any arg2 Target data (player or character).

Returns:

boolean True if recognized; nil/false otherwise.

Example Usage:

    hook.Add("OnCharRecognized", "AlwaysRecognizeTeam", function(client, target)
        if target:getFaction() == client:Team() then return true end
    end)

OnCharTradeVendor(client, vendor, item, isSellingToVendor, character, itemType, isFailed)

Fired after a player completes a vendor trade interaction.

After buy/sell attempt is processed, including failures.

Parameters:

Player client Player trading.

Entity vendor Vendor entity.

Item item Item instance if available.

boolean isSellingToVendor True if player sold to vendor.

Character character Player character.

string itemType Item uniqueID.

boolean isFailed True if the trade failed.

Example Usage:

    hook.Add("OnCharTradeVendor", "TrackVendorTrade", function(client, vendor, item, selling)
        lia.log.add(client, selling and "vendorSell" or "vendorBuy", item and item.uniqueID or "unknown")
    end)

OnCheaterCaught(client)

Triggered when a player is flagged as a cheater by detection logic.

After anti-cheat routines identify suspicious behavior.

Parameters:

Player client Player detected.

Example Usage:

    hook.Add("OnCheaterCaught", "AutoKickCheaters", function(client)
        client:Kick("Cheating detected")
    end)

OnDataSet(key, value, gamemode, map)

Fires when lia.data.set writes a value so other modules can react.

Immediately after a data key is set.

Parameters:

string key Data key.

any value Value written.

string gamemode Gamemode identifier (namespace).

string map Map name associated with the data.

Example Usage:

    hook.Add("OnDataSet", "MirrorToCache", function(key, value)
        lia.cache.set(key, value)
    end)

OnDatabaseLoaded()

Indicates that the database has finished loading queued data.

After tables/data are loaded on startup.

Example Usage:

    hook.Add("OnDatabaseLoaded", "StartSalaryTimers", function()
        hook.Run("CreateSalaryTimers")
    end)

OnDeathSoundPlayed(client, deathSound)

Notifies that a death sound has been played for a player.

After emitting the death sound in PlayerDeath.

Parameters:

Player client Player who died.

string deathSound Sound path played.

Example Usage:

    hook.Add("OnDeathSoundPlayed", "BroadcastDeathSound", function(client, sound)
        lia.log.add(client, "deathSound", sound)
    end)

OnEntityLoaded(ent, data)

Called when an entity is loaded from persistence with its saved data.

After entity creation during map load and persistence restore.

Parameters:

Entity ent Entity loaded.

table data Saved data applied.

Example Usage:

    hook.Add("OnEntityLoaded", "RestoreHealth", function(ent, data)
        if data.health then ent:SetHealth(data.health) end
    end)

OnEntityPersistUpdated(ent, data)

Notifies that persistent data for an entity has been updated.

After persistence storage for an entity is rewritten.

Parameters:

Entity ent Entity whose data changed.

table data New persistence data.

Example Usage:

    hook.Add("OnEntityPersistUpdated", "RefreshDataCache", function(ent, data)
        ent.cachedPersist = data
    end)

OnEntityPersisted(ent, entData)

Called when an entity is first persisted to storage.

At the moment entity data is captured for saving.

Parameters:

Entity ent Entity being persisted.

table entData Data collected for saving.

Example Usage:

    hook.Add("OnEntityPersisted", "AddOwnerData", function(ent, data)
        if ent:GetNWString("owner") then data.owner = ent:GetNWString("owner") end
    end)

OnItemSpawned(itemEntity)

Fired when an item entity spawns into the world.

After an item entity is created (drop or spawn).

Parameters:

Entity itemEntity Item entity instance.

Example Usage:

    hook.Add("OnItemSpawned", "ApplyItemGlow", function(itemEntity)
        itemEntity:SetRenderFX(kRenderFxGlowShell)
    end)

OnLoadTables()

Signals that data tables for the gamemode have been loaded.

After loading tables during startup.

Example Usage:

    hook.Add("OnLoadTables", "InitVendors", function()
        lia.vendor.loadAll()
    end)

OnNPCTypeSet(client, npc, npcID, filteredData)

Allows overriding the NPC type assignment for an NPC entity.

When setting an NPC's type using management tools.

Parameters:

Player client Player setting the type.

Entity npc NPC entity.

string npcID Target NPC type ID.

table filteredData Data prepared for the NPC.

Example Usage:

    hook.Add("OnNPCTypeSet", "LogNPCType", function(client, npc, npcID)
        lia.log.add(client, "npcTypeSet", npcID)
    end)

OnOOCMessageSent(client, message)

Fired when an OOC chat message is sent to the server.

After an OOC message passes cooldown checks.

Parameters:

Player client Speaker.

string message Message text.

Example Usage:

    hook.Add("OnOOCMessageSent", "RelayToDiscord", function(client, message)
        lia.discord.send("OOC", client:Name(), message)
    end)

OnPainSoundPlayed(entity, painSound)

Notifies that a pain sound has been played for an entity.

After a pain sound is emitted.

Parameters:

Entity entity Entity that made the sound.

string painSound Sound path.

Example Usage:

    hook.Add("OnPainSoundPlayed", "CountPainSounds", function(entity, sound)
        lia.metrics.bump("painSounds")
    end)

OnPickupMoney(activator, moneyEntity)

Fired when a player picks up a money entity from the world.

After money is collected.

Parameters:

Player activator Player who picked up the money.

Entity moneyEntity Money entity removed.

Example Usage:

    hook.Add("OnPickupMoney", "LogMoneyPickup", function(ply, moneyEnt)
        lia.log.add(ply, "moneyPickup", moneyEnt:getAmount())
    end)

OnPlayerEnterSequence(client, sequenceName, callback, time, noFreeze)

Called when a player starts an animated sequence (e.g., sit or custom act).

When sequence playback is initiated through player sequences.

Parameters:

Player client Player entering the sequence.

string sequenceName Sequence identifier.

function callback Function to call when sequence ends.

number time Duration of the sequence.

boolean noFreeze Whether player movement is frozen.

Example Usage:

    hook.Add("OnPlayerEnterSequence", "SequenceLog", function(client, sequenceName)
        lia.log.add(client, "sequenceStart", sequenceName)
    end)

OnPlayerInteractItem(client, action, item, result, data)

Runs after a player interacts with an item and receives a result.

After item interaction logic completes.

Parameters:

Player client Player performing the action.

string action Action identifier.

Item item Item involved.

boolean|string|table result Result of the action.

table data Additional action data.

Example Usage:

    hook.Add("OnPlayerInteractItem", "NotifyUse", function(client, action, item, result)
        if result then client:notifyLocalized("itemAction", action, item:getName()) end
    end)

OnPlayerJoinClass(target, arg2, oldClass)

Triggered when a player joins a class or team variant.

After the class change is applied.

Parameters:

Player target Player who changed class.

any arg2 New class data/index.

any oldClass Previous class data/index.

Example Usage:

    hook.Add("OnPlayerJoinClass", "ClassLog", function(client, newClass, oldClass)
        lia.log.add(client, "classJoined", tostring(newClass))
    end)

OnPlayerLeaveSequence(client)

Fired when a player exits an animated sequence.

When the sequence finishes or is cancelled.

Parameters:

Player client Player leaving the sequence.

Example Usage:

    hook.Add("OnPlayerLeaveSequence", "SequenceEndLog", function(client)
        lia.log.add(client, "sequenceEnd")
    end)

OnPlayerLostStackItem(itemTypeOrItem)

Notifies when a player loses a stackable item (stack count reaches zero).

After stack removal logic.

Parameters:

string|Item itemTypeOrItem Item uniqueID or item instance removed.

Example Usage:

    hook.Add("OnPlayerLostStackItem", "RevokeBuff", function(itemTypeOrItem)
        if itemTypeOrItem == "medkit" then lia.buff.remove("healing") end
    end)

OnPlayerObserve(client, state)

Notifies when a player toggles observer mode (freecam/third person).

When observation state changes via admin commands or mechanics.

Parameters:

Player client Player entering or exiting observe.

boolean state True when entering observe mode.

Example Usage:

    hook.Add("OnPlayerObserve", "HideHUD", function(client, state)
        client:setNetVar("hideHUD", state)
    end)

OnPlayerRagdolled(client, ragdoll)

Fired when a player is ragdolled (knocked out, physics ragdoll).

Immediately after the ragdoll is created.

Parameters:

Player client Player ragdolled.

Entity ragdoll Ragdoll entity created.

Example Usage:

    hook.Add("OnPlayerRagdolled", "TrackRagdoll", function(client, ragdoll)
        ragdoll:SetCollisionGroup(COLLISION_GROUP_DEBRIS_TRIGGER)
    end)

OnPlayerSwitchClass(client, class, oldClass)

Notifies that a player switched to a different class.

After the class transition is applied.

Parameters:

Player client Player switching class.

table|number class New class identifier or data.

table|number oldClass Previous class identifier or data.

Example Usage:

    hook.Add("OnPlayerSwitchClass", "RefreshLoadout", function(client, class, oldClass)
        lia.loadout.give(client)
    end)

OnRequestItemTransfer(inventoryPanel, itemID, targetInventoryID, x, y)

Allows modules to override item transfer requests before processing.

When an inventory panel asks to move an item to another inventory.

Parameters:

Panel inventoryPanel UI panel requesting transfer.

number|string itemID Item instance ID.

number|string targetInventoryID Destination inventory.

number x X slot.

number y Y slot.

Example Usage:

    hook.Add("OnRequestItemTransfer", "BlockDuringTrade", function(_, _, targetInv)
        if lia.trade.isActive(targetInv) then return false end
    end)

OnSalaryAdjust(client)

Allows adjusting salary amount just before payment.

During salary payout calculation.

Parameters:

Player client Player receiving pay.

Returns:

number Modified salary value.

Example Usage:

    hook.Add("OnSalaryAdjust", "TaxSalary", function(client)
        return client:isTaxed() and -50 or 0
    end)

OnSalaryGiven(client, char, pay, faction, class)

Fired when salary is granted to a player.

After salary is deposited into the character.

Parameters:

Player client Player receiving salary.

Character char Character object.

number pay Amount paid.

table faction Faction data.

table class Class data (if any).

Example Usage:

    hook.Add("OnSalaryGiven", "LogSalary", function(client, char, pay)
        lia.log.add(client, "salaryGiven", pay)
    end)

OnSetUsergroup(sid, new, source, ply)

Called when a player's usergroup is changed.

After a player's usergroup has been successfully changed.

Parameters:

string sid Steam ID of the player whose usergroup changed.

string new New usergroup name.

string source Source of the change (e.g., "Lilia").

Player ply Player entity whose usergroup changed.

Example Usage:

    hook.Add("OnSetUsergroup", "LogUsergroupChange", function(sid, new, source, ply)
        print(string.format("Usergroup changed for %s to %s by %s", sid, new, source))
    end)

OnSavedItemLoaded(loadedItems)

Notifies that saved item instances have been loaded from storage.

After loading saved items on startup.

Parameters:

table loadedItems Table of item instances.

Example Usage:

    hook.Add("OnSavedItemLoaded", "IndexCustomData", function(loadedItems)
        lia.items.buildCache(loadedItems)
    end)

OnServerLog(client, logType, logString, category)

Central logging hook for server log entries.

Whenever lia.log.add writes to the server log.

Parameters:

Player client Player associated with the log (may be nil).

string logType Log type identifier.

string logString Formatted log message.

string category Log category.

Example Usage:

    hook.Add("OnServerLog", "ForwardToDiscord", function(client, logType, text, category)
        lia.discord.send(category, logType, text)
    end)

OnTicketClaimed(client, requester, ticketMessage)

Fired when a staff member claims a support ticket.

After claim assignment succeeds.

Parameters:

Player client Staff claiming the ticket.

string requester SteamID of the requester.

string ticketMessage Ticket text.

Example Usage:

    hook.Add("OnTicketClaimed", "AnnounceClaim", function(client, requester)
        client:notifyLocalized("ticketClaimed", requester)
    end)

OnTicketClosed(client, requester, ticketMessage)

Fired when a support ticket is closed.

After the ticket is marked closed and responders notified.

Parameters:

Player client Staff closing the ticket.

string requester SteamID of the requester.

string ticketMessage Original ticket text.

Example Usage:

    hook.Add("OnTicketClosed", "LogTicketClose", function(client, requester)
        lia.log.add(client, "ticketClosed", requester)
    end)

OnTicketCreated(noob, message)

Fired when a support ticket is created.

Right after a player submits a ticket.

Parameters:

Player noob Player submitting the ticket.

string message Ticket text.

Example Usage:

    hook.Add("OnTicketCreated", "NotifyStaff", function(noob, message)
        lia.staff.notifyAll(noob:Nick() .. ": " .. message)
    end)

OnUsergroupPermissionsChanged(groupName, arg2)

Notifies that usergroup permissions have changed.

After a usergroup permission update occurs.

Parameters:

string groupName Usergroup name.

table arg2 New permission data.

Example Usage:

    hook.Add("OnUsergroupPermissionsChanged", "RefreshCachedPerms", function(groupName)
        lia.permissions.refresh(groupName)
    end)

OnVendorEdited(client, vendor, key)

Fired when a vendor entity is edited via the vendor interface.

After vendor key/value is changed.

Parameters:

Player client Player editing.

Entity vendor Vendor entity.

string key Property key edited.

Example Usage:

    hook.Add("OnVendorEdited", "SyncVendorEdits", function(client, vendor, key)
        lia.vendor.sync(vendor)
    end)

OnVoiceTypeChanged(client)

Signals that a player's voice chat style has changed (whisper/talk/yell).

After a player updates their voice type.

Parameters:

Player client Player whose voice type changed.

Example Usage:

    hook.Add("OnVoiceTypeChanged", "UpdateVoiceRadius", function(client)
        lia.voice.updateHearTables()
    end)

OptionReceived(arg1, key, value)

Called when a networked option value is received or changed.

When lia.option.set broadcasts an option that should network.

Parameters:

Player arg1 optional Player who triggered the change (nil when server initiated).

string key Option key.

any value New value.

Example Usage:

    hook.Add("OptionReceived", "ApplyOption", function(_, key, value)
        if key == "TalkRange" then lia.config.set("TalkRange", value) end
    end)

PlayerAccessVendor(client, vendor)

Checks if a player is permitted to access vendor management.

When a player attempts to open vendor edit controls.

Parameters:

Player client Player requesting access.

Entity vendor Vendor entity.

Returns:

boolean False to block, true/nil to allow.

Example Usage:

    hook.Add("PlayerAccessVendor", "AdminOnlyVendorEdit", function(client)
        if not client:IsAdmin() then return false end
    end)

PlayerCheatDetected(client)

Triggered when cheat detection flags a player.

After the cheat system confirms suspicious behavior.

Parameters:

Player client Player detected.

Example Usage:

    hook.Add("PlayerCheatDetected", "AutoBan", function(client)
        lia.bans.add(client:SteamID(), "Cheat detected", 0)
    end)

PlayerGagged(target, admin)

Fired when a player is gagged (voice chat disabled).

After gag state toggles to true.

Parameters:

Player target Player gagged.

Player admin Admin who issued the gag.

Example Usage:

    hook.Add("PlayerGagged", "LogGag", function(target, admin)
        lia.log.add(admin, "playerGagged", target:Name())
    end)

PlayerLiliaDataLoaded(client)

Notifies that Lilia player data has finished loading for a client.

After lia data, items, doors, and panels are synced to the client.

Parameters:

Player client Player whose data is loaded.

Example Usage:

    hook.Add("PlayerLiliaDataLoaded", "SendWelcome", function(client)
        client:notifyLocalized("welcomeBack")
    end)

PlayerLoadedChar(client, character, currentChar)

Fired after a player's character has been fully loaded.

Once character variables are applied and the player is spawned.

Parameters:

Player client Player whose character loaded.

Character character Active character.

number currentChar Character ID index.

Example Usage:

    hook.Add("PlayerLoadedChar", "ApplyLoadout", function(client, character)
        lia.loadout.give(client)
    end)

PlayerMessageSend(speaker, chatType, text, anonymous, receivers)

Allows modifying chat text before it is sent to listeners.

During chat send for all chat types.

Parameters:

Player speaker Player speaking.

string chatType Chat class identifier.

string text Raw message text.

boolean anonymous Whether the message is anonymous.

table receivers List of recipients (optional).

Returns:

string Replacement message text, or nil to keep.

Example Usage:

    hook.Add("PlayerMessageSend", "CensorCurseWords", function(_, _, text)
        return text:gsub("badword", "****")
    end)

PlayerModelChanged(client, value)

Triggered when a player's model changes.

After a new model is set on the player.

Parameters:

Player client Player whose model changed.

string value New model path.

Example Usage:

    hook.Add("PlayerModelChanged", "ReapplyBodygroups", function(client)
        lia.models.applyBodygroups(client)
    end)

PlayerMuted(target, admin)

Fired when a player is muted (text chat disabled).

After muting is applied.

Parameters:

Player target Player muted.

Player admin Admin who muted.

Example Usage:

    hook.Add("PlayerMuted", "LogMute", function(target, admin)
        lia.log.add(admin, "playerMuted", target:Name())
    end)

PlayerShouldPermaKill(client, inflictor, attacker)

Determines if a death should result in a permanent character kill.

During PlayerDeath when checking perma-kill conditions.

Parameters:

Player client Player who died.

Entity inflictor Entity inflicting damage.

Entity attacker Attacker entity.

Returns:

boolean True to perma-kill, false/nil to avoid.

Example Usage:

    hook.Add("PlayerShouldPermaKill", "HardcoreMode", function(client)
        return lia.config.get("HardcoreMode", false)
    end)

PlayerSpawnPointSelected(client, pos, ang)

Allows overriding the spawn point chosen for a player.

When selecting a specific spawn point entity/position.

Parameters:

Player client Player spawning.

Vector pos Proposed position.

Angle ang Proposed angle.

Returns:

vector, angle Replacement spawn location or nil to keep.

Example Usage:

    hook.Add("PlayerSpawnPointSelected", "SpawnInZone", function(client)
        return lia.spawns.pickSafe(), Angle(0, 0, 0)
    end)

PlayerStaminaGained(client)

Notifies that stamina has been gained by a player.

After stamina increase is applied.

Parameters:

Player client Player gaining stamina.

Example Usage:

    hook.Add("PlayerStaminaGained", "RewardRecovery", function(client)
        client:notifyLocalized("staminaRestored")
    end)

PlayerStaminaLost(client)

Notifies that stamina has been reduced for a player.

After stamina drain is applied.

Parameters:

Player client Player losing stamina.

Example Usage:

    hook.Add("PlayerStaminaLost", "WarnLowStamina", function(client)
        if client:getLocalVar("stm", 100) < 10 then client:notifyLocalized("lowStamina") end
    end)

PlayerUngagged(target, admin)

Fired when a gag on a player is removed.

After gag state switches to false.

Parameters:

Player target Player ungagged.

Player admin Admin lifting the gag.

Example Usage:

    hook.Add("PlayerUngagged", "LogUngag", function(target, admin)
        lia.log.add(admin, "playerUngagged", target:Name())
    end)

PlayerUnmuted(target, admin)

Fired when a mute on a player is removed.

After muting state switches to false.

Parameters:

Player target Player unmuted.

Player admin Admin lifting the mute.

Example Usage:

    hook.Add("PlayerUnmuted", "LogUnmute", function(target, admin)
        lia.log.add(admin, "playerUnmuted", target:Name())
    end)

PlayerUseDoor(client, door)

Final permission check before a player uses a door entity.

When a use input is received on a door.

Parameters:

Player client Player using the door.

Entity door Door entity.

Returns:

boolean False to block use; true/nil to allow.

Example Usage:

    hook.Add("PlayerUseDoor", "RaidLockdown", function(client)
        if lia.state.isRaid() then return false end
    end)

PostDoorDataLoad(ent, doorData)

Runs after door data has been loaded from persistence.

After door ownership/vars are applied on map load.

Parameters:

Entity ent Door entity.

table doorData Data restored for the door.

Example Usage:

    hook.Add("PostDoorDataLoad", "ApplyDoorSkin", function(ent, data)
        if data.skin then ent:SetSkin(data.skin) end
    end)

PostLoadData()

Called after all gamemode data loading is complete.

At the end of server initialization once stored data is in memory.

Example Usage:

    hook.Add("PostLoadData", "WarmCache", function()
        lia.cache.preload()
    end)

PostPlayerInitialSpawn(client)

Runs after the player's initial spawn setup finishes.

Right after PlayerInitialSpawn processing completes.

Parameters:

Player client Newly spawned player.

Example Usage:

    hook.Add("PostPlayerInitialSpawn", "SendMOTD", function(client)
        lia.motd.send(client)
    end)

PostPlayerLoadedChar(client, character, currentChar)

Runs after a player's character and inventories have been loaded.

Immediately after PlayerLoadedChar finishes syncing.

Parameters:

Player client Player.

Character character Loaded character.

number currentChar Character index.

Example Usage:

    hook.Add("PostPlayerLoadedChar", "GiveStarterItems", function(client, character)
        lia.items.giveStarter(character)
    end)

PostPlayerLoadout(client)

Fired after PlayerLoadout has finished giving items and weapons.

After the default loadout logic completes.

Parameters:

Player client Player who spawned.

Example Usage:

    hook.Add("PostPlayerLoadout", "AddExtraGear", function(client)
        client:Give("weapon_crowbar")
    end)

PostPlayerSay(client, message, chatType, anonymous)

Allows modules to modify chat behavior after PlayerSay builds recipients.

After chat data is prepared but before sending to clients.

Parameters:

Player client Speaker.

string message Message text.

string chatType Chat class.

boolean anonymous Whether the message is anonymous.

Returns:

string, boolean Optionally return modified text and anonymity.

Example Usage:

    hook.Add("PostPlayerSay", "AddOOCPrefix", function(client, message, chatType, anonymous)
        if chatType == "ooc" then return "[OOC] " .. message, anonymous end
    end)

PostScaleDamage(hitgroup, dmgInfo, damageScale)

Fired after damage scaling is applied to a hitgroup.

At the end of ScalePlayerDamage.

Parameters:

number hitgroup Hitgroup hit.

CTakeDamageInfo dmgInfo Damage info object.

number damageScale Scale that was applied.

Example Usage:

    hook.Add("PostScaleDamage", "TrackDamage", function(hitgroup, dmgInfo, scale)
        lia.metrics.bump("damage", dmgInfo:GetDamage() * scale)
    end)

PreCharDelete(id)

Pre-deletion hook for characters to run cleanup logic.

Just before a character is removed from the database.

Parameters:

number id Character ID to delete.

Example Usage:

    hook.Add("PreCharDelete", "ArchiveChar", function(id)
        lia.backup.character(id)
    end)

PreDoorDataSave(door, doorData)

Allows adding extra data before door data is saved to persistence.

During door save routines.

Parameters:

Entity door Door entity.

table doorData Data about to be saved.

Example Usage:

    hook.Add("PreDoorDataSave", "SaveDoorSkin", function(door, data)
        data.skin = door:GetSkin()
    end)

PrePlayerInteractItem(client, action, item)

Lets modules validate an item interaction before it runs.

Prior to executing an item action.

Parameters:

Player client Player performing the action.

string action Action identifier.

Item item Item being interacted with.

Returns:

boolean False to block; true/nil to allow.

Example Usage:

    hook.Add("PrePlayerInteractItem", "BlockWhileBusy", function(client)
        if client:isBusy() then return false end
    end)

PrePlayerLoadedChar(client, character, currentChar)

Runs before character data is fully loaded into a player.

Prior to PlayerLoadedChar logic.

Parameters:

Player client Player about to load a character.

Character character Character object.

number currentChar Character index.

Example Usage:

    hook.Add("PrePlayerLoadedChar", "ResetRagdoll", function(client)
        client:removeRagdoll()
    end)

PreSalaryGive(client, char, pay, faction, class)

Allows modification of salary payout before it is given.

During salary calculation loop, before pay is issued.

Parameters:

Player client Player due for salary.

Character char Character.

number pay Current calculated pay.

table faction Faction data.

table class Class data.

Returns:

number Adjusted pay or nil to keep.

Example Usage:

    hook.Add("PreSalaryGive", "ApplyTax", function(client, char, pay)
        return pay * 0.9
    end)

PreScaleDamage(hitgroup, dmgInfo, damageScale)

Called before damage scaling is calculated.

At the start of ScalePlayerDamage.

Parameters:

number hitgroup Hitgroup hit.

CTakeDamageInfo dmgInfo Damage info object.

number damageScale Starting scale value.

Example Usage:

    hook.Add("PreScaleDamage", "ArmorPiercing", function(hitgroup, dmgInfo, scale)
        if dmgInfo:IsExplosionDamage() then dmgInfo:ScaleDamage(scale * 1.2) end
    end)

RemoveWarning(charID, index)

Removes a warning entry for a character and informs listeners.

When an admin deletes a warning record.

Parameters:

number|string charID Character database ID.

number index Position of the warning in the list to remove.

Returns:

deferred|table Deferred resolving to removed warning row or nil.

Example Usage:

    hook.Add("RemoveWarning", "MirrorWarningRemoval", function(charID, index)
        print("Warning removed", charID, index)
    end)

SaveData()

Performs a full save of gamemode persistence (entities, data, etc.).

When persistence save is triggered manually or automatically.

Example Usage:

    hook.Add("SaveData", "ExtraSave", function()
        lia.custom.saveAll()
    end)

SendPopup(noob, message)

Displays a popup notification to a player with custom text.

Whenever the server wants to send a popup dialog.

Parameters:

Player noob Player receiving the popup.

string message Text to show.

Example Usage:

    hook.Add("SendPopup", "PopupExample", function(client, message)
        client:notifyLocalized(message)
    end)

SetupBotPlayer(client)

Builds and spawns a bot player with default character data.

When the server requests creation of a bot player.

Parameters:

Player client Bot player entity.

Example Usage:

    hook.Add("SetupBotPlayer", "BotWelcome", function(client)
        print("Bot setup complete", client)
    end)

SetupDatabase()

Sets up database tables, indexes, and initial schema.

During gamemode initialization after database connection is established.

Example Usage:

    hook.Add("SetupDatabase", "InitCustomTables", function()
        lia.db.query("CREATE TABLE IF NOT EXISTS custom(id INT)")
    end)

SetupPlayerModel(modelEntity, character)

Configure a player model entity after it has been created.

When spawning a playable model entity for preview or vendors.

Parameters:

Entity modelEntity The spawned model entity.

Character character Character data used for appearance.

Example Usage:

    hook.Add("SetupPlayerModel", "ApplyCharSkin", function(modelEntity, character)
        modelEntity:SetSkin(character:getSkin() or 0)
    end)

ShouldDataBeSaved()

Determines if persistence data should be saved at this time.

Before performing a save cycle.

Returns:

boolean False to skip saving; true/nil to proceed.

Example Usage:

    hook.Add("ShouldDataBeSaved", "OnlyDuringGrace", function()
        return not lia.state.isCombatPhase()
    end)

ShouldOverrideSalaryTimers()

Determines if the default salary timer creation should be overridden.

Before creating salary timers to allow custom salary systems.

Returns:

boolean True to prevent default salary timer creation; false/nil to allow.

Example Usage:

    hook.Add("ShouldOverrideSalaryTimers", "CustomSalarySystem", function()
        return true -- Prevent default timers, handle salary elsewhere
    end)

ShouldDeleteSavedItems()

Decides whether saved item data should be deleted on map cleanup.

Before removing saved items.

Returns:

boolean False to keep saved items; true/nil to delete.

Example Usage:

    hook.Add("ShouldDeleteSavedItems", "KeepForTesting", function()
        return false
    end)

ShouldPlayDeathSound(client, deathSound)

Decide if a death sound should play for a player.

Right before emitting the death sound.

Parameters:

Player client Player who died.

string deathSound Sound that would be played.

Returns:

boolean False to suppress; true/nil to allow.

Example Usage:

    hook.Add("ShouldPlayDeathSound", "MuteStaff", function(client)
        if client:Team() == FACTION_STAFF then return false end
    end)

ShouldPlayPainSound(entity, painSound)

Decide if a pain sound should play for an entity.

When choosing whether to emit pain audio.

Parameters:

Entity entity Entity that would play the sound.

string painSound Sound path.

Returns:

boolean False to suppress; true/nil to allow.

Example Usage:

    hook.Add("ShouldPlayPainSound", "MuteRobots", function(entity)
        if entity:IsPlayer() and entity:IsCombine() then return false end
    end)

ShouldSpawnClientRagdoll(client)

Controls whether a client ragdoll should be spawned on death.

During PlayerDeath ragdoll handling.

Parameters:

Player client Player who died.

Returns:

boolean False to prevent ragdoll; true/nil to allow.

Example Usage:

    hook.Add("ShouldSpawnClientRagdoll", "NoRagdollInVehicles", function(client)
        return not client:InVehicle()
    end)

StorageCanTransferItem(client, storage, item)

Validates whether an item can be transferred to/from storage inventories.

When an item move involving storage is requested.

Parameters:

Player client Player performing the move.

Entity|table storage Storage entity or inventory table.

Item item Item being moved.

Returns:

boolean False to block; true/nil to allow.

Example Usage:

    hook.Add("StorageCanTransferItem", "LimitWeapons", function(client, storage, item)
        if item.isWeapon then return false end
    end)

StorageEntityRemoved(storageEntity, inventory)

Fired when a storage entity is removed from the world.

On removal/deletion of the storage entity.

Parameters:

Entity storageEntity Storage entity removed.

Inventory inventory Inventory associated.

Example Usage:

    hook.Add("StorageEntityRemoved", "SaveStorage", function(storageEntity, inventory)
        lia.storage.saveInventory(inventory)
    end)

StorageInventorySet(entity, inventory, isCar)

Fired when a storage inventory is assigned to an entity.

After inventory is set on a storage entity.

Parameters:

Entity entity Entity receiving the inventory.

Inventory inventory Inventory assigned.

boolean isCar True if the storage is a vehicle trunk.

Example Usage:

    hook.Add("StorageInventorySet", "TrackStorage", function(ent, inv)
        lia.log.add(nil, "storageSet", inv:getID())
    end)

StorageItemRemoved()

Notifies that an item was removed from a storage inventory.

After removal occurs.

Example Usage:

    hook.Add("StorageItemRemoved", "RecountStorage", function()
        lia.storage.updateCapacity()
    end)

StorageRestored(ent, inventory)

Fired when a storage inventory is restored from disk.

During storage load routines.

Parameters:

Entity ent Storage entity.

Inventory inventory Inventory object restored.

Example Usage:

    hook.Add("StorageRestored", "SyncRestoredStorage", function(ent, inventory)
        inventory:sync(ent)
    end)

StoreSpawns(spawns)

Persists the current spawn positions to storage.

When spawns are being saved.

Parameters:

table spawns Spawn data to store.

Example Usage:

    hook.Add("StoreSpawns", "CustomSpawnStore", function(spawns)
        file.Write("lilia/spawns.json", util.TableToJSON(spawns))
    end)

SyncCharList(client)

Syncs the character list data to a specific client.

When a player requests an updated character list.

Parameters:

Player client Player receiving the list.

Example Usage:

    hook.Add("SyncCharList", "AddExtraFields", function(client)
        lia.char.sync(client)
    end)

TicketSystemClaim(client, requester, ticketMessage)

Allows custom validation when a player attempts to claim a support ticket.

When a claim request is made for a ticket.

Parameters:

Player client Player claiming the ticket.

Player|string requester Ticket requester or their SteamID.

string ticketMessage Ticket description.

Returns:

boolean False to block; true/nil to allow.

Example Usage:

    hook.Add("TicketSystemClaim", "AllowStaffOnlyClaims", function(client)
        if not client:isStaffOnDuty() then return false end
    end)

TicketSystemClose(client, requester, ticketMessage)

Allows custom validation when a player attempts to close a support ticket.

When a close request is made for a ticket.

Parameters:

Player client Player closing the ticket.

Player|string requester Ticket requester or SteamID.

string ticketMessage Ticket description.

Returns:

boolean False to block; true/nil to allow.

Example Usage:

    hook.Add("TicketSystemClose", "OnlyOwnerOrStaff", function(client, requester)
        if client ~= requester and not client:isStaffOnDuty() then return false end
    end)

ToggleLock(client, door, state)

Signals that a door lock state was toggled.

After a lock/unlock action completes.

Parameters:

Player client Player toggling.

Entity door Door entity.

boolean state True if locked after toggle.

Example Usage:

    hook.Add("ToggleLock", "LogToggleLock", function(client, door, state)
        lia.log.add(client, "toggleLock", tostring(state))
    end)

UpdateEntityPersistence(vendor)

Writes updated persistence data for an entity (commonly vendors).

After data changes that must be persisted.

Parameters:

Entity vendor Entity whose persistence should be updated.

Example Usage:

    hook.Add("UpdateEntityPersistence", "SaveVendorChanges", function(vendor)
        lia.entity.save(vendor)
    end)

VendorClassUpdated(vendor, id, allowed)

Fired when a vendor's class allow list changes.

After toggling a class for vendor access.

Parameters:

Entity vendor Vendor entity.

number|string id Class identifier.

boolean allowed Whether the class is allowed.

Example Usage:

    hook.Add("VendorClassUpdated", "SyncVendorClassUpdate", function(vendor)
        lia.vendor.sync(vendor)
    end)

VendorEdited(liaVendorEnt, key)

General notification that a vendor property was edited.

Whenever vendor data is modified through the editor.

Parameters:

Entity liaVendorEnt Vendor entity.

string key Property key changed.

Example Usage:

    hook.Add("VendorEdited", "ResyncOnEdit", function(vendor)
        lia.vendor.sync(vendor)
    end)

VendorFactionBuyScaleUpdated(vendor, factionID, scale)

Notifies that a vendor's faction-specific buy multiplier was updated.

After setting faction buy scale.

Parameters:

Entity vendor Vendor entity.

number|string factionID Faction identifier.

number scale New buy scale.

Example Usage:

    hook.Add("VendorFactionBuyScaleUpdated", "SyncFactionBuyScale", function(vendor)
        lia.vendor.sync(vendor)
    end)

VendorFactionSellScaleUpdated(vendor, factionID, scale)

Notifies that a vendor's faction-specific sell multiplier was updated.

After setting faction sell scale.

Parameters:

Entity vendor Vendor entity.

number|string factionID Faction identifier.

number scale New sell scale.

Example Usage:

    hook.Add("VendorFactionSellScaleUpdated", "SyncFactionSellScale", function(vendor)
        lia.vendor.sync(vendor)
    end)

VendorFactionUpdated(vendor, id, allowed)

Fired when a vendor's faction allow/deny list is changed.

After toggling faction access.

Parameters:

Entity vendor Vendor entity.

number|string id Faction identifier.

boolean allowed Whether the faction is allowed.

Example Usage:

    hook.Add("VendorFactionUpdated", "SyncFactionAccess", function(vendor)
        lia.vendor.sync(vendor)
    end)

VendorItemMaxStockUpdated(vendor, itemType, value)

Fired when the maximum stock for a vendor item is updated.

After editing item stock limits.

Parameters:

Entity vendor Vendor entity.

string itemType Item uniqueID.

number value New max stock.

Example Usage:

    hook.Add("VendorItemMaxStockUpdated", "SyncMaxStockChange", function(vendor)
        lia.vendor.sync(vendor)
    end)

VendorItemModeUpdated(vendor, itemType, value)

Fired when a vendor item's trade mode changes (buy/sell/both).

After updating item mode.

Parameters:

Entity vendor Vendor entity.

string itemType Item uniqueID.

number value Mode constant.

Example Usage:

    hook.Add("VendorItemModeUpdated", "SyncItemModeChange", function(vendor)
        lia.vendor.sync(vendor)
    end)

VendorItemPriceUpdated(vendor, itemType, value)

Fired when a vendor item's price is changed.

After setting a new price for an item.

Parameters:

Entity vendor Vendor entity.

string itemType Item uniqueID.

number value New price.

Example Usage:

    hook.Add("VendorItemPriceUpdated", "SyncPriceChange", function(vendor)
        lia.vendor.sync(vendor)
    end)

VendorItemStockUpdated(vendor, itemType, value)

Fired when a vendor item's current stock value changes.

After stock is set manually.

Parameters:

Entity vendor Vendor entity.

string itemType Item uniqueID.

number value New stock.

Example Usage:

    hook.Add("VendorItemStockUpdated", "SyncStockChange", function(vendor)
        lia.vendor.sync(vendor)
    end)

VendorMessagesUpdated(vendor)

Fired when vendor dialogue/messages are updated.

After editing vendor message strings.

Parameters:

Entity vendor Vendor entity.

Example Usage:

    hook.Add("VendorMessagesUpdated", "SyncVendorMsgs", function(vendor)
        lia.vendor.sync(vendor)
    end)

VendorSynchronized(vendor)

Notifies that vendor data has been synchronized to clients.

After vendor network sync completes.

Parameters:

Entity vendor Vendor entity.

Example Usage:

    hook.Add("VendorSynchronized", "AfterVendorSync", function(vendor)
        print("Vendor synced", vendor)
    end)

VendorTradeEvent(client, vendor, itemType, isSellingToVendor)

Generic hook for vendor trade events (buying or selling).

After a vendor transaction completes.

Parameters:

Player client Player trading.

Entity vendor Vendor entity.

string itemType Item uniqueID.

boolean isSellingToVendor True if player sold to vendor.

Example Usage:

    hook.Add("VendorTradeEvent", "TrackTrade", function(client, vendor, itemType, selling)
        lia.log.add(client, selling and "vendorSell" or "vendorBuy", itemType)
    end)

WarningIssued(client, target, reason, severity, count, warnerSteamID, targetSteamID)

Fired when a warning is issued to a player.

Immediately after creating a warning record.

Parameters:

Player client Admin issuing the warning.

Player target Player receiving the warning.

string reason Warning reason.

string severity Severity level.

number count Total warnings after issuance.

string warnerSteamID Issuer SteamID.

string targetSteamID Target SteamID.

Example Usage:

    hook.Add("WarningIssued", "RelayToDiscord", function(client, target, reason, severity)
        lia.discord.send("warnings", client:Name(), reason .. " (" .. severity .. ")")
    end)

WarningRemoved(client, targetClient, arg3, arg4, arg5, arg6)

Fired when a warning is removed from a player.

After the warning record is deleted.

Parameters:

Player client Admin removing the warning.

Player targetClient Player whose warning was removed.

table arg3 Warning data table.

any arg4 Additional context.

any arg5 Additional context.

any arg6 Additional context.

Example Usage:

    hook.Add("WarningRemoved", "NotifyRemoval", function(client, targetClient, data)
        targetClient:notifyLocalized("warningRemovedNotify", client:Name())
    end)

OverrideVoiceHearingStatus(listener, speaker, baseCanHear)

Allows overriding whether a listener can hear a speaker's voice, overriding the default distance-based calculation.

During voice hearing calculations, after the base distance check is performed.

Parameters:

Player listener Player who would be listening to the voice.

Player speaker Player who is speaking.

boolean baseCanHear The default hearing status based on distance and voice type (whisper/talk/yell ranges).

Returns:

boolean|nil Return true to force the listener to hear the speaker, false to block hearing, or nil to use the default baseCanHear value.

Example Usage:

    hook.Add("OverrideVoiceHearingStatus", "BlockDTVoice", function(listener, speaker, baseCanHear)
        if speaker:getNetVar("dtScramblerEnabled", false) and listener:Team() ~= FACTION_DT then
            return false
        end
    end)