Examples¶
Practical code examples for common Parallax Framework tasks.
Table of Contents¶
- Example 1: Creating a Custom Faction
- Example 2: Creating a Food Item
- Example 3: Adding Chat Commands
- Example 4: Extending Character Data
- Example 5: Creating a Module
- Example 6: Schema-Specific Hooks
Example 1: Creating a Custom Faction¶
-- schema/factions/sh_medical.lua
FACTION.name = "Medical Staff"
FACTION.description = "Trained medical personnel providing care to citizens."
FACTION.color = Color(0, 255, 0)
FACTION.image = ax.util:GetMaterial("parallax/hl2rp/banners/medical.png")
FACTION.models = {
"models/humans/group01/male_06.mdl",
"models/humans/group01/female_06.mdl",
}
-- Precache models for performance
for i = 1, #FACTION.models do
util.PrecacheModel(FACTION.models[i])
ax.animations:SetModelClass(FACTION.models[i], "citizen_male")
end
-- Custom validation
function FACTION:CanBecome(client)
local char = client:GetCharacter()
-- Must have medical training flag
if !char:HasFlag("medical_training") then
return false, "You must complete medical training first"
end
-- Must be citizen
if char:GetFaction() != FACTION_CITIZEN then
return false, "Only citizens can become medical staff"
end
return true
end
FACTION_MEDICAL = FACTION.index
Example 2: Creating a Food Item¶
-- schema/items/base/sh_food.lua
ITEM.name = "Food Base"
ITEM.description = "Base class for food items"
ITEM.category = "Food"
ITEM.weight = 0.5
ITEM.isBase = true
function ITEM:CanUse(client)
return client:Alive()
end
function ITEM:Consume(client)
-- Override in derived items
return true
end
-- Derived food item
-- schema/items/food/sh_bread.lua
ITEM.name = "Bread"
ITEM.description = "A loaf of fresh bread."
ITEM.model = "models/props/food/bread.mdl"
ITEM.weight = 0.3
ITEM.category = "Food"
ITEM.base = "food"
-- Nutrition data
ITEM.nutrition = 25 -- HP restored
function ITEM:Consume(client)
local hp = client:Health()
local newHp = math.min(hp + self.nutrition, 100)
client:SetHealth(newHp)
client:Notify("You ate the bread and restored " .. (newHp - hp) .. " HP")
return true -- Consume the item
end
-- Add eat action
ITEM:AddAction("eat", {
name = "Eat",
icon = "icon16/cake.png",
order = 1,
CanUse = function(this, client)
return client:Alive() and client:Health() < 100
end,
OnRun = function(action, item, client)
local success = item:Consume(client)
if success then
-- Remove item
return true
end
return false
end
})
Example 3: Adding Chat Commands¶
-- schema/core/sh_commands.lua
ax.command:Add("me", {
description = "Perform an action (roleplay emote)",
arguments = {
{
name = "action",
type = ax.type.text,
required = true
}
},
OnRun = function(this, client, action)
local char = client:GetCharacter()
local name = char:GetName()
local message = "** " .. name .. " " .. action
-- Send to nearby players
for _, ply in ipairs(player.GetAll()) do
if client:GetPos():Distance(ply:GetPos()) < 300 then
ply:ChatPrint(message)
end
end
return true
end
})
ax.command:Add("pm", {
alias = {"privatemessage", "whisper", "w"},
description = "Send a private message to a player",
arguments = {
{
name = "target",
type = ax.type.player,
required = true
},
{
name = "message",
type = ax.type.text,
required = true
}
},
OnRun = function(this, client, target, message)
if !IsValid(target) then
client:Notify("Player not found")
return false
end
local senderName = client:GetCharacter():GetName()
local receiverName = target:GetCharacter():GetName()
client:ChatPrint("[PM] To " .. receiverName .. ": " .. message)
target:ChatPrint("[PM] From " .. senderName .. ": " .. message)
return true
end
})
ax.command:Add("ooc", {
alias = {"outofcharacter"},
description = "Send an out-of-character message",
arguments = {
{
name = "message",
type = ax.type.text,
required = true
}
},
OnRun = function(this, client, message)
local name = client:Nick()
local msg = "(OOC) " .. name .. ": " .. message
for _, ply in ipairs(player.GetAll()) do
ply:ChatPrint(msg)
end
return true
end
})
Example 4: Extending Character Data¶
-- schema/meta/sh_character.lua
function ax.character.meta:IsArrested()
return self:GetVar("arrested", false)
end
function ax.character.meta:SetArrested(arrested)
self:SetVar("arrested", arrested)
end
function ax.character.meta:GetWarrant()
return self:GetVar("warrant", nil)
end
function ax.character.meta:SetWarrant(issuer, reason)
self:SetVar("warrant", {
issuer = issuer:GetCharacter():GetName(),
reason = reason,
time = os.time()
})
end
-- schema/core/sh_character.lua
ax.character:RegisterVar("arrested", {
default = false,
fieldType = ax.type.bool
})
ax.character:RegisterVar("warrant", {
fieldType = ax.type.data
})
-- Usage
local char = client:GetCharacter()
if char:IsArrested() then
client:Notify("You are under arrest!")
end
-- Set warrant
char:SetWarrant(officer, "Possession of contraband")
-- Check warrant
local warrant = char:GetWarrant()
if warrant then
print("Warrant issued by:", warrant.issuer)
print("Reason:", warrant.reason)
print("Time:", os.date("%Y-%m-%d %H:%M:%S", warrant.time))
end
Example 5: Creating a Module¶
-- modules/medic_system/boot.lua
MODULE = MODULE or {}
MODULE.name = "Medic System"
MODULE.description = "Advanced medical treatment system"
MODULE.author = "YourName"
function MODULE:Initialize()
-- Register heal command
ax.command:Add("heal", {
description = "Heal a player",
arguments = {
{
name = "target",
type = ax.type.player,
required = true
},
{
name = "amount",
type = ax.type.number,
default = 25,
min = 1,
max = 100
}
},
OnRun = function(this, client, target, amount)
local char = client:GetCharacter()
-- Check if medic
if char:GetFaction() != FACTION_MEDICAL then
client:Notify("Only medical staff can heal!")
return false
end
-- Check if target is alive
if !target:Alive() then
client:Notify("Target is not alive!")
return false
end
-- Heal target
local hp = target:Health()
local newHp = math.min(hp + amount, target:GetMaxHealth())
target:SetHealth(newHp)
-- Notify
client:Notify("You healed " .. target:Nick() .. " for " .. (newHp - hp) .. " HP")
target:Notify("You were healed by " .. char:GetName() .. " for " .. (newHp - hp) .. " HP")
return true
end
})
ax.util:PrintSuccess("Module '" .. MODULE.name .. "' loaded!")
end
return MODULE
Example 6: Schema-Specific Hooks¶
-- schema/hooks/sh_hooks.lua
-- Modify combine camera sounds
function SCHEMA:EntityEmitSound(data)
local ent = data.Entity
if !IsValid(ent) then return end
if ent:GetClass() == "npc_combine_camera" then
-- Reduce camera sound volume
data.SoundLevel = 60
return true
end
-- Reduce NPC sounds
if ent:IsNPC() then
data.SoundLevel = data.SoundLevel - 15
return true
end
end
-- Custom door detection
local combineDoorModels = {
["models/props_combine/combine_door01.mdl"] = true,
["models/combine_gate_vehicle.mdl"] = true,
["models/combine_gate_citizen.mdl"] = true,
}
function SCHEMA:IsEntityDoor(entity, class)
return class == "prop_dynamic" and combineDoorModels[string.lower(entity:GetModel())]
end
-- Custom player spawn logic
function SCHEMA:PlayerSpawn(client)
local char = client:GetCharacter()
if char:IsCombine() then
-- Combine spawn logic
client:SetModel(char:GetModel())
client:SetMaxHealth(150)
client:SetHealth(150)
client:SetArmor(50)
else
-- Citizen spawn logic
client:SetModel(char:GetModel())
client:SetMaxHealth(100)
client:SetHealth(100)
client:SetArmor(0)
end
end
-- Player death hook
function SCHEMA:PostPlayerDeath(client, inflictor, attacker)
local char = client:GetCharacter()
if char then
-- Drop items on death
local inv = ax.inventory:Get(char:GetInventoryID())
if inv then
for itemID, item in pairs(inv.items) do
ax.item:Transfer(item, inv, 0)
end
end
-- Create death marker
local pos = client:GetPos()
ax.net:StartPVS(pos, "death_marker", client:SteamID64(), pos, os.time())
end
end
-- Player pickup item hook
function SCHEMA:PlayerCanPickupItem(client, item)
local char = client:GetCharacter()
-- Prevent citizens from picking up weapons
if item.category == "Weapons" and char:GetFaction() == FACTION_CITIZEN then
client:Notify("You cannot pick up weapons!")
return false
end
return true
end
Additional Examples¶
Creating a Custom Inventory¶
-- Create a storage container inventory
ax.inventory:Create({maxWeight = 100}, function(inventory)
print("Created storage inventory:", inventory.id)
-- Spawn a container entity
local container = ents.Create("prop_physics")
container:SetModel("models/props_junk/wood_crate001a.mdl")
container:SetPos(Vector(0, 0, 0))
container:Spawn()
container:SetNWInt("InventoryID", inventory.id)
-- Add storage action
container:SetUseType(SIMPLE_USE)
function container:Use(activator, caller)
if activator:IsPlayer() then
ax.net:Start(activator, "open_storage", inventory.id)
end
end
end)
Item Transfer Between Players¶
-- Transfer item from player A to player B
ax.command:Add("give", {
description = "Give an item to another player",
arguments = {
{
name = "target",
type = ax.type.player,
required = true
},
{
name = "item",
type = ax.type.text,
required = true
}
},
OnRun = function(this, client, target, itemName)
local char = client:GetCharacter()
local targetChar = target:GetCharacter()
-- Find item in player's inventory
local playerInv = ax.inventory:Get(char:GetInventoryID())
local targetInv = ax.inventory:Get(targetChar:GetInventoryID())
-- Search for item
local itemToGive = nil
for itemID, item in pairs(playerInv.items) do
if string.lower(item.name) == string.lower(itemName) then
itemToGive = item
break
end
end
if !itemToGive then
client:Notify("You don't have that item!")
return false
end
-- Transfer item
local success, reason = ax.item:Transfer(itemToGive, playerInv, targetInv, function(success)
if success then
client:Notify("You gave " .. itemToGive.name .. " to " .. target:Nick())
target:Notify("You received " .. itemToGive.name .. " from " .. client:Nick())
else
client:Notify("Failed to give item: " .. reason)
end
end)
return success, reason
end
})
Custom Character Creation¶
ax.command:Add("charcreate", {
description = "Create a new character",
arguments = {
{
name = "name",
type = ax.type.string,
required = true
},
{
name = "description",
type = ax.type.text,
required = true
},
{
name = "gender",
type = ax.type.string,
choices = {
male = true,
female = true
}
}
},
OnRun = function(this, client, name, description, gender)
-- Validate name
if string.len(name) < 2 or string.len(name) > 32 then
client:Notify("Name must be between 2 and 32 characters!")
return false
end
-- Validate description
if string.len(description) < 16 then
client:Notify("Description must be at least 16 characters!")
return false
end
-- Create character
ax.character:Create(client, {
name = name,
description = description,
faction = FACTION_CITIZEN,
gender = gender or "male"
}, function(character)
if character then
client:Notify("Character created successfully!")
client:SpawnCharacter(character)
else
client:Notify("Failed to create character!")
end
end)
return true
end
})
Continue to: Best Practices