Classes Library
Character class management and validation system for the Lilia framework.
Overview
The classes library provides comprehensive functionality for managing character classes in the Lilia framework. It handles registration, validation, and management of player classes within factions. The library operates on both server and client sides, allowing for dynamic class creation, whitelist management, and player class assignment validation. It includes functionality for loading classes from directories, checking class availability, retrieving class information, and managing class limits. The library ensures proper faction validation and provides hooks for custom class behavior and restrictions.
lia.class.register
đ Purpose
Registers a new character class with the specified unique ID and data
â° When Called
During gamemode initialization or when dynamically creating classes
âī¸ Parameters
| Parameter | Type | Description |
|---|---|---|
uniqueID |
string | Unique identifier for the class |
data |
table | Table containing class properties (name, desc, limit, faction, etc.) |
âŠī¸ Returns
- The registered class table
đ Realm
Shared
đĄ Example Usage
đ° Low Complexity
lia.class.register("citizen", {
name = "Citizen",
desc = "A regular citizen",
faction = FACTION_CITIZEN,
limit = 0
})
đ Medium Complexity
lia.class.register("police_officer", {
name = "Police Officer",
desc = "A law enforcement officer",
faction = FACTION_POLICE,
limit = 5,
OnCanBe = function(self, client)
return client:getChar():getAttrib("strength", 0) >= 10
end
})
âī¸ High Complexity
local classData = {
name = "Elite Soldier",
desc = "A highly trained military operative",
faction = FACTION_MILITARY,
limit = 2,
isWhitelisted = true,
OnCanBe = function(self, client)
local char = client:getChar()
return char:getAttrib("strength", 0) >= 15 and
char:getAttrib("endurance", 0) >= 12 and
client:IsAdmin()
end,
OnSpawn = function(self, client)
client:Give("weapon_ar2")
client:SetHealth(150)
end
}
lia.class.register("elite_soldier", classData)
lia.class.loadFromDir
đ Purpose
Loads character classes from a directory containing class definition files
â° When Called
During gamemode initialization to load classes from files
âī¸ Parameters
| Parameter | Type | Description |
|---|---|---|
directory |
string | Path to directory containing class files |
âŠī¸ Returns
- nil
đ Realm
Shared
đĄ Example Usage
đ° Low Complexity
đ Medium Complexity
local classDir = "gamemodes/lilia/modules/custom_classes/classes"
if file.Exists(classDir, "LUA") then
lia.class.loadFromDir(classDir)
end
âī¸ High Complexity
local classDirectories = {
"gamemodes/lilia/classes",
"gamemodes/lilia/modules/factions/classes",
"gamemodes/lilia/modules/custom_classes/classes"
}
for _, dir in ipairs(classDirectories) do
if file.Exists(dir, "LUA") then
print("Loading classes from: " .. dir)
lia.class.loadFromDir(dir)
end
end
lia.class.canBe
đ Purpose
Checks if a client can join a specific character class
â° When Called
When a player attempts to join a class or when checking class availability
âī¸ Parameters
| Parameter | Type | Description |
|---|---|---|
client |
Player | The player attempting to join the class |
class |
number | The class index to check |
âŠī¸ Returns
- boolean, string - Whether the player can join and reason if they cannot
đ Realm
Shared
đĄ Example Usage
đ° Low Complexity
local canJoin, reason = lia.class.canBe(client, 1)
if canJoin then
print("Player can join class")
else
print("Cannot join: " .. reason)
end
đ Medium Complexity
local function checkClassAvailability(client, className)
local classIndex = lia.class.retrieveClass(className)
if not classIndex then
return false, "Class not found"
end
local canJoin, reason = lia.class.canBe(client, classIndex)
return canJoin, reason
end
âī¸ High Complexity
local function validateClassSwitch(client, newClass)
local currentChar = client:getChar()
if not currentChar then
return false, "No character"
end
local currentClass = currentChar:getClass()
if currentClass == newClass then
return false, "Already in this class"
end
local canJoin, reason = lia.class.canBe(client, newClass)
if not canJoin then
return false, reason
end
-- Additional custom validation
if hook.Run("CustomClassValidation", client, newClass) == false then
return false, "Custom validation failed"
end
return true, "Valid"
end
lia.class.get
đ Purpose
Retrieves a character class by its identifier (index or uniqueID)
â° When Called
When needing to access class information or properties
âī¸ Parameters
| Parameter | Type | Description |
|---|---|---|
identifier |
number/string | Class index or uniqueID to retrieve |
âŠī¸ Returns
- table - The class data table or nil if not found
đ Realm
Shared
đĄ Example Usage
đ° Low Complexity
đ Medium Complexity
local function getClassInfo(identifier)
local class = lia.class.get(identifier)
if not class then
return nil, "Class not found"
end
return {
name = class.name,
description = class.desc,
limit = class.limit,
faction = class.faction
}
end
âī¸ High Complexity
local function getClassDetails(identifier)
local class = lia.class.get(identifier)
if not class then
return nil, "Class not found"
end
local players = lia.class.getPlayers(identifier)
local playerCount = #players
return {
info = class,
currentPlayers = players,
playerCount = playerCount,
isAvailable = class.limit == 0 or playerCount < class.limit,
isWhitelisted = class.isWhitelisted or false,
canJoin = function(client)
return lia.class.canBe(client, identifier)
end
}
end
lia.class.getPlayers
đ Purpose
Gets all players currently using a specific character class
â° When Called
When needing to find players in a particular class or check class population
âī¸ Parameters
| Parameter | Type | Description |
|---|---|---|
class |
number | The class index to get players for |
âŠī¸ Returns
- table - Array of player entities in the specified class
đ Realm
Shared
đĄ Example Usage
đ° Low Complexity
đ Medium Complexity
local function getClassMembers(className)
local classIndex = lia.class.retrieveClass(className)
if not classIndex then
return {}
end
local players = lia.class.getPlayers(classIndex)
local memberNames = {}
for _, player in ipairs(players) do
table.insert(memberNames, player:Name())
end
return memberNames
end
âī¸ High Complexity
local function getClassStatistics(classIndex)
local players = lia.class.getPlayers(classIndex)
local stats = {
count = #players,
players = {},
onlineTime = 0,
averageLevel = 0
}
for _, player in ipairs(players) do
local char = player:getChar()
if char then
table.insert(stats.players, {
name = player:Name(),
level = char:getLevel(),
playtime = char:getPlayTime()
})
stats.onlineTime = stats.onlineTime + char:getPlayTime()
end
end
if stats.count > 0 then
stats.averageLevel = stats.onlineTime / stats.count
end
return stats
end
lia.class.getPlayerCount
đ Purpose
Gets the count of players currently using a specific character class
â° When Called
When needing to check class population without retrieving player objects
âī¸ Parameters
| Parameter | Type | Description |
|---|---|---|
class |
number | The class index to count players for |
âŠī¸ Returns
- number - Number of players in the specified class
đ Realm
Shared
đĄ Example Usage
đ° Low Complexity
đ Medium Complexity
local function checkClassAvailability(classIndex)
local class = lia.class.get(classIndex)
if not class then
return false, "Class not found"
end
local currentCount = lia.class.getPlayerCount(classIndex)
local isFull = class.limit > 0 and currentCount >= class.limit
return not isFull, isFull and "Class is full" or "Available"
end
âī¸ High Complexity
local function getClassPopulationReport()
local report = {}
for i, class in ipairs(lia.class.list) do
local count = lia.class.getPlayerCount(i)
local percentage = 0
if class.limit > 0 then
percentage = (count / class.limit) * 100
end
table.insert(report, {
name = class.name,
currentCount = count,
limit = class.limit,
percentage = percentage,
isFull = class.limit > 0 and count >= class.limit,
faction = class.faction
})
end
return report
end
lia.class.retrieveClass
đ Purpose
Finds a class by matching its uniqueID or name with a search string
â° When Called
When needing to find a class by name or partial identifier
âī¸ Parameters
| Parameter | Type | Description |
|---|---|---|
class |
string | String to match against class uniqueID or name |
âŠī¸ Returns
- number - The class index if found, nil otherwise
đ Realm
Shared
đĄ Example Usage
đ° Low Complexity
local classIndex = lia.class.retrieveClass("citizen")
if classIndex then
print("Found class at index: " .. classIndex)
end
đ Medium Complexity
local function findClassByName(searchTerm)
local classIndex = lia.class.retrieveClass(searchTerm)
if not classIndex then
return nil, "Class '" .. searchTerm .. "' not found"
end
local class = lia.class.get(classIndex)
return classIndex, class
end
âī¸ High Complexity
local function searchClasses(searchTerm)
local results = {}
local term = string.lower(searchTerm)
for i, class in ipairs(lia.class.list) do
local uniqueID = string.lower(class.uniqueID or "")
local name = string.lower(class.name or "")
if string.find(uniqueID, term) or string.find(name, term) then
table.insert(results, {
index = i,
class = class,
matchType = string.find(uniqueID, term) and "uniqueID" or "name"
})
end
end
return results
end
lia.class.hasWhitelist
đ Purpose
Checks if a character class has whitelist restrictions
â° When Called
When checking if a class requires special permissions or whitelist access
âī¸ Parameters
| Parameter | Type | Description |
|---|---|---|
class |
number | The class index to check for whitelist |
âŠī¸ Returns
- boolean - True if the class has whitelist restrictions, false otherwise
đ Realm
Shared
đĄ Example Usage
đ° Low Complexity
local hasWhitelist = lia.class.hasWhitelist(1)
if hasWhitelist then
print("This class requires whitelist")
end
đ Medium Complexity
local function checkClassAccess(client, classIndex)
local class = lia.class.get(classIndex)
if not class then
return false, "Class not found"
end
if lia.class.hasWhitelist(classIndex) then
-- Check if player has whitelist access
local hasAccess = client:IsAdmin() or client:IsSuperAdmin()
return hasAccess, hasAccess and "Access granted" or "Whitelist required"
end
return true, "No whitelist required"
end
âī¸ High Complexity
local function getWhitelistClasses()
local whitelistClasses = {}
local regularClasses = {}
for i, class in ipairs(lia.class.list) do
if lia.class.hasWhitelist(i) then
table.insert(whitelistClasses, {
index = i,
class = class,
requiredPermissions = class.requiredPermissions or {}
})
else
table.insert(regularClasses, {
index = i,
class = class
})
end
end
return {
whitelist = whitelistClasses,
regular = regularClasses,
totalWhitelist = #whitelistClasses,
totalRegular = #regularClasses
}
end
lia.class.retrieveJoinable
đ Purpose
Retrieves all classes that a specific client can join
â° When Called
When displaying available classes to a player or checking joinable options
âī¸ Parameters
| Parameter | Type | Description |
|---|---|---|
client |
Player | The player to check joinable classes for (optional, defaults to LocalPlayer on client) |
âŠī¸ Returns
- table - Array of class tables that the client can join
đ Realm
Shared
đĄ Example Usage
đ° Low Complexity
local joinableClasses = lia.class.retrieveJoinable(client)
print("Player can join " .. #joinableClasses .. " classes")
đ Medium Complexity
local function getJoinableClassNames(client)
local joinableClasses = lia.class.retrieveJoinable(client)
local classNames = {}
for _, class in ipairs(joinableClasses) do
table.insert(classNames, class.name)
end
return classNames
end
âī¸ High Complexity
local function getDetailedJoinableClasses(client)
local joinableClasses = lia.class.retrieveJoinable(client)
local detailedClasses = {}
for _, class in ipairs(joinableClasses) do
local playerCount = lia.class.getPlayerCount(class.index)
local isFull = class.limit > 0 and playerCount >= class.limit
table.insert(detailedClasses, {
class = class,
playerCount = playerCount,
limit = class.limit,
isFull = isFull,
availability = isFull and "Full" or "Available",
requiresWhitelist = lia.class.hasWhitelist(class.index)
})
end
-- Sort by availability and name
table.sort(detailedClasses, function(a, b)
if a.isFull ~= b.isFull then
return not a.isFull -- Available classes first
end
return a.class.name < b.class.name
end)
return detailedClasses
end