RPG Xdocumentation About RPG X

Scripted buffs

Buffs and debuffs as files, like SWEPs: putting them on players and NPCs, and writing your own.

Buffs and debuffs are scripted like SWEPs: one file per buff, and the file name is its id. The gamemode's own are in gamemode/buffs/; any addon's go in lua/rpgx/buffs/*.lua (loaded on both sides). Applying one is a single line (server), on players and NPCs alike:

ent:AddBuff( "slowed" )           -- for its own Duration; again = one more stack, time restarts
ent:AddBuff( "frozen", 5 )        -- 5 seconds (0 = until removed)
ent:AddBuff( "slowed", nil, 3 )   -- 3 stacks at once (up to its MaxStacks)
ent:RemoveBuff( "slowed" )
ent:ClearBuffs()
-- both sides:
ent:HasBuff( "frozen" )   ent:GetBuffStacks( "slowed" )   ent:GetBuffs()   -- id -> { stacks, ends, duration, data, ... }

A buff file, e.g. lua/rpgx/buffs/poisoned.lua:

BUFF.Name = "Poisoned"
BUFF.Icon = "icon16/bug.png"     -- any icon16/... (https://wiki.facepunch.com/gmod/Silkicons) or your own material
BUFF.Debuff = true
BUFF.Duration = 8
BUFF.MaxStacks = 3
BUFF.Regen = { stamina = 0.5 }   -- stamina refills at half speed
BUFF.DamageTaken = function( self, ent, inst ) return 1 + 0.1 * inst.stacks end

function BUFF:GetDescription( ent, inst ) return "Stamina refills at half speed, and you take more damage." end
function BUFF:Think( ent, inst ) end   -- server, every tick

Whatever a buff leaves out comes from its base: BUFF.Base, "base" when not set (gamemode/buffs/base.lua lists every value and function with its default). Any buff can be a base: Frozen is BUFF.Base = "slowed". self.BaseClass is the base, like with SWEPs, and BUFF.Abstract = true makes one that can't be applied or picked anywhere (buffs deriving from it aren't abstract).

Value Default
Name, Icon, Description "Buff", icon16/star.png, none What the HUD shows (tooltip: Description or GetDescription)
Debuff false Red edge instead of green
Hidden false Not on the HUD
Duration 10 Seconds when applied without saying; 0 = until removed
MaxStacks 1 Applying it again adds a stack, up to this
RemoveOnDeath true
Speed Players: movement speed times this (0 = can't move)
NoJump, NoAttack Players: true = can't jump / neither attack button does anything
Regen Refilling times this, per resource: { stamina = 0.5, mana = 2 }
DamageTaken, DamageDealt Damage times this

The effects can also be a function( self, ent, inst ) returning the value (inst.stacks for stacking ones); several buffs multiply. Functions: OnApply( ent, inst ), OnStack( ent, inst ), OnRemove( ent, inst, reason ) (expired / removed / death / gone), Think( ent, inst ), EntityTakeDamage( ent, dmg, inst ) (server); SetupMove( ply, mv, cmd, inst ), GetDescription( ent, inst ) (both). inst.data is a table for the buff's own use.

Built in: Slowed (-20% speed per stack, up to 3, 5 s) and Frozen (can't move, jump or attack for 3 s; NPCs stop and turn blue). Buffs show on the HUD with the others (see Buffs and debuffs); death clears them unless RemoveOnDeath = false.

Also: GAMEMODE:RegisterBuff( id, table ) registers one from code (both sides), GAMEMODE:BuffList() is every appliable one, and the server hooks RPGXBuffAdded( ent, id, inst ) and RPGXBuffRemoved( ent, id, inst, reason ). To try one out: rpgx_buff <id> [seconds] [stacks] puts it on the player or NPC you look at (else yourself), rpgx_buff clear removes them all (permission buff_debug).