Lua Scripting
No Quarter Wiki
No Quarter, as of version 1.2.5, supports server-side modifications via the Lua scripting language. It is highly recommended to use the latest No Quarter release for full Lua support. For more information about Lua, check out the Reference Manual, Lua Mod API, the online edition of the book Programming in Lua or the Lua-users wiki.
Contents |
Lua API
No Quarter's Lua API (the Interface for communication between Lua and NQ) follows mostly the ETPub-Implementation, which itself is build to be compatible with ETPro's Lua-implementation. Therefore, all scripts written in ETpro's documentation should be valid and more or less compatible with No Quarter's Lua API.
The basic idea for this Lua API is event-management. After a certain event (lets say a player dies), the lua-interaction-code in No Quarter executes a predefined function (in this case et_Obituary( victim, killer, meansOfDeath )
), with additional predefined arguments. The Lua API allows you to manipulate and control this information. In some cases you can also return a value to NQ, whenever you intercepted something (i.e. a command), and prevent NQ to handle it further.
This way, you can easily define new commands, or alter existing ones. Through special functions, it is also possible to alter No Quarter's internal structures or Entities (Remap shaders, manipulate client XP, set and read cvars etc.).
No Quarter Specials
As NQ isn't ETPro, and as NQ got a lot more features, the NQ Developers added additional commands and functions to the API, to help coders produce better and mightier code. Those will be documented here.
Functions
- et.G_shrubbot_permission( ent, flag )
This function returns if the Entity(Player) ent has the appropriate permission to execute the command specified with flag flag. Flag can be found in the Shrubbot documentation, as entity you should perhaps use the clientNum.
- et.G_shrubbot_level( ent )
As the above function, this is for shrub-interaction, and query's for the actual adminlevel of Player ent. ClientNum works.
- et.G_XP_Set ( clientNum , xp, skill, add )
This function handles the new ways of XP-Save. Sets XP for ClientNum, or adds it to their existing XP when "add" is "1". "skill" sets their skill-level. This function only works if XPSave is turned on in the server config.
- et.ClientNumberFromString (name)
This is a shiny little helper, as it does what the name implies; it searches for a client which equals the given string in "name". If no client is found, or if there are 2 which fit for the given string, nil is returned.
Entity Fields
Some new fields for entities are also available:
name | type | r/w | desc |
---|---|---|---|
sess.uci | INT | readonly | the country code determined by the geolocation (if enabled) |
sess.newton | INT | readonly | |
sess.rifleNade | INT | readonly | |
sess.executions | INT | readonly | |
sess.killingSpree | INT | readonly | |
sess.poisoneer | INT | readonly | |
sess.panzernoob | INT | readonly | |
sess.kickass | INT | readonly | |
sess.missionair | INT | readonly | |
sess.darwin | INT | readonly | |
sess.goomba | INT | readonly | |
sess.ignoreClients | INT | r/w | |
sess.skillpoints | array/table(floats) | readonly | |
sess.kstreak | INT | readonly | |
pers.lastkilled_client | INT | readonly | |
pers.lastrevive_client | INT | readonly | |
pers.lastkiller_client | INT | readonly | |
pers.lastammo_client | INT | readonly | |
pers.lasthealth_client | INT | readonly | |
pers.lastteambleed_client | INT | readonly | |
pers.lastteambleed_dmg | INT | readonly |
- More to come
sess.muted
In No Quarter 1.2.7 and higer, sess.muted
returns 1 if the corresponding player is muted (0 if not). Prior Versions have a bug which causes this function to return -1 every time it's called.
If you set this value, note that it will work, but as no userinfochange is announced, nobody will see that this client is muted or un-muted (icon in PLayerlist etc.).
To announce this, set the clients userinfo via et.trap_SetUserinfo( clientnum, userinfo )
and then call et.ClientUserinfoChanged( clientNum )
to announce it.
Lua Examples
As an example, additionally to the ones found in ETpro's Lua Mod API, we will build our own (very small and useless, as /lua_status cannot be overridden, which I at first intended...) mod. We will just disable /kill for low adminlevels (as said, useless).
At first, we need to think about the call which we want to intercept. In this case, it's a user-command. Search in the Lua Mod API for a function that is called when a client-command is executed.
et_ClientCommand( clientNum, command )
seems to be perfect.
From the Lua Mod API
- "The mod should return 1 if the command was intercepted by the mod, and 0 if the command was ignored by the mod and should be passed through to the server (and other mods in the chain)."
That's perfect. We can intercept all clientcommands! And prevent NQ from executing it. The function to fetch a player's adminlevel can be found in the No Quarter Specials, et.G_shrubbot_level( ent )
.
But, hey, how should we determine which command the user typed? What if its /m , not /kill? For this, we need the argument-handling functions provided by the API. Or we just check the given string "command". I prefer argument handling, even if it has its bugs (later).
et.trap_Argv( argnum )
should work for our check if its /kill. Therefore, we just call it, requesting the first argument (the one after the "/" ) and check if its "kill" If it is, we check for the adminlevel, and if its to low, we return "1" to the mod and give the user a warning, if not, we just ignore it and return "0".
To put it together:
-- Lua mod to prevent /kill without a certain adminlevel (No warranty!) -- change it to the adminlevel that fits for you needed_level = 3 -- if we have a clientcommand function et_ClientCommand( clientNum, command ) -- get the first argument arg1 = et.trap_Argv( 0 ) -- check for /kill if arg1 == "kill" then -- well, its /kill, now we need to get the players adminlevel lvl = et.G_shrubbot_level( clientNum ) -- we got it. then compare if lvl <= needed_level then -- Hey, his lvl isn't high enough! Lets send him a message -- You don't know this function? I didn't mention it? well, search for its syntax, try to understand it et.trap_SendServerCommand( clientNum, "chat \\"^1/kill^3 is disabled") -- return 1, cause we don't want NQ to display info return 1 -- end of our lvl test end -- end of /kill test end -- if its not /kill, we do nothing end
Lua SQL
More information about the Lua SQL manager (NOQ) for NQ can be found on the NQ Lua development project.
Notes
- On releases after 1.2.7
ClientConnect
is only called once after the 1st player connection.
No Quarter Constants
The following info refers to NQ 1.2.7 and higher.
Weapons
WP_NONE, // 0 - nothing, sometimes kick reference as this WP_KNIFE, // 1 - axis knife WP_LUGER, // 2 - P08 9mm Luger pistol WP_MP40, // 3 - MP40 smg WP_GRENADE_LAUNCHER, // 4 - Axis stick grenade WP_PANZERFAUST, // 5 - Axis Panzerfaust weapon WP_FLAMETHROWER, // 6 - American flamethrower WP_COLT, // 7 - American Colt .45 cal pistol WP_THOMPSON, // 8 - M1 smg WP_GRENADE_PINEAPPLE, // 9 - American frag grenade WP_STEN, // 10 - British Sten MKII WP_MEDIC_SYRINGE, // 11 - Morphin syringe WP_AMMO, // 12 - Ammo pack WP_ARTY, // 13 - Arty shell, also it's ammo sents airstrike/arty availability to client WP_SILENCER, // 14 - P08 with silencer on WP_DYNAMITE, // 15 - Dynamite pack WP_SMOKETRAIL, // 16 - Smoke on arty hit as well as it's explosion VERYBIGEXPLOSION, // 17 - explosion effect for airplanes WP_MEDKIT, // 18 - Medkit 'launcher' WP_BINOCULARS, // 19 - Binoculars WP_PLIERS, // 20 - Enineer's pliers to build/repair/plant/disarm stuff WP_SMOKE_MARKER, // 21 - Airstrike marker smoke grenade WP_KAR98, // 22 - Engineer's K43 WP_CARBINE, // 23 - Engineer's M1 Garand WP_GARAND, // 24 - Covert's M1 Garand WP_LANDMINE, // 25 - landmine WP_SATCHEL, // 26 - satchel 'launcher' WP_SATCHEL_DET, // 27 - satchel detonator WP_SMOKE_BOMB, // 28 - Covert's smoke grenade WP_MOBILE_MG42, // 29 - Mobile MG42 WP_K43, // 30 - Covert's K43 WP_FG42, // 31 - FG42 WP_DUMMY_MG42, // 32 - storing heat on mounted mg42s WP_MORTAR, // 33 - Allied Mortar WP_AKIMBO_COLT, // 34 - akimbo colts WP_AKIMBO_LUGER, // 35 - akimbo lugers WP_GPG40, // 36 - Grenade launcher for K43 WP_M7, // 37 - grenade launcher for M1 Garand WP_SILENCED_COLT, // 38 - Colt with silencer on WP_GARAND_SCOPE, // 39 - Active scoped M1 Garand WP_K43_SCOPE, // 40 - Active scoped K43 WP_FG42SCOPE, // 41 - Active scoped FG42 WP_MORTAR_SET, // 42 - deployed mortar WP_MEDIC_ADRENALINE, // 43 - adrenaline syringe WP_AKIMBO_SILENCEDCOLT, // 44 - akimbo silenced colts WP_AKIMBO_SILENCEDLUGER, // 45 - akimbo silenced lugers WP_MOBILE_MG42_SET, // 46 - deployed MG42 WP_SHOTGUN, // 47 - Winchester Model 1897 12-gauge WP_KNIFE_KABAR, // 48 - US KABAR Combat Knife WP_MOBILE_BROWNING, // 49 - Browning .30 Light Machinegun WP_MOBILE_BROWNING_SET, // 50 - (as above with bipod deployed) WP_BAR, // 51 - Browning Automatic Rifle WP_BAR_SET, // 52 - (as above with bipod deployed) WP_STG44, // 53 - Sturmgewehr 44 Assault Rifle WP_STEN_MKII, // 54 - Sten MkII SMG (unsilenced) WP_BAZOOKA, // 55 - M1 Bazooka Anti-Tank WP_MP34, // 56 - Solothurn S1-100 SMG WP_MORTAR2, // 57 - Axis mortar WP_MORTAR2_SET, // 58 - deployed Axis mortar WP_VENOM, // 59 - Venom machinegun WP_POISON_SYRINGE, // 60 - poisoned syringe WP_FOOTKICK, // 61 - foot kick WP_NUM_WEAPONS // 62 - NOTE: this cannot be larger than 64 for AI/player weapons!
MOD: Means of Death
MOD_UNKNOWN, // 0 MOD_MACHINEGUN, // 1 MOD_BROWNING, // 2 MOD_MG42, // 3 MOD_GRENADE, // 4 MOD_KNIFE, // 5 MOD_LUGER, // 6 MOD_COLT, // 7 MOD_MP40, // 8 MOD_THOMPSON, // 9 MOD_STEN, // 10 MOD_GARAND, // 11 MOD_SILENCER, // 12 MOD_FG42, // 13 MOD_FG42_SCOPE, // 14 MOD_PANZERFAUST, // 15 MOD_GRENADE_LAUNCHER, // 16 MOD_FLAMETHROWER, // 17 MOD_GRENADE_PINEAPPLE, // 18 MOD_MAPMORTAR, // 19 MOD_MAPMORTAR_SPLASH, // 20 MOD_KICKED, // 21 MOD_DYNAMITE, // 22 MOD_AIRSTRIKE, // 23 MOD_SYRINGE, // 24 MOD_AMMO, // 25 MOD_ARTY, // 26 MOD_WATER, // 27 MOD_SLIME, // 28 MOD_LAVA, // 29 MOD_CRUSH, // 30 MOD_TELEFRAG, // 31 MOD_FALLING, // 32 MOD_SUICIDE, // 33 MOD_TARGET_LASER, // 34 MOD_TRIGGER_HURT, // 35 MOD_EXPLOSIVE, // 36 MOD_CARBINE, // 37 MOD_KAR98, // 38 MOD_GPG40, // 39 MOD_M7, // 40 MOD_LANDMINE, // 41 MOD_SATCHEL, // 42 MOD_SMOKEBOMB, // 43 MOD_MOBILE_MG42, // 44 MOD_SILENCED_COLT, // 45 MOD_GARAND_SCOPE, // 46 MOD_CRUSH_CONSTRUCTION, // 47 MOD_CRUSH_CONSTRUCTIONDEATH, // 48 MOD_CRUSH_CONSTRUCTIONDEATH_NOATTACKER, // 49 MOD_K43, // 50 MOD_K43_SCOPE, // 51 MOD_MORTAR, // 52 MOD_AKIMBO_COLT, // 53 MOD_AKIMBO_LUGER, // 54 MOD_AKIMBO_SILENCEDCOLT, // 55 MOD_AKIMBO_SILENCEDLUGER, // 56 MOD_SMOKEGRENADE, // 57 MOD_SWAP_PLACES, // 58 MOD_SWITCHTEAM, // 59 MOD_GOOMBA, // 60 MOD_POISON, // 61 MOD_FEAR, // 62 MOD_CENSORED, // 63 MOD_SHOTGUN, // 64 MOD_BACKSTAB, // 65 MOD_MOBILE_BROWNING, // 66 MOD_BAR, // 67 MOD_STG44, // 68 MOD_BAZOOKA, // 69 MOD_STEN_MKII, // 70 MOD_MP34, // 71 MOD_VENOM, // 72 MOD_SHOVE, // 73 MOD_THROWKNIFE, // 74 MOD_NUM_MODS // 75