Enemy-Territory resources‎ > ‎mods‎ > ‎etpub 1.0.0‎ > ‎

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
BitTypeDescription
1DAMAGE_RADIUSdamage was indirect
2DAMAGE_HALF_KNOCKBACKdo less knockback
8DAMAGE_NO_KNOCKBACKdo not affect velocity, just view angles
16DAMAGE_NO_TEAM_PROTECTIONarmor, shields, invulnerability, and godmode have no effect
32DAMAGE_NO_PROTECTIONarmor, shields, invulnerability, and godmode have no effect
64DAMAGE_DISTANCEFALLOFFdistance falloff
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
NumberTypeDescription
0TR_STATIONARY 
1TR_INTERPOLATEnon-parametric, but interpolate between snapshots
2TR_LINEAR 
3TR_LINEAR_STOP 
4TR_LINEAR_STOP_BACKreverse movement can be different than forward
5TR_SINEvalue = base + sin(time / duration) * delta
6TR_GRAVITY 
7TR_GRAVITY_LOW 
8TR_GRAVITY_FLOATsuper low grav with no gravity acceleration
9TR_GRAVITY_PAUSEDhas stopped, but trace to see if it should be switched back to TR_GRAVITY
10TR_ACCELERATE 
11TR_DECCELERATE 
12TR_SPLINE 
13TR_LINEAR_PATH 

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
IndexWeapon
0WS_KNIFE
1WS_LUGER
2WS_COLT
3WS_MP40
4WS_THOMPSON
5WS_STEN
6WS_FG42
7WS_PANZERFAUST
8WS_FLAMETHROWER
9WS_GRENADE
10WS_MORTAR
11WS_DYNAMITE
12WS_AIRSTRIKE
13WS_ARTILLERY
14WS_SYRINGE
15WS_SMOKE
16WS_SATCHEL
17WS_GRENADELAUNCHER
18WS_LANDMINE
19WS_MG42
20WS_GARAND
21WS_K43

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").

Comments