Client-Side Hooks
Client-side hook system for the Lilia framework.
Overview
Client-side hooks in the Lilia framework handle UI, rendering, input, and other client-specific functionality; they can be used to customize the user experience and can be overridden or extended by addons and modules.
AddBarField
Purpose
Adds a bar field to a character information section in the F1 menu
When Called
When you want to add a progress bar field to display character statistics
Parameters
sectionName(string): The name of the section to add the field tofieldName(string): Unique identifier for the fieldlabelText(string): Display text for the field labelminFunc(function): Function that returns the minimum value for the barmaxFunc(function): Function that returns the maximum value for the barvalueFunc(function): Function that returns the current value for the bar
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add a health bar field
hook.Run("AddBarField", "character", "health", "Health",
function() return 0 end,
function() return 100 end,
function() return LocalPlayer():Health() end)
Medium Complexity:
-- Medium: Add a stamina bar field with character data
hook.Run("AddBarField", "character", "stamina", "Stamina",
function() return 0 end,
function() return 100 end,
function()
local char = LocalPlayer():getChar()
return char and char:getAttrib("stm") or 0
end)
High Complexity:
-- High: Add multiple attribute bars dynamically
local attributes = {"str", "con", "dex", "int", "wis", "cha"}
for _, attrId in ipairs(attributes) do
local attr = lia.attribs.list[attrId]
if attr then
hook.Run("AddBarField", "attributes", attrId, attr.name,
function() return attr.min or 0 end,
function() return hook.Run("GetAttributeMax", LocalPlayer(), attrId) or attr.max or 100 end,
function()
local char = LocalPlayer():getChar()
return char and char:getAttrib(attrId) or 0
end)
end
end
AddSection
Purpose
Adds a new section to the character information panel in the F1 menu
When Called
When you want to create a new section for displaying character information
Parameters
sectionName(string): The name of the section to createcolor(Color): The color for the section header (optional)priority(number): Display priority, lower numbers appear first (optional)location(number): Location of the section in the panel (optional)
Returns
- None
Realm
Client
Example Usage
Low Complexity:
Medium Complexity:
-- Medium: Add a section with custom styling
hook.Run("AddSection", "Character Stats", Color(100, 150, 200), 2, 1)
High Complexity:
-- High: Add multiple sections with conditional logic
local sections = {
{name = "Basic Info", color = Color(255, 255, 255), priority = 1},
{name = "Attributes", color = Color(100, 200, 100), priority = 2},
{name = "Skills", color = Color(200, 100, 100), priority = 3}
}
for _, section in ipairs(sections) do
hook.Run("AddSection", section.name, section.color, section.priority, 1)
end
AddTextField
Purpose
Adds a text field to a character information section in the F1 menu
When Called
When you want to add a text field to display character information
Parameters
sectionName(string): The name of the section to add the field tofieldName(string): Unique identifier for the fieldlabelText(string): Display text for the field labelvalueFunc(function): Function that returns the current value to display
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add a character name field
hook.Run("AddTextField", "General Info", "name", "Name",
function() return LocalPlayer():Name() end)
Medium Complexity:
-- Medium: Add a faction field with character data
hook.Run("AddTextField", "General Info", "faction", "Faction",
function()
local char = LocalPlayer():getChar()
return char and char:getFaction() and char:getFaction().name or "Unknown"
end)
High Complexity:
-- High: Add multiple character info fields dynamically
local infoFields = {
{name = "name", label = "Name", func = function() return LocalPlayer():Name() end},
{name = "desc", label = "Description", func = function()
local char = LocalPlayer():getChar()
return char and char:getDesc() or "No description"
end},
{name = "money", label = "Money", func = function()
local char = LocalPlayer():getChar()
return char and lia.currency.format(char:getMoney()) or "$0"
end}
}
for _, field in ipairs(infoFields) do
hook.Run("AddTextField", "General Info", field.name, field.label, field.func)
end
AddToAdminStickHUD
Purpose
Adds information to the admin stick HUD display when looking at entities
When Called
When an admin uses the admin stick and looks at an entity
Parameters
client(Player): The admin player using the admin sticktarget(Entity): The entity being looked atinformation(table): Table to add information strings to
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add basic entity information
hook.Add("AddToAdminStickHUD", "MyAddon", function(client, target, information)
if IsValid(target) then
table.insert(information, "Entity: " .. target:GetClass())
end
end)
Medium Complexity:
-- Medium: Add vendor-specific information
hook.Add("AddToAdminStickHUD", "VendorInfo", function(client, target, information)
if IsValid(target) and target.IsVendor then
local name = target:getName()
if name and name ~= "" then
table.insert(information, "Vendor Name: " .. name)
end
local animation = target:getNetVar("animation", "")
if animation and animation ~= "" then
table.insert(information, "Animation: " .. animation)
end
end
end)
High Complexity:
-- High: Add comprehensive entity information with validation
hook.Add("AddToAdminStickHUD", "DetailedInfo", function(client, target, information)
if not IsValid(target) then return end
-- Basic entity info
table.insert(information, "Class: " .. target:GetClass())
table.insert(information, "Model: " .. target:GetModel())
-- Position info
local pos = target:GetPos()
table.insert(information, string.format("Position: %.1f, %.1f, %.1f", pos.x, pos.y, pos.z))
-- Custom entity data
if target.IsVendor then
local name = target:getName()
if name and name ~= "" then
table.insert(information, "Vendor: " .. name)
end
elseif target.IsDoor then
local doorData = target:getNetVar("doorData")
if doorData then
table.insert(information, "Door Title: " .. (doorData.title or "Untitled"))
table.insert(information, "Door Price: $" .. (doorData.price or 0))
end
end
end)
AdjustPACPartData
Purpose
Allows modification of PAC3 part data before it's applied to a player
When Called
When PAC3 parts are being attached to a player, allowing customization
Parameters
wearer(Player): The player who will wear the PAC3 partid(string): The identifier of the PAC3 partdata(table): The PAC3 part data to be modified
Returns
- table|nil - Modified part data, or nil to use original data
Realm
Client
Example Usage
Low Complexity:
-- Simple: Modify part color
hook.Add("AdjustPACPartData", "MyAddon", function(wearer, id, data)
if id == "my_hat" then
data.color = Color(255, 0, 0) -- Make hat red
return data
end
end)
Medium Complexity:
-- Medium: Modify part based on player faction
hook.Add("AdjustPACPartData", "FactionPAC", function(wearer, id, data)
local char = wearer:getChar()
if not char then return end
if id == "uniform" then
local faction = char:getFaction()
if faction == "police" then
data.color = Color(0, 0, 255) -- Blue for police
elseif faction == "medic" then
data.color = Color(255, 255, 255) -- White for medics
end
return data
end
end)
High Complexity:
-- High: Complex PAC part modification system
hook.Add("AdjustPACPartData", "AdvancedPAC", function(wearer, id, data)
local char = wearer:getChar()
if not char then return end
-- Check if this is an item-based part
local item = lia.item.list[id]
if item and isfunction(item.pacAdjust) then
local result = item:pacAdjust(data, wearer)
if result ~= nil then return result end
end
-- Apply faction-specific modifications
local faction = char:getFaction()
local modifications = {
["police"] = {
["badge"] = {scale = 1.2, color = Color(255, 215, 0)},
["uniform"] = {color = Color(0, 0, 100)}
},
["medic"] = {
["uniform"] = {color = Color(255, 255, 255)},
["cross"] = {scale = 1.5, color = Color(255, 0, 0)}
}
}
local factionMods = modifications[faction]
if factionMods and factionMods[id] then
local mod = factionMods[id]
for key, value in pairs(mod) do
data[key] = value
end
end
-- Apply character-specific modifications
local charData = char:getData()
if charData.rank and charData.rank == "officer" then
data.scale = (data.scale or 1) * 1.1 -- Officers get slightly larger parts
end
return data
end)
AttachPart
Purpose
Attaches a PAC3 part to a player
When Called
When a PAC3 part needs to be attached to a player
Parameters
client(Player): The player to attach the part toid(string): The identifier of the PAC3 part to attach
Returns
- None
Realm
Client
Example Usage
Low Complexity:
Medium Complexity:
-- Medium: Attach part with validation
hook.Add("AttachPart", "MyAddon", function(client, id)
if id == "special_hat" then
local char = client:getChar()
if char and char:getFaction() == "police" then
-- Only police can wear this hat
hook.Run("AttachPart", client, id)
end
end
end)
High Complexity:
-- High: Complex part attachment system
hook.Add("AttachPart", "AdvancedPAC", function(client, id)
local char = client:getChar()
if not char then return end
-- Check if player has permission for this part
local partPermissions = {
["police_badge"] = {"police", "sheriff"},
["medic_cross"] = {"medic", "doctor"},
["crown"] = {"mayor", "king"}
}
local allowedFactions = partPermissions[id]
if allowedFactions then
local faction = char:getFaction()
if not table.HasValue(allowedFactions, faction) then
client:ChatPrint("You don't have permission to wear this item!")
return
end
end
-- Check character level requirements
local levelRequirements = {
["epic_armor"] = 10,
["legendary_weapon"] = 20
}
local requiredLevel = levelRequirements[id]
if requiredLevel then
local charLevel = char:getData("level", 1)
if charLevel < requiredLevel then
client:ChatPrint("You need to be level " .. requiredLevel .. " to wear this item!")
return
end
end
-- Attach the part
hook.Run("AttachPart", client, id)
-- Log the attachment
print(client:Name() .. " attached PAC part: " .. id)
end)
CanDisplayCharInfo
Purpose
Determines if character information should be displayed for a given name
When Called
When displaying character information in UI elements
Parameters
name(string): The character name to check
Returns
- boolean - True if info should be displayed, false otherwise
Realm
Client
Example Usage
Low Complexity:
-- Simple: Display all character info
hook.Add("CanDisplayCharInfo", "MyAddon", function(name)
return true
end)
Medium Complexity:
-- Medium: Hide info for certain characters
hook.Add("CanDisplayCharInfo", "PrivacyMode", function(name)
local hiddenNames = {"admin", "moderator", "staff"}
for _, hidden in ipairs(hiddenNames) do
if string.find(string.lower(name), string.lower(hidden)) then
return false
end
end
return true
end)
High Complexity:
-- High: Complex privacy system
hook.Add("CanDisplayCharInfo", "AdvancedPrivacy", function(name)
local char = LocalPlayer():getChar()
if not char then return true end
-- Check if player has privacy mode enabled
if char:getData("privacyMode", false) then
return false
end
-- Check faction restrictions
local faction = char:getFaction()
if faction == "police" then
-- Police can see all info
return true
elseif faction == "citizen" then
-- Citizens can only see other citizens
local targetChar = lia.char.getCharacters()[name]
if targetChar and targetChar:getFaction() ~= "citizen" then
return false
end
end
return true
end)
CanOpenBagPanel
Purpose
Called to check if a bag panel can be opened
When Called
When attempting to open a bag's inventory panel
Parameters
item(Item): The bag item being opened
Returns
- boolean - True to allow, false to deny
Realm
Client
Example Usage
Low Complexity:
Medium Complexity:
-- Medium: Check if bag is locked
hook.Add("CanOpenBagPanel", "BagPanelCheck", function(item)
if item:getData("locked", false) then
LocalPlayer():ChatPrint("This bag is locked")
return false
end
return true
end)
High Complexity:
-- High: Complex bag access system
hook.Add("CanOpenBagPanel", "AdvancedBagAccess", function(item)
local char = LocalPlayer():getChar()
if not char then return false end
-- Check if bag is locked
if item:getData("locked", false) then
local hasKey = char:getInv():hasItem("bag_key_" .. item:getID())
if not hasKey then
LocalPlayer():ChatPrint("This bag is locked and you don't have the key")
return false
end
end
-- Check bag ownership
local owner = item:getData("owner")
if owner and owner ~= char:getID() then
LocalPlayer():ChatPrint("This bag belongs to someone else")
return false
end
return true
end)
CharListColumns
Purpose
Called to modify character list columns
When Called
When building the character list display
Parameters
columns(table): The columns to display in the character list
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add custom column
hook.Add("CharListColumns", "MyAddon", function(columns)
table.insert(columns, "Custom Column")
end)
Medium Complexity:
-- Medium: Modify existing columns
hook.Add("CharListColumns", "ColumnModification", function(columns)
-- Add custom columns
table.insert(columns, "Level")
table.insert(columns, "Faction")
-- Remove default columns
for i = #columns, 1, -1 do
if columns[i] == "Unwanted Column" then
table.remove(columns, i)
end
end
end)
High Complexity:
-- High: Complex column system
hook.Add("CharListColumns", "AdvancedColumns", function(columns)
-- Clear existing columns
columns = {}
-- Add custom columns
table.insert(columns, "Name")
table.insert(columns, "Level")
table.insert(columns, "Faction")
table.insert(columns, "Money")
table.insert(columns, "Last Seen")
-- Add faction-specific columns
local char = LocalPlayer():getChar()
if char then
local faction = char:getFaction()
if faction == "police" then
table.insert(columns, "Warnings")
table.insert(columns, "Arrests")
elseif faction == "medic" then
table.insert(columns, "Heals")
table.insert(columns, "Revives")
end
end
-- Add admin columns
if LocalPlayer():IsAdmin() then
table.insert(columns, "SteamID")
table.insert(columns, "IP Address")
end
end)
CharListEntry
Purpose
Called to modify character list entries
When Called
When building each character list entry
Parameters
entry(table): The character data for this entryrow(Panel): The row panel being created
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add custom data to entry
hook.Add("CharListEntry", "MyAddon", function(entry, row)
entry.customData = "Custom Value"
end)
Medium Complexity:
-- Medium: Modify entry display
hook.Add("CharListEntry", "EntryModification", function(entry, row)
-- Add level data
entry.level = entry.level or 1
-- Add faction data
entry.faction = entry.faction or "citizen"
-- Add money data
entry.money = entry.money or 0
end)
High Complexity:
-- High: Complex entry system
hook.Add("CharListEntry", "AdvancedEntry", function(entry, row)
-- Add level data
entry.level = entry.level or 1
-- Add faction data
entry.faction = entry.faction or "citizen"
-- Add money data
entry.money = entry.money or 0
-- Add last seen data
entry.lastSeen = entry.lastSeen or "Never"
-- Add faction-specific data
if entry.faction == "police" then
entry.warnings = entry.warnings or 0
entry.arrests = entry.arrests or 0
elseif entry.faction == "medic" then
entry.heals = entry.heals or 0
entry.revives = entry.revives or 0
end
-- Add admin data
if LocalPlayer():IsAdmin() then
entry.steamID = entry.steamID or "Unknown"
entry.ipAddress = entry.ipAddress or "Unknown"
end
-- Add custom styling
if entry.level >= 10 then
entry.isHighLevel = true
end
if entry.money >= 10000 then
entry.isRich = true
end
end)
CharListExtraDetails
Purpose
Called to add extra details to character list entries
When Called
When building character list entries with additional information
Parameters
client(Player): The client viewing the character listentry(table): The character data for this entrystored(table): The stored character data
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add basic extra details
hook.Add("CharListExtraDetails", "MyAddon", function(client, entry, stored)
entry.extraInfo = "Additional Information"
end)
Medium Complexity:
-- Medium: Add faction-specific details
hook.Add("CharListExtraDetails", "FactionDetails", function(client, entry, stored)
local faction = entry.faction or "citizen"
if faction == "police" then
entry.extraInfo = "Police Officer"
elseif faction == "medic" then
entry.extraInfo = "Medical Staff"
else
entry.extraInfo = "Civilian"
end
end)
High Complexity:
-- High: Complex extra details system
hook.Add("CharListExtraDetails", "AdvancedExtraDetails", function(client, entry, stored)
-- Add basic extra details
entry.extraInfo = "Additional Information"
-- Add faction-specific details
local faction = entry.faction or "citizen"
if faction == "police" then
entry.extraInfo = "Police Officer"
entry.rank = entry.rank or "Officer"
entry.badge = entry.badge or "0000"
elseif faction == "medic" then
entry.extraInfo = "Medical Staff"
entry.rank = entry.rank or "Nurse"
entry.license = entry.license or "N/A"
else
entry.extraInfo = "Civilian"
entry.occupation = entry.occupation or "Unemployed"
end
-- Add level-based details
local level = entry.level or 1
if level >= 10 then
entry.extraInfo = entry.extraInfo .. " (High Level)"
end
-- Add money-based details
local money = entry.money or 0
if money >= 10000 then
entry.extraInfo = entry.extraInfo .. " (Rich)"
end
-- Add admin details
if client:IsAdmin() then
entry.adminInfo = "Admin View"
entry.steamID = entry.steamID or "Unknown"
entry.ipAddress = entry.ipAddress or "Unknown"
end
end)
CharListLoaded
Purpose
Called when character list is loaded
When Called
When the character list data is successfully loaded
Parameters
newCharList(table): The loaded character list data
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log character list loading
hook.Add("CharListLoaded", "MyAddon", function(newCharList)
print("Character list loaded with " .. #newCharList .. " characters")
end)
Medium Complexity:
-- Medium: Process character list data
hook.Add("CharListLoaded", "CharListProcessing", function(newCharList)
-- Count characters by faction
local factionCount = {}
for _, char in ipairs(newCharList) do
local faction = char.faction or "citizen"
factionCount[faction] = (factionCount[faction] or 0) + 1
end
-- Display faction counts
for faction, count in pairs(factionCount) do
print(faction .. ": " .. count .. " characters")
end
end)
High Complexity:
-- High: Complex character list processing
hook.Add("CharListLoaded", "AdvancedCharListProcessing", function(newCharList)
-- Count characters by faction
local factionCount = {}
for _, char in ipairs(newCharList) do
local faction = char.faction or "citizen"
factionCount[faction] = (factionCount[faction] or 0) + 1
end
-- Display faction counts
for faction, count in pairs(factionCount) do
print(faction .. ": " .. count .. " characters")
end
-- Process character data
for _, char in ipairs(newCharList) do
-- Add level data
char.level = char.level or 1
-- Add faction data
char.faction = char.faction or "citizen"
-- Add money data
char.money = char.money or 0
-- Add last seen data
char.lastSeen = char.lastSeen or "Never"
-- Add faction-specific data
if char.faction == "police" then
char.warnings = char.warnings or 0
char.arrests = char.arrests or 0
elseif char.faction == "medic" then
char.heals = char.heals or 0
char.revives = char.revives or 0
end
end
-- Sort characters by level
table.sort(newCharList, function(a, b)
return (a.level or 1) > (b.level or 1)
end)
print("Character list loaded and processed with " .. #newCharList .. " characters")
end)
CharListUpdated
Purpose
Called when character list is updated
When Called
When the character list data is modified
Parameters
oldCharList(table): The previous character list datanewCharList(table): The updated character list data
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log character list updates
hook.Add("CharListUpdated", "MyAddon", function(oldCharList, newCharList)
print("Character list updated from " .. #oldCharList .. " to " .. #newCharList .. " characters")
end)
Medium Complexity:
-- Medium: Track character changes
hook.Add("CharListUpdated", "CharChangeTracking", function(oldCharList, newCharList)
-- Find new characters
for _, newChar in ipairs(newCharList) do
local found = false
for _, oldChar in ipairs(oldCharList) do
if oldChar.id == newChar.id then
found = true
break
end
end
if not found then
print("New character: " .. newChar.name)
end
end
-- Find removed characters
for _, oldChar in ipairs(oldCharList) do
local found = false
for _, newChar in ipairs(newCharList) do
if oldChar.id == newChar.id then
found = true
break
end
end
if not found then
print("Removed character: " .. oldChar.name)
end
end
end)
High Complexity:
-- High: Complex character list update system
hook.Add("CharListUpdated", "AdvancedCharListUpdate", function(oldCharList, newCharList)
-- Create lookup tables for efficient comparison
local oldChars = {}
for _, char in ipairs(oldCharList) do
oldChars[char.id] = char
end
local newChars = {}
for _, char in ipairs(newCharList) do
newChars[char.id] = char
end
-- Find new characters
for _, newChar in ipairs(newCharList) do
if not oldChars[newChar.id] then
print("New character: " .. newChar.name .. " (ID: " .. newChar.id .. ")")
end
end
-- Find removed characters
for _, oldChar in ipairs(oldCharList) do
if not newChars[oldChar.id] then
print("Removed character: " .. oldChar.name .. " (ID: " .. oldChar.id .. ")")
end
end
-- Find modified characters
for _, newChar in ipairs(newCharList) do
local oldChar = oldChars[newChar.id]
if oldChar then
-- Check for changes
if oldChar.name ~= newChar.name then
print("Character name changed: " .. oldChar.name .. " -> " .. newChar.name)
end
if oldChar.faction ~= newChar.faction then
print("Character faction changed: " .. oldChar.name .. " " .. oldChar.faction .. " -> " .. newChar.faction)
end
if oldChar.level ~= newChar.level then
print("Character level changed: " .. newChar.name .. " " .. oldChar.level .. " -> " .. newChar.level)
end
end
end
-- Update character counts
local oldCount = #oldCharList
local newCount = #newCharList
print("Character list updated: " .. oldCount .. " -> " .. newCount .. " characters")
end)
CharMenuClosed
Purpose
Called when the character menu is closed
When Called
When the character selection menu is closed
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log menu closing
hook.Add("CharMenuClosed", "MyAddon", function()
print("Character menu closed")
end)
Medium Complexity:
-- Medium: Clean up menu data
hook.Add("CharMenuClosed", "MenuCleanup", function()
-- Clear cached character data
lia.charCache = nil
print("Character menu closed and cache cleared")
end)
High Complexity:
-- High: Complex menu close handling
hook.Add("CharMenuClosed", "AdvancedMenuClose", function()
-- Clear cached character data
lia.charCache = nil
-- Reset menu state
lia.menuState = nil
-- Log menu close time
local closeTime = os.time()
lia.lastMenuClose = closeTime
print("Character menu closed at " .. os.date("%H:%M:%S", closeTime))
end)
CharMenuOpened
Purpose
Called when the character menu is opened
When Called
When the character selection menu is opened
Parameters
self(Panel): The character menu panel
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log menu opening
hook.Add("CharMenuOpened", "MyAddon", function(self)
print("Character menu opened")
end)
Medium Complexity:
-- Medium: Load character data
hook.Add("CharMenuOpened", "MenuDataLoad", function(self)
-- Load character list
lia.charList = lia.char.getAll()
print("Character menu opened with " .. #lia.charList .. " characters")
end)
High Complexity:
-- High: Complex menu open handling
hook.Add("CharMenuOpened", "AdvancedMenuOpen", function(self)
-- Load character list
lia.charList = lia.char.getAll()
-- Set menu state
lia.menuState = "open"
-- Log menu open time
local openTime = os.time()
lia.lastMenuOpen = openTime
-- Apply custom styling
if self then
self:SetBackgroundColor(Color(0, 0, 0, 200))
end
print("Character menu opened at " .. os.date("%H:%M:%S", openTime))
end)
ChatAddText
Purpose
Called to add text to the chat
When Called
When text is being added to the chatbox
Parameters
markup(table): The markup table containing text formatting
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log chat text
hook.Add("ChatAddText", "MyAddon", function(markup, ...)
print("Chat text added")
end)
Medium Complexity:
-- Medium: Modify chat text color
hook.Add("ChatAddText", "ChatColorMod", function(markup, ...)
-- Change text color based on content
local args = {...}
for i, arg in ipairs(args) do
if isstring(arg) and string.find(arg, "important") then
markup.color = Color(255, 0, 0)
end
end
end)
High Complexity:
-- High: Complex chat text processing
hook.Add("ChatAddText", "AdvancedChatText", function(markup, ...)
local args = {...}
-- Process each argument
for i, arg in ipairs(args) do
if isstring(arg) then
-- Highlight player names
if string.find(arg, LocalPlayer():Name()) then
markup.color = Color(255, 255, 0)
end
-- Filter inappropriate content
local bannedWords = {"spam", "hack"}
for _, word in ipairs(bannedWords) do
if string.find(string.lower(arg), string.lower(word)) then
return false -- Block the message
end
end
end
end
end)
ChatboxPanelCreated
Purpose
Called when the chatbox panel is created
When Called
When the chatbox UI panel is initialized
Parameters
panel(Panel): The chatbox panel
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log panel creation
hook.Add("ChatboxPanelCreated", "MyAddon", function(panel)
print("Chatbox panel created")
end)
Medium Complexity:
-- Medium: Customize chatbox appearance
hook.Add("ChatboxPanelCreated", "ChatboxCustomize", function(panel)
if panel then
panel:SetBackgroundColor(Color(0, 0, 0, 200))
end
end)
High Complexity:
-- High: Complex chatbox customization
hook.Add("ChatboxPanelCreated", "AdvancedChatbox", function(panel)
if not panel then return end
-- Customize appearance
panel:SetBackgroundColor(Color(0, 0, 0, 200))
panel:SetSize(500, 300)
-- Add custom buttons
local closeBtn = panel:Add("DButton")
closeBtn:SetText("X")
closeBtn:SetSize(20, 20)
closeBtn.DoClick = function()
panel:SetVisible(false)
end
print("Chatbox panel created and customized")
end)
ChatboxTextAdded
Purpose
Called when text is added to the chatbox
When Called
When new text is displayed in the chatbox
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log chatbox text
hook.Add("ChatboxTextAdded", "MyAddon", function(...)
print("Text added to chatbox")
end)
Medium Complexity:
-- Medium: Process chatbox text
hook.Add("ChatboxTextAdded", "ChatboxProcess", function(...)
local args = {...}
for i, arg in ipairs(args) do
if isstring(arg) then
print("Chatbox text: " .. arg)
end
end
end)
High Complexity:
-- High: Complex chatbox text handling
hook.Add("ChatboxTextAdded", "AdvancedChatboxText", function(...)
local args = {...}
-- Process each argument
for i, arg in ipairs(args) do
if isstring(arg) then
-- Highlight player mentions
if string.find(arg, "@" .. LocalPlayer():Name()) then
surface.PlaySound("buttons/button15.wav")
end
-- Log important messages
if string.find(arg, "[ADMIN]") or string.find(arg, "[SYSTEM]") then
lia.chatLog = lia.chatLog or {}
table.insert(lia.chatLog, {text = arg, time = os.time()})
end
end
end
end)
ChooseCharacter
Purpose
Called when a character is chosen
When Called
When a player selects a character to play
Parameters
id(number): The ID of the character being chosen
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log character choice
hook.Add("ChooseCharacter", "MyAddon", function(id)
print("Chose character ID: " .. id)
end)
Medium Complexity:
-- Medium: Cache character data
hook.Add("ChooseCharacter", "CharacterCache", function(id)
lia.selectedCharID = id
print("Selected character: " .. id)
end)
High Complexity:
-- High: Complex character selection
hook.Add("ChooseCharacter", "AdvancedCharSelect", function(id)
-- Cache character ID
lia.selectedCharID = id
-- Log selection time
lia.charSelectTime = os.time()
-- Play selection sound
surface.PlaySound("buttons/button14.wav")
-- Notify server
net.Start("CharacterSelected")
net.WriteUInt(id, 32)
net.SendToServer()
print("Selected character ID: " .. id .. " at " .. os.date("%H:%M:%S"))
end)
ConfigUpdated
Purpose
Called when a configuration is updated
When Called
When a config value is synchronized or updated
Parameters
key(string): The configuration key that was updated
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log config updates
hook.Add("ConfigUpdated", "MyAddon", function(key)
print("Config updated: " .. key)
end)
Medium Complexity:
-- Medium: Refresh UI on config update
hook.Add("ConfigUpdated", "ConfigUIRefresh", function(key)
if key == "theme" then
-- Refresh UI theme
lia.gui.refreshTheme()
end
end)
High Complexity:
-- High: Complex config update handling
hook.Add("ConfigUpdated", "AdvancedConfigUpdate", function(key)
-- Handle specific config updates
if key == "theme" then
lia.gui.refreshTheme()
elseif key == "language" then
lia.lang.refresh()
elseif key == "hud" then
lia.hud.refresh()
end
-- Cache updated config
lia.configCache = lia.configCache or {}
lia.configCache[key] = lia.config.get(key)
print("Config " .. key .. " updated and cached")
end)
ConfigureCharacterCreationSteps
Purpose
Called to configure character creation steps
When Called
When setting up the character creation process
Parameters
self(Panel): The character creation panel
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log creation step configuration
hook.Add("ConfigureCharacterCreationSteps", "MyAddon", function(self)
print("Configuring character creation steps")
end)
Medium Complexity:
-- Medium: Add custom creation step
hook.Add("ConfigureCharacterCreationSteps", "CustomStep", function(self)
if self then
self:AddStep("Custom", function(panel)
-- Custom step UI
local label = panel:Add("DLabel")
label:SetText("Custom Step")
end)
end
end)
High Complexity:
-- High: Complex creation step configuration
hook.Add("ConfigureCharacterCreationSteps", "AdvancedCreationSteps", function(self)
if not self then return end
-- Add custom background step
self:AddStep("Background", function(panel)
local label = panel:Add("DLabel")
label:SetText("Select Background")
label:Dock(TOP)
local combo = panel:Add("DComboBox")
combo:Dock(TOP)
combo:AddChoice("Soldier")
combo:AddChoice("Merchant")
combo:AddChoice("Scholar")
end)
-- Add custom traits step
self:AddStep("Traits", function(panel)
local label = panel:Add("DLabel")
label:SetText("Select Traits")
label:Dock(TOP)
for i = 1, 3 do
local checkbox = panel:Add("DCheckBoxLabel")
checkbox:SetText("Trait " .. i)
checkbox:Dock(TOP)
end
end)
print("Character creation steps configured")
end)
CreateChat
Purpose
Called to create the chat interface
When Called
When the chat UI is being initialized
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log chat creation
hook.Add("CreateChat", "MyAddon", function()
print("Chat interface created")
end)
Medium Complexity:
-- Medium: Customize chat appearance
hook.Add("CreateChat", "ChatCustomize", function()
if lia.chat then
lia.chat:SetBackgroundColor(Color(0, 0, 0, 200))
end
end)
High Complexity:
-- High: Complex chat customization
hook.Add("CreateChat", "AdvancedChatSetup", function()
if not lia.chat then return end
-- Customize appearance
lia.chat:SetBackgroundColor(Color(0, 0, 0, 200))
lia.chat:SetSize(500, 300)
-- Add custom chat tabs
lia.chat:AddTab("Global", Color(255, 255, 255))
lia.chat:AddTab("Local", Color(100, 200, 100))
lia.chat:AddTab("Admin", Color(255, 0, 0))
print("Chat interface created and customized")
end)
CreateInformationButtons
Purpose
Called to create information buttons in the F1 menu
When Called
When building the information panel buttons
Parameters
pages(table): The pages table to add buttons to
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add a basic information button
hook.Add("CreateInformationButtons", "MyAddon", function(pages)
pages["Custom"] = function(panel)
panel:Add("DLabel"):SetText("Custom Information")
end
end)
Medium Complexity:
-- Medium: Add multiple information pages
hook.Add("CreateInformationButtons", "InfoPages", function(pages)
pages["Rules"] = function(panel)
local label = panel:Add("DLabel")
label:SetText("Server Rules")
label:Dock(TOP)
end
pages["Commands"] = function(panel)
local label = panel:Add("DLabel")
label:SetText("Available Commands")
label:Dock(TOP)
end
end)
High Complexity:
-- High: Complex information pages
hook.Add("CreateInformationButtons", "AdvancedInfoPages", function(pages)
pages["Rules"] = function(panel)
local scroll = panel:Add("DScrollPanel")
scroll:Dock(FILL)
local rules = {
"1. No RDM",
"2. No prop spam",
"3. Respect staff"
}
for i, rule in ipairs(rules) do
local label = scroll:Add("DLabel")
label:SetText(rule)
label:Dock(TOP)
end
end
pages["Commands"] = function(panel)
local scroll = panel:Add("DScrollPanel")
scroll:Dock(FILL)
for cmd, data in pairs(lia.command.list) do
local label = scroll:Add("DLabel")
label:SetText("/" .. cmd .. " - " .. (data.description or "No description"))
label:Dock(TOP)
end
end
end)
CreateInventoryPanel
Purpose
Called to create an inventory panel
When Called
When an inventory UI panel needs to be created
Parameters
inventory(Inventory): The inventory to create a panel forparent(Panel): The parent panel
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log inventory panel creation
hook.Add("CreateInventoryPanel", "MyAddon", function(inventory, parent)
print("Creating inventory panel")
end)
Medium Complexity:
-- Medium: Customize inventory panel
hook.Add("CreateInventoryPanel", "InventoryCustomize", function(inventory, parent)
if parent then
parent:SetBackgroundColor(Color(50, 50, 50, 200))
end
end)
High Complexity:
-- High: Complex inventory panel customization
hook.Add("CreateInventoryPanel", "AdvancedInventoryPanel", function(inventory, parent)
if not parent then return end
-- Customize appearance
parent:SetBackgroundColor(Color(50, 50, 50, 200))
-- Add weight display
local weightLabel = parent:Add("DLabel")
weightLabel:SetText("Weight: " .. inventory:getWeight() .. "/" .. inventory:getMaxWeight())
weightLabel:Dock(BOTTOM)
-- Add money display
local char = LocalPlayer():getChar()
if char then
local moneyLabel = parent:Add("DLabel")
moneyLabel:SetText("Money: $" .. char:getMoney())
moneyLabel:Dock(BOTTOM)
end
print("Inventory panel created and customized")
end)
CreateMenuButtons
Purpose
Called to create menu buttons
When Called
When building the main menu button tabs
Parameters
tabs(table): The tabs table to add buttons to
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add a basic menu button
hook.Add("CreateMenuButtons", "MyAddon", function(tabs)
tabs["Custom"] = function(panel)
panel:Add("DLabel"):SetText("Custom Menu")
end
end)
Medium Complexity:
-- Medium: Add multiple menu tabs
hook.Add("CreateMenuButtons", "MenuTabs", function(tabs)
tabs["Settings"] = function(panel)
local label = panel:Add("DLabel")
label:SetText("Settings")
label:Dock(TOP)
end
tabs["Help"] = function(panel)
local label = panel:Add("DLabel")
label:SetText("Help & Support")
label:Dock(TOP)
end
end)
High Complexity:
-- High: Complex menu system
hook.Add("CreateMenuButtons", "AdvancedMenu", function(tabs)
tabs["Settings"] = function(panel)
local scroll = panel:Add("DScrollPanel")
scroll:Dock(FILL)
-- Add settings options
local options = {
{name = "Volume", type = "slider"},
{name = "FOV", type = "slider"},
{name = "HUD Scale", type = "slider"}
}
for _, option in ipairs(options) do
local container = scroll:Add("DPanel")
container:Dock(TOP)
container:SetHeight(50)
local label = container:Add("DLabel")
label:SetText(option.name)
label:Dock(LEFT)
if option.type == "slider" then
local slider = container:Add("DNumSlider")
slider:Dock(FILL)
end
end
end
end)
DermaSkinChanged
Purpose
Called when derma skin is changed
When Called
When the UI skin is changed
Parameters
newSkin(string): The new skin name
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log skin change
hook.Add("DermaSkinChanged", "MyAddon", function(newSkin)
print("Skin changed to: " .. newSkin)
end)
Medium Complexity:
-- Medium: Save skin preference
hook.Add("DermaSkinChanged", "SkinPreference", function(newSkin)
local char = LocalPlayer():getChar()
if char then
char:setData("preferredSkin", newSkin)
end
print("Skin changed to: " .. newSkin)
end)
High Complexity:
-- High: Complex skin management system
hook.Add("DermaSkinChanged", "AdvancedSkinManagement", function(newSkin)
local char = LocalPlayer():getChar()
if char then
char:setData("preferredSkin", newSkin)
end
-- Update UI elements
for _, panel in ipairs(vgui.GetWorldPanel():GetChildren()) do
if IsValid(panel) and panel.UpdateSkin then
panel:UpdateSkin(newSkin)
end
end
-- Save to file
file.Write("lilia_skin.txt", newSkin)
print("Skin changed to: " .. newSkin .. " and saved")
end)
DrawCharInfo
Purpose
Called to draw character information
When Called
When character information needs to be rendered
Parameters
client(Player): The player whose character info is being drawncharacter(Character): The character being displayedinfo(table): The information table to populate
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add basic character info
hook.Add("DrawCharInfo", "MyAddon", function(client, character, info)
info["Name"] = character:getName()
end)
Medium Complexity:
-- Medium: Add multiple character details
hook.Add("DrawCharInfo", "CharDetails", function(client, character, info)
info["Name"] = character:getName()
info["Faction"] = character:getFaction()
info["Money"] = "$" .. character:getMoney()
end)
High Complexity:
-- High: Complex character information display
hook.Add("DrawCharInfo", "AdvancedCharInfo", function(client, character, info)
-- Basic info
info["Name"] = character:getName()
info["Faction"] = character:getFaction()
info["Money"] = "$" .. character:getMoney()
-- Level and experience
local level = character:getData("level", 1)
local exp = character:getData("experience", 0)
info["Level"] = level .. " (" .. exp .. " XP)"
-- Attributes
local attributes = character:getAttribs()
for attr, value in pairs(attributes) do
info["Attribute: " .. attr] = value
end
-- Play time
local playTime = character:getData("playTime", 0)
local hours = math.floor(playTime / 3600)
local minutes = math.floor((playTime % 3600) / 60)
info["Play Time"] = hours .. "h " .. minutes .. "m"
end)
DrawDoorInfoBox
Purpose
Called to draw door information box
When Called
When rendering door information UI
Parameters
entity(Entity): The door entityinfoTexts(table): The information texts to displayalphaOverride(number): Alpha override value for transparency
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add basic door info
hook.Add("DrawDoorInfoBox", "MyAddon", function(entity, infoTexts, alphaOverride)
table.insert(infoTexts, "Door: " .. entity:EntIndex())
end)
Medium Complexity:
-- Medium: Add door ownership info
hook.Add("DrawDoorInfoBox", "DoorOwnership", function(entity, infoTexts, alphaOverride)
local owner = entity:getNetVar("owner")
if owner then
table.insert(infoTexts, "Owner: " .. owner)
else
table.insert(infoTexts, "Unowned")
end
end)
High Complexity:
-- High: Complex door information display
hook.Add("DrawDoorInfoBox", "AdvancedDoorInfo", function(entity, infoTexts, alphaOverride)
-- Door title
local title = entity:getNetVar("title", "Door")
table.insert(infoTexts, "Title: " .. title)
-- Owner info
local owner = entity:getNetVar("owner")
if owner then
table.insert(infoTexts, "Owner: " .. owner)
else
table.insert(infoTexts, "Unowned")
end
-- Price info
local price = entity:getNetVar("price", 0)
if price > 0 then
table.insert(infoTexts, "Price: $" .. price)
end
-- Lock status
local locked = entity:getNetVar("locked", false)
table.insert(infoTexts, "Status: " .. (locked and "Locked" or "Unlocked"))
-- Faction restriction
local faction = entity:getNetVar("faction")
if faction then
table.insert(infoTexts, "Faction: " .. faction)
end
end)
DrawEntityInfo
Purpose
Called to draw entity information
When Called
When rendering entity information UI
Parameters
entity(Entity): The entity to draw information foralpha(number): The alpha/transparency valueposition(Vector): The position to draw at
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add basic entity info
hook.Add("DrawEntityInfo", "MyAddon", function(entity, alpha, position)
draw.SimpleText(entity:GetClass(), "Default", position.x, position.y, Color(255, 255, 255, alpha))
end)
Medium Complexity:
-- Medium: Add entity details
hook.Add("DrawEntityInfo", "EntityDetails", function(entity, alpha, position)
local text = entity:GetClass()
if entity:GetModel() then
text = text .. "\n" .. entity:GetModel()
end
draw.SimpleText(text, "Default", position.x, position.y, Color(255, 255, 255, alpha))
end)
High Complexity:
-- High: Complex entity information display
hook.Add("DrawEntityInfo", "AdvancedEntityInfo", function(entity, alpha, position)
local y = position.y
-- Entity class
draw.SimpleText("Class: " .. entity:GetClass(), "Default", position.x, y, Color(255, 255, 255, alpha))
y = y + 15
-- Entity model
if entity:GetModel() then
draw.SimpleText("Model: " .. entity:GetModel(), "Default", position.x, y, Color(200, 200, 200, alpha))
y = y + 15
end
-- Entity health
if entity:Health() > 0 then
draw.SimpleText("Health: " .. entity:Health(), "Default", position.x, y, Color(100, 255, 100, alpha))
y = y + 15
end
-- Custom entity data
if entity.getName then
local name = entity:getName()
if name and name ~= "" then
draw.SimpleText("Name: " .. name, "Default", position.x, y, Color(255, 255, 100, alpha))
end
end
end)
DrawLiliaModelView
Purpose
Called to draw Lilia model view
When Called
When rendering a model view panel
Parameters
self(Panel): The model view panelent(Entity): The entity being displayed
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log model view drawing
hook.Add("DrawLiliaModelView", "MyAddon", function(self, ent)
print("Drawing model view")
end)
Medium Complexity:
-- Medium: Customize model view
hook.Add("DrawLiliaModelView", "ModelViewCustomize", function(self, ent)
if ent then
ent:SetAngles(Angle(0, 45, 0))
end
end)
High Complexity:
-- High: Complex model view customization
hook.Add("DrawLiliaModelView", "AdvancedModelView", function(self, ent)
if not ent then return end
-- Rotate model
local ang = ent:GetAngles()
ang.y = ang.y + FrameTime() * 30
ent:SetAngles(ang)
-- Apply lighting
local lightPos = ent:GetPos() + Vector(0, 0, 50)
render.SetLightingOrigin(lightPos)
-- Draw model with custom material
if ent.customMaterial then
ent:SetMaterial(ent.customMaterial)
end
end)
DrawPlayerRagdoll
Purpose
Called to draw a player's ragdoll
When Called
When rendering a player ragdoll entity
Parameters
entity(Entity): The ragdoll entity
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log ragdoll drawing
hook.Add("DrawPlayerRagdoll", "MyAddon", function(entity)
print("Drawing ragdoll: " .. entity:EntIndex())
end)
Medium Complexity:
-- Medium: Customize ragdoll appearance
hook.Add("DrawPlayerRagdoll", "RagdollCustomize", function(entity)
if entity:GetModel() then
entity:SetColor(Color(255, 200, 200))
end
end)
High Complexity:
-- High: Complex ragdoll rendering
hook.Add("DrawPlayerRagdoll", "AdvancedRagdoll", function(entity)
if not IsValid(entity) then return end
-- Apply custom material
local owner = entity:getNetVar("owner")
if owner then
local ply = player.GetBySteamID(owner)
if IsValid(ply) then
local char = ply:getChar()
if char then
-- Apply faction-based coloring
local faction = char:getFaction()
local colors = {
["police"] = Color(0, 0, 255),
["medic"] = Color(255, 255, 255),
["citizen"] = Color(200, 200, 200)
}
local color = colors[faction] or Color(255, 255, 255)
entity:SetColor(color)
end
end
end
-- Draw death time
local deathTime = entity:getNetVar("deathTime", 0)
if deathTime > 0 then
local timeSinceDeath = CurTime() - deathTime
local pos = entity:GetPos() + Vector(0, 0, 50)
local ang = LocalPlayer():EyeAngles()
ang:RotateAroundAxis(ang:Forward(), 90)
ang:RotateAroundAxis(ang:Right(), 90)
cam.Start3D2D(pos, ang, 0.1)
draw.SimpleText("Dead for: " .. math.floor(timeSinceDeath) .. "s", "Default", 0, 0, Color(255, 255, 255), TEXT_ALIGN_CENTER)
cam.End3D2D()
end
end)
ExitStorage
Purpose
Called when exiting storage
When Called
When a player closes a storage container
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log storage exit
hook.Add("ExitStorage", "MyAddon", function()
print("Exited storage")
end)
Medium Complexity:
-- Medium: Clean up storage UI
hook.Add("ExitStorage", "StorageCleanup", function()
if lia.storagePanel then
lia.storagePanel:Remove()
lia.storagePanel = nil
end
end)
High Complexity:
-- High: Complex storage exit handling
hook.Add("ExitStorage", "AdvancedStorageExit", function()
-- Clean up storage UI
if lia.storagePanel then
lia.storagePanel:Remove()
lia.storagePanel = nil
end
-- Clear storage cache
lia.currentStorage = nil
-- Log storage exit time
local exitTime = os.time()
lia.lastStorageExit = exitTime
-- Calculate storage session duration
if lia.storageEnterTime then
local duration = exitTime - lia.storageEnterTime
print("Storage session duration: " .. duration .. " seconds")
lia.storageEnterTime = nil
end
-- Notify server
net.Start("StorageExited")
net.SendToServer()
end)
F1MenuClosed
Purpose
Called when the F1 menu is closed
When Called
When the F1 character information menu is closed
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log F1 menu closing
hook.Add("F1MenuClosed", "MyAddon", function()
print("F1 menu closed")
end)
Medium Complexity:
-- Medium: Clean up F1 menu data
hook.Add("F1MenuClosed", "F1MenuCleanup", function()
lia.f1MenuOpen = false
print("F1 menu closed and state updated")
end)
High Complexity:
-- High: Complex F1 menu close handling
hook.Add("F1MenuClosed", "AdvancedF1Close", function()
-- Update menu state
lia.f1MenuOpen = false
-- Log menu close time
local closeTime = os.time()
lia.lastF1Close = closeTime
-- Calculate menu session duration
if lia.f1OpenTime then
local duration = closeTime - lia.f1OpenTime
print("F1 menu session duration: " .. duration .. " seconds")
lia.f1OpenTime = nil
end
-- Clear cached character data
lia.f1CharCache = nil
print("F1 menu closed at " .. os.date("%H:%M:%S", closeTime))
end)
F1MenuOpened
Purpose
Called when the F1 menu is opened
When Called
When the F1 character information menu is opened
Parameters
self(Panel): The F1 menu panel
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log F1 menu opening
hook.Add("F1MenuOpened", "MyAddon", function(self)
print("F1 menu opened")
end)
Medium Complexity:
-- Medium: Update F1 menu state
hook.Add("F1MenuOpened", "F1MenuState", function(self)
lia.f1MenuOpen = true
lia.f1OpenTime = os.time()
print("F1 menu opened")
end)
High Complexity:
-- High: Complex F1 menu open handling
hook.Add("F1MenuOpened", "AdvancedF1Open", function(self)
-- Update menu state
lia.f1MenuOpen = true
-- Log menu open time
local openTime = os.time()
lia.f1OpenTime = openTime
-- Cache character data
local char = LocalPlayer():getChar()
if char then
lia.f1CharCache = {
name = char:getName(),
faction = char:getFaction(),
money = char:getMoney(),
level = char:getData("level", 1)
}
end
-- Customize panel appearance
if self then
self:SetBackgroundColor(Color(0, 0, 0, 200))
end
print("F1 menu opened at " .. os.date("%H:%M:%S", openTime))
end)
FilterCharModels
Purpose
Called to filter character models
When Called
When character models need to be filtered or restricted
Parameters
models(table): The table of available models to filter
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log model filtering
hook.Add("FilterCharModels", "MyAddon", function(models)
print("Filtering " .. #models .. " character models")
end)
Medium Complexity:
-- Medium: Remove specific models
hook.Add("FilterCharModels", "ModelRestriction", function(models)
local bannedModels = {
"models/player/combine_soldier.mdl",
"models/player/combine_super_soldier.mdl"
}
for i = #models, 1, -1 do
if table.HasValue(bannedModels, models[i]) then
table.remove(models, i)
end
end
end)
High Complexity:
-- High: Complex model filtering system
hook.Add("FilterCharModels", "AdvancedModelFilter", function(models)
local char = LocalPlayer():getChar()
if not char then return end
local faction = char:getFaction()
-- Faction-specific model restrictions
local factionModels = {
["police"] = {
allowed = {"models/player/police.mdl", "models/player/cop.mdl"},
banned = {"models/player/criminal.mdl"}
},
["criminal"] = {
allowed = {"models/player/criminal.mdl", "models/player/thug.mdl"},
banned = {"models/player/police.mdl"}
}
}
local restrictions = factionModels[faction]
if restrictions then
for i = #models, 1, -1 do
local model = models[i]
-- Check if model is banned
if table.HasValue(restrictions.banned, model) then
table.remove(models, i)
-- Check if only specific models are allowed
elseif restrictions.allowed and #restrictions.allowed > 0 then
if not table.HasValue(restrictions.allowed, model) then
table.remove(models, i)
end
end
end
end
print("Filtered models for " .. faction .. ": " .. #models .. " remaining")
end)
FilterDoorInfo
Purpose
Called to filter door information
When Called
When door information is being displayed
Parameters
entity(Entity): The door entitydoorData(table): The door datadoorInfo(table): The door information to filter
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log door info filtering
hook.Add("FilterDoorInfo", "MyAddon", function(entity, doorData, doorInfo)
print("Filtering door info for " .. entity:EntIndex())
end)
Medium Complexity:
-- Medium: Hide sensitive door information
hook.Add("FilterDoorInfo", "DoorInfoSecurity", function(entity, doorData, doorInfo)
local char = LocalPlayer():getChar()
if not char then return end
-- Hide owner info for non-owners
local owner = entity:getNetVar("owner")
if owner and owner ~= char:getID() then
doorInfo.owner = "Hidden"
end
end)
High Complexity:
-- High: Complex door information filtering
hook.Add("FilterDoorInfo", "AdvancedDoorInfoFilter", function(entity, doorData, doorInfo)
local char = LocalPlayer():getChar()
if not char then return end
local faction = char:getFaction()
local owner = entity:getNetVar("owner")
local isOwner = owner and owner == char:getID()
-- Filter based on ownership
if not isOwner then
-- Hide sensitive information from non-owners
doorInfo.owner = "Private"
doorInfo.price = "Hidden"
doorInfo.sharedWith = nil
end
-- Filter based on faction
if faction == "police" then
-- Police can see more information
doorInfo.locked = entity:getNetVar("locked", false)
doorInfo.faction = entity:getNetVar("faction")
elseif faction == "criminal" then
-- Criminals see limited information
doorInfo.owner = "Unknown"
doorInfo.price = "Unknown"
end
-- Add faction-specific warnings
local doorFaction = entity:getNetVar("faction")
if doorFaction and doorFaction ~= faction then
doorInfo.warning = "Restricted Access"
end
end)
GetAdjustedPartData
Purpose
Called to get adjusted PAC part data
When Called
When retrieving PAC part data with adjustments applied
Parameters
wearer(Player): The player wearing the partid(string): The part ID
Returns
- table - The adjusted part data
Realm
Client
Example Usage
Low Complexity:
-- Simple: Return basic part data
hook.Add("GetAdjustedPartData", "MyAddon", function(wearer, id)
return {scale = 1, color = Color(255, 255, 255)}
end)
Medium Complexity:
-- Medium: Apply basic adjustments
hook.Add("GetAdjustedPartData", "PartAdjustments", function(wearer, id)
local char = wearer:getChar()
if not char then return {} end
local data = {scale = 1, color = Color(255, 255, 255)}
-- Apply faction-based adjustments
local faction = char:getFaction()
if faction == "police" then
data.color = Color(0, 0, 255)
elseif faction == "medic" then
data.color = Color(255, 255, 255)
end
return data
end)
High Complexity:
-- High: Complex part data adjustment system
hook.Add("GetAdjustedPartData", "AdvancedPartData", function(wearer, id)
local char = wearer:getChar()
if not char then return {} end
local data = {scale = 1, color = Color(255, 255, 255)}
-- Apply faction-based adjustments
local faction = char:getFaction()
local factionMods = {
["police"] = {color = Color(0, 0, 255), scale = 1.1},
["medic"] = {color = Color(255, 255, 255), scale = 1.0},
["criminal"] = {color = Color(255, 0, 0), scale = 0.9}
}
local mod = factionMods[faction]
if mod then
data.color = mod.color
data.scale = mod.scale
end
-- Apply level-based adjustments
local level = char:getData("level", 1)
if level >= 10 then
data.scale = data.scale * 1.2
end
-- Apply character-specific data
local charData = char:getData("partMods", {})
if charData[id] then
for key, value in pairs(charData[id]) do
data[key] = value
end
end
return data
end)
GetDoorInfoForAdminStick
Purpose
Called to get door information for admin stick
When Called
When displaying door information in the admin stick HUD
Parameters
target(Entity): The door entityextraInfo(table): Additional information to add
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add basic door info
hook.Add("GetDoorInfoForAdminStick", "MyAddon", function(target, extraInfo)
table.insert(extraInfo, "Door: " .. target:EntIndex())
end)
Medium Complexity:
-- Medium: Add door ownership info
hook.Add("GetDoorInfoForAdminStick", "DoorOwnership", function(target, extraInfo)
local owner = target:getNetVar("owner")
if owner then
table.insert(extraInfo, "Owner: " .. owner)
else
table.insert(extraInfo, "Unowned")
end
local locked = target:getNetVar("locked", false)
table.insert(extraInfo, "Status: " .. (locked and "Locked" or "Unlocked"))
end)
High Complexity:
-- High: Complex door information display
hook.Add("GetDoorInfoForAdminStick", "AdvancedDoorInfo", function(target, extraInfo)
-- Door title
local title = target:getNetVar("title", "Door")
table.insert(extraInfo, "Title: " .. title)
-- Owner information
local owner = target:getNetVar("owner")
if owner then
local ownerChar = lia.char.getByID(owner)
if ownerChar then
table.insert(extraInfo, "Owner: " .. ownerChar:getName() .. " (ID: " .. owner .. ")")
else
table.insert(extraInfo, "Owner: " .. owner)
end
else
table.insert(extraInfo, "Unowned")
end
-- Price information
local price = target:getNetVar("price", 0)
if price > 0 then
table.insert(extraInfo, "Price: $" .. price)
end
-- Lock status
local locked = target:getNetVar("locked", false)
table.insert(extraInfo, "Status: " .. (locked and "Locked" or "Unlocked"))
-- Faction restriction
local faction = target:getNetVar("faction")
if faction then
table.insert(extraInfo, "Faction: " .. faction)
end
-- Shared with information
local sharedWith = target:getNetVar("sharedWith", {})
if #sharedWith > 0 then
table.insert(extraInfo, "Shared with: " .. #sharedWith .. " players")
end
end)
GetInjuredText
Purpose
Called to get injured text
When Called
When displaying injury status text
Parameters
c(Character): The character to get injury text for
Returns
- string - The injury text to display
Realm
Client
Example Usage
Low Complexity:
-- Simple: Return basic injury text
hook.Add("GetInjuredText", "MyAddon", function(c)
return "Injured"
end)
Medium Complexity:
-- Medium: Base text on health level
hook.Add("GetInjuredText", "HealthBasedText", function(c)
local health = c:getData("health", 100)
if health <= 0 then
return "Dead"
elseif health <= 25 then
return "Critically Injured"
elseif health <= 50 then
return "Badly Injured"
elseif health <= 75 then
return "Slightly Injured"
else
return "Healthy"
end
end)
High Complexity:
-- High: Complex injury text system
hook.Add("GetInjuredText", "AdvancedInjuryText", function(c)
local health = c:getData("health", 100)
local maxHealth = c:getData("maxHealth", 100)
local healthPercent = (health / maxHealth) * 100
local injuryText = ""
-- Health status
if health <= 0 then
injuryText = "Dead"
elseif healthPercent <= 10 then
injuryText = "Critically Injured"
elseif healthPercent <= 25 then
injuryText = "Badly Injured"
elseif healthPercent <= 50 then
injuryText = "Injured"
elseif healthPercent <= 75 then
injuryText = "Slightly Injured"
else
injuryText = "Healthy"
end
-- Add specific injury types
local injuries = c:getData("injuries", {})
if #injuries > 0 then
injuryText = injuryText .. " (" .. table.concat(injuries, ", ") .. ")"
end
-- Add bleeding status
if c:getData("bleeding", false) then
injuryText = injuryText .. " [BLEEDING]"
end
-- Add unconscious status
if c:getData("unconscious", false) then
injuryText = "Unconscious"
end
return injuryText
end)
GetMainMenuPosition
Purpose
Called to get main menu position
When Called
When positioning the main menu UI
Parameters
character(Character): The character to position menu for
Returns
- table - Position data for the menu
Realm
Client
Example Usage
Low Complexity:
-- Simple: Return default position
hook.Add("GetMainMenuPosition", "MyAddon", function(character)
return {x = 100, y = 100}
end)
Medium Complexity:
-- Medium: Position based on screen size
hook.Add("GetMainMenuPosition", "ScreenBasedPosition", function(character)
local w, h = ScrW(), ScrH()
return {
x = w * 0.1,
y = h * 0.1,
w = w * 0.8,
h = h * 0.8
}
end)
High Complexity:
-- High: Complex menu positioning system
hook.Add("GetMainMenuPosition", "AdvancedMenuPosition", function(character)
local w, h = ScrW(), ScrH()
-- Get character-specific settings
local charData = character:getData("menuSettings", {})
local savedPos = charData.position
if savedPos then
-- Use saved position
return {
x = savedPos.x,
y = savedPos.y,
w = savedPos.w or w * 0.8,
h = savedPos.h or h * 0.8
}
end
-- Default positioning based on faction
local faction = character:getFaction()
local positions = {
["police"] = {x = w * 0.05, y = h * 0.05},
["medic"] = {x = w * 0.1, y = h * 0.1},
["citizen"] = {x = w * 0.15, y = h * 0.15}
}
local pos = positions[faction] or {x = w * 0.1, y = h * 0.1}
return {
x = pos.x,
y = pos.y,
w = w * 0.8,
h = h * 0.8
}
end)
GetWeaponName
Purpose
Called to get weapon name
When Called
When displaying the name of a weapon
Parameters
weapon(Weapon): The weapon entity
Returns
- string - The display name of the weapon
Realm
Client
Example Usage
Low Complexity:
-- Simple: Return weapon class name
hook.Add("GetWeaponName", "MyAddon", function(weapon)
return weapon:GetClass()
end)
Medium Complexity:
-- Medium: Use weapon print name
hook.Add("GetWeaponName", "WeaponPrintName", function(weapon)
return weapon:GetPrintName() or weapon:GetClass()
end)
High Complexity:
-- High: Complex weapon naming system
hook.Add("GetWeaponName", "AdvancedWeaponNaming", function(weapon)
local baseName = weapon:GetPrintName() or weapon:GetClass()
-- Check for custom weapon data
local weaponData = weapon:getNetVar("weaponData", {})
if weaponData.customName then
baseName = weaponData.customName
end
-- Add quality prefix
local quality = weaponData.quality or "common"
local qualityPrefixes = {
["common"] = "",
["uncommon"] = "[Uncommon] ",
["rare"] = "[Rare] ",
["epic"] = "[Epic] ",
["legendary"] = "[Legendary] "
}
local qualityPrefix = qualityPrefixes[quality] or ""
-- Add enchantment suffix
local enchantments = weaponData.enchantments or {}
local enchantmentSuffix = ""
if #enchantments > 0 then
enchantmentSuffix = " of " .. table.concat(enchantments, ", ")
end
-- Add durability suffix
local durability = weaponData.durability
local maxDurability = weaponData.maxDurability
if durability and maxDurability then
local durabilityPercent = (durability / maxDurability) * 100
if durabilityPercent < 25 then
enchantmentSuffix = enchantmentSuffix .. " (Damaged)"
elseif durabilityPercent < 50 then
enchantmentSuffix = enchantmentSuffix .. " (Worn)"
end
end
return qualityPrefix .. baseName .. enchantmentSuffix
end)
HUDVisibilityChanged
Purpose
Called when HUD visibility changes
When Called
When the HUD is shown or hidden
Parameters
visible(boolean): Whether the HUD is visible
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log visibility change
hook.Add("HUDVisibilityChanged", "MyAddon", function(visible)
print("HUD visibility: " .. tostring(visible))
end)
Medium Complexity:
-- Medium: Toggle custom UI elements
hook.Add("HUDVisibilityChanged", "CustomUIToggle", function(visible)
if IsValid(MyCustomPanel) then
MyCustomPanel:SetVisible(visible)
end
end)
High Complexity:
-- High: Complex HUD visibility management
hook.Add("HUDVisibilityChanged", "AdvancedHUDManagement", function(visible)
-- Toggle all custom UI elements
local customPanels = {"MyCustomPanel", "MyInventoryPanel", "MyStatsPanel"}
for _, panelName in ipairs(customPanels) do
local panel = _G[panelName]
if IsValid(panel) then
panel:SetVisible(visible)
end
end
-- Save visibility state
local char = LocalPlayer():getChar()
if char then
char:setData("hudVisible", visible)
end
-- Trigger custom events
if visible then
hook.Run("CustomHUDShown")
else
hook.Run("CustomHUDHidden")
end
end)
InitializedKeybinds
Purpose
Called when keybinds are initialized
When Called
When the keybind system has finished loading
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log keybind initialization
hook.Add("InitializedKeybinds", "MyAddon", function()
print("Keybinds initialized")
end)
Medium Complexity:
-- Medium: Register custom keybinds
hook.Add("InitializedKeybinds", "CustomKeybinds", function()
lia.keybind.add("my_action", "My Action", KEY_F1, function()
print("My action triggered!")
end)
end)
High Complexity:
-- High: Complex keybind initialization system
hook.Add("InitializedKeybinds", "AdvancedKeybindInit", function()
-- Register custom keybinds
local keybinds = {
{
key = "my_action",
name = "My Action",
keyCode = KEY_F1,
callback = function()
print("My action triggered!")
end
},
{
key = "my_other_action",
name = "My Other Action",
keyCode = KEY_F2,
callback = function()
print("My other action triggered!")
end
}
}
for _, keybind in ipairs(keybinds) do
lia.keybind.add(keybind.key, keybind.name, keybind.keyCode, keybind.callback)
end
-- Set up keybind categories
lia.keybind.addCategory("My Addon", "Custom keybinds for my addon")
-- Load saved keybind settings
local savedKeybinds = lia.data.get("myAddonKeybinds", {})
for key, keyCode in pairs(savedKeybinds) do
lia.keybind.setKey(key, keyCode)
end
print("Keybind system initialized with " .. #keybinds .. " custom keybinds")
end)
InitializedOptions
Purpose
Called when options are initialized
When Called
When the option system has finished loading
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log option initialization
hook.Add("InitializedOptions", "MyAddon", function()
print("Options initialized")
end)
Medium Complexity:
-- Medium: Register custom options
hook.Add("InitializedOptions", "CustomOptions", function()
lia.option.add("myOption", "My Option", "A custom option", true)
end)
High Complexity:
-- High: Complex option initialization system
hook.Add("InitializedOptions", "AdvancedOptionInit", function()
-- Register custom options
local options = {
{
key = "myOption",
name = "My Option",
description = "A custom option",
default = true,
type = "boolean"
},
{
key = "myValue",
name = "My Value",
description = "A custom value",
default = 100,
type = "number",
min = 0,
max = 1000
},
{
key = "myString",
name = "My String",
description = "A custom string",
default = "default",
type = "string"
}
}
for _, option in ipairs(options) do
lia.option.add(option.key, option.name, option.description, option.default)
end
-- Set up option callbacks
lia.option.addCallback("myOption", function(value)
print("My option changed: " .. tostring(value))
end)
-- Load saved options
local savedOptions = lia.data.get("myAddonOptions", {})
for key, value in pairs(savedOptions) do
lia.option.set(key, value)
end
print("Option system initialized with " .. #options .. " custom options")
end)
InteractionMenuClosed
Purpose
Called when the interaction menu is closed
When Called
When the interaction menu UI is closed
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log menu closing
hook.Add("InteractionMenuClosed", "MyAddon", function()
print("Interaction menu closed")
end)
Medium Complexity:
-- Medium: Clean up menu data
hook.Add("InteractionMenuClosed", "MenuCleanup", function()
lia.interactionMenuOpen = false
lia.currentInteractionTarget = nil
end)
High Complexity:
-- High: Complex interaction menu close handling
hook.Add("InteractionMenuClosed", "AdvancedMenuClose", function()
-- Update menu state
lia.interactionMenuOpen = false
-- Clear interaction target
lia.currentInteractionTarget = nil
-- Log menu close time
local closeTime = os.time()
lia.lastInteractionMenuClose = closeTime
-- Calculate menu session duration
if lia.interactionMenuOpenTime then
local duration = closeTime - lia.interactionMenuOpenTime
print("Interaction menu session duration: " .. duration .. " seconds")
lia.interactionMenuOpenTime = nil
end
-- Clear cached interaction data
lia.interactionCache = nil
print("Interaction menu closed at " .. os.date("%H:%M:%S", closeTime))
end)
InteractionMenuOpened
Purpose
Called when the interaction menu is opened
When Called
When the interaction menu UI is opened
Parameters
frame(Panel): The interaction menu frame
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log menu opening
hook.Add("InteractionMenuOpened", "MyAddon", function(frame)
print("Interaction menu opened")
end)
Medium Complexity:
-- Medium: Update menu state
hook.Add("InteractionMenuOpened", "MenuState", function(frame)
lia.interactionMenuOpen = true
lia.interactionMenuOpenTime = os.time()
end)
High Complexity:
-- High: Complex interaction menu open handling
hook.Add("InteractionMenuOpened", "AdvancedMenuOpen", function(frame)
-- Update menu state
lia.interactionMenuOpen = true
-- Log menu open time
local openTime = os.time()
lia.interactionMenuOpenTime = openTime
-- Cache interaction target
local target = lia.util.getEntityInDirection(LocalPlayer())
if IsValid(target) then
lia.currentInteractionTarget = target
-- Cache interaction data
lia.interactionCache = {
entity = target,
class = target:GetClass(),
model = target:GetModel(),
position = target:GetPos()
}
end
-- Customize frame appearance
if frame then
frame:SetBackgroundColor(Color(0, 0, 0, 200))
frame:SetSize(300, 400)
end
print("Interaction menu opened at " .. os.date("%H:%M:%S", openTime))
end)
InterceptClickItemIcon
Purpose
Called when an item icon is clicked
When Called
When a player clicks on an item icon in inventory
Parameters
self(Panel): The inventory panelitemIcon(Panel): The item icon that was clickedkeyCode(number): The mouse button code
Returns
- boolean - True to intercept, false to allow
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log item clicks
hook.Add("InterceptClickItemIcon", "MyAddon", function(self, itemIcon, keyCode)
print("Item clicked: " .. (itemIcon.item and itemIcon.item.name or "Unknown"))
end)
Medium Complexity:
-- Medium: Custom right-click menu
hook.Add("InterceptClickItemIcon", "CustomItemMenu", function(self, itemIcon, keyCode)
if keyCode == MOUSE_RIGHT then
local menu = DermaMenu()
menu:AddOption("Use", function()
itemIcon.item:use()
end)
menu:AddOption("Drop", function()
itemIcon.item:drop()
end)
menu:Open()
return true
end
end)
High Complexity:
-- High: Complex item interaction system
hook.Add("InterceptClickItemIcon", "AdvancedItemInteraction", function(self, itemIcon, keyCode)
if not itemIcon.item then return end
local item = itemIcon.item
local char = LocalPlayer():getChar()
if not char then return end
-- Right-click for context menu
if keyCode == MOUSE_RIGHT then
local menu = DermaMenu()
-- Add use option
menu:AddOption("Use", function()
item:use()
end)
-- Add drop option if not equipped
if not item:getData("equipped", false) then
menu:AddOption("Drop", function()
item:drop()
end)
end
-- Add equip/unequip option
if item:getData("equipped", false) then
menu:AddOption("Unequip", function()
item:unequip()
end)
else
menu:AddOption("Equip", function()
item:equip()
end)
end
-- Add examine option
menu:AddOption("Examine", function()
item:examine()
end)
menu:Open()
return true
end
-- Middle-click for quick use
if keyCode == MOUSE_MIDDLE then
item:use()
return true
end
end)
InventoryClosed
Purpose
Called when an inventory is closed
When Called
When a player closes an inventory panel
Parameters
self(Panel): The inventory panelinventory(Inventory): The inventory that was closed
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log inventory close
hook.Add("InventoryClosed", "MyAddon", function(self, inventory)
print("Inventory closed")
end)
Medium Complexity:
-- Medium: Save inventory state
hook.Add("InventoryClosed", "SaveInventoryState", function(self, inventory)
local char = LocalPlayer():getChar()
if char then
char:setData("lastInventoryClose", os.time())
end
end)
High Complexity:
-- High: Complex inventory close handling
hook.Add("InventoryClosed", "AdvancedInventoryClose", function(self, inventory)
local char = LocalPlayer():getChar()
if not char then return end
-- Save inventory state
char:setData("lastInventoryClose", os.time())
-- Check for unsaved changes
if inventory:hasUnsavedChanges() then
Derma_Query(
"You have unsaved changes. Save before closing?",
"Unsaved Changes",
"Save",
function()
inventory:save()
end,
"Don't Save",
function()
inventory:revert()
end
)
end
-- Clear selection
inventory:clearSelection()
-- Trigger custom event
hook.Run("CustomInventoryClosed", inventory)
end)
InventoryItemIconCreated
Purpose
Called when an inventory item icon is created
When Called
When building the visual icon for an item in inventory
Parameters
icon(Panel): The icon panel being createditem(Item): The item the icon representsself(Panel): The inventory panel
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log icon creation
hook.Add("InventoryItemIconCreated", "MyAddon", function(icon, item, self)
print("Item icon created: " .. item.name)
end)
Medium Complexity:
-- Medium: Customize icon appearance
hook.Add("InventoryItemIconCreated", "CustomizeItemIcon", function(icon, item, self)
-- Set icon size
icon:SetSize(64, 64)
-- Add quality border
local quality = item:getData("quality", "common")
if quality == "rare" then
icon:SetBorderColor(Color(0, 100, 255))
elseif quality == "epic" then
icon:SetBorderColor(Color(150, 0, 255))
end
end)
High Complexity:
-- High: Complex item icon customization
hook.Add("InventoryItemIconCreated", "AdvancedItemIcon", function(icon, item, self)
-- Set icon size
icon:SetSize(64, 64)
-- Add quality border
local quality = item:getData("quality", "common")
local borderColors = {
["common"] = Color(150, 150, 150),
["uncommon"] = Color(0, 200, 0),
["rare"] = Color(0, 100, 255),
["epic"] = Color(150, 0, 255),
["legendary"] = Color(255, 200, 0)
}
icon:SetBorderColor(borderColors[quality] or Color(150, 150, 150))
-- Add durability bar
local durability = item:getData("durability")
if durability then
local durabilityBar = icon:Add("DPanel")
durabilityBar:SetSize(icon:GetWide(), 5)
durabilityBar:SetPos(0, icon:GetTall() - 5)
local durabilityPercent = durability / 100
local barColor = Color(255 * (1 - durabilityPercent), 255 * durabilityPercent, 0)
durabilityBar:SetBackgroundColor(barColor)
end
-- Add quantity label
local quantity = item:getData("quantity", 1)
if quantity > 1 then
local quantityLabel = icon:Add("DLabel")
quantityLabel:SetText("x" .. quantity)
quantityLabel:SetFont("DermaDefaultBold")
quantityLabel:SetTextColor(Color(255, 255, 255))
quantityLabel:SizeToContents()
quantityLabel:SetPos(icon:GetWide() - quantityLabel:GetWide() - 5, 5)
end
-- Add equipped indicator
if item:getData("equipped", false) then
local equippedIcon = icon:Add("DLabel")
equippedIcon:SetText("E")
equippedIcon:SetFont("DermaDefaultBold")
equippedIcon:SetTextColor(Color(0, 255, 0))
equippedIcon:SizeToContents()
equippedIcon:SetPos(5, 5)
end
end)
InventoryOpened
Purpose
Called when an inventory is opened
When Called
When a player opens an inventory panel
Parameters
panel(Panel): The inventory panelinventory(Inventory): The inventory being opened
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log inventory open
hook.Add("InventoryOpened", "MyAddon", function(panel, inventory)
print("Inventory opened")
end)
Medium Complexity:
-- Medium: Save open state
hook.Add("InventoryOpened", "SaveInventoryOpen", function(panel, inventory)
local char = LocalPlayer():getChar()
if char then
char:setData("lastInventoryOpen", os.time())
end
end)
High Complexity:
-- High: Complex inventory open handling
hook.Add("InventoryOpened", "AdvancedInventoryOpen", function(panel, inventory)
local char = LocalPlayer():getChar()
if not char then return end
-- Save open state
char:setData("lastInventoryOpen", os.time())
-- Customize panel appearance
panel:SetBackgroundColor(Color(50, 50, 50, 200))
panel:SetSize(600, 400)
panel:Center()
-- Add custom title
local title = panel:Add("DLabel")
title:SetText("Inventory - " .. char:getName())
title:SetFont("DermaLarge")
title:Dock(TOP)
title:SetHeight(30)
-- Add weight display
local weight = inventory:getData("weight", 0)
local maxWeight = inventory:getData("maxWeight", 100)
local weightLabel = panel:Add("DLabel")
weightLabel:SetText(string.format("Weight: %d / %d", weight, maxWeight))
weightLabel:Dock(BOTTOM)
weightLabel:SetHeight(20)
-- Trigger custom event
hook.Run("CustomInventoryOpened", inventory)
end)
InventoryPanelCreated
Purpose
Called when an inventory panel is created
When Called
When building an inventory UI panel
Parameters
panel(Panel): The inventory panel being createdinventory(Inventory): The inventory the panel representsparent(Panel): The parent panel
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log panel creation
hook.Add("InventoryPanelCreated", "MyAddon", function(panel, inventory, parent)
print("Inventory panel created")
end)
Medium Complexity:
-- Medium: Customize panel appearance
hook.Add("InventoryPanelCreated", "CustomizeInventoryPanel", function(panel, inventory, parent)
panel:SetBackgroundColor(Color(50, 50, 50, 200))
panel:SetSize(500, 350)
end)
High Complexity:
-- High: Complex inventory panel customization
hook.Add("InventoryPanelCreated", "AdvancedInventoryPanel", function(panel, inventory, parent)
-- Customize appearance
panel:SetBackgroundColor(Color(50, 50, 50, 200))
panel:SetSize(600, 400)
-- Add title bar
local titleBar = panel:Add("DPanel")
titleBar:Dock(TOP)
titleBar:SetHeight(30)
titleBar:SetBackgroundColor(Color(30, 30, 30, 255))
local title = titleBar:Add("DLabel")
title:SetText("Inventory")
title:SetFont("DermaLarge")
title:Dock(FILL)
title:SetContentAlignment(5)
-- Add close button
local closeBtn = titleBar:Add("DButton")
closeBtn:SetText("X")
closeBtn:Dock(RIGHT)
closeBtn:SetWidth(30)
closeBtn.DoClick = function()
panel:Close()
end
-- Add weight bar
local weight = inventory:getData("weight", 0)
local maxWeight = inventory:getData("maxWeight", 100)
local weightBar = panel:Add("DPanel")
weightBar:Dock(BOTTOM)
weightBar:SetHeight(25)
weightBar:SetBackgroundColor(Color(30, 30, 30, 255))
local weightLabel = weightBar:Add("DLabel")
weightLabel:SetText(string.format("Weight: %d / %d (%.1f%%)", weight, maxWeight, (weight / maxWeight) * 100))
weightLabel:Dock(FILL)
weightLabel:SetContentAlignment(5)
-- Add filter buttons
local filterPanel = panel:Add("DPanel")
filterPanel:Dock(TOP)
filterPanel:SetHeight(30)
filterPanel:SetBackgroundColor(Color(40, 40, 40, 255))
local filterAll = filterPanel:Add("DButton")
filterAll:SetText("All")
filterAll:Dock(LEFT)
filterAll:SetWidth(60)
filterAll.DoClick = function()
inventory:setFilter(nil)
end
local filterWeapons = filterPanel:Add("DButton")
filterWeapons:SetText("Weapons")
filterWeapons:Dock(LEFT)
filterWeapons:SetWidth(80)
filterWeapons.DoClick = function()
inventory:setFilter("weapon")
end
local filterArmor = filterPanel:Add("DButton")
filterArmor:SetText("Armor")
filterArmor:Dock(LEFT)
filterArmor:SetWidth(70)
filterArmor.DoClick = function()
inventory:setFilter("armor")
end
end)
ItemPaintOver
Purpose
Called to paint over an item icon
When Called
When rendering additional graphics on an item icon
Parameters
self(Panel): The item icon panelitemTable(table): The item data tablew(number): The width of the iconh(number): The height of the icon
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Draw item name
hook.Add("ItemPaintOver", "MyAddon", function(self, itemTable, w, h)
draw.SimpleText(itemTable.name, "DermaDefault", w / 2, h - 10, Color(255, 255, 255), TEXT_ALIGN_CENTER)
end)
Medium Complexity:
-- Medium: Draw durability bar
hook.Add("ItemPaintOver", "DrawDurabilityBar", function(self, itemTable, w, h)
local item = self.item
if not item then return end
local durability = item:getData("durability", 100)
local barWidth = (w - 4) * (durability / 100)
surface.SetDrawColor(0, 0, 0, 200)
surface.DrawRect(2, h - 8, w - 4, 6)
local barColor = Color(255 * (1 - durability / 100), 255 * (durability / 100), 0)
surface.SetDrawColor(barColor)
surface.DrawRect(2, h - 8, barWidth, 6)
end)
High Complexity:
-- High: Complex item icon overlay
hook.Add("ItemPaintOver", "AdvancedItemOverlay", function(self, itemTable, w, h)
local item = self.item
if not item then return end
-- Draw durability bar
local durability = item:getData("durability", 100)
if durability < 100 then
local barWidth = (w - 4) * (durability / 100)
surface.SetDrawColor(0, 0, 0, 200)
surface.DrawRect(2, h - 8, w - 4, 6)
local barColor = Color(255 * (1 - durability / 100), 255 * (durability / 100), 0)
surface.SetDrawColor(barColor)
surface.DrawRect(2, h - 8, barWidth, 6)
end
-- Draw quantity
local quantity = item:getData("quantity", 1)
if quantity > 1 then
draw.SimpleText("x" .. quantity, "DermaDefaultBold", w - 5, 5, Color(255, 255, 255), TEXT_ALIGN_RIGHT)
end
-- Draw equipped indicator
if item:getData("equipped", false) then
draw.SimpleText("E", "DermaDefaultBold", 5, 5, Color(0, 255, 0))
end
-- Draw quality border
local quality = item:getData("quality", "common")
local borderColors = {
["common"] = Color(150, 150, 150),
["uncommon"] = Color(0, 200, 0),
["rare"] = Color(0, 100, 255),
["epic"] = Color(150, 0, 255),
["legendary"] = Color(255, 200, 0)
}
local borderColor = borderColors[quality] or Color(150, 150, 150)
surface.SetDrawColor(borderColor)
surface.DrawOutlinedRect(0, 0, w, h, 2)
end)
ItemShowEntityMenu
Purpose
Called to show entity menu for an item
When Called
When displaying the interaction menu for an item entity
Parameters
entity(Entity): The item entity
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log entity menu display
hook.Add("ItemShowEntityMenu", "MyAddon", function(entity)
print("Showing menu for: " .. tostring(entity))
end)
Medium Complexity:
-- Medium: Add custom menu options
hook.Add("ItemShowEntityMenu", "CustomEntityMenu", function(entity)
local item = entity:getNetVar("item")
if not item then return end
local menu = DermaMenu()
menu:AddOption("Examine", function()
chat.AddText("You examine the " .. item.name)
end)
menu:Open()
end)
High Complexity:
-- High: Complex entity menu system
hook.Add("ItemShowEntityMenu", "AdvancedEntityMenu", function(entity)
if not IsValid(entity) then return end
local item = entity:getNetVar("item")
if not item then return end
local client = LocalPlayer()
local char = client:getChar()
if not char then return end
-- Create menu
local menu = DermaMenu()
-- Add examine option
menu:AddOption("Examine", function()
local desc = item.desc or "No description"
chat.AddText(Color(255, 255, 255), "You examine the ", Color(100, 200, 255), item.name, Color(255, 255, 255), ": " .. desc)
end)
-- Add pickup option if close enough
local distance = client:GetPos():Distance(entity:GetPos())
if distance < 100 then
menu:AddOption("Pick Up", function()
net.Start("liaItemPickup")
net.WriteEntity(entity)
net.SendToServer()
end)
else
local option = menu:AddOption("Pick Up (Too Far)")
option:SetEnabled(false)
end
-- Add custom options based on item type
if item.category == "weapons" then
menu:AddOption("Inspect Weapon", function()
chat.AddText("This weapon has " .. (item:getData("ammo", 0)) .. " rounds")
end)
end
menu:Open()
end)
KeybindsLoaded
Purpose
Called when keybinds are loaded
When Called
After all keybinds have been initialized
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log keybinds loaded
hook.Add("KeybindsLoaded", "MyAddon", function()
print("Keybinds have been loaded")
end)
Medium Complexity:
-- Medium: Setup custom keybinds
hook.Add("KeybindsLoaded", "SetupCustomKeybinds", function()
-- Register custom keybind
lia.keybind.register("customAction", KEY_F, function()
print("Custom action triggered")
end, "Custom Action")
end)
High Complexity:
-- High: Complex keybind system
hook.Add("KeybindsLoaded", "AdvancedKeybinds", function()
-- Load saved keybinds from data
local savedBinds = lia.data.get("customKeybinds", {})
-- Register custom keybinds
for action, key in pairs(savedBinds) do
lia.keybind.register(action, key, function()
net.Start("liaCustomAction")
net.WriteString(action)
net.SendToServer()
end, action)
end
-- Setup keybind categories
local categories = {
["Movement"] = {"forward", "backward", "left", "right"},
["Actions"] = {"use", "attack", "reload"},
["Menu"] = {"inventory", "character", "scoreboard"}
}
-- Create keybind menu
concommand.Add("lia_keybinds", function()
local frame = vgui.Create("DFrame")
frame:SetSize(600, 400)
frame:Center()
frame:MakePopup()
frame:SetTitle("Keybind Settings")
local list = vgui.Create("DScrollPanel", frame)
list:Dock(FILL)
for category, binds in pairs(categories) do
local label = list:Add("DLabel")
label:SetText(category)
label:Dock(TOP)
end
end)
end)
KickedFromChar
Purpose
Called when a player is kicked from a character
When Called
When a player is forcibly removed from their character
Parameters
id(number): The character IDisCurrentChar(boolean): Whether this is the current character
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log character kick
hook.Add("KickedFromChar", "MyAddon", function(id, isCurrentChar)
print("Kicked from character: " .. id)
end)
Medium Complexity:
-- Medium: Show notification
hook.Add("KickedFromChar", "NotifyCharKick", function(id, isCurrentChar)
if isCurrentChar then
lia.util.notify("You have been kicked from your character")
end
end)
High Complexity:
-- High: Complex character kick handling
hook.Add("KickedFromChar", "AdvancedCharKick", function(id, isCurrentChar)
-- Show notification
if isCurrentChar then
lia.util.notify("You have been kicked from your character", 4)
-- Clear character-specific UI
if IsValid(lia.gui.charInfo) then
lia.gui.charInfo:Remove()
end
if IsValid(lia.gui.inventory) then
lia.gui.inventory:Remove()
end
-- Log the kick
lia.log.write("client_char_kick", {
charID = id,
timestamp = os.time()
})
-- Save any pending data
net.Start("liaSaveCharData")
net.WriteUInt(id, 32)
net.SendToServer()
-- Return to character selection
timer.Simple(1, function()
vgui.Create("liaCharacterMenu")
end)
else
-- Just log if not current character
print("Character " .. id .. " was kicked")
end
end)
LoadCharInformation
Purpose
Called to load character information
When Called
When character data needs to be loaded
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log character info load
hook.Add("LoadCharInformation", "MyAddon", function()
print("Loading character information")
end)
Medium Complexity:
-- Medium: Load custom character data
hook.Add("LoadCharInformation", "LoadCustomCharData", function()
local char = LocalPlayer():getChar()
if char then
-- Request custom data from server
netstream.Start("RequestCustomCharData", char:getID())
end
end)
High Complexity:
-- High: Complex character data loading
hook.Add("LoadCharInformation", "AdvancedCharDataLoad", function()
local char = LocalPlayer():getChar()
if not char then return end
-- Request custom data from server
netstream.Start("RequestCustomCharData", char:getID())
-- Initialize client-side character systems
MyAddon.InitializeCharacter(char)
-- Load character preferences
local prefs = char:getData("preferences", {})
for key, value in pairs(prefs) do
MyAddon.SetPreference(key, value)
end
print("Character information loaded for " .. char:getName())
end)
LoadMainMenuInformation
Purpose
Called to load main menu information
When Called
When building the main menu character information
Parameters
info(table): The information table to populatecharacter(Character): The character being displayed
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add basic info
hook.Add("LoadMainMenuInformation", "MyAddon", function(info, character)
info["Level"] = character:getData("level", 1)
end)
Medium Complexity:
-- Medium: Add multiple info fields
hook.Add("LoadMainMenuInformation", "AddCharacterInfo", function(info, character)
info["Level"] = character:getData("level", 1)
info["Experience"] = character:getData("exp", 0)
info["Money"] = lia.currency.get(character:getMoney())
end)
High Complexity:
-- High: Complex menu information system
hook.Add("LoadMainMenuInformation", "AdvancedMenuInfo", function(info, character)
-- Basic info
info["Level"] = character:getData("level", 1)
info["Experience"] = character:getData("exp", 0) .. " / " .. character:getData("expNeeded", 100)
info["Money"] = lia.currency.get(character:getMoney())
-- Faction info
local faction = lia.faction.indices[character:getFaction()]
if faction then
info["Faction"] = faction.name
info["Rank"] = character:getData("rankName", "Recruit")
end
-- Stats
info["Health"] = character:getData("health", 100)
info["Armor"] = character:getData("armor", 0)
-- Playtime
local playTime = character:getData("playTime", 0)
local hours = math.floor(playTime / 3600)
local minutes = math.floor((playTime % 3600) / 60)
info["Playtime"] = string.format("%dh %dm", hours, minutes)
end)
ModifyScoreboardModel
Purpose
Called to modify a player's model on the scoreboard
When Called
When rendering a player's model in the scoreboard
Parameters
client(Player): The viewing playerply(Player): The player whose model is being displayed
Returns
- string - The modified model path
Realm
Client
Example Usage
Low Complexity:
-- Simple: Return player model
hook.Add("ModifyScoreboardModel", "MyAddon", function(client, ply)
return ply:GetModel()
end)
Medium Complexity:
-- Medium: Show faction models
hook.Add("ModifyScoreboardModel", "ScoreboardFactionModels", function(client, ply)
local char = ply:getChar()
if char then
return char:getModel()
end
return ply:GetModel()
end)
High Complexity:
-- High: Complex scoreboard model system
hook.Add("ModifyScoreboardModel", "AdvancedScoreboardModel", function(client, ply)
local char = ply:getChar()
if not char then return ply:GetModel() end
-- Show outfit model if equipped
local outfit = char:getData("outfit")
if outfit then
local outfitItem = lia.item.instances[outfit]
if outfitItem and outfitItem.model then
return outfitItem.model
end
end
-- Show character model
return char:getModel()
end)
OnAdminStickMenuClosed
Purpose
Called when admin stick menu is closed
When Called
When the admin stick context menu is closed
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log menu close
hook.Add("OnAdminStickMenuClosed", "MyAddon", function()
print("Admin stick menu closed")
end)
Medium Complexity:
-- Medium: Clean up menu state
hook.Add("OnAdminStickMenuClosed", "CleanupAdminMenu", function()
MyAddon.selectedEntity = nil
MyAddon.menuOpen = false
end)
High Complexity:
-- High: Complex menu cleanup
hook.Add("OnAdminStickMenuClosed", "AdvancedMenuCleanup", function()
-- Clear selection
MyAddon.selectedEntity = nil
MyAddon.menuOpen = false
-- Save menu state
local char = LocalPlayer():getChar()
if char then
char:setData("lastAdminMenuClose", os.time())
end
-- Clean up temporary data
MyAddon.tempData = {}
print("Admin stick menu closed and cleaned up")
end)
OnChatReceived
Purpose
Called when a chat message is received
When Called
When a player receives a chat message
Parameters
client(Player): The player receiving the messagechatType(string): The type of chat messagetext(string): The message textanonymous(boolean): Whether the message is anonymous
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log received messages
hook.Add("OnChatReceived", "MyAddon", function(client, chatType, text, anonymous)
print("Received " .. chatType .. " message: " .. text)
end)
Medium Complexity:
-- Medium: Filter messages based on type
hook.Add("OnChatReceived", "MessageFiltering", function(client, chatType, text, anonymous)
if chatType == "ooc" then
-- OOC messages are always visible
return true
elseif chatType == "ic" then
-- IC messages only if player has character
local char = client:getChar()
return char ~= nil
end
return false
end)
High Complexity:
-- High: Complex chat system
hook.Add("OnChatReceived", "AdvancedChat", function(client, chatType, text, anonymous)
local char = client:getChar()
if not char then return end
-- Check if player is muted
if char:getData("muted", false) then
client:ChatPrint("You are muted and cannot receive messages")
return false
end
-- Check if player is gagged
if char:getData("gagged", false) then
client:ChatPrint("You are gagged and cannot receive messages")
return false
end
-- Check message type restrictions
local faction = char:getFaction()
if chatType == "ooc" and faction == "police" then
client:ChatPrint("Police officers cannot use OOC chat")
return false
end
-- Check for spam protection
local lastMessage = char:getData("lastMessage", 0)
local messageCooldown = 1 -- 1 second cooldown
if os.time() - lastMessage < messageCooldown then
client:ChatPrint("Please wait before sending another message")
return false
end
-- Check for inappropriate content
local bannedWords = {"spam", "hack", "cheat", "exploit"}
for _, word in ipairs(bannedWords) do
if string.find(string.lower(text), string.lower(word)) then
client:ChatPrint("Your message was blocked for inappropriate content")
return false
end
end
-- Update last message time
char:setData("lastMessage", os.time())
-- Check for admin commands
if string.sub(text, 1, 1) == "!" then
local command = string.sub(text, 2)
if command == "admin" then
-- Admin command
client:ChatPrint("Admin command executed")
return false
end
end
-- Log message
print(string.format("[%s] %s: %s", chatType, client:Name(), text))
end)
OnCreateItemInteractionMenu
Purpose
Called when creating an item interaction menu
When Called
When building the context menu for an item
Parameters
self(Item): The item instancemenu(Menu): The menu being createditemTable(table): The item table data
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add basic menu option
hook.Add("OnCreateItemInteractionMenu", "MyAddon", function(self, menu, itemTable)
menu:AddOption("Use Item", function()
print("Used item: " .. itemTable.name)
end)
end)
Medium Complexity:
-- Medium: Add conditional menu options
hook.Add("OnCreateItemInteractionMenu", "ItemMenuOptions", function(self, menu, itemTable)
-- Always add use option
menu:AddOption("Use", function()
self:use()
end)
-- Add drop option if not equipped
if not self:getData("equipped", false) then
menu:AddOption("Drop", function()
self:drop()
end)
end
-- Add examine option
menu:AddOption("Examine", function()
self:examine()
end)
end)
High Complexity:
-- High: Complex item interaction menu system
hook.Add("OnCreateItemInteractionMenu", "AdvancedItemMenu", function(self, menu, itemTable)
local char = LocalPlayer():getChar()
if not char then return end
-- Basic options
menu:AddOption("Use", function()
self:use()
end)
-- Conditional options based on item state
if not self:getData("equipped", false) then
menu:AddOption("Equip", function()
self:equip()
end)
menu:AddOption("Drop", function()
self:drop()
end)
else
menu:AddOption("Unequip", function()
self:unequip()
end)
end
-- Examine option
menu:AddOption("Examine", function()
self:examine()
end)
-- Admin options
if LocalPlayer():IsAdmin() then
menu:AddSpacer()
menu:AddOption("Admin: Delete", function()
self:remove()
end)
menu:AddOption("Admin: Duplicate", function()
local newItem = lia.item.instance(itemTable.uniqueID)
if newItem then
char:getInv():add(newItem)
end
end)
end
-- Faction-specific options
local faction = char:getFaction()
if faction == "police" and itemTable.uniqueID == "weapon_pistol" then
menu:AddOption("Police: Check Ammo", function()
local ammo = self:getData("ammo", 0)
LocalPlayer():ChatPrint("Ammo: " .. ammo)
end)
end
end)
OnCreateStoragePanel
Purpose
Called when creating a storage panel
When Called
When building the storage UI panel
Parameters
localInvPanel(Panel): The local inventory panelstorageInvPanel(Panel): The storage inventory panelstorage(Entity): The storage entity
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log storage panel creation
hook.Add("OnCreateStoragePanel", "MyAddon", function(localInvPanel, storageInvPanel, storage)
print("Storage panel created")
end)
Medium Complexity:
-- Medium: Customize storage panel appearance
hook.Add("OnCreateStoragePanel", "StoragePanelCustomize", function(localInvPanel, storageInvPanel, storage)
if localInvPanel then
localInvPanel:SetBackgroundColor(Color(50, 50, 50, 200))
end
if storageInvPanel then
storageInvPanel:SetBackgroundColor(Color(100, 50, 50, 200))
end
end)
High Complexity:
-- High: Complex storage panel system
hook.Add("OnCreateStoragePanel", "AdvancedStoragePanel", function(localInvPanel, storageInvPanel, storage)
if not IsValid(storage) then return end
-- Customize local inventory panel
if localInvPanel then
localInvPanel:SetBackgroundColor(Color(50, 50, 50, 200))
localInvPanel:SetSize(400, 300)
-- Add title
local title = localInvPanel:Add("DLabel")
title:SetText("Your Inventory")
title:SetFont("DermaDefault")
title:Dock(TOP)
title:SetHeight(25)
end
-- Customize storage inventory panel
if storageInvPanel then
storageInvPanel:SetBackgroundColor(Color(100, 50, 50, 200))
storageInvPanel:SetSize(400, 300)
-- Add title
local title = storageInvPanel:Add("DLabel")
title:SetText("Storage")
title:SetFont("DermaDefault")
title:Dock(TOP)
title:SetHeight(25)
end
-- Add storage info
local storageType = storage:getNetVar("storageType", "general")
local maxWeight = storage:getNetVar("maxWeight", 100)
local maxItems = storage:getNetVar("maxItems", 50)
-- Add info labels
if storageInvPanel then
local infoLabel = storageInvPanel:Add("DLabel")
infoLabel:SetText(string.format("Type: %s | Weight: %d | Items: %d",
storageType, maxWeight, maxItems))
infoLabel:SetFont("DermaDefault")
infoLabel:Dock(TOP)
infoLabel:SetHeight(20)
end
print("Storage panel created for " .. storageType .. " storage")
end)
OnDeathSoundPlayed
Purpose
Called when a death sound is played
When Called
When a player death sound is triggered
Parameters
client(Player): The player who dieddeathSound(string): The sound file that was played
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log death sounds
hook.Add("OnDeathSoundPlayed", "MyAddon", function(client, deathSound)
print("Death sound played: " .. deathSound)
end)
Medium Complexity:
-- Medium: Track death sounds
hook.Add("OnDeathSoundPlayed", "TrackDeathSounds", function(client, deathSound)
MyAddon.deathSounds = MyAddon.deathSounds or {}
table.insert(MyAddon.deathSounds, {
player = client:Name(),
sound = deathSound,
time = os.time()
})
end)
High Complexity:
-- High: Complex death sound handling
hook.Add("OnDeathSoundPlayed", "AdvancedDeathSound", function(client, deathSound)
-- Log death sound
lia.log.write("death_sound_played", {
player = client:SteamID(),
sound = deathSound,
timestamp = os.time()
})
-- Check for custom death sounds
local char = client:getChar()
if char then
local customSound = char:getData("customDeathSound")
if customSound and customSound ~= deathSound then
client:EmitSound(customSound)
end
end
-- Add death sound to statistics
local stats = client:getData("deathStats", {sounds = {}})
stats.sounds[deathSound] = (stats.sounds[deathSound] or 0) + 1
client:setData("deathStats", stats)
end)
OnFontsRefreshed
Purpose
Called when fonts are refreshed
When Called
When the font system is reloaded or updated
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log font refresh
hook.Add("OnFontsRefreshed", "MyAddon", function()
print("Fonts have been refreshed")
end)
Medium Complexity:
-- Medium: Reload custom fonts
hook.Add("OnFontsRefreshed", "ReloadCustomFonts", function()
surface.CreateFont("MyAddonFont", {
font = "Arial",
size = 24,
weight = 500
})
print("Custom fonts reloaded")
end)
High Complexity:
-- High: Complex font refresh handling
hook.Add("OnFontsRefreshed", "AdvancedFontRefresh", function()
-- Clear existing fonts
MyAddon.fonts = {}
-- Create custom font set
local fontSizes = {12, 16, 20, 24, 32, 48}
for _, size in ipairs(fontSizes) do
surface.CreateFont("MyAddonFont" .. size, {
font = "Arial",
size = size,
weight = 500,
antialias = true
})
end
-- Update UI elements
if IsValid(MyAddon.mainPanel) then
MyAddon.mainPanel:UpdateFonts()
end
print("Advanced font system refreshed")
end)
OnOpenVendorMenu
Purpose
Called when a vendor menu is opened
When Called
When a player opens a vendor's trading interface
Parameters
self(Entity): The vendor entityvendor(table): The vendor data
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log vendor menu opening
hook.Add("OnOpenVendorMenu", "MyAddon", function(self, vendor)
print("Vendor menu opened: " .. vendor.name)
end)
Medium Complexity:
-- Medium: Customize vendor menu appearance
hook.Add("OnOpenVendorMenu", "VendorCustomization", function(self, vendor)
if vendor.faction == "police" then
-- Police vendors have special styling
self:SetColor(Color(0, 0, 255, 255))
elseif vendor.faction == "medic" then
-- Medic vendors have different styling
self:SetColor(Color(255, 255, 255, 255))
end
end)
High Complexity:
-- High: Complex vendor menu system
hook.Add("OnOpenVendorMenu", "AdvancedVendorMenu", function(self, vendor)
local char = LocalPlayer():getChar()
if not char then return end
-- Check faction restrictions
local allowedFactions = vendor.allowedFactions
if allowedFactions and not table.HasValue(allowedFactions, char:getFaction()) then
LocalPlayer():ChatPrint("Your faction cannot access this vendor")
return false
end
-- Check level requirements
local requiredLevel = vendor.requiredLevel
if requiredLevel then
local charLevel = char:getData("level", 1)
if charLevel < requiredLevel then
LocalPlayer():ChatPrint("You need to be level " .. requiredLevel .. " to access this vendor")
return false
end
end
-- Check time restrictions
local timeRestriction = vendor.timeRestriction
if timeRestriction then
local currentHour = tonumber(os.date("%H"))
if currentHour < timeRestriction.start or currentHour > timeRestriction.end then
LocalPlayer():ChatPrint("This vendor is only open from " .. timeRestriction.start .. ":00 to " .. timeRestriction.end .. ":00")
return false
end
end
-- Apply faction-specific discounts
local faction = char:getFaction()
local discounts = {
["police"] = 0.1, -- 10% discount
["medic"] = 0.05, -- 5% discount
["citizen"] = 0.0 -- No discount
}
local discount = discounts[faction] or 0
vendor.discount = discount
-- Update vendor appearance based on faction
if faction == "police" then
self:SetColor(Color(0, 0, 255, 255))
elseif faction == "medic" then
self:SetColor(Color(255, 255, 255, 255))
else
self:SetColor(Color(255, 255, 255, 255))
end
-- Log vendor access
print(string.format("%s accessed vendor %s (Faction: %s)",
LocalPlayer():Name(), vendor.name, faction))
end)
OnPainSoundPlayed
Purpose
Called when a pain sound is played
When Called
When a player pain sound is triggered
Parameters
client(Player): The player who is in painpainSound(string): The sound file that was played
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log pain sounds
hook.Add("OnPainSoundPlayed", "MyAddon", function(client, painSound)
print("Pain sound played: " .. painSound)
end)
Medium Complexity:
-- Medium: Track pain sounds
hook.Add("OnPainSoundPlayed", "TrackPainSounds", function(client, painSound)
MyAddon.painSounds = MyAddon.painSounds or {}
table.insert(MyAddon.painSounds, {
player = client:Name(),
sound = painSound,
time = os.time()
})
end)
High Complexity:
-- High: Complex pain sound handling
hook.Add("OnPainSoundPlayed", "AdvancedPainSound", function(client, painSound)
-- Log pain sound
lia.log.write("pain_sound_played", {
player = client:SteamID(),
sound = painSound,
timestamp = os.time()
})
-- Check for custom pain sounds
local char = client:getChar()
if char then
local customSound = char:getData("customPainSound")
if customSound and customSound ~= painSound then
client:EmitSound(customSound)
end
end
-- Add pain sound to statistics
local stats = client:getData("painStats", {sounds = {}})
stats.sounds[painSound] = (stats.sounds[painSound] or 0) + 1
client:setData("painStats", stats)
end)
OnPlayerDataSynced
Purpose
Called when player data is synchronized
When Called
When player data is synced between client and server
Parameters
player(Player): The player whose data was syncedlastID(number): The last character ID that was synced
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log data sync
hook.Add("OnPlayerDataSynced", "MyAddon", function(player, lastID)
print("Player data synced for " .. player:Name())
end)
Medium Complexity:
-- Medium: Update UI after sync
hook.Add("OnPlayerDataSynced", "UISync", function(player, lastID)
if player == LocalPlayer() then
-- Update character information
local char = player:getChar()
if char then
-- Update character display
hook.Run("CharLoaded", char:getID())
end
end
end)
High Complexity:
-- High: Complex data sync system
hook.Add("OnPlayerDataSynced", "AdvancedDataSync", function(player, lastID)
if player == LocalPlayer() then
local char = player:getChar()
if not char then return end
-- Update character information
local charData = char:getData()
-- Update UI elements
if IsValid(lia.gui.info) then
lia.gui.info:updateCharacterInfo()
end
-- Update inventory display
if IsValid(lia.gui.inv1) then
lia.gui.inv1:updateInventory()
end
-- Update faction display
local faction = char:getFaction()
if faction then
player:SetTeam(faction)
end
-- Update character model
local model = char:getModel()
if model then
player:SetModel(model)
end
-- Update character attributes
local attributes = char:getAttribs()
for attr, value in pairs(attributes) do
player:setNetVar("attr_" .. attr, value)
end
-- Update character money
local money = char:getMoney()
player:setNetVar("money", money)
-- Update character level
local level = char:getData("level", 1)
player:setNetVar("level", level)
-- Update character experience
local experience = char:getData("experience", 0)
player:setNetVar("experience", experience)
-- Update character health
local health = char:getData("health", 100)
player:SetHealth(health)
-- Update character armor
local armor = char:getData("armor", 0)
player:SetArmor(armor)
-- Update character stamina
local stamina = char:getData("stamina", 100)
player:setNetVar("stamina", stamina)
-- Notify other systems
hook.Run("CharLoaded", char:getID())
-- Log sync
print("Player data synced for " .. player:Name() .. " (Char ID: " .. lastID .. ")")
end
end)
OnThemeChanged
Purpose
Called when the UI theme is changed
When Called
When the active theme is switched
Parameters
themeName(string): The name of the new themethemeData(table): The theme configuration data
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log theme changes
hook.Add("OnThemeChanged", "MyAddon", function(themeName, themeData)
print("Theme changed to: " .. themeName)
end)
Medium Complexity:
-- Medium: Update UI colors
hook.Add("OnThemeChanged", "UpdateUIColors", function(themeName, themeData)
if themeData.colors then
MyAddon.primaryColor = themeData.colors.primary
MyAddon.secondaryColor = themeData.colors.secondary
end
end)
High Complexity:
-- High: Complex theme change handling
hook.Add("OnThemeChanged", "AdvancedThemeChange", function(themeName, themeData)
-- Update all UI elements
if IsValid(MyAddon.mainPanel) then
MyAddon.mainPanel:SetBackgroundColor(themeData.colors.background)
end
-- Reload custom fonts
if themeData.fonts then
for fontName, fontData in pairs(themeData.fonts) do
surface.CreateFont(fontName, fontData)
end
end
-- Save theme preference
lia.data.set("preferredTheme", themeName)
-- Notify user
lia.util.notify("Theme changed to " .. themeName)
end)
OpenAdminStickUI
Purpose
Called when the admin stick UI is opened
When Called
When an admin opens the admin stick interface
Parameters
tgt(Entity): The target entity being examined
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log admin stick usage
hook.Add("OpenAdminStickUI", "MyAddon", function(tgt)
print("Admin stick UI opened for " .. tostring(tgt))
end)
Medium Complexity:
-- Medium: Customize admin stick display
hook.Add("OpenAdminStickUI", "CustomAdminStick", function(tgt)
if IsValid(tgt) and tgt:IsPlayer() then
local char = tgt:getChar()
if char then
print("Examining player: " .. char:getName())
end
end
end)
High Complexity:
-- High: Complex admin stick functionality
hook.Add("OpenAdminStickUI", "AdvancedAdminStick", function(tgt)
if not IsValid(tgt) then return end
-- Store target for later use
MyAddon.currentTarget = tgt
-- Add custom information to admin stick
if tgt:IsPlayer() then
local char = tgt:getChar()
if char then
hook.Run("AddToAdminStickHUD", LocalPlayer(), tgt, {
"Character: " .. char:getName(),
"Faction: " .. char:getFaction(),
"Class: " .. char:getClass()
})
end
end
-- Log admin stick usage
lia.log.write("admin_stick_opened", {
admin = LocalPlayer():SteamID(),
target = IsValid(tgt) and tgt:EntIndex() or "Invalid",
timestamp = os.time()
})
end)
PaintItem
Purpose
Called to paint/render an item
When Called
When an item needs custom rendering
Parameters
item(Item): The item being painted
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Draw item name
hook.Add("PaintItem", "MyAddon", function(item)
draw.SimpleText(item.name, "DermaDefault", 10, 10, Color(255, 255, 255))
end)
Medium Complexity:
-- Medium: Draw item with quality color
hook.Add("PaintItem", "PaintItemQuality", function(item)
local quality = item:getData("quality", "common")
local color = Color(255, 255, 255)
if quality == "rare" then
color = Color(0, 100, 255)
elseif quality == "epic" then
color = Color(150, 0, 255)
end
draw.SimpleText(item.name, "DermaDefault", 10, 10, color)
end)
High Complexity:
-- High: Complex item rendering
hook.Add("PaintItem", "AdvancedItemPaint", function(item)
local x, y = 10, 10
-- Draw item name with quality color
local quality = item:getData("quality", "common")
local qualityColors = {
["common"] = Color(150, 150, 150),
["uncommon"] = Color(0, 200, 0),
["rare"] = Color(0, 100, 255),
["epic"] = Color(150, 0, 255),
["legendary"] = Color(255, 200, 0)
}
local color = qualityColors[quality] or Color(255, 255, 255)
draw.SimpleText(item.name, "DermaDefaultBold", x, y, color)
-- Draw durability
local durability = item:getData("durability", 100)
y = y + 20
draw.SimpleText("Durability: " .. durability .. "%", "DermaDefault", x, y, Color(255, 255, 255))
-- Draw quantity
local quantity = item:getData("quantity", 1)
if quantity > 1 then
y = y + 15
draw.SimpleText("Quantity: x" .. quantity, "DermaDefault", x, y, Color(255, 255, 255))
end
end)
PopulateAdminStick
Purpose
Called to populate the admin stick menu
When Called
When building the admin stick context menu
Parameters
tempMenu(Menu): The menu being populatedtgt(Entity): The target entity
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add basic option
hook.Add("PopulateAdminStick", "MyAddon", function(tempMenu, tgt)
tempMenu:AddOption("Custom Action", function()
print("Custom action performed")
end)
end)
Medium Complexity:
-- Medium: Add conditional options
hook.Add("PopulateAdminStick", "ConditionalAdminOptions", function(tempMenu, tgt)
if IsValid(tgt) and tgt:IsPlayer() then
tempMenu:AddOption("Teleport To", function()
RunConsoleCommand("lia_plyteleporttome", tgt:SteamID())
end)
end
end)
High Complexity:
-- High: Complex admin stick menu
hook.Add("PopulateAdminStick", "AdvancedAdminStick", function(tempMenu, tgt)
if not IsValid(tgt) then return end
-- Player options
if tgt:IsPlayer() then
tempMenu:AddOption("Teleport To", function()
RunConsoleCommand("lia_plyteleporttome", tgt:SteamID())
end)
tempMenu:AddOption("Kick", function()
RunConsoleCommand("lia_kick", tgt:SteamID())
end)
tempMenu:AddOption("Ban", function()
RunConsoleCommand("lia_ban", tgt:SteamID())
end)
end
-- Entity options
tempMenu:AddOption("Remove", function()
RunConsoleCommand("lia_removeentity", tgt:EntIndex())
end)
tempMenu:AddOption("Copy Model", function()
SetClipboardText(tgt:GetModel())
end)
end)
PopulateAdminTabs
Purpose
Called to populate admin tabs
When Called
When building the admin panel tabs
Parameters
adminPages(table): The admin pages table
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add basic tab
hook.Add("PopulateAdminTabs", "MyAddon", function(adminPages)
adminPages["Custom"] = function(parent)
local panel = parent:Add("DPanel")
panel:Dock(FILL)
return panel
end
end)
Medium Complexity:
-- Medium: Add tab with content
hook.Add("PopulateAdminTabs", "CustomAdminTab", function(adminPages)
adminPages["Custom Tools"] = function(parent)
local panel = parent:Add("DPanel")
panel:Dock(FILL)
local button = panel:Add("DButton")
button:SetText("Custom Action")
button:Dock(TOP)
button.DoClick = function()
RunConsoleCommand("lia_customaction")
end
return panel
end
end)
High Complexity:
-- High: Complex admin tab system
hook.Add("PopulateAdminTabs", "AdvancedAdminTabs", function(adminPages)
adminPages["Custom Management"] = function(parent)
local panel = parent:Add("DPanel")
panel:Dock(FILL)
panel:SetBackgroundColor(Color(50, 50, 50))
-- Add title
local title = panel:Add("DLabel")
title:SetText("Custom Management Tools")
title:SetFont("DermaLarge")
title:Dock(TOP)
title:SetHeight(30)
-- Add buttons
local btnPanel = panel:Add("DPanel")
btnPanel:Dock(TOP)
btnPanel:SetHeight(200)
local teleportBtn = btnPanel:Add("DButton")
teleportBtn:SetText("Teleport All Players")
teleportBtn:Dock(TOP)
teleportBtn:SetHeight(30)
teleportBtn.DoClick = function()
RunConsoleCommand("lia_teleportall")
end
local healBtn = btnPanel:Add("DButton")
healBtn:SetText("Heal All Players")
healBtn:Dock(TOP)
healBtn:SetHeight(30)
healBtn.DoClick = function()
RunConsoleCommand("lia_healall")
end
return panel
end
end)
PopulateConfigurationButtons
Purpose
Called to populate configuration buttons
When Called
When building the configuration menu
Parameters
pages(table): The configuration pages table
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add basic config page
hook.Add("PopulateConfigurationButtons", "MyAddon", function(pages)
pages["Custom"] = function(parent)
local panel = parent:Add("DPanel")
panel:Dock(FILL)
return panel
end
end)
Medium Complexity:
-- Medium: Add config page with options
hook.Add("PopulateConfigurationButtons", "CustomConfigPage", function(pages)
pages["My Settings"] = function(parent)
local panel = parent:Add("DPanel")
panel:Dock(FILL)
local checkbox = panel:Add("DCheckBoxLabel")
checkbox:SetText("Enable Feature")
checkbox:Dock(TOP)
checkbox:SetValue(GetConVar("myfeature_enabled"):GetBool())
checkbox.OnChange = function(self, val)
RunConsoleCommand("myfeature_enabled", val and "1" or "0")
end
return panel
end
end)
High Complexity:
-- High: Complex configuration system
hook.Add("PopulateConfigurationButtons", "AdvancedConfigSystem", function(pages)
pages["Advanced Settings"] = function(parent)
local panel = parent:Add("DPanel")
panel:Dock(FILL)
panel:SetBackgroundColor(Color(50, 50, 50))
-- Add title
local title = panel:Add("DLabel")
title:SetText("Advanced Configuration")
title:SetFont("DermaLarge")
title:Dock(TOP)
title:SetHeight(30)
-- Add settings
local settingsPanel = panel:Add("DPanel")
settingsPanel:Dock(FILL)
-- Enable feature checkbox
local enableCheckbox = settingsPanel:Add("DCheckBoxLabel")
enableCheckbox:SetText("Enable Advanced Features")
enableCheckbox:Dock(TOP)
enableCheckbox:SetValue(GetConVar("advanced_enabled"):GetBool())
enableCheckbox.OnChange = function(self, val)
RunConsoleCommand("advanced_enabled", val and "1" or "0")
end
-- Slider for value
local slider = settingsPanel:Add("DNumSlider")
slider:SetText("Feature Intensity")
slider:Dock(TOP)
slider:SetMin(0)
slider:SetMax(100)
slider:SetValue(GetConVar("advanced_intensity"):GetInt())
slider.OnValueChanged = function(self, val)
RunConsoleCommand("advanced_intensity", tostring(math.floor(val)))
end
return panel
end
end)
PopulateInventoryItems
Purpose
Called to populate inventory items
When Called
When building the inventory item list
Parameters
pnlContent(Panel): The content paneltree(Panel): The tree view panel
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add basic category
hook.Add("PopulateInventoryItems", "MyAddon", function(pnlContent, tree)
local node = tree:AddNode("Custom Items")
end)
Medium Complexity:
-- Medium: Add category with items
hook.Add("PopulateInventoryItems", "CustomInventoryItems", function(pnlContent, tree)
local node = tree:AddNode("Custom Items")
for _, item in pairs(lia.item.list) do
if item.category == "custom" then
local itemNode = node:AddNode(item.name)
itemNode.DoClick = function()
-- Show item details
end
end
end
end)
High Complexity:
-- High: Complex inventory population
hook.Add("PopulateInventoryItems", "AdvancedInventoryPopulation", function(pnlContent, tree)
-- Group items by custom category
local categories = {}
for _, item in pairs(lia.item.list) do
local category = item.customCategory or "Other"
categories[category] = categories[category] or {}
table.insert(categories[category], item)
end
-- Create nodes for each category
for category, items in pairs(categories) do
local categoryNode = tree:AddNode(category)
categoryNode:SetIcon("icon16/folder.png")
-- Add items to category
for _, item in ipairs(items) do
local itemNode = categoryNode:AddNode(item.name)
itemNode:SetIcon("icon16/box.png")
itemNode.DoClick = function()
-- Show item details in content panel
pnlContent:Clear()
local itemPanel = pnlContent:Add("DPanel")
itemPanel:Dock(FILL)
local nameLabel = itemPanel:Add("DLabel")
nameLabel:SetText(item.name)
nameLabel:SetFont("DermaLarge")
nameLabel:Dock(TOP)
local descLabel = itemPanel:Add("DLabel")
descLabel:SetText(item.desc or "No description")
descLabel:Dock(TOP)
end
end
end
end)
PostDrawInventory
Purpose
Called after drawing the inventory
When Called
After the inventory UI has been rendered
Parameters
mainPanel(Panel): The main inventory panelparentPanel(Panel): The parent panel
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log inventory draw
hook.Add("PostDrawInventory", "MyAddon", function(mainPanel, parentPanel)
print("Inventory drawn")
end)
Medium Complexity:
-- Medium: Add custom UI elements
hook.Add("PostDrawInventory", "CustomInventoryUI", function(mainPanel, parentPanel)
if IsValid(mainPanel) then
local label = mainPanel:Add("DLabel")
label:SetText("Custom Inventory")
label:Dock(BOTTOM)
end
end)
High Complexity:
-- High: Complex inventory UI customization
hook.Add("PostDrawInventory", "AdvancedInventoryUI", function(mainPanel, parentPanel)
if not IsValid(mainPanel) then return end
local char = LocalPlayer():getChar()
if not char then return end
-- Add weight display
local inventory = char:getInv()
if inventory then
local weight = inventory:getData("weight", 0)
local maxWeight = inventory:getData("maxWeight", 100)
local weightLabel = mainPanel:Add("DLabel")
weightLabel:SetText(string.format("Weight: %d / %d", weight, maxWeight))
weightLabel:Dock(BOTTOM)
weightLabel:SetHeight(20)
end
end)
PostLoadFonts
Purpose
Called after fonts are loaded
When Called
After the font system has been initialized
Parameters
mainFont(string): The main font nameconfiguredFont(string): The configured font name
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log font load
hook.Add("PostLoadFonts", "MyAddon", function(mainFont, configuredFont)
print("Fonts loaded: " .. mainFont)
end)
Medium Complexity:
-- Medium: Create custom fonts
hook.Add("PostLoadFonts", "CreateCustomFonts", function(mainFont, configuredFont)
surface.CreateFont("MyCustomFont", {
font = mainFont,
size = 24,
weight = 500
})
end)
High Complexity:
-- High: Complex font system
hook.Add("PostLoadFonts", "AdvancedFontSystem", function(mainFont, configuredFont)
-- Create custom fonts
local fontSizes = {16, 20, 24, 28, 32}
for _, size in ipairs(fontSizes) do
surface.CreateFont("MyCustomFont_" .. size, {
font = mainFont,
size = size,
weight = 500,
antialias = true
})
end
-- Create bold variants
for _, size in ipairs(fontSizes) do
surface.CreateFont("MyCustomFontBold_" .. size, {
font = mainFont,
size = size,
weight = 700,
antialias = true
})
end
print("Custom fonts created")
end)
PreDrawPhysgunBeam
Purpose
Called before drawing the physgun beam
When Called
Before the physgun beam is rendered
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log physgun beam
hook.Add("PreDrawPhysgunBeam", "MyAddon", function()
print("Drawing physgun beam")
end)
Medium Complexity:
-- Medium: Customize beam appearance
hook.Add("PreDrawPhysgunBeam", "CustomizeBeam", function()
local client = LocalPlayer()
if IsValid(client) and client:GetActiveWeapon():GetClass() == "weapon_physgun" then
-- Custom beam color
render.SetColorMaterial()
render.DrawBeam(client:GetShootPos(), client:GetEyeTrace().HitPos, 8, 0, 1, Color(255, 0, 0, 255))
end
end)
High Complexity:
-- High: Complex physgun beam system
hook.Add("PreDrawPhysgunBeam", "AdvancedPhysgunBeam", function()
local client = LocalPlayer()
if not IsValid(client) then return end
local weapon = client:GetActiveWeapon()
if not IsValid(weapon) or weapon:GetClass() ~= "weapon_physgun" then return end
local trace = client:GetEyeTrace()
if not trace.Hit then return end
local target = trace.Entity
if not IsValid(target) then return end
-- Different colors for different entities
local color = Color(255, 255, 255, 255)
if target:IsPlayer() then
color = Color(255, 0, 0, 255)
elseif target:IsVehicle() then
color = Color(0, 255, 0, 255)
elseif target:GetClass():find("prop_") then
color = Color(0, 0, 255, 255)
end
-- Draw custom beam
render.SetColorMaterial()
render.DrawBeam(client:GetShootPos(), trace.HitPos, 8, 0, 1, color)
end)
RefreshFonts
Purpose
Called to refresh fonts
When Called
When the font system needs to be refreshed
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log font refresh
hook.Add("RefreshFonts", "MyAddon", function()
print("Fonts refreshed")
end)
Medium Complexity:
-- Medium: Recreate custom fonts
hook.Add("RefreshFonts", "RecreateCustomFonts", function()
surface.CreateFont("MyCustomFont", {
font = "Arial",
size = 24,
weight = 500
})
end)
High Complexity:
-- High: Complex font refresh system
hook.Add("RefreshFonts", "AdvancedFontRefresh", function()
-- Clear existing fonts
for k, v in pairs(surface.GetFonts()) do
if string.find(k, "MyCustom") then
surface.CreateFont(k, {
font = "Arial",
size = 24,
weight = 500
})
end
end
-- Create new fonts with current settings
local mainFont = GetConVar("lia_font"):GetString()
for i = 16, 32, 4 do
surface.CreateFont("MyCustomFont_" .. i, {
font = mainFont,
size = i,
weight = 500,
antialias = true
})
end
end)
RemovePart
Purpose
Called when a PAC3 part is removed
When Called
When a PAC3 part is detached from a player
Parameters
client(Player): The player losing the partid(string): The part ID
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log part removal
hook.Add("RemovePart", "MyAddon", function(client, id)
print(client:Name() .. " removed part: " .. id)
end)
Medium Complexity:
-- Medium: Track part usage
hook.Add("RemovePart", "TrackPartUsage", function(client, id)
local char = client:getChar()
if char then
local partsUsed = char:getData("partsUsed", {})
partsUsed[id] = (partsUsed[id] or 0) + 1
char:setData("partsUsed", partsUsed)
end
end)
High Complexity:
-- High: Complex part removal system
hook.Add("RemovePart", "AdvancedPartRemoval", function(client, id)
local char = client:getChar()
if not char then return end
-- Track part usage
local partsUsed = char:getData("partsUsed", {})
partsUsed[id] = (partsUsed[id] or 0) + 1
char:setData("partsUsed", partsUsed)
-- Log to database
lia.db.query("INSERT INTO part_logs (timestamp, charid, partid, action) VALUES (?, ?, ?, ?)",
os.time(), char:getID(), id, "removed")
-- Notify nearby players
for _, ply in ipairs(player.GetAll()) do
if ply ~= client and ply:GetPos():Distance(client:GetPos()) < 500 then
ply:ChatPrint(client:Name() .. " removed a part")
end
end
end)
ResetCharacterPanel
Purpose
Called to reset the character panel
When Called
When the character panel needs to be refreshed
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log panel reset
hook.Add("ResetCharacterPanel", "MyAddon", function()
print("Character panel reset")
end)
Medium Complexity:
-- Medium: Clear custom data
hook.Add("ResetCharacterPanel", "ClearCustomData", function()
MyAddon.selectedCharacter = nil
MyAddon.panelData = {}
end)
High Complexity:
-- High: Complex panel reset system
hook.Add("ResetCharacterPanel", "AdvancedPanelReset", function()
-- Clear custom data
MyAddon.selectedCharacter = nil
MyAddon.panelData = {}
MyAddon.customButtons = {}
-- Reset UI state
if IsValid(MyAddon.customPanel) then
MyAddon.customPanel:Remove()
MyAddon.customPanel = nil
end
-- Rebuild panel
timer.Simple(0.1, function()
MyAddon.RebuildPanel()
end)
end)
ScoreboardClosed
Purpose
Called when the scoreboard is closed
When Called
When the scoreboard UI is closed
Parameters
self(Panel): The scoreboard panel
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log scoreboard close
hook.Add("ScoreboardClosed", "MyAddon", function(self)
print("Scoreboard closed")
end)
Medium Complexity:
-- Medium: Clean up scoreboard data
hook.Add("ScoreboardClosed", "CleanupScoreboard", function(self)
MyAddon.scoreboardData = {}
MyAddon.selectedPlayer = nil
end)
High Complexity:
-- High: Complex scoreboard cleanup
hook.Add("ScoreboardClosed", "AdvancedScoreboardCleanup", function(self)
-- Clean up data
MyAddon.scoreboardData = {}
MyAddon.selectedPlayer = nil
MyAddon.customPanels = {}
-- Save scoreboard state
local char = LocalPlayer():getChar()
if char then
char:setData("lastScoreboardClose", os.time())
end
-- Notify other systems
hook.Run("CustomScoreboardClosed", self)
end)
ScoreboardOpened
Purpose
Called when the scoreboard is opened
When Called
When the scoreboard UI is displayed
Parameters
self(Panel): The scoreboard panel
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log scoreboard open
hook.Add("ScoreboardOpened", "MyAddon", function(self)
print("Scoreboard opened")
end)
Medium Complexity:
-- Medium: Initialize scoreboard data
hook.Add("ScoreboardOpened", "InitializeScoreboard", function(self)
MyAddon.scoreboardData = {
players = player.GetAll(),
lastUpdate = os.time()
}
end)
High Complexity:
-- High: Complex scoreboard initialization
hook.Add("ScoreboardOpened", "AdvancedScoreboardInit", function(self)
-- Initialize data
MyAddon.scoreboardData = {
players = player.GetAll(),
lastUpdate = os.time(),
customData = {}
}
-- Load custom panels
MyAddon.customPanels = {}
-- Add custom buttons
local customBtn = self:Add("DButton")
customBtn:SetText("Custom Action")
customBtn:Dock(TOP)
customBtn.DoClick = function()
hook.Run("CustomScoreboardAction")
end
-- Notify other systems
hook.Run("CustomScoreboardOpened", self)
end)
ScoreboardRowCreated
Purpose
Called when a scoreboard row is created
When Called
When a player row is added to the scoreboard
Parameters
slot(Panel): The row panelply(Player): The player for the row
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log row creation
hook.Add("ScoreboardRowCreated", "MyAddon", function(slot, ply)
print("Scoreboard row created for " .. ply:Name())
end)
Medium Complexity:
-- Medium: Customize row appearance
hook.Add("ScoreboardRowCreated", "CustomizeRow", function(slot, ply)
local char = ply:getChar()
if char then
local faction = char:getFaction()
if faction == "police" then
slot:SetBackgroundColor(Color(0, 0, 255, 50))
end
end
end)
High Complexity:
-- High: Complex scoreboard row customization
hook.Add("ScoreboardRowCreated", "AdvancedRowCustomization", function(slot, ply)
local char = ply:getChar()
if not char then return end
-- Faction-based coloring
local faction = char:getFaction()
local factionColors = {
["police"] = Color(0, 0, 255, 50),
["medic"] = Color(0, 255, 0, 50),
["criminal"] = Color(255, 0, 0, 50)
}
local color = factionColors[faction] or Color(255, 255, 255, 50)
slot:SetBackgroundColor(color)
-- Add custom elements
local customLabel = slot:Add("DLabel")
customLabel:SetText("[" .. faction .. "]")
customLabel:Dock(RIGHT)
customLabel:SetTextColor(Color(255, 255, 255))
end)
ScoreboardRowRemoved
Purpose
Called when a scoreboard row is removed
When Called
When a player row is removed from the scoreboard
Parameters
self(Panel): The scoreboard panelply(Player): The player whose row was removed
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log row removal
hook.Add("ScoreboardRowRemoved", "MyAddon", function(self, ply)
print("Scoreboard row removed for " .. ply:Name())
end)
Medium Complexity:
-- Medium: Clean up row data
hook.Add("ScoreboardRowRemoved", "CleanupRowData", function(self, ply)
MyAddon.playerData[ply:SteamID()] = nil
end)
High Complexity:
-- High: Complex row cleanup
hook.Add("ScoreboardRowRemoved", "AdvancedRowCleanup", function(self, ply)
-- Clean up player data
MyAddon.playerData[ply:SteamID()] = nil
-- Remove custom elements
if IsValid(MyAddon.customElements[ply:SteamID()]) then
MyAddon.customElements[ply:SteamID()]:Remove()
MyAddon.customElements[ply:SteamID()] = nil
end
-- Update scoreboard statistics
MyAddon.UpdateStats()
end)
SetupPACDataFromItems
Purpose
Called to set up PAC3 data from items
When Called
When configuring PAC3 data based on equipped items
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log PAC3 setup
hook.Add("SetupPACDataFromItems", "MyAddon", function()
print("Setting up PAC3 data from items")
end)
Medium Complexity:
-- Medium: Apply item-based PAC3 data
hook.Add("SetupPACDataFromItems", "ApplyItemPAC3", function()
local char = LocalPlayer():getChar()
if char then
local inv = char:getInv()
if inv then
for _, item in pairs(inv:getItems()) do
if item:getData("equipped", false) and item.pacData then
hook.Run("AttachPart", LocalPlayer(), item.pacData)
end
end
end
end
end)
High Complexity:
-- High: Complex PAC3 item system
hook.Add("SetupPACDataFromItems", "AdvancedPAC3Items", function()
local char = LocalPlayer():getChar()
if not char then return end
local inv = char:getInv()
if not inv then return end
-- Clear existing PAC3 data
hook.Run("RemoveAllParts", LocalPlayer())
-- Apply item-based PAC3 data
for _, item in pairs(inv:getItems()) do
if item:getData("equipped", false) then
local pacData = item:getData("pacData")
if pacData then
hook.Run("AttachPart", LocalPlayer(), pacData)
end
-- Apply item-specific PAC3 effects
if item.pacEffects then
for _, effect in ipairs(item.pacEffects) do
hook.Run("ApplyPACEffect", LocalPlayer(), effect)
end
end
end
end
-- Apply faction-specific PAC3 data
local faction = char:getFaction()
local factionPAC = lia.faction.indices[faction] and lia.faction.indices[faction].pacData
if factionPAC then
hook.Run("AttachPart", LocalPlayer(), factionPAC)
end
end)
SetupQuickMenu
Purpose
Called to set up the quick menu
When Called
When initializing the quick access menu
Parameters
self(Panel): The quick menu panel
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log quick menu setup
hook.Add("SetupQuickMenu", "MyAddon", function(self)
print("Setting up quick menu")
end)
Medium Complexity:
-- Medium: Add custom buttons
hook.Add("SetupQuickMenu", "AddCustomButtons", function(self)
local customBtn = self:Add("DButton")
customBtn:SetText("Custom Action")
customBtn:Dock(TOP)
customBtn.DoClick = function()
print("Custom action clicked")
end
end)
High Complexity:
-- High: Complex quick menu system
hook.Add("SetupQuickMenu", "AdvancedQuickMenu", function(self)
local char = LocalPlayer():getChar()
if not char then return end
-- Add faction-specific buttons
local faction = char:getFaction()
if faction == "police" then
local arrestBtn = self:Add("DButton")
arrestBtn:SetText("Arrest")
arrestBtn:Dock(TOP)
arrestBtn.DoClick = function()
RunConsoleCommand("lia_arrest")
end
elseif faction == "medic" then
local healBtn = self:Add("DButton")
healBtn:SetText("Heal")
healBtn:Dock(TOP)
healBtn.DoClick = function()
RunConsoleCommand("lia_heal")
end
end
-- Add universal buttons
local inventoryBtn = self:Add("DButton")
inventoryBtn:SetText("Inventory")
inventoryBtn:Dock(TOP)
inventoryBtn.DoClick = function()
RunConsoleCommand("lia_inventory")
end
end)
ShouldAllowScoreboardOverride
Purpose
Called to check if scoreboard override should be allowed
When Called
When determining if a player can override scoreboard behavior
Parameters
ply(Player): The playeroverride(string): The override type
Returns
- boolean - True to allow, false to deny
Realm
Client
Example Usage
Low Complexity:
-- Simple: Allow all overrides
hook.Add("ShouldAllowScoreboardOverride", "MyAddon", function(ply, override)
return true
end)
Medium Complexity:
-- Medium: Check admin status
hook.Add("ShouldAllowScoreboardOverride", "AdminOverride", function(ply, override)
return ply:IsAdmin()
end)
High Complexity:
-- High: Complex override system
hook.Add("ShouldAllowScoreboardOverride", "AdvancedOverride", function(ply, override)
-- Admins can always override
if ply:IsAdmin() then return true end
-- Check specific override types
if override == "customization" then
return ply:getNetVar("canCustomizeScoreboard", false)
elseif override == "sorting" then
return ply:getNetVar("canSortScoreboard", false)
end
return false
end)
ShouldBarDraw
Purpose
Called to check if a bar should be drawn
When Called
When determining if a UI bar should be rendered
Parameters
bar(table): The bar data
Returns
- boolean - True to draw, false to hide
Realm
Client
Example Usage
Low Complexity:
Medium Complexity:
-- Medium: Hide specific bars
hook.Add("ShouldBarDraw", "HideSpecificBars", function(bar)
if bar.name == "health" and LocalPlayer():Health() >= 100 then
return false
end
return true
end)
High Complexity:
-- High: Complex bar visibility system
hook.Add("ShouldBarDraw", "AdvancedBarVisibility", function(bar)
local char = LocalPlayer():getChar()
if not char then return false end
-- Hide bars for specific factions
local faction = char:getFaction()
if faction == "ghost" and bar.name ~= "stamina" then
return false
end
-- Hide bars when in cutscene
if char:getData("inCutscene", false) then
return false
end
-- Hide bars when dead
if LocalPlayer():Health() <= 0 then
return false
end
return true
end)
ShouldDisableThirdperson
Purpose
Called to check if thirdperson should be disabled
When Called
When determining if thirdperson view should be blocked
Parameters
self(Player): The player
Returns
- boolean - True to disable, false to allow
Realm
Client
Example Usage
Low Complexity:
-- Simple: Never disable thirdperson
hook.Add("ShouldDisableThirdperson", "MyAddon", function(self)
return false
end)
Medium Complexity:
-- Medium: Disable in specific areas
hook.Add("ShouldDisableThirdperson", "DisableInAreas", function(self)
local pos = self:GetPos()
local restrictedAreas = {
Vector(0, 0, 0), -- Example restricted area
}
for _, area in ipairs(restrictedAreas) do
if pos:Distance(area) < 500 then
return true
end
end
return false
end)
High Complexity:
-- High: Complex thirdperson restrictions
hook.Add("ShouldDisableThirdperson", "AdvancedThirdpersonRestrictions", function(self)
local char = self:getChar()
if not char then return false end
-- Disable for specific factions
local faction = char:getFaction()
if faction == "ghost" then
return true
end
-- Disable in vehicles
if self:InVehicle() then
return true
end
-- Disable when tied
if char:getData("tied", false) then
return true
end
-- Disable in restricted areas
local pos = self:GetPos()
local restrictedAreas = lia.data.get("restrictedAreas", {})
for _, area in ipairs(restrictedAreas) do
if pos:Distance(area.pos) < area.radius then
return true
end
end
return false
end)
ShouldDrawAmmo
Purpose
Called to check if ammo should be drawn
When Called
When determining if weapon ammo should be displayed
Parameters
wpn(Weapon): The weapon
Returns
- boolean - True to draw, false to hide
Realm
Client
Example Usage
Low Complexity:
Medium Complexity:
-- Medium: Hide ammo for specific weapons
hook.Add("ShouldDrawAmmo", "HideSpecificAmmo", function(wpn)
local weaponClass = wpn:GetClass()
local hideAmmoWeapons = {"weapon_crowbar", "weapon_stunstick"}
return not table.HasValue(hideAmmoWeapons, weaponClass)
end)
High Complexity:
-- High: Complex ammo display system
hook.Add("ShouldDrawAmmo", "AdvancedAmmoDisplay", function(wpn)
local char = LocalPlayer():getChar()
if not char then return false end
-- Hide ammo for melee weapons
local weaponClass = wpn:GetClass()
local meleeWeapons = {"weapon_crowbar", "weapon_stunstick", "weapon_knife"}
if table.HasValue(meleeWeapons, weaponClass) then
return false
end
-- Hide ammo when in cutscene
if char:getData("inCutscene", false) then
return false
end
-- Hide ammo for specific factions
local faction = char:getFaction()
if faction == "ghost" then
return false
end
-- Check weapon ammo type
local ammoType = wpn:GetPrimaryAmmoType()
if ammoType == -1 then
return false
end
return true
end)
ShouldDrawEntityInfo
Purpose
Called to check if entity info should be drawn
When Called
When determining if entity information should be displayed
Parameters
e(Entity): The entity
Returns
- boolean - True to draw, false to hide
Realm
Client
Example Usage
Low Complexity:
-- Simple: Always draw entity info
hook.Add("ShouldDrawEntityInfo", "MyAddon", function(e)
return true
end)
Medium Complexity:
-- Medium: Hide info for specific entities
hook.Add("ShouldDrawEntityInfo", "HideSpecificInfo", function(e)
local class = e:GetClass()
local hideClasses = {"prop_physics", "prop_dynamic"}
return not table.HasValue(hideClasses, class)
end)
High Complexity:
-- High: Complex entity info system
hook.Add("ShouldDrawEntityInfo", "AdvancedEntityInfo", function(e)
if not IsValid(e) then return false end
local char = LocalPlayer():getChar()
if not char then return false end
-- Hide info when in cutscene
if char:getData("inCutscene", false) then
return false
end
-- Hide info for specific entity types
local class = e:GetClass()
local hideClasses = {
"prop_physics",
"prop_dynamic",
"func_door",
"func_button"
}
if table.HasValue(hideClasses, class) then
return false
end
-- Show info for players
if e:IsPlayer() then
return true
end
-- Show info for vehicles
if e:IsVehicle() then
return true
end
-- Show info for NPCs
if e:IsNPC() then
return true
end
return false
end)
ShouldDrawPlayerInfo
Purpose
Determines if player information should be drawn
When Called
When deciding whether to draw player info above a player
Parameters
e(Entity): The entity to check
Returns
- boolean - True if player info should be drawn, false otherwise
Realm
Client
Example Usage
Low Complexity:
-- Simple: Draw all player info
hook.Add("ShouldDrawPlayerInfo", "MyAddon", function(e)
return true
end)
Medium Complexity:
-- Medium: Hide info for certain players
hook.Add("ShouldDrawPlayerInfo", "PlayerInfoVisibility", function(e)
if not e:IsPlayer() then return false end
local char = e:getChar()
if not char then return false end
-- Hide info for hidden players
if char:getData("hidden", false) then
return false
end
return true
end)
High Complexity:
-- High: Complex player info visibility system
hook.Add("ShouldDrawPlayerInfo", "AdvancedPlayerInfo", function(e)
if not e:IsPlayer() then return false end
local ply = LocalPlayer()
local char = ply:getChar()
if not char then return false end
local targetChar = e:getChar()
if not targetChar then return false end
-- Don't draw info for self
if e == ply then return false end
-- Check distance
local distance = ply:GetPos():Distance(e:GetPos())
if distance > 500 then return false end
-- Check if target is hidden
if targetChar:getData("hidden", false) then
return false
end
-- Check if target is in stealth mode
if targetChar:getData("stealth", false) then
return false
end
-- Check faction visibility
local plyFaction = char:getFaction()
local targetFaction = targetChar:getFaction()
if plyFaction == "police" and targetFaction == "criminal" then
-- Police can always see criminals
return true
elseif plyFaction == "criminal" and targetFaction == "police" then
-- Criminals can see police
return true
elseif plyFaction == targetFaction then
-- Same faction can see each other
return true
end
-- Check if player has recognition
if targetChar:isRecognized(ply) then
return true
end
-- Check if target is in same group
local plyGroup = char:getData("group")
local targetGroup = targetChar:getData("group")
if plyGroup and plyGroup == targetGroup then
return true
end
-- Check if target is in same team
if ply:Team() == e:Team() then
return true
end
return false
end)
ShouldDrawWepSelect
Purpose
Called to determine if weapon selection should be drawn
When Called
When the system checks if weapon selection UI should be displayed
Parameters
client(Player): The player to check for
Returns
- boolean - Whether to draw weapon selection (true) or not (false)
Realm
Client
Example Usage
Low Complexity:
-- Simple: Always show weapon selection
hook.Add("ShouldDrawWepSelect", "MyAddon", function(client)
return true
end)
Medium Complexity:
-- Medium: Conditional weapon selection
hook.Add("ShouldDrawWepSelect", "ConditionalWepSelect", function(client)
local char = client:getChar()
if char and char:getData("hideWeaponSelect", false) then
return false
end
return true
end)
High Complexity:
-- High: Complex weapon selection logic
hook.Add("ShouldDrawWepSelect", "AdvancedWepSelect", function(client)
-- Check if player is in a vehicle
if client:InVehicle() then
return false
end
-- Check if player is typing
if client:IsTyping() then
return false
end
-- Check custom conditions
local char = client:getChar()
if char then
local faction = char:getFaction()
if faction == FACTION_CITIZEN then
return true
elseif faction == FACTION_POLICE then
return char:getData("showWeaponSelect", true)
end
end
-- Check admin status
if client:IsAdmin() then
return true
end
return false
end)
ShouldHideBars
Purpose
Determines if all bars should be hidden
When Called
When the bar system is about to render
Returns
- boolean - True if bars should be hidden, false otherwise
Realm
Client
Example Usage
Low Complexity:
Medium Complexity:
-- Medium: Hide bars in certain situations
hook.Add("ShouldHideBars", "BarHiding", function()
local ply = LocalPlayer()
-- Hide bars when dead
if not ply:Alive() then
return true
end
-- Hide bars when in vehicle
if ply:InVehicle() then
return true
end
return false
end)
High Complexity:
-- High: Complex bar hiding system
hook.Add("ShouldHideBars", "AdvancedBarHiding", function()
local ply = LocalPlayer()
local char = ply:getChar()
if not char then return true end
-- Hide bars when dead
if not ply:Alive() then
return true
end
-- Hide bars when in vehicle
if ply:InVehicle() then
return true
end
-- Hide bars when in menu
if IsValid(lia.gui.menu) and lia.gui.menu:IsVisible() then
return true
end
-- Hide bars when in character creation
if IsValid(lia.gui.charCreate) and lia.gui.charCreate:IsVisible() then
return true
end
-- Hide bars when in inventory
if IsValid(lia.gui.inv1) and lia.gui.inv1:IsVisible() then
return true
end
-- Hide bars when in third person
if ply:GetViewEntity() ~= ply then
return true
end
-- Hide bars when in cinematic mode
if char:getData("cinematicMode", false) then
return true
end
-- Hide bars when in spectator mode
if ply:GetObserverMode() ~= OBS_MODE_NONE then
return true
end
-- Hide bars when HUD is disabled
if not ply:ShouldDrawLocalPlayer() then
return true
end
-- Hide bars when in admin mode
if ply:IsAdmin() and ply:getData("adminMode", false) then
return true
end
return false
end)
ShouldMenuButtonShow
Purpose
Called to check if a menu button should be shown
When Called
When displaying menu buttons
Parameters
button(string): The button identifier
Returns
- boolean - True to show, false to hide
Realm
Client
Example Usage
Low Complexity:
-- Simple: Show all buttons
hook.Add("ShouldMenuButtonShow", "MyAddon", function(button)
return true
end)
Medium Complexity:
-- Medium: Hide specific buttons
hook.Add("ShouldMenuButtonShow", "HideButtons", function(button)
local hiddenButtons = {"admin", "debug"}
return not table.HasValue(hiddenButtons, button)
end)
High Complexity:
-- High: Complex button visibility system
hook.Add("ShouldMenuButtonShow", "AdvancedButtonVisibility", function(button)
local client = LocalPlayer()
if not IsValid(client) then return false end
local char = client:getChar()
if not char then return false end
-- Check permissions
local permissions = {
["admin"] = client:IsAdmin(),
["moderator"] = client:IsAdmin() or client:IsSuperAdmin(),
["character"] = true,
["inventory"] = true,
["settings"] = true
}
-- Check faction restrictions
local faction = char:getFaction()
if button == "faction" and faction == "ghost" then
return false
end
-- Check character level
local level = char:getData("level", 1)
if button == "advanced" and level < 10 then
return false
end
return permissions[button] or false
end)
ShouldPlayDeathSound
Purpose
Called to check if a death sound should be played
When Called
When a player dies
Parameters
client(Player): The player who dieddeathSound(string): The death sound to play
Returns
- boolean - True to play, false to suppress
Realm
Client
Example Usage
Low Complexity:
-- Simple: Play all death sounds
hook.Add("ShouldPlayDeathSound", "MyAddon", function(client, deathSound)
return true
end)
Medium Complexity:
-- Medium: Suppress specific sounds
hook.Add("ShouldPlayDeathSound", "SuppressSounds", function(client, deathSound)
local suppressedSounds = {"vo/npc/male01/pain01.wav"}
return not table.HasValue(suppressedSounds, deathSound)
end)
High Complexity:
-- High: Complex death sound system
hook.Add("ShouldPlayDeathSound", "AdvancedDeathSound", function(client, deathSound)
if not IsValid(client) then return false end
local char = client:getChar()
if not char then return true end
-- Check if sounds are enabled
local soundEnabled = lia.config.get("deathSounds", true)
if not soundEnabled then return false end
-- Check faction restrictions
local faction = char:getFaction()
if faction == "ghost" then
return false
end
-- Check death type
local deathType = char:getData("deathType", "normal")
if deathType == "silent" then
return false
end
-- Check distance to other players
local pos = client:GetPos()
local nearbyPlayers = 0
for _, ply in ipairs(player.GetAll()) do
if ply ~= client and ply:GetPos():Distance(pos) < 500 then
nearbyPlayers = nearbyPlayers + 1
end
end
-- Only play if other players are nearby
return nearbyPlayers > 0
end)
ShouldPlayPainSound
Purpose
Called to check if a pain sound should be played
When Called
When a player takes damage
Parameters
client(Player): The player taking damagepainSound(string): The pain sound to play
Returns
- boolean - True to play, false to suppress
Realm
Client
Example Usage
Low Complexity:
-- Simple: Play all pain sounds
hook.Add("ShouldPlayPainSound", "MyAddon", function(client, painSound)
return true
end)
Medium Complexity:
-- Medium: Suppress specific sounds
hook.Add("ShouldPlayPainSound", "SuppressPainSounds", function(client, painSound)
local suppressedSounds = {"vo/npc/male01/pain01.wav"}
return not table.HasValue(suppressedSounds, painSound)
end)
High Complexity:
-- High: Complex pain sound system
hook.Add("ShouldPlayPainSound", "AdvancedPainSound", function(client, painSound)
if not IsValid(client) then return false end
local char = client:getChar()
if not char then return true end
-- Check if sounds are enabled
local soundEnabled = lia.config.get("painSounds", true)
if not soundEnabled then return false end
-- Check faction restrictions
local faction = char:getFaction()
if faction == "ghost" then
return false
end
-- Check pain threshold
local health = client:Health()
local maxHealth = client:GetMaxHealth()
local healthPercent = health / maxHealth
if healthPercent > 0.8 then
return false
end
-- Check damage type
local damageType = char:getData("lastDamageType", "generic")
if damageType == "silent" then
return false
end
-- Check distance to other players
local pos = client:GetPos()
local nearbyPlayers = 0
for _, ply in ipairs(player.GetAll()) do
if ply ~= client and ply:GetPos():Distance(pos) < 300 then
nearbyPlayers = nearbyPlayers + 1
end
end
-- Only play if other players are nearby
return nearbyPlayers > 0
end)
ShouldRespawnScreenAppear
Purpose
Called to check if the respawn screen should appear
When Called
When a player dies
Returns
- boolean - True to show respawn screen, false to hide
Realm
Client
Example Usage
Low Complexity:
-- Simple: Always show respawn screen
hook.Add("ShouldRespawnScreenAppear", "MyAddon", function()
return true
end)
Medium Complexity:
-- Medium: Hide respawn screen for specific factions
hook.Add("ShouldRespawnScreenAppear", "HideForFactions", function()
local char = LocalPlayer():getChar()
if not char then return true end
local faction = char:getFaction()
local hiddenFactions = {"ghost", "spectator"}
return not table.HasValue(hiddenFactions, faction)
end)
High Complexity:
-- High: Complex respawn screen system
hook.Add("ShouldRespawnScreenAppear", "AdvancedRespawnScreen", function()
local client = LocalPlayer()
if not IsValid(client) then return true end
local char = client:getChar()
if not char then return true end
-- Check if respawn screen is enabled
local respawnEnabled = lia.config.get("respawnScreen", true)
if not respawnEnabled then return false end
-- Check faction restrictions
local faction = char:getFaction()
if faction == "ghost" then
return false
end
-- Check death type
local deathType = char:getData("deathType", "normal")
if deathType == "instant" then
return false
end
-- Check if player has respawn tokens
local respawnTokens = char:getData("respawnTokens", 0)
if respawnTokens <= 0 then
return false
end
-- Check time restrictions
local lastDeath = char:getData("lastDeath", 0)
local timeSinceDeath = CurTime() - lastDeath
if timeSinceDeath < 5 then
return false
end
return true
end)
ShouldShowClassOnScoreboard
Purpose
Called to check if a class should be shown on the scoreboard
When Called
When displaying the scoreboard
Parameters
clsData(table): The class data
Returns
- boolean - True to show, false to hide
Realm
Client
Example Usage
Low Complexity:
-- Simple: Show all classes
hook.Add("ShouldShowClassOnScoreboard", "MyAddon", function(clsData)
return true
end)
Medium Complexity:
-- Medium: Hide specific classes
hook.Add("ShouldShowClassOnScoreboard", "HideClasses", function(clsData)
local hiddenClasses = {"admin", "debug"}
return not table.HasValue(hiddenClasses, clsData.uniqueID)
end)
High Complexity:
-- High: Complex class visibility system
hook.Add("ShouldShowClassOnScoreboard", "AdvancedClassVisibility", function(clsData)
local client = LocalPlayer()
if not IsValid(client) then return false end
local char = client:getChar()
if not char then return false end
-- Check if scoreboard is enabled
local scoreboardEnabled = lia.config.get("scoreboard", true)
if not scoreboardEnabled then return false end
-- Check faction restrictions
local faction = char:getFaction()
if clsData.faction and clsData.faction ~= faction then
return false
end
-- Check level requirements
local level = char:getData("level", 1)
if clsData.minLevel and level < clsData.minLevel then
return false
end
-- Check permissions
if clsData.adminOnly and not client:IsAdmin() then
return false
end
-- Check if class is active
if clsData.disabled then
return false
end
return true
end)
ShouldShowFactionOnScoreboard
Purpose
Called to check if a faction should be shown on the scoreboard
When Called
When displaying the scoreboard
Parameters
ply(Player): The player whose faction is being checked
Returns
- boolean - True to show, false to hide
Realm
Client
Example Usage
Low Complexity:
-- Simple: Show all factions
hook.Add("ShouldShowFactionOnScoreboard", "MyAddon", function(ply)
return true
end)
Medium Complexity:
-- Medium: Hide specific factions
hook.Add("ShouldShowFactionOnScoreboard", "HideFactions", function(ply)
local char = ply:getChar()
if not char then return false end
local faction = char:getFaction()
local hiddenFactions = {"ghost", "spectator"}
return not table.HasValue(hiddenFactions, faction)
end)
High Complexity:
-- High: Complex faction visibility system
hook.Add("ShouldShowFactionOnScoreboard", "AdvancedFactionVisibility", function(ply)
if not IsValid(ply) then return false end
local char = ply:getChar()
if not char then return false end
local client = LocalPlayer()
if not IsValid(client) then return false end
-- Check if scoreboard is enabled
local scoreboardEnabled = lia.config.get("scoreboard", true)
if not scoreboardEnabled then return false end
-- Check faction restrictions
local faction = char:getFaction()
if faction == "ghost" then
return false
end
-- Check if player is recognized
local clientChar = client:getChar()
if clientChar then
local isRecognized = clientChar:isRecognized(ply)
if not isRecognized then
return false
end
end
-- Check distance
local distance = client:GetPos():Distance(ply:GetPos())
if distance > 1000 then
return false
end
-- Check if faction is public
local factionData = lia.faction.list[faction]
if factionData and factionData.hidden then
return false
end
return true
end)
ShouldShowPlayerOnScoreboard
Purpose
Called to check if a player should be shown on the scoreboard
When Called
When displaying the scoreboard
Parameters
ply(Player): The player to check
Returns
- boolean - True to show, false to hide
Realm
Client
Example Usage
Low Complexity:
-- Simple: Show all players
hook.Add("ShouldShowPlayerOnScoreboard", "MyAddon", function(ply)
return true
end)
Medium Complexity:
-- Medium: Hide specific players
hook.Add("ShouldShowPlayerOnScoreboard", "HidePlayers", function(ply)
local char = ply:getChar()
if not char then return false end
local faction = char:getFaction()
local hiddenFactions = {"ghost", "spectator"}
return not table.HasValue(hiddenFactions, faction)
end)
High Complexity:
-- High: Complex player visibility system
hook.Add("ShouldShowPlayerOnScoreboard", "AdvancedPlayerVisibility", function(ply)
if not IsValid(ply) then return false end
local char = ply:getChar()
if not char then return false end
local client = LocalPlayer()
if not IsValid(client) then return false end
-- Check if scoreboard is enabled
local scoreboardEnabled = lia.config.get("scoreboard", true)
if not scoreboardEnabled then return false end
-- Check faction restrictions
local faction = char:getFaction()
if faction == "ghost" then
return false
end
-- Check if player is recognized
local clientChar = client:getChar()
if clientChar then
local isRecognized = clientChar:isRecognized(ply)
if not isRecognized then
return false
end
end
-- Check distance
local distance = client:GetPos():Distance(ply:GetPos())
if distance > 1000 then
return false
end
-- Check if player is online
if not ply:IsValid() or not ply:IsConnected() then
return false
end
-- Check if player is in same area
local area = char:getData("area", "unknown")
local clientArea = clientChar and clientChar:getData("area", "unknown") or "unknown"
if area ~= clientArea then
return false
end
return true
end)
ShouldSpawnClientRagdoll
Purpose
Called to check if a client ragdoll should be spawned
When Called
When a player dies
Parameters
client(Player): The player who died
Returns
- boolean - True to spawn, false to suppress
Realm
Client
Example Usage
Low Complexity:
-- Simple: Spawn all ragdolls
hook.Add("ShouldSpawnClientRagdoll", "MyAddon", function(client)
return true
end)
Medium Complexity:
-- Medium: Suppress ragdolls for specific factions
hook.Add("ShouldSpawnClientRagdoll", "SuppressRagdolls", function(client)
local char = client:getChar()
if not char then return true end
local faction = char:getFaction()
local suppressedFactions = {"ghost", "spectator"}
return not table.HasValue(suppressedFactions, faction)
end)
High Complexity:
-- High: Complex ragdoll spawning system
hook.Add("ShouldSpawnClientRagdoll", "AdvancedRagdollSpawning", function(client)
if not IsValid(client) then return false end
local char = client:getChar()
if not char then return true end
-- Check if ragdolls are enabled
local ragdollsEnabled = lia.config.get("ragdolls", true)
if not ragdollsEnabled then return false end
-- Check faction restrictions
local faction = char:getFaction()
if faction == "ghost" then
return false
end
-- Check death type
local deathType = char:getData("deathType", "normal")
if deathType == "disintegrate" then
return false
end
-- Check if player has ragdoll tokens
local ragdollTokens = char:getData("ragdollTokens", 0)
if ragdollTokens <= 0 then
return false
end
-- Check performance
local ragdollCount = 0
for _, ent in ipairs(ents.FindByClass("prop_ragdoll")) do
ragdollCount = ragdollCount + 1
end
if ragdollCount > 10 then
return false
end
-- Check distance to other players
local pos = client:GetPos()
local nearbyPlayers = 0
for _, ply in ipairs(player.GetAll()) do
if ply ~= client and ply:GetPos():Distance(pos) < 500 then
nearbyPlayers = nearbyPlayers + 1
end
end
-- Only spawn if other players are nearby
return nearbyPlayers > 0
end)
ShowPlayerOptions
Purpose
Called to show player options menu
When Called
When displaying player options
Parameters
ply(Player): The player to show options forinitialOpts(table): Initial options table
Returns
- table - Modified options table
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add basic options
hook.Add("ShowPlayerOptions", "MyAddon", function(ply, initialOpts)
table.insert(initialOpts, {"Examine", function() print("Examining " .. ply:Name()) end})
return initialOpts
end)
Medium Complexity:
-- Medium: Add faction-specific options
hook.Add("ShowPlayerOptions", "FactionOptions", function(ply, initialOpts)
local char = ply:getChar()
if not char then return initialOpts end
local faction = char:getFaction()
if faction == "police" then
table.insert(initialOpts, {"Arrest", function() print("Arresting " .. ply:Name()) end})
end
return initialOpts
end)
High Complexity:
-- High: Complex player options system
hook.Add("ShowPlayerOptions", "AdvancedPlayerOptions", function(ply, initialOpts)
if not IsValid(ply) then return initialOpts end
local char = ply:getChar()
if not char then return initialOpts end
local client = LocalPlayer()
if not IsValid(client) then return initialOpts end
local clientChar = client:getChar()
if not clientChar then return initialOpts end
-- Check if player is recognized
local isRecognized = clientChar:isRecognized(ply)
if not isRecognized then
table.insert(initialOpts, {"Recognize", function()
net.Start("liaRecognizePlayer")
net.WriteEntity(ply)
net.SendToServer()
end})
end
-- Check faction permissions
local faction = char:getFaction()
local clientFaction = clientChar:getFaction()
if clientFaction == "police" then
table.insert(initialOpts, {"Arrest", function()
net.Start("liaArrestPlayer")
net.WriteEntity(ply)
net.SendToServer()
end})
table.insert(initialOpts, {"Search", function()
net.Start("liaSearchPlayer")
net.WriteEntity(ply)
net.SendToServer()
end})
end
if clientFaction == "medic" then
table.insert(initialOpts, {"Heal", function()
net.Start("liaHealPlayer")
net.WriteEntity(ply)
net.SendToServer()
end})
end
-- Check admin permissions
if client:IsAdmin() then
table.insert(initialOpts, {"Admin Options", function()
local menu = DermaMenu()
menu:AddOption("Kick", function() ply:Kick("Kicked by admin") end)
menu:AddOption("Ban", function() ply:Ban(0, "Banned by admin") end)
menu:Open()
end})
end
return initialOpts
end)
StorageUnlockPrompt
Purpose
Called when storage unlock prompt is shown
When Called
When a player attempts to unlock a locked storage
Parameters
entity(Entity): The storage entity being unlocked
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log unlock prompt
hook.Add("StorageUnlockPrompt", "MyAddon", function(entity)
print("Storage unlock prompt shown for " .. tostring(entity))
end)
Medium Complexity:
-- Medium: Show custom unlock message
hook.Add("StorageUnlockPrompt", "CustomMessage", function(entity)
lia.util.notify("This storage is locked. You need a key to open it.")
end)
High Complexity:
-- High: Complex storage unlock system
hook.Add("StorageUnlockPrompt", "AdvancedStorageUnlock", function(entity)
if not IsValid(entity) then return end
local client = LocalPlayer()
if not IsValid(client) then return end
local char = client:getChar()
if not char then return end
-- Check if player has key
local inventory = char:getInv()
if inventory then
local hasKey = false
for _, item in pairs(inventory:getItems()) do
if item.uniqueID == "storage_key" then
hasKey = true
break
end
end
if hasKey then
lia.util.notify("You have a key for this storage. Press E to unlock.")
else
lia.util.notify("This storage is locked. You need a storage key to open it.")
end
end
-- Check storage type
local storageType = entity:getNetVar("storageType", "normal")
if storageType == "vault" then
lia.util.notify("This is a vault. You need a vault key to open it.")
elseif storageType == "safe" then
lia.util.notify("This is a safe. You need a safe key to open it.")
end
-- Check if storage is owned
local owner = entity:getNetVar("owner")
if owner and owner ~= char:getID() then
lia.util.notify("This storage belongs to someone else.")
end
-- Show unlock options
local menu = DermaMenu()
menu:AddOption("Try to unlock", function()
net.Start("liaStorageUnlock")
net.WriteEntity(entity)
net.SendToServer()
end)
menu:AddOption("Cancel", function() end)
menu:Open()
end)
ThirdPersonToggled
Purpose
Called when third person is toggled
When Called
When third person view is enabled or disabled
Parameters
newValue(boolean): The new third person state
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log third person toggle
hook.Add("ThirdPersonToggled", "MyAddon", function(newValue)
print("Third person " .. (newValue and "enabled" or "disabled"))
end)
Medium Complexity:
-- Medium: Show notification
hook.Add("ThirdPersonToggled", "NotifyToggle", function(newValue)
lia.util.notify("Third person " .. (newValue and "enabled" or "disabled"))
end)
High Complexity:
-- High: Complex third person system
hook.Add("ThirdPersonToggled", "AdvancedThirdPerson", function(newValue)
local client = LocalPlayer()
if not IsValid(client) then return end
-- Update UI
if IsValid(lia.gui.thirdPersonSettings) then
lia.gui.thirdPersonSettings:SetEnabled(newValue)
end
-- Save setting
lia.data.set("thirdPerson", newValue)
-- Notify player
lia.util.notify("Third person " .. (newValue and "enabled" or "disabled"), 3)
-- Update camera
if newValue then
client:SetViewEntity(client)
else
client:SetViewEntity(client)
end
-- Log the change
lia.log.write("third_person_toggle", {
enabled = newValue,
timestamp = os.time()
})
-- Update character model visibility
local char = client:getChar()
if char then
char:setData("thirdPerson", newValue)
end
end)
TicketFrame
Purpose
Called to create a ticket frame
When Called
When displaying a support ticket
Parameters
requester(Player): The player who requested the ticketmessage(string): The ticket messageclaimed(boolean): Whether the ticket is claimed
Returns
- Panel - The ticket frame panel
Realm
Client
Example Usage
Low Complexity:
-- Simple: Create basic ticket frame
hook.Add("TicketFrame", "MyAddon", function(requester, message, claimed)
local frame = vgui.Create("DFrame")
frame:SetSize(400, 300)
frame:Center()
frame:SetTitle("Support Ticket")
frame:MakePopup()
return frame
end)
Medium Complexity:
-- Medium: Create styled ticket frame
hook.Add("TicketFrame", "StyledTicket", function(requester, message, claimed)
local frame = vgui.Create("DFrame")
frame:SetSize(500, 400)
frame:Center()
frame:SetTitle("Support Ticket - " .. (claimed and "Claimed" or "Open"))
frame:MakePopup()
local label = vgui.Create("DLabel", frame)
label:SetText("Requester: " .. requester:Name())
label:Dock(TOP)
local text = vgui.Create("DTextEntry", frame)
text:SetText(message)
text:SetMultiline(true)
text:Dock(FILL)
return frame
end)
High Complexity:
-- High: Complex ticket frame system
hook.Add("TicketFrame", "AdvancedTicketFrame", function(requester, message, claimed)
local frame = vgui.Create("DFrame")
frame:SetSize(600, 500)
frame:Center()
frame:SetTitle("Support Ticket - " .. (claimed and "Claimed" or "Open"))
frame:MakePopup()
-- Header
local header = vgui.Create("DPanel", frame)
header:Dock(TOP)
header:SetHeight(50)
local requesterLabel = vgui.Create("DLabel", header)
requesterLabel:SetText("Requester: " .. requester:Name())
requesterLabel:Dock(LEFT)
local statusLabel = vgui.Create("DLabel", header)
statusLabel:SetText("Status: " .. (claimed and "Claimed" or "Open"))
statusLabel:Dock(RIGHT)
-- Message area
local messageArea = vgui.Create("DTextEntry", frame)
messageArea:SetText(message)
messageArea:SetMultiline(true)
messageArea:SetEditable(false)
messageArea:Dock(FILL)
-- Buttons
local buttonPanel = vgui.Create("DPanel", frame)
buttonPanel:Dock(BOTTOM)
buttonPanel:SetHeight(40)
local claimButton = vgui.Create("DButton", buttonPanel)
claimButton:SetText("Claim Ticket")
claimButton:Dock(LEFT)
claimButton:SetWide(100)
claimButton.DoClick = function()
net.Start("liaClaimTicket")
net.WriteEntity(requester)
net.SendToServer()
end
local closeButton = vgui.Create("DButton", buttonPanel)
closeButton:SetText("Close")
closeButton:Dock(RIGHT)
closeButton:SetWide(100)
closeButton.DoClick = function()
frame:Close()
end
return frame
end)
TooltipInitialize
Purpose
Called to initialize a tooltip
When Called
When a tooltip is being created
Parameters
self(Panel): The tooltip panelpanel(Panel): The parent panel
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Set basic tooltip properties
hook.Add("TooltipInitialize", "MyAddon", function(self, panel)
self:SetText("Tooltip")
end)
Medium Complexity:
-- Medium: Set tooltip based on panel
hook.Add("TooltipInitialize", "PanelTooltip", function(self, panel)
if panel:GetClassName() == "DButton" then
self:SetText("Click me!")
elseif panel:GetClassName() == "DTextEntry" then
self:SetText("Enter text here")
end
end)
High Complexity:
-- High: Complex tooltip system
hook.Add("TooltipInitialize", "AdvancedTooltip", function(self, panel)
if not IsValid(self) or not IsValid(panel) then return end
-- Set tooltip properties
self:SetText("")
self:SetFont("DermaDefault")
self:SetTextColor(Color(255, 255, 255))
-- Get panel information
local panelClass = panel:GetClassName()
local panelText = panel:GetText() or ""
-- Set tooltip based on panel type
if panelClass == "DButton" then
if panelText == "Close" then
self:SetText("Close this window")
elseif panelText == "Save" then
self:SetText("Save your changes")
else
self:SetText("Click to interact")
end
elseif panelClass == "DTextEntry" then
self:SetText("Enter text in this field")
elseif panelClass == "DCheckBox" then
self:SetText("Toggle this option")
elseif panelClass == "DComboBox" then
self:SetText("Select an option from the dropdown")
end
-- Set tooltip position
self:SetPos(panel:GetPos())
self:SetSize(200, 20)
-- Set tooltip delay
self:SetDelay(0.5)
end)
TooltipLayout
Purpose
Called to layout a tooltip
When Called
When a tooltip needs to be laid out
Parameters
self(Panel): The tooltip panel
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Set basic layout
hook.Add("TooltipLayout", "MyAddon", function(self)
self:SizeToContents()
end)
Medium Complexity:
-- Medium: Set layout with constraints
hook.Add("TooltipLayout", "ConstrainedLayout", function(self)
self:SizeToContents()
local w, h = self:GetSize()
if w > 300 then
self:SetWide(300)
end
if h > 100 then
self:SetTall(100)
end
end)
High Complexity:
-- High: Complex tooltip layout system
hook.Add("TooltipLayout", "AdvancedTooltipLayout", function(self)
if not IsValid(self) then return end
-- Get text size
self:SizeToContents()
local w, h = self:GetSize()
local maxWidth = 400
local maxHeight = 200
-- Constrain width
if w > maxWidth then
self:SetWide(maxWidth)
self:SetWrap(true)
end
-- Constrain height
if h > maxHeight then
self:SetTall(maxHeight)
self:SetScrollable(true)
end
-- Position tooltip
local x, y = gui.MousePos()
local screenW, screenH = ScrW(), ScrH()
-- Adjust position if tooltip goes off screen
if x + w > screenW then
x = screenW - w - 10
end
if y + h > screenH then
y = screenH - h - 10
end
self:SetPos(x + 10, y + 10)
-- Set z position
self:SetZPos(1000)
-- Set background
self:SetBackgroundColor(Color(0, 0, 0, 200))
self:SetBorderColor(Color(100, 100, 100))
end)
TooltipPaint
Purpose
Called to paint a tooltip
When Called
When a tooltip is being painted
Parameters
self(Panel): The tooltip panelw(number): The width of the tooltiph(number): The height of the tooltip
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Draw basic background
hook.Add("TooltipPaint", "MyAddon", function(self, w, h)
draw.RoundedBox(4, 0, 0, w, h, Color(0, 0, 0, 200))
end)
Medium Complexity:
-- Medium: Draw styled tooltip
hook.Add("TooltipPaint", "StyledTooltip", function(self, w, h)
-- Background
draw.RoundedBox(4, 0, 0, w, h, Color(0, 0, 0, 200))
-- Border
draw.RoundedBox(4, 0, 0, w, h, Color(100, 100, 100, 255))
-- Text
draw.SimpleText(self:GetText(), "DermaDefault", w/2, h/2, Color(255, 255, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
end)
High Complexity:
-- High: Complex tooltip painting system
hook.Add("TooltipPaint", "AdvancedTooltipPaint", function(self, w, h)
if not IsValid(self) then return end
-- Get tooltip data
local text = self:GetText() or ""
local textColor = self:GetTextColor() or Color(255, 255, 255)
local bgColor = self:GetBackgroundColor() or Color(0, 0, 0, 200)
local borderColor = self:GetBorderColor() or Color(100, 100, 100)
-- Draw background with gradient
local gradient = Material("gui/gradient_up")
surface.SetMaterial(gradient)
surface.SetDrawColor(bgColor)
surface.DrawTexturedRect(0, 0, w, h)
-- Draw border
draw.RoundedBox(4, 0, 0, w, h, borderColor)
-- Draw inner background
draw.RoundedBox(4, 1, 1, w-2, h-2, Color(bgColor.r, bgColor.g, bgColor.b, bgColor.a * 0.8))
-- Draw text with shadow
local textX, textY = w/2, h/2
-- Shadow
draw.SimpleText(text, "DermaDefault", textX+1, textY+1, Color(0, 0, 0, 100), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
-- Main text
draw.SimpleText(text, "DermaDefault", textX, textY, textColor, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
-- Draw icon if available
local icon = self:GetIcon()
if icon then
surface.SetMaterial(icon)
surface.SetDrawColor(Color(255, 255, 255, 200))
surface.DrawTexturedRect(5, 5, 16, 16)
end
end)
TryViewModel
Purpose
Called to try to view a model
When Called
When attempting to view an entity model
Parameters
entity(Entity): The entity to view
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log model view attempt
hook.Add("TryViewModel", "MyAddon", function(entity)
print("Trying to view model: " .. tostring(entity))
end)
Medium Complexity:
-- Medium: Check if entity is valid
hook.Add("TryViewModel", "ValidateEntity", function(entity)
if IsValid(entity) then
local model = entity:GetModel()
if model and model ~= "" then
print("Viewing model: " .. model)
end
end
end)
High Complexity:
-- High: Complex model viewing system
hook.Add("TryViewModel", "AdvancedModelView", function(entity)
if not IsValid(entity) then return end
local client = LocalPlayer()
if not IsValid(client) then return end
-- Check if entity is viewable
local model = entity:GetModel()
if not model or model == "" then
client:ChatPrint("This entity has no model")
return
end
-- Check distance
local distance = client:GetPos():Distance(entity:GetPos())
if distance > 200 then
client:ChatPrint("You are too far away to view this model")
return
end
-- Check if entity is owned
local owner = entity:getNetVar("owner")
if owner then
local char = client:getChar()
if char and owner ~= char:getID() then
client:ChatPrint("This entity belongs to someone else")
return
end
end
-- Create model view panel
local frame = vgui.Create("DFrame")
frame:SetSize(400, 300)
frame:Center()
frame:SetTitle("Model Viewer - " .. entity:GetClass())
frame:MakePopup()
local modelPanel = vgui.Create("DModelPanel", frame)
modelPanel:Dock(FILL)
modelPanel:SetModel(model)
-- Set up model panel
local ent = modelPanel:GetEntity()
if ent then
ent:SetPos(Vector(0, 0, 0))
ent:SetAngles(Angle(0, 0, 0))
end
-- Add controls
local controlPanel = vgui.Create("DPanel", frame)
controlPanel:Dock(BOTTOM)
controlPanel:SetHeight(50)
local rotateButton = vgui.Create("DButton", controlPanel)
rotateButton:SetText("Rotate")
rotateButton:Dock(LEFT)
rotateButton:SetWide(100)
rotateButton.DoClick = function()
if ent then
ent:SetAngles(ent:GetAngles() + Angle(0, 45, 0))
end
end
local closeButton = vgui.Create("DButton", controlPanel)
closeButton:SetText("Close")
closeButton:Dock(RIGHT)
closeButton:SetWide(100)
closeButton.DoClick = function()
frame:Close()
end
end)
UpdateScoreboardColors
Purpose
Called to update scoreboard colors
When Called
When scoreboard colors need to be updated
Parameters
teamColors(table): The team colors table
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log color update
hook.Add("UpdateScoreboardColors", "MyAddon", function(teamColors)
print("Updating scoreboard colors")
end)
Medium Complexity:
-- Medium: Set custom colors
hook.Add("UpdateScoreboardColors", "CustomColors", function(teamColors)
teamColors[1] = Color(255, 0, 0) -- Red
teamColors[2] = Color(0, 255, 0) -- Green
teamColors[3] = Color(0, 0, 255) -- Blue
end)
High Complexity:
-- High: Complex scoreboard color system
hook.Add("UpdateScoreboardColors", "AdvancedScoreboardColors", function(teamColors)
if not teamColors then return end
local client = LocalPlayer()
if not IsValid(client) then return end
local char = client:getChar()
if not char then return end
-- Get faction colors
local faction = char:getFaction()
local factionColors = {
["police"] = Color(0, 100, 255),
["medic"] = Color(0, 255, 100),
["citizen"] = Color(255, 255, 255),
["criminal"] = Color(255, 100, 100)
}
-- Set faction color
local factionColor = factionColors[faction] or Color(255, 255, 255)
teamColors[1] = factionColor
-- Set other team colors
teamColors[2] = Color(100, 100, 100) -- Spectators
teamColors[3] = Color(200, 200, 200) -- Admins
-- Apply color scheme
local colorScheme = lia.config.get("scoreboardColorScheme", "default")
if colorScheme == "dark" then
for i, color in ipairs(teamColors) do
teamColors[i] = Color(color.r * 0.5, color.g * 0.5, color.b * 0.5)
end
elseif colorScheme == "bright" then
for i, color in ipairs(teamColors) do
teamColors[i] = Color(math.min(255, color.r * 1.5), math.min(255, color.g * 1.5), math.min(255, color.b * 1.5))
end
end
-- Update scoreboard panel if it exists
if IsValid(lia.gui.scoreboard) then
lia.gui.scoreboard:UpdateColors(teamColors)
end
end)
VendorExited
Purpose
Called when a vendor is exited
When Called
When a player closes a vendor
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log vendor exit
hook.Add("VendorExited", "MyAddon", function()
print("Vendor exited")
end)
Medium Complexity:
-- Medium: Clean up vendor data
hook.Add("VendorExited", "CleanupVendor", function()
lia.vendor.current = nil
lia.vendor.cache = {}
end)
High Complexity:
-- High: Complex vendor exit system
hook.Add("VendorExited", "AdvancedVendorExit", function()
local client = LocalPlayer()
if not IsValid(client) then return end
local char = client:getChar()
if not char then return end
-- Clean up vendor data
lia.vendor.current = nil
lia.vendor.cache = {}
-- Save vendor interaction data
local vendorData = char:getData("vendorData", {})
vendorData.lastInteraction = os.time()
vendorData.totalInteractions = (vendorData.totalInteractions or 0) + 1
char:setData("vendorData", vendorData)
-- Close vendor UI
if IsValid(lia.gui.vendor) then
lia.gui.vendor:Close()
end
-- Notify player
lia.util.notify("Vendor closed", 2)
-- Log to database
lia.log.write("vendor_exit", {
steamid = client:SteamID(),
timestamp = os.time()
})
-- Update character stats
local vendorStats = char:getData("vendorStats", {})
vendorStats.exits = (vendorStats.exits or 0) + 1
char:setData("vendorStats", vendorStats)
end)
VendorSynchronized
Purpose
Called when a vendor is synchronized
When Called
When vendor data is synced between client and server
Parameters
vendor(Entity): The vendor entity
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log vendor sync
hook.Add("VendorSynchronized", "MyAddon", function(vendor)
print("Vendor synchronized: " .. tostring(vendor))
end)
Medium Complexity:
-- Medium: Update vendor UI
hook.Add("VendorSynchronized", "UpdateVendorUI", function(vendor)
if IsValid(lia.gui.vendor) and lia.gui.vendor.vendor == vendor then
lia.gui.vendor:Populate()
end
end)
High Complexity:
-- High: Complex vendor sync system
hook.Add("VendorSynchronized", "AdvancedVendorSync", function(vendor)
if not IsValid(vendor) then return end
-- Update local vendor cache
local vendorID = vendor:EntIndex()
lia.vendor.cache = lia.vendor.cache or {}
lia.vendor.cache[vendorID] = {
name = vendor:getNetVar("name", "Vendor"),
items = vendor:getNetVar("items", {}),
money = vendor:getNetVar("money", 0),
lastSync = CurTime()
}
-- Update UI if vendor panel is open
if IsValid(lia.gui.vendor) and lia.gui.vendor.vendor == vendor then
lia.gui.vendor:Populate()
lia.gui.vendor:UpdateMoney()
end
-- Notify player
local client = LocalPlayer()
if client:GetPos():Distance(vendor:GetPos()) < 200 then
lia.util.notify("Vendor inventory updated")
end
end)
VoiceToggled
Purpose
Called when voice chat is toggled
When Called
When voice chat is enabled or disabled
Parameters
enabled(boolean): Whether voice chat is enabled
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log voice toggle
hook.Add("VoiceToggled", "MyAddon", function(enabled)
print("Voice chat " .. (enabled and "enabled" or "disabled"))
end)
Medium Complexity:
-- Medium: Show notification
hook.Add("VoiceToggled", "NotifyVoiceToggle", function(enabled)
lia.util.notify("Voice chat " .. (enabled and "enabled" or "disabled"))
end)
High Complexity:
-- High: Complex voice toggle system
hook.Add("VoiceToggled", "AdvancedVoiceToggle", function(enabled)
-- Update UI
if IsValid(lia.gui.voiceSettings) then
lia.gui.voiceSettings:SetEnabled(enabled)
end
-- Save setting
lia.data.set("voiceEnabled", enabled)
-- Notify player
lia.util.notify("Voice chat " .. (enabled and "enabled" or "disabled"), 3)
-- Update voice icon
if IsValid(lia.gui.voiceIcon) then
lia.gui.voiceIcon:SetVisible(enabled)
end
-- Log the change
lia.log.write("voice_toggle", {
enabled = enabled,
timestamp = os.time()
})
end)
WeaponCycleSound
Purpose
Called to get the weapon cycle sound
When Called
When cycling through weapons
Returns
- string - The sound path
Realm
Client
Example Usage
Low Complexity:
-- Simple: Return default sound
hook.Add("WeaponCycleSound", "MyAddon", function()
return "common/wpn_select.wav"
end)
Medium Complexity:
-- Medium: Return custom sound based on settings
hook.Add("WeaponCycleSound", "CustomCycleSound", function()
local soundEnabled = lia.config.get("weaponSounds", true)
if not soundEnabled then return "" end
return "common/wpn_select.wav"
end)
High Complexity:
-- High: Complex weapon cycle sound system
hook.Add("WeaponCycleSound", "AdvancedCycleSound", function()
local client = LocalPlayer()
if not IsValid(client) then return "common/wpn_select.wav" end
-- Check if sounds are enabled
local soundEnabled = lia.config.get("weaponSounds", true)
if not soundEnabled then return "" end
-- Get character-specific sound
local char = client:getChar()
if char then
local faction = char:getFaction()
local factionSounds = {
["police"] = "hl1/fvox/blip.wav",
["military"] = "buttons/button14.wav",
["citizen"] = "common/wpn_select.wav"
}
return factionSounds[faction] or "common/wpn_select.wav"
end
return "common/wpn_select.wav"
end)
WeaponSelectSound
Purpose
Called to get the weapon select sound
When Called
When selecting a weapon
Returns
- string - The sound path
Realm
Client
Example Usage
Low Complexity:
-- Simple: Return default sound
hook.Add("WeaponSelectSound", "MyAddon", function()
return "common/wpn_hudoff.wav"
end)
Medium Complexity:
-- Medium: Return custom sound based on settings
hook.Add("WeaponSelectSound", "CustomSelectSound", function()
local soundEnabled = lia.config.get("weaponSounds", true)
if not soundEnabled then return "" end
return "common/wpn_hudoff.wav"
end)
High Complexity:
-- High: Complex weapon select sound system
hook.Add("WeaponSelectSound", "AdvancedSelectSound", function()
local client = LocalPlayer()
if not IsValid(client) then return "common/wpn_hudoff.wav" end
-- Check if sounds are enabled
local soundEnabled = lia.config.get("weaponSounds", true)
if not soundEnabled then return "" end
-- Get character-specific sound
local char = client:getChar()
if char then
local faction = char:getFaction()
local factionSounds = {
["police"] = "hl1/fvox/activated.wav",
["military"] = "buttons/button15.wav",
["citizen"] = "common/wpn_hudoff.wav"
}
return factionSounds[faction] or "common/wpn_hudoff.wav"
end
return "common/wpn_hudoff.wav"
end)
WebImageDownloaded
Purpose
Called when a web image is downloaded
When Called
When an image from a URL is successfully downloaded
Parameters
url(string): The URL of the imagematerial(Material): The downloaded material
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log image download
hook.Add("WebImageDownloaded", "MyAddon", function(url, material)
print("Image downloaded: " .. url)
end)
Medium Complexity:
-- Medium: Cache downloaded images
hook.Add("WebImageDownloaded", "CacheImages", function(url, material)
lia.webImage.cache = lia.webImage.cache or {}
lia.webImage.cache[url] = material
end)
High Complexity:
-- High: Complex web image system
hook.Add("WebImageDownloaded", "AdvancedWebImage", function(url, material)
-- Cache the material
lia.webImage.cache = lia.webImage.cache or {}
lia.webImage.cache[url] = material
-- Update any panels waiting for this image
for _, panel in ipairs(lia.webImage.waiting[url] or {}) do
if IsValid(panel) then
panel:SetMaterial(material)
panel:InvalidateLayout()
end
end
-- Clear waiting list
lia.webImage.waiting[url] = nil
-- Log download
lia.log.write("web_image_download", {
url = url,
timestamp = os.time()
})
-- Notify completion
hook.Run("OnWebImageReady", url, material)
end)
WebSoundDownloaded
Purpose
Called when a web sound is downloaded
When Called
When a sound from a URL is successfully downloaded
Parameters
name(string): The name of the soundpath(string): The path to the downloaded sound
Returns
- None
Realm
Client
Example Usage
Low Complexity:
-- Simple: Log sound download
hook.Add("WebSoundDownloaded", "MyAddon", function(name, path)
print("Sound downloaded: " .. name)
end)
Medium Complexity:
-- Medium: Cache downloaded sounds
hook.Add("WebSoundDownloaded", "CacheSounds", function(name, path)
lia.webSound.cache = lia.webSound.cache or {}
lia.webSound.cache[name] = path
end)
High Complexity:
-- High: Complex web sound system
hook.Add("WebSoundDownloaded", "AdvancedWebSound", function(name, path)
-- Cache the sound
lia.webSound.cache = lia.webSound.cache or {}
lia.webSound.cache[name] = path
-- Update any sounds waiting for this file
for _, soundData in ipairs(lia.webSound.waiting[name] or {}) do
if soundData.callback then
soundData.callback(path)
end
end
-- Clear waiting list
lia.webSound.waiting[name] = nil
-- Log download
lia.log.write("web_sound_download", {
name = name,
path = path,
timestamp = os.time()
})
-- Notify completion
hook.Run("OnWebSoundReady", name, path)
end)
ColorToHex
Purpose
Allows modification of the voice indicator text displayed when a player is speaking
When Called
When the voice indicator is being drawn and a player is currently speaking
Parameters
client(Player): The LocalPlayer() who is currently speakingvoiceText(string): The current voice indicator text (e.g., "You are talking - 3 players can hear you")voiceType(string): The voice type string (e.g., "talking", "whispering", "yelling")
Returns
- string or nil - Return a string to replace the voice text, or return nil/false to keep the original text
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add emojis to voice indicator
hook.Add("ModifyVoiceIndicatorText", "AddVoiceEmojis", function(client, voiceText, voiceType)
if voiceType == L("whispering") then
return "🔇 " .. voiceText .. " 🔇"
elseif voiceType == L("yelling") then
return "📢 " .. voiceText .. " 📢"
elseif voiceType == L("talking") then
return "💬 " .. voiceText .. " 💬"
end
return nil -- Keep original text
end)
Medium Complexity:
-- Medium: Custom formatting based on voice type
hook.Add("ModifyVoiceIndicatorText", "CustomVoiceFormat", function(client, voiceText, voiceType)
local char = client:getChar()
if not char then return nil end
local name = char:getName()
if voiceType == L("whispering") then
return name .. " is whispering quietly..."
elseif voiceType == L("yelling") then
return name .. " is YELLING LOUDLY!"
elseif voiceType == L("talking") then
return name .. " is speaking normally"
end
return nil -- Keep original text
end)
High Complexity:
-- High: Advanced voice indicator with custom styling
hook.Add("ModifyVoiceIndicatorText", "AdvancedVoiceIndicator", function(client, voiceText, voiceType)
local char = client:getChar()
if not char then return nil end
local name = char:getName()
local faction = char:getFaction()
local factionData = lia.faction.get(faction)
-- Get listener count if voice range is enabled
local listenerCount = 0
if lia.option.get("voiceRange", false) then
-- Calculate listeners (simplified version)
local baseRange = voiceType == L("whispering") and lia.config.get("WhisperRange", 70) or
voiceType == L("talking") and lia.config.get("TalkRange", 280) or
voiceType == L("yelling") and lia.config.get("YellRange", 840) or
lia.config.get("TalkRange", 280)
local count = 0
local clientPos = client:GetPos()
for _, ply in player.Iterator() do
if ply ~= client and IsValid(ply) and ply:getChar() and ply:Alive() then
local distance = clientPos:Distance(ply:GetPos())
local clearLOS = IsLineOfSightClear(client, ply)
local effectiveRange = clearLOS and baseRange or baseRange * 0.16
if distance <= effectiveRange then
count = count + 1
end
end
end
listenerCount = count
end
-- Custom formatting based on faction and voice type
local prefix = ""
local suffix = ""
if factionData and factionData.color then
local color = factionData.color
prefix = string.format("[%s] ", ColorToHex(color))
end
if voiceType == L("whispering") then
suffix = " whispers softly"
elseif voiceType == L("yelling") then
suffix = " YELLS LOUDLY"
elseif voiceType == L("talking") then
suffix = " speaks"
end
local result = prefix .. name .. suffix
if listenerCount > 0 then
result = result .. " - " .. listenerCount .. " players can hear you"
end
return result
end)
-- Helper function for color conversion
function ColorToHex(color)
return string.format("#%02X%02X%02X", color.r, color.g, color.b)
end
ModifyVoiceIndicatorText
Purpose
Allows modification of the voice indicator text displayed when a player is speaking
When Called
When the voice indicator is being drawn and a player is currently speaking
Parameters
client(Player): The LocalPlayer() who is currently speakingvoiceText(string): The current voice indicator text (e.g., "You are talking - 3 players can hear you")voiceType(string): The voice type string (e.g., "talking", "whispering", "yelling")
Returns
- string or nil - Return a string to replace the voice text, or return nil/false to keep the original text
Realm
Client
Example Usage
Low Complexity:
-- Simple: Add emojis to voice indicator
hook.Add("ModifyVoiceIndicatorText", "AddVoiceEmojis", function(client, voiceText, voiceType)
if voiceType == L("whispering") then
return "🔇 " .. voiceText .. " 🔇"
elseif voiceType == L("yelling") then
return "📢 " .. voiceText .. " 📢"
elseif voiceType == L("talking") then
return "💬 " .. voiceText .. " 💬"
end
return nil -- Keep original text
end)
Medium Complexity:
-- Medium: Custom formatting based on voice type
hook.Add("ModifyVoiceIndicatorText", "CustomVoiceFormat", function(client, voiceText, voiceType)
local char = client:getChar()
if not char then return nil end
local name = char:getName()
if voiceType == L("whispering") then
return name .. " is whispering quietly..."
elseif voiceType == L("yelling") then
return name .. " is YELLING LOUDLY!"
elseif voiceType == L("talking") then
return name .. " is speaking normally"
end
return nil -- Keep original text
end)
High Complexity:
-- High: Advanced voice indicator with custom styling
hook.Add("ModifyVoiceIndicatorText", "AdvancedVoiceIndicator", function(client, voiceText, voiceType)
local char = client:getChar()
if not char then return nil end
local name = char:getName()
local faction = char:getFaction()
local factionData = lia.faction.get(faction)
-- Get listener count if voice range is enabled
local listenerCount = 0
if lia.option.get("voiceRange", false) then
-- Calculate listeners (simplified version)
local baseRange = voiceType == L("whispering") and lia.config.get("WhisperRange", 70) or
voiceType == L("talking") and lia.config.get("TalkRange", 280) or
voiceType == L("yelling") and lia.config.get("YellRange", 840) or
lia.config.get("TalkRange", 280)
local count = 0
local clientPos = client:GetPos()
for _, ply in player.Iterator() do
if ply ~= client and IsValid(ply) and ply:getChar() and ply:Alive() then
local distance = clientPos:Distance(ply:GetPos())
local clearLOS = IsLineOfSightClear(client, ply)
local effectiveRange = clearLOS and baseRange or baseRange * 0.16
if distance <= effectiveRange then
count = count + 1
end
end
end
listenerCount = count
end
-- Custom formatting based on faction and voice type
local prefix = ""
local suffix = ""
if factionData and factionData.color then
local color = factionData.color
prefix = string.format("[%s] ", ColorToHex(color))
end
if voiceType == L("whispering") then
suffix = " whispers softly"
elseif voiceType == L("yelling") then
suffix = " YELLS LOUDLY"
elseif voiceType == L("talking") then
suffix = " speaks"
end
local result = prefix .. name .. suffix
if listenerCount > 0 then
result = result .. " - " .. listenerCount .. " players can hear you"
end
return result
end)
-- Helper function for color conversion
function ColorToHex(color)
return string.format("#%02X%02X%02X", color.r, color.g, color.b)
end