lua

ETPUB LUA API DOCUMENTATION

etpub's Lua API is aiming to be fully compatible to etpro's Lua API. Differences between etpub's and etpro's Lua API are described in this documentation.

*Marks differences between etpub's and etpro's Lua API

LUA RESOURCES

COMMANDS

Client Commands

lua_status

Lists all currently loaded lua modules.

Lua modules cannot override this client command.

Server Commands

lua_status

Lists all currently loaded lua modules.

CVARS

Server Cvars

lua_modules

Space separated list of lua modules for ETPub to load. Modules will be run in the order listed.

Default is "" (Disabled)

lua_allowedModules

If set, only lua modules with the matching sha1 signatures listed in this cvar will be allowed to load.

Default is "" (Disabled)

Changing either cvar will cause all currently loaded modules to quit and be unloaded until the next map_restart, reset_match or map change.

ET LIBRARY CALLS

Clients

*clientnum = et.G_ClientNumberFromString( string )

Searches for one partial match with string. If one is found the clientnum is returned. If there is none or more than one match -1 is returned.

LUA CODE EXAMPLE

-- get number from client with partial name match 'ETPla' clientnum = et.G_ClientNumberFromString("ETPla")

ET Filesystem

fd, len = et.trap_FS_FOpenFile( filename, mode )

Attempts to open the file filename with the access mode mode (see et.FS_* constants). Returns the filedescriptor fd and file length len. On error, len returns -1.

LUA CODE EXAMPLE

fd, len = et.trap_FS_FOpenFile("mymodule.log", et.FS_READ)

filedata = et.trap_FS_Read( fd, count )

Reads count bytes from filedescriptor fd.

LUA CODE EXAMPLE

fd, len = et.trap_FS_FOpenFile("mymodule.log", et.FS_READ) if len ~= -1 then filedata = et.trap_FS_Read(fd, len) end et.trap_FS_FCloseFile(fd)

count = et.trap_FS_Write( filedata, count, fd )

Attempts to write count bytes of filedata to filedescriptor fd. Returns number of bytes (count) successfully written.

LUA CODE EXAMPLE

fd, len = et.trap_FS_FOpenFile("mymodule.log", et.FS_APPEND) content = "MODEVENT: X Y: Player X does something with player Y.\n" if len ~= -1 then count = et.trap_FS_Write(content, string.len(content), fd) end et.trap_FS_FCloseFile(fd)

et.trap_FS_Rename( oldname, newname )

Renames file oldname to newname.

LUA CODE EXAMPLE

et.trap_FS_Rename("mymodule.log", "mymodule.bak")

et.trap_FS_FCloseFile( fd )

Closes filedescriptor fd.

LUA CODE EXAMPLE

fd, len = et.trap_FS_FOpenFile("mymodule.log", et.FS_READ) -- read file content here et.trap_FS_FCloseFile(fd)

Sound

*et.G_ClientSound( clientnum, soundindex )

Plays the sound soundindex for the client with clientnum only.

LUA CODE EXAMPLE

-- play a sound for client #3 only soundindex = et.G_SoundIndex("sound/world/alarm_01.wav") et.G_ClientSound(3, soundindex)

Miscellaneous

milliseconds = et.trap_Milliseconds()

Returns a number (milliseconds) indicating the current server time in milliseconds.

LUA CODE EXAMPLE

milliseconds = et.trap_Milliseconds()

et.G_Damage( target, inflictor, attacker, damage, dflags, mod )

Does amount of damage on target inflicted by inflictor and cased by attacker.

- target, inflictor and attacker are entity numbers.

- dflags is a bitflag number to decide how the damage is inflicted.

- mod is a number from 0 up to *69 to set the type of damage.

Damage flags are bitflags with the following available bits.

DFLAGS AVAILABLE BITS

LUA CODE EXAMPLE

-- do 50 damage with no protection (dflags = 32) on client #0 -- with MOD_UNKNOWN (mod = 0) as <world> entity (inflictor, attacker = 1022) et.G_Damage(0, 1022, 1022, 50, 32, 0)

*flooding = et.ClientIsFlooding( clientnum )

Checks if client clientnum is flooding (1) or not (0).

Note: There will be done no update to the flood protect behaviour on running this library call. ETPub only checks on callvote, say, m, mt, ma, say_team, vsay, vsay_team, say_buddy, vsay_buddy, fireteam, rconAuth, ready, say_teamnl, specinvite, readyteam client commands for flooding.

LUA CODE EXAMPLE

if et.ClientIsFlooding(clientnum) == 1 then -- client is flooding, do something end

*et.G_AddSkillPoints( ent, skill, points )

Note: To remove skill points you can also use negative points values.

LUA CODE EXAMPLE

-- add 100.5 points to heavy weapons skill (skill = 5) of client #0 et.G_AddSkillPoints(0, 5, 100.5)

*et.G_LoseSkillPoints( ent, skill, points )

LUA CODE EXAMPLE

-- remove 100.5 points from heavy weapons skill (skill = 5) of client #0 et.G_LoseSkillPoints(0, 5, 100.5)

Entities

(variable) = et.gentity_get ( entnum, fieldname, arrayindex )

Gets the value of fieldname from entity entnum out of the g_entity struct. For NULL entities, nil is returned.

arrayindex is used to specify which element of an array entity field to get. It is required when accessing array type fields. Entity field array indexes start at 0.

et.gentity_set( entnum, fieldname, arrayindex, value )

Sets the value of fieldname from entity entnum in the g_entity struct to value.

arrayindex is used to specify which element of an array entity field to set.

Shrubbot

*permission = et.G_shrubbot_permission( ent, flag )

Checks if client ent has permission (1) for flag or not (0).

Note: Use nil or -1 to check permission for console (Console always returns 1!).

LUA CODE EXAMPLE

-- check if client #1 has permission for flag "C" if et.G_shrubbot_permission(1, "C") == 1 then -- client has permission, do something end

*level = et.G_shrubbot_level( ent )

Returns the level for client ent.

Note: Use nil or -1 to get the level for console.

LUA CODE EXAMPLE

-- get shrubbot level for client #2 level = et.G_shrubbot_level(2)

CALLBACKS

qagame Execution

Client Management

et_ClientSpawn( clientNum, revived, *teamChange, *restoreHealth )

Commands

intercepted = et_ClientCommand( clientNum, command )

intercepted = et_ConsoleCommand( *command )

Miscellaneous

(customObit) = et_Obituary( victim, killer, meansOfDeath )

Called whenever a player is killed. *Modules should return a string (customObit) to override the default obituary or nil to leave it as it is.

LUA CODE EXAMPLE

function et_Obituary(victim, killer, meansOfDeath) if victim == killer and meansOfDeath == 26 then customObit = "%s ^7had an ^1EXPLOSIVE ^7relationship with his dynamite." return string.format(customObit, et.gentity_get(victim, "pers.netname")) end end

PREDEFINED CONSTANTS

*et.CS_PLAYERS

et.EXEC_NOW

et.EXEC_INSERT

et.EXEC_APPEND

et.FS_READ

et.FS_WRITE

et.FS_APPEND

et.FS_APPEND_SYNC

et.SAY_ALL

et.SAY_TEAM

et.SAY_BUDDY

et.SAY_TEAMNL

et.HOSTARCH

Set to WIN32 or UNIX depending on the host architecture qagame is running on.

*LUA_PATH

Set to fs_homepath/fs_game/?.lua;fs_homepath/fs_game/lualibs/?.lua in order to ease use of the require function. Depending on the configuration fs_basepath/fs_game/?.lua;fs_basepath/fs_game/lualibs/?.lua will be added to the LUA_PATH.

*LUA_CPATH

Set to fs_homepath/fs_game/lualibs/?.(so|dll) in order to ease use of the require function. Depending on the configuration fs_basepath/fs_game/lualibs/?.(so|dll) will be added to the LUA_CPATH.

*LUA_DIRSEP

Set to \ or / depending on the host architecture qagame is running on.

CONFIG

ET VARIABLE TYPES

vec3

A vec3 is a 3-element array of numbers. It is usually used to store and process coordinates in 3D space. In lua a vector is an array (table indexed by integers) containing 3 numbers. It can be accessed by doing:

LUA CODE EXAMPLE

origin = et.gentity_get(entNum, "origin") x, y, z = origin[1], origin[2], origin[3]

trajectory

A trajectory is returned as a lua table described below.

LUA TRAJECTORY TABLE

{ trType = <number>, -- int (see below for allowed values) trTime = <number>, -- int trDuration = <number>, -- int trBase = <vec3>, -- vec3 (as described above) trDelta = <vec3> -- vec3 }

The allowed values for trType (along with the enum names and original comments from the ET source), are as follows. Note that not all values make sense for all entity types.

TRTYPE ALLOWED VALUES

weaponstats

A weaponstats is a 5-element array of integers. It is usually used to store weapon statistics such as atts (shots), deaths, headshots, hits and kills. In lua a weaponstats is an array (table indexed by integers) containing 5 integers. It can be accessed by doing:

LUA CODE EXAMPLE

ws = et.gentity_get(clientNum, "sess.aWeaponStats", 3) -- MP40 atts, deaths, headshots, hits, kills = ws[1], ws[2], ws[3], ws[4], ws[5]

The available weapon indexes are as follows.

WEAPONSTATS AVAILABLE INDEXES

SERVER COMMANDS

et.trap_SendServerCommand() is used to send a command from the server to one or more clients. The first argument is the slot number of the client the command will be sent to. If it's equal to -1, the command will be broadcast to all clients.

The following commands can be issued with this function:

Chatting

"c clientNum \"message\""

c prints message as a global chat message on behalf of the client specified by clientNum.

"tc clientNum \"message\" X-location Y-location Z-location"

tc prints message as a team chat message on behalf of the client specified by clientNum.

The X, Y and Z-location's are optional parameters that represent the client's location.

If the X, Y and Z-location's are left out then the message will be printed without a location.

"bc clientNum \"message\" X-location Y-location Z-location"

bc prints message as a fireteam chat message on behalf of the client specified by clientNum.

The X, Y and Z-location's are optional parameters that represent the client's location.

If the X, Y and Z-location's are left out then the message will be printed without a location.

CAVEATS

Like qagame, lua modules are unloaded and reloaded on map_restart and map changes. This means that all global variables and other information is lost. Modules may choose to store persistent data in cvars or external files.

FAQ

Q: OMG I hate the libary prefix et.* on everything!

A: Use the following code to remove the prefix:

LUA CODE EXAMPLE

table.foreach(et, function(func, value) _G[func] = value; end)

Q: How do I reload my lua module without restarting the whole server?

A: Use map_restart, reset_match or simply change the map.

Q: OMG my lua module doesn't work!

A: Make sure you added your module's filename to the lua_modules cvar (e.g. set lua_modules "mymodule.lua").