Difference between revisions of "Lua Tutorials"

From WolfWiki
Jump to: navigation, search
(-_-)
 
(command dumpuserid part 2)
 
(17 intermediate revisions by 5 users not shown)
Line 1: Line 1:
 
__NOEDITSECTION__
 
__NOEDITSECTION__
  
This page isn't finished but its supposed to make you understand [[ETPro]] [http://www.lua.org/ lua] functions.
+
This page is here to help you understand [[ETPro]] [http://www.lua.org/ Lua] functions.
  
Before you start on this tutorial its assumed you do know basic [http://www.lua.org/ lua] scripting ,if not then i suggest you take a look at the online edition of the book [http://www.lua.org/pil/ Programming in Lua] or the [http://lua-users.org/wiki/ lua-users wiki].
+
Before you start on this tutorial I assume you know basic [http://www.lua.org/ Lua] scripting.  If not then I suggest you take a look at the online edition of the book [http://www.lua.org/pil/ Programming in Lua] or the [http://lua-users.org/wiki/ lua-users wiki].
You can also take a look at someone else his code, a list of [[ETPro]] mods can be found [[:Category:ETPro:Mods|here]].
+
You can also take a look at code made by someone else, a list of [[ETPro]] mods that can be found [[:Category:ETPro:Mods|here]], or our [[ETPro:Lua Sample Code|Lua Sample Code]].
  
 
==Getting started==
 
==Getting started==
 
===Loading a Script===
 
===Loading a Script===
:Scripts are loaded by their file name out of the /etpro subdirectory of your Enemy Territory installation, so don't forget to save them in the right folder.<br>
+
:Scripts are loaded by their file name out of the /etpro sub directory of your Enemy Territory installation, so don't forget to save them in the right folder.<br>
 
:if you want to load HelloWorld.lua you would have to set the server cvar '''lua_modules''' to ''"HelloWorld.lua"''.<br>
 
:if you want to load HelloWorld.lua you would have to set the server cvar '''lua_modules''' to ''"HelloWorld.lua"''.<br>
 
:If you want to load more mods you can add them to the same variables separated by a space like ''"HelloWorld.lua lol.lua pingpong.lua"''
 
:If you want to load more mods you can add them to the same variables separated by a space like ''"HelloWorld.lua lol.lua pingpong.lua"''
:'''NOTE''': if u moddify this cvar all currently loaded [http://www.lua.org/ lua] modules will be unloaded.
+
:'''NOTE''': if you modify this cvar all currently loaded [http://www.lua.org/ lua] modules will be unloaded.
  
 
:After editing your script you save it and then reload it in [[ETPro]] to make your chances take effect, this can simply be done by '''reset_match''' server command.
 
:After editing your script you save it and then reload it in [[ETPro]] to make your chances take effect, this can simply be done by '''reset_match''' server command.
  
 
===Development Environment===
 
===Development Environment===
:While scripting you will see your code gets hard to read, its much easier to read whit syntax highlighting. this can de done be scripting inside an [http://www.lua.org/ lua] development environment.
+
:While scripting you will see your code gets hard to read, its much easier to read with syntax highlighting. This can be done by scripting inside an [http://www.lua.org/ lua] development environment.
  
:At [http://lua-users.org/wiki/LuaAddons this page] under ''[http://lua-users.org/wiki/LuaAddons development environments]'' you will find a list of [[http://lua-users.org/wiki/LuaAddons development environments].
+
:These can be found under the ''Development Environments'' heading at  [http://lua-users.org/wiki/LuaAddons this page].
  
 
==Tutorials==
 
==Tutorials==
:'''NOTE''': Lines written in '''Bold''' are the actual lines we gonna write to our script.
+
:'''NOTE''': Lines written in '''Bold''' are the actual lines we are going to write in our scripts.
 
===Hello World===
 
===Hello World===
:here we will show an simple hello world example for the server console
+
:Here we will show a simple hello world example for the server console.
:just follow the steps and read the comments.
+
:Just follow the steps and read the comments.
  
:1. First we need a new file so, create a new file and name it HelloWorld.lua.
+
:1. First we need a new file so, create a new file and name it ''HelloWorld.lua''.
  
::Now we need a [[ETPro]] [http://www.lua.org/ lua] function that will automagicly called by [[ETPro]] when we want it. Therefor we will use ''et_InitGame(levelTime,randomSeed,restart)'' that function is called ones every round at the beginning. its a good function to do some initial settings. We don't have to worry about those parameters (levelTime,randomSeed,restart) in this example.
+
::Now we need an [[ETPro]] [http://www.lua.org/ lua] function that will be called automatically by [[ETPro]] when we want it. Therefore we will use ''et_InitGame(levelTime,randomSeed,restart)''. That function is called once every round at the beginning. It's a good function to do some initial settings. We do not have to worry about those parameters (levelTime,randomSeed,restart) in this example.
  
:2. inside our file at line ''1'' we will write '''function et_InitGame(levelTime,randomSeed,restart) --called at beginning of a gameround'''
+
:2. Inside our file at line ''1'' we will write '''function et_InitGame(levelTime,randomSeed,restart) -- called at beginning of a gameround'''
  
::Now we got a part of our script that is called at the beginning of a round so, now we can add our code to it. we are going to print ''"hello world"'' in the server console therefor we will use ''et.G_Print("message")'' that function will simply print the ''"message"'' in the server console
+
::Now we got a part of our script that is called at the beginning of a round so now we can add our code to it. We are going to print ''"hello world"'' in the server console. To do this we will use ''et.G_Print("message")''. That function will simply print the ''"message"'' in the server console.
  
:3. now at line ''2'' we will write '''    et.G_Print("Hello World!!!\n") --printout our text to the console'''
+
:3. At line ''2'' we will write '''    et.G_Print("Hello World!!!\n") -- printout our text to the console'''
  
::and as last we need to end out function at line ''1'' whit a simple ''end''
+
::Lastly we need to end out function at line ''1'' with a simple ''end''
  
:4. at line ''3'' place '''end --close et_InitGame()'''
+
:4. At line ''3'' place '''end --close et_InitGame()'''
  
::now if you did it right you should have something like [http://home.zonnet.nl/westhof99/lua/HelloWorld.lua this]:
+
::Now if you did it right you should have something like [http://home.zonnet.nl/westhof99/lua/HelloWorld.lua this]:
  <font color="blue">function</font> et_InitGame(levelTime,randomSeed,restart) <font color="green">--called at beginning of a gameround</font>
+
  <font color="blue">function</font> et_InitGame(levelTime,randomSeed,restart) <font color="green">-- called at beginning of a gameround</font>
     et.G_Print(<font color="darkblue">"Hello World!!!\n"</font>) <font color="green">--printout our text to the console</font>
+
     et.G_Print(<font color="darkblue">"Hello World!!!\n"</font>) <font color="green">-- printout our text to the console</font>
 
  <font color="blue">end</font> <font color="green">--close et_InitGame()</font>
 
  <font color="blue">end</font> <font color="green">--close et_InitGame()</font>
  
::now save and load your script and you will see Hello World!!! in the server console.
+
::Now save and load your script and you will see Hello World!!! in the server console.
  
 
<hr>
 
<hr>
 
===Hello Spam===
 
===Hello Spam===
:here we will show an simpel Spammy hello world example for the server console
+
:Here we will show a simple Spammy hello world example for the server console.
:just follow the steps abnd read the comments.
+
:Just follow the steps and read the comments.
  
:1. First we need a new file so, create a new file and name it '''HelloSpam.lua'''.
+
:1. First we need a new file so, create a new file and name it ''HelloSpam.lua''.
  
::Now we need a [[ETPro]] [http://www.lua.org/ lua] function that will automagicly called by [[ETPro]] many times to make it spammy. Therefor we will use ''et_RunFrame(levelTime)'' that function is called every server frame. its a good function for stuff u need to constandly check but u should not put to much code in here. We dont have to worry about those parameter (levelTime) in this example.
+
::Now we need an [[ETPro]] [http://www.lua.org/ lua] function that will be called automatically by [[ETPro]] many times to make it spammy. Therefore we will use ''et_RunFrame(levelTime)''. That function is called every server frame. It is a good function for stuff you need to constantly check but you should not put to much code in here. We do not have to worry about those parameter (levelTime) in this example.
  
:2. inside our file at line ''1'' we will write '''function et_RunFrame(levelTime) --called every serverframe'''
+
:2. Inside our file at line ''1'' we will write '''function et_RunFrame(levelTime) --called every serverframe'''
  
::Now we got a part of our script that is called at the beggining of a round so, now we can add our code to it. we are gonig to print ''"hello world"'' in the server console therefor we will use ''et.G_Print("message")'' that function will simpely print the ''"message"'' in the server console
+
::Now we got a part of our script that is called at the beginning of a round so, now we can add our code to it. We are going to print ''"hello world"'' in the server console. To do this we will use ''et.G_Print("message")''; that function will simply print the ''"message"'' in the server console
  
:3. now at line ''2'' we will write '''    et.G_Print("Hello Spam!!!\n") --printout our text to the console'''
+
:3. Now at line ''2'' we will write '''    et.G_Print("Hello Spam!!!\n") -- printout our text to the console'''
  
::and as last we need to end our function at line ''1'' whit a simpel at line ''3'' ''end''
+
::Lastly we need to end our function at line ''1'' with a simple at line ''3'' ''end''
  
:4. at line ''3'' place '''end --close et_RunFrame()'''
+
:4. At line ''3'' place '''end --close et_RunFrame()'''
  
::now if u did it right u should have something like [http://home.zonnet.nl/westhof99/lua/HelloSpam.lua this]:
+
::Now if you did it right you should have something like [http://home.zonnet.nl/westhof99/lua/HelloSpam.lua this]:
 
  <font color="blue">function</font> et_RunFrame(levelTime) <font color="green">--called every serverframe</font>
 
  <font color="blue">function</font> et_RunFrame(levelTime) <font color="green">--called every serverframe</font>
     et.G_Print(<font color="darkblue">"Hello Spam!!!\n"</font>) <font color="green">--printout our text to the console</font>
+
     et.G_Print(<font color="darkblue">"Hello Spam!!!\n"</font>) <font color="green">-- printout our text to the console</font>
 
  <font color="blue">end</font> <font color="green">--close et_RunFrame()</font>
 
  <font color="blue">end</font> <font color="green">--close et_RunFrame()</font>
::now save and load your script and u will see Hello Spam!!! in the server console.
+
::Now save and load your script and you will see Hello Spam!!! in the server console.
 
<hr>
 
<hr>
 
===Hello Client===
 
===Hello Client===
:here we will show a simple hello world example for the client console
+
:Here we will show a simple hello world example for the client console.
:just follow the steps and read the comments.
+
:Just follow the steps and read the comments.
  
:1. First we need a new file so, create a new file and name it HelloClient.lua.
+
:1. First we need a new file so, create a new file and name it ''HelloClient.lua''.
  
::Now we need a [[ETPro]] [http://www.lua.org/ lua] function that will automagicly called by [[ETPro]] when we want it. Therefor we will use ''et_InitGame(levelTime,randomSeed,restart)'' as shown in the ''Hello World'' example.
+
::Now we need a [[ETPro]] [http://www.lua.org/ lua] function that will be called automatically by [[ETPro]] when we want it. To do this we will use ''et_InitGame(levelTime,randomSeed,restart)'' as shown in the ''Hello World'' example.
  
:2. inside our file at line ''1'' we will write '''function et_InitGame(levelTime,randomSeed,restart) --called at beginning of a gameround'''
+
:2. Inside our file at line ''1'' we will write '''function et_InitGame(levelTime,randomSeed,restart) --called at beginning of a gameround'''
  
::Now we need a function to print a message to the client his console therefor we will use et.trap_SendServerCommand(-1,"print \"message\n\"")'' that function will simply print the ''"message"'' in the client console console.
+
::Now we need a function to print a message to the client his console. We will use et.trap_SendServerCommand(-1,"print \"message\n\"")'' to achieve this. That function will simply print the ''"message"'' in the client's console.
::The first parameter is client slot to send to if is -1 it will send to all clients. the 2nd parameters looks confusing and it is. First u got the main command witch is "print  .." then, at the place of the dots comes the data to send whit the print in our case its "message\n""
+
::The first parameter is the client slot to send to. When this is -1 ETPro will send the message to all clients. The 2nd parameter looks confusing and like the original author's spelling, it is. First you have the main command witch is "print  ..". Then, at the place of the dots, comes the data to send with the print. In our case this is "message\n"".
::The \n will send a newline command to the console so the next message written to the console is on the next line. The \" are just " but since they are already inside a string u need to prefix them whit a \
+
::The \n will send a newline command to the console so the next message written to the console is on the next line. The \" are just quotes but since they are already inside a string you need to prefix them with a \ (commonly known as an escape character).
  
:3. so just write this at line ''2'' '''    et.trap_SendServerCommand(-1,"print \"Hello Client\n\"") --printout our text to the console'''
+
:3. So just write this at line ''2'' '''    et.trap_SendServerCommand(-1,"print \"Hello Client\n\"") -- printout our text to the console'''
  
::and as last we need to end out function at line ''1'' with a simple ''end''
+
::Last we need to end our function at line ''1'' with a simple ''end''
  
:4. at line ''3'' place '''end --close et_InitGame()'''
+
:4. At line ''3'' place '''end --close et_InitGame()'''
  
::now if you did it right you should have something like [http://home.zonnet.nl/westhof99/lua/HelloClient.lua this]:
+
::Now if you did it right you should have something like [http://home.zonnet.nl/westhof99/lua/HelloClient.lua this]:
  <font color="blue">function</font> et_InitGame(levelTime,randomSeed,restart) <font color="green">--called at beginning of a gameround</font>
+
  <font color="blue">function</font> et_InitGame(levelTime,randomSeed,restart) <font color="green">-- called at beginning of a gameround</font>
     et.trap_SendServerCommand(-<font color="blue">1</font>,<font color="darkblue">"print \"Hello Client\n\""</font>) <font color="green">--printout our text to the console</font>
+
     et.trap_SendServerCommand(-<font color="blue">1</font>,<font color="darkblue">"print \"Hello Client\n\""</font>) <font color="green">-- printout our text to the console</font>
  <font color="blue">end</font> <font color="green">--close et_InitGame()</font>
+
  <font color="blue">end</font> <font color="green">-- close et_InitGame()</font>
  
::now save and load your script and you will see Hello World!!! in the client console at the begin of a round.
+
::Now save and load your script and you will see Hello World!!! in the client's console at the begin of a round.
 
<hr>
 
<hr>
[[Category:ETPro]]
+
 
[[Category:ETPro:Mods]]
+
===Server Command lol===
[[Category:ETPro:LUA]]
+
:Here we will show how to make a new server command that will simply print ''hihi''.
 +
:Just follow the steps and read the comments.
 +
 
 +
:1. First we need to create a new file for the script.  Create a new file and name it ''ServerCmdLol.lua''.
 +
 
 +
::To start we need an ETPro Lua function that will be called automatically by ETPro when a certain server command has been entered.
 +
::To do this we will use et_ConsoleCommand()''.
 +
::It is called for every server command but not for engine commands like ''say'',''broadcast'',''echo''.
 +
 
 +
:2. Inside our file at line ''1'' we will write '''function et_ConsoleCommand()--called when someone types a command in conosle or uses sa todo a server command'''
 +
 
 +
::Now the first thing we need to know is what command was entered.
 +
::Commands that are entered will be split up by spaces, so ''cmd1 hello all'' will be split up into "cmd1", "hello" and "all".
 +
::The only exception is that ''cmd2 "hello all"'' will be split up in "cmd2" and "hello all" because, "hello all" is entered as one string by enclosing them in quotes.
 +
::To get a part of the command you should use et.trap_Argv(''partnumber'')
 +
::''partnumber'' 0 is the actual command and, ''partnumber'' 1 is the first parameter of the command
 +
:: so in our example above we would get:
 +
:::et.trap_Argv(0) = "cmd1"
 +
:::et.trap_Argv(1) = "hello"
 +
:::et.trap_Argv(2) = "all"
 +
 
 +
:3. At line ''2'' we will write ''' local cmd = et.trap_Argv(0) --load out the first parameter of the test typed in console (the command itself)'''
 +
 
 +
::The commands are sent the same way they were entered, so if you enter ''cMd3'' you will get ''cMd3''.
 +
::To detect all variations, we will convert the string to lowercase using a normal Lua function.
 +
 
 +
:4. To make it lower case we will write ''' cmd = string.lower(cmd) --convert it to lowercase so it is easier to match in our if statements''' at line ''3''
 +
 
 +
::Now we can use a simple ''if'' statement to check if the command is ''lol''.
 +
 
 +
:5. At line ''4'' write ''' if cmd == "lol" then --run our code if the command was "lol"'''
 +
 
 +
::If thats true then the script should print "hihi".
 +
 
 +
:6. To do this, at line ''5'' write '''        et.G_Print("hihi\n") --print out "hihi"'''
 +
 
 +
::Now that we have handled the command in our [[ETPro]] [http://www.lua.org/ Lua] script, we do not need to send it to the normal ETPro code since that will return "Unknown Command" anyway.
 +
::We can let ETPro ignore the command by returning 1 out of our function.
 +
 
 +
:7. So at line ''6'' we will write '''        return 1 --return 1 to make ETPro ignore the command so you wont get an 'invalid command' warning'''
 +
 
 +
::Thats all we need to do for this command so we can start closing our function
 +
 
 +
:8. At line ''7'' we end our if statement of line ''4'' so we will write ''' end                      --close the if at line 4'''
 +
 
 +
::Now we get to the code that gets executed when the command was not ''lol''.
 +
::We got nothing todo here so we will return 0 to make [[ETPro]] handle it.
 +
 
 +
:9. To make ETPro handle all other commands, write ''' return 0 --if the command wasnt 'lol' then we will get here and return 0 to make ETPro handle it''' at line ''8''
 +
 
 +
::Now we are almost done just end our function.
 +
 
 +
:10. So at line ''9'' we will write '''end --close function et_ConsoleCommand() at line 1'''
 +
 
 +
::Now if you did it right you should have something like [http://home.zonnet.nl/westhof99/lua/ServerCmdLol.lua this]:
 +
<font color="blue">function</font> et_ConsoleCommand() <font color="green">--called when someone types a cokmmand in conosle or uses sa todo a server command</font>
 +
    <font color="blue">local</font> cmd = et.trap_Argv(<font color="blue">0</font>) <font color="green">--load out the first parameter of the test typed in console (the command itself)</font>
 +
    cmd = string.lower(cmd) <font color="green">--convert it to lower case so its easyer to match in our if statements</font>
 +
    <font color="blue">if</font> cmd == <font color="darkblue">"lol"</font> <font color="blue">then</font> <font color="green">--run our code if the command was 'lol'</font>
 +
        et.G_Print(<font color="darkblue">"hihi\n"</font>) <font color="green">--print out 'hihi'</font>
 +
        <font color="blue">return</font> <font color="blue">1</font> <font color="green">--return 1 to make etpro ignore the command so u wont get an 'invalid command' warning</font>
 +
    <font color="blue">end</font> <font color="green">--close the if at line 7</font>
 +
    <font color="blue">return</font> <font color="blue">0</font> <font color="green">--if the command wasnt 'lol' then we will get here and return 0 to make etpro handle it</font>
 +
<font color="blue">end</font> <font color="green">-- close et_ConsoleCommand()</font>
 +
 
 +
::Now save and load your script and you will be able to use ''lol'' as a server command.
 +
<hr>
 +
 
 +
===Server Command Dumpuserid===
 +
:Here we will show how to make a new server command that will simply preform a the dumpuser cmd on the name of the client slot we enter.
 +
:Just follow the steps and read the comments.
 +
 
 +
:1. First we need to create a new file for the script.  Create a new file and name it ''ServerCmdDumpuserid.lua''.
 +
 
 +
::To start we need an ETPro Lua function that will be called automatically by ETPro when a certain server command has been entered.
 +
::To do this we will use et_ConsoleCommand()''.
 +
::It is called for every server command but not for engine commands like ''say'',''broadcast'',''echo''.
 +
 
 +
:2. Inside our file at line ''1'' we will write '''function et_ConsoleCommand() --called when someone types a command in conosle or uses sa todo a server command'''
 +
 
 +
::Now the first thing we need to know is what command was entered.
 +
::Commands that are entered will be split up by spaces, so ''cmd1 hello all'' will be split up into "cmd1", "hello" and "all".
 +
::The only exception is that ''cmd2 "hello all"'' will be split up in "cmd2" and "hello all" because, "hello all" is entered as one string by enclosing them in quotes.
 +
::To get a part of the command you should use et.trap_Argv(''partnumber'')
 +
::''partnumber'' 0 is the actual command and, ''partnumber'' 1 is the first parameter of the command
 +
:: so in our example above we would get:
 +
:::et.trap_Argv(0) = "cmd1"
 +
:::et.trap_Argv(1) = "hello"
 +
:::et.trap_Argv(2) = "all"
 +
 
 +
:3. At line ''2'' we will write ''' local cmd = et.trap_Argv(0) --load out the first parameter of the test typed in console (the command itself)'''
 +
 
 +
::The commands are sent the same way they were entered, so if you enter ''cMd3'' you will get ''cMd3''.
 +
::To detect all variations, we will convert the string to lowercase using a normal Lua function.
 +
 
 +
:4. To make it lower case we will write ''' cmd = string.lower(cmd) --convert it to lowercase so it is easier to match in our if statements''' at line ''3''
 +
 
 +
::Now we can use a simple ''if'' statement to check if the command is ''dumpuserid''.
 +
 
 +
:5. At line ''4'' write ''' if cmd == "dumpuserid" then --run our code if the command was "dumpuserid"'''
 +
 
 +
::If thats true then we need to know witch client id to dump the userinfo from, therefor we just load in the 2nd comand parameter whit et.trap_Argv(1).
 +
 
 +
:6. To do this, at line ''5'' write '''        local id = et.trap_Argv(1) --load out the first parameter the command (the userid to dump)'''
 +
 
 +
::now we got the 2nd parameter as string, the first thing we do now is check if it isnt an empty string ("")
 +
 
 +
:7. So at line ''6'' write '''    if id ~= "" then --check if parameter1 isnt empty'''
 +
 
 +
::if its not an empty string then we wil contiune but if it is we will print back an error. We will get to the error later at line ''17''. Now we will go on whit the next step. We will convert our string to a number this way, we not only get it as a number but, we can also get a nil if it can be coverted so, we can see if the 2nd parameter of the command is a real number and not a word.
 +
 
 +
:8. so at line ''7'' write '''    local idnumber = tonumber(id) --get a number out of the string'''
 +
 
 +
::Now we will check if its a real number and not a nil. Todo this we can simpely check if its 'true' since only 'nil' and 'false' are 'false' in lua. If its 'false' we will print back an error but we will handle that at line ''15''.
 +
 
 +
:9. Todo this we will write at line ''8'' '''    if idnumber then --check if its not a nil'''
 +
 
 +
::Now we go on assuming we got a normal client slot id so we will try to parse his name. there are 3 ways to parse a name but i use the most simpel one. the other ways are to get it out of a configstring or userinfo. but we will use the  et.gentity_get() on the 'pers.netname'
 +
 
 +
:10. So at line ''9'' we write '''        local idnickname = et.gentity_get(id,"pers.netname") --get the player name for player slot "id"'''
 +
 
 +
::Now if the person entered a wrong number where there is no client connected then we get an enpty string so first we now check if our string is not empty. if its empty we will print an error but we handle that at line ''13''
 +
 
 +
:11. At line ''10'' write '''        if idnickname ~= "" then --check if the username isnt empty'''
 +
 
 +
::Now we go on. We got a username so wut we can do next is make a server command whit it
 +
 
 +
:12. At line ''11'' write '''        local servercommand = "dumpuser ".. idnickname --create the command to send back to the server'''
 +
 
 +
::Oke now its ready to send to the server as a command this is done by et.trap_SendConsoleCommand()
 +
 
 +
:13. So at line ''12'' write '''            et.trap_SendConsoleCommand(et.EXEC_APPEND,servercommand) --send our command to the server tobe executed'''
 +
 
 +
::Now we are done all that left now is to close the stuff up and add the error messages for when one of our if statements return false. first we add the error message for the ifstatement of line ''10''. we make an else whit a et.G_Print()
 +
 
 +
:14. at line ''13'' write '''            else et.G_Print("Player ".. id .." is not on the server\n") --warning message if the used a wrong slot number'''
 +
 
 +
::Now Close the if at line ''10''
 +
 
 +
:15. at line ''14'' write '''            end --close the if at line 10'''
 +
 
 +
::Now the error message for the if at line ''8''
 +
 
 +
:16. at line ''15'' write ''' else et.G_Print("invalid player slot, useage: dumpuserid <player slot>\n") --print out a warning that they have to enter player slot'''
 +
 
 +
::Now Close the if at line ''8''
 +
 
 +
:17. at line ''16'' write '''            end --close the if at line 12'''
 +
 
 +
::Now the error message for the if at line ''6'''
 +
 
 +
:18. at line ''17'' write ''' else et.G_Print("invalid player slot, useage: dumpuserid <player slot>\n") --print out a warning that they have to enter player slot'''
 +
 
 +
::Close the if at line ''18''
 +
 
 +
:19. at line ''18'' write  ''18'' write ''' end --close the if at line 6'''
 +
 
 +
::If u look carefulle u will see that all the thing we did so far are all whitin the first if statement that checks if the command is "dumpuserid". We are about to close that if statement but first we got to make sure this command does not get handled by the server since, we already handled and the server would just say "Uknown Command dumpuserid" anyway. in order to stop it from going to the server its command list we will return 1
 +
 
 +
:20. So at line ''19'' u write '''     return 1 --return 1 to make etpro ignore the command so u wont get an 'invalid command' warning'''
 +
 
 +
::Now we can close the if at line '4'
 +
 
 +
:21. At line ''20'' write ''' end --close the if at line 8'''
 +
 
 +
::For all other commands we want the server to decide wut todo whit it not our script there we will return 0 to just let the server handle it
 +
 
 +
:22. At line ''21'' write ''' return 0 --if the command wasnt 'dumpuserid' then we will get here and return 0 to make etpro handle it'''
 +
 
 +
::Now all that left is to close the function
 +
 
 +
:23. At the line ''22'' write '''end --close function et_ConsoleCommand() at line 5'''
 +
 
 +
::Now if you did it right you should have something like [http://home.zonnet.nl/westhof99/lua/ServerCmdDumpuserid.lua this]:
 +
<font color="blue">function</font> et_ConsoleCommand()<font color="green">--called when someone types a command in conosle or uses sa todo a server command</font>
 +
    <font color="blue">local</font> cmd = et.trap_Argv(<font color="blue">0</font>) <font color="green">--load out the first parameter of the test typed in console (the command itself)</font>
 +
    cmd = string.lower(cmd) <font color="green">--convert it to lower case so its easyer to match in our if statements</font>
 +
    <font color="blue">if</font> cmd == <font color="darkblue">"dumpuserid"</font> <font color="blue">then</font> <font color="green">--run our code if the command was 'dumpuserid'</font>
 +
        <font color="blue">local</font> id = et.trap_Argv(<font color="blue">1</font>) <font color="green">--load out the first parameter the command (the userid to dump)</font>
 +
        <font color="blue">if</font> id ~= <font color="darkblue">""</font> <font color="blue">then</font> <font color="green">--check if parameter1 isnt empty</font>
 +
            <font color="blue">local</font> idnumber = tonumber(id) <font color="green">--get a number out of the string</font>
 +
            <font color="blue">if</font> idnumber <font color="blue">then</font> <font color="green">--check if its not a nil</font>
 +
                <font color="blue">local</font> idnickname = et.gentity_get(id,<font color="darkblue">"pers.netname"</font>) <font color="green">--get the player name for player slot "id"</font>
 +
                <font color="blue">if</font> idnickname ~= <font color="darkblue">""</font> <font color="blue">then</font> <font color="green">--check if the username isnt empty</font>
 +
                    <font color="blue">local</font> servercommand = <font color="darkblue">"dumpuser "</font>.. idnickname <font color="green">--create the command to send back to the server</font>
 +
                    et.trap_SendConsoleCommand(et.EXEC_APPEND,servercommand) <font color="green">--send our command to the server tobe executed</font>
 +
                <font color="blue">else</font> et.G_Print(<font color="darkblue">"Player "</font>.. id ..<font color="darkblue">" is not on the server\n"</font>) <font color="green">--warning message if the used a wrong slot number</font>           
 +
                <font color="blue">end</font> <font color="green">--close the if at line 14</font>
 +
            <font color="blue">else</font> et.G_Print(<font color="darkblue">"invalid player slot, useage: dumpuserid <player slot>\n"</font>) <font color="green">--print out a warning that they have to enter player slot</font>
 +
            <font color="blue">end</font> <font color="green">--close the if at line 12</font>
 +
        <font color="blue">else</font> et.G_Print(<font color="darkblue">"invalid player slot, useage: dumpuserid <player slot>\n"</font>) <font color="green">--print out a warning that they have to enter player slot</font>
 +
        <font color="blue">end</font> <font color="green">--close the if at line 10</font>
 +
    <font color="blue">return</font> <font color="blue">1</font> <font color="green">--return 1 to make etpro ignore the command so u wont get an 'invalid command' warning</font>
 +
    <font color="blue">end</font> <font color="green">--close the if at line 8</font>
 +
<font color="blue">return</font> <font color="blue">0</font> <font color="green">--if the command wasnt 'dumpuserid' then we will get here and return 0 to make etpro handle it</font>
 +
<font color="blue">end</font> <font color="green">--close function et_ConsoleCommand() at line 5</font>
 +
 
 +
::Now save and load your script and you will be able to use ''dumpuserid'' as a server command.
 +
<hr>
 +
 
 +
[[Category:Lua]]

Latest revision as of 16:35, 29 August 2006


This page is here to help you understand ETPro Lua functions.

Before you start on this tutorial I assume you know basic Lua scripting. If not then I suggest you take a look at the online edition of the book Programming in Lua or the lua-users wiki. You can also take a look at code made by someone else, a list of ETPro mods that can be found here, or our Lua Sample Code.

Getting started

Loading a Script

Scripts are loaded by their file name out of the /etpro sub directory of your Enemy Territory installation, so don't forget to save them in the right folder.
if you want to load HelloWorld.lua you would have to set the server cvar lua_modules to "HelloWorld.lua".
If you want to load more mods you can add them to the same variables separated by a space like "HelloWorld.lua lol.lua pingpong.lua"
NOTE: if you modify this cvar all currently loaded lua modules will be unloaded.
After editing your script you save it and then reload it in ETPro to make your chances take effect, this can simply be done by reset_match server command.

Development Environment

While scripting you will see your code gets hard to read, its much easier to read with syntax highlighting. This can be done by scripting inside an lua development environment.
These can be found under the Development Environments heading at this page.

Tutorials

NOTE: Lines written in Bold are the actual lines we are going to write in our scripts.

Hello World

Here we will show a simple hello world example for the server console.
Just follow the steps and read the comments.
1. First we need a new file so, create a new file and name it HelloWorld.lua.
Now we need an ETPro lua function that will be called automatically by ETPro when we want it. Therefore we will use et_InitGame(levelTime,randomSeed,restart). That function is called once every round at the beginning. It's a good function to do some initial settings. We do not have to worry about those parameters (levelTime,randomSeed,restart) in this example.
2. Inside our file at line 1 we will write function et_InitGame(levelTime,randomSeed,restart) -- called at beginning of a gameround
Now we got a part of our script that is called at the beginning of a round so now we can add our code to it. We are going to print "hello world" in the server console. To do this we will use et.G_Print("message"). That function will simply print the "message" in the server console.
3. At line 2 we will write et.G_Print("Hello World!!!\n") -- printout our text to the console
Lastly we need to end out function at line 1 with a simple end
4. At line 3 place end --close et_InitGame()
Now if you did it right you should have something like this:
function et_InitGame(levelTime,randomSeed,restart) -- called at beginning of a gameround
    et.G_Print("Hello World!!!\n") -- printout our text to the console
end --close et_InitGame()
Now save and load your script and you will see Hello World!!! in the server console.

Hello Spam

Here we will show a simple Spammy hello world example for the server console.
Just follow the steps and read the comments.
1. First we need a new file so, create a new file and name it HelloSpam.lua.
Now we need an ETPro lua function that will be called automatically by ETPro many times to make it spammy. Therefore we will use et_RunFrame(levelTime). That function is called every server frame. It is a good function for stuff you need to constantly check but you should not put to much code in here. We do not have to worry about those parameter (levelTime) in this example.
2. Inside our file at line 1 we will write function et_RunFrame(levelTime) --called every serverframe
Now we got a part of our script that is called at the beginning of a round so, now we can add our code to it. We are going to print "hello world" in the server console. To do this we will use et.G_Print("message"); that function will simply print the "message" in the server console
3. Now at line 2 we will write et.G_Print("Hello Spam!!!\n") -- printout our text to the console
Lastly we need to end our function at line 1 with a simple at line 3 end
4. At line 3 place end --close et_RunFrame()
Now if you did it right you should have something like this:
function et_RunFrame(levelTime) --called every serverframe
    et.G_Print("Hello Spam!!!\n") -- printout our text to the console
end --close et_RunFrame()
Now save and load your script and you will see Hello Spam!!! in the server console.

Hello Client

Here we will show a simple hello world example for the client console.
Just follow the steps and read the comments.
1. First we need a new file so, create a new file and name it HelloClient.lua.
Now we need a ETPro lua function that will be called automatically by ETPro when we want it. To do this we will use et_InitGame(levelTime,randomSeed,restart) as shown in the Hello World example.
2. Inside our file at line 1 we will write function et_InitGame(levelTime,randomSeed,restart) --called at beginning of a gameround
Now we need a function to print a message to the client his console. We will use et.trap_SendServerCommand(-1,"print \"message\n\"") to achieve this. That function will simply print the "message" in the client's console.
The first parameter is the client slot to send to. When this is -1 ETPro will send the message to all clients. The 2nd parameter looks confusing and like the original author's spelling, it is. First you have the main command witch is "print ..". Then, at the place of the dots, comes the data to send with the print. In our case this is "message\n"".
The \n will send a newline command to the console so the next message written to the console is on the next line. The \" are just quotes but since they are already inside a string you need to prefix them with a \ (commonly known as an escape character).
3. So just write this at line 2 et.trap_SendServerCommand(-1,"print \"Hello Client\n\"") -- printout our text to the console
Last we need to end our function at line 1 with a simple end
4. At line 3 place end --close et_InitGame()
Now if you did it right you should have something like this:
function et_InitGame(levelTime,randomSeed,restart) -- called at beginning of a gameround
    et.trap_SendServerCommand(-1,"print \"Hello Client\n\"") -- printout our text to the console
end -- close et_InitGame()
Now save and load your script and you will see Hello World!!! in the client's console at the begin of a round.

Server Command lol

Here we will show how to make a new server command that will simply print hihi.
Just follow the steps and read the comments.
1. First we need to create a new file for the script. Create a new file and name it ServerCmdLol.lua.
To start we need an ETPro Lua function that will be called automatically by ETPro when a certain server command has been entered.
To do this we will use et_ConsoleCommand().
It is called for every server command but not for engine commands like say,broadcast,echo.
2. Inside our file at line 1 we will write function et_ConsoleCommand()--called when someone types a command in conosle or uses sa todo a server command
Now the first thing we need to know is what command was entered.
Commands that are entered will be split up by spaces, so cmd1 hello all will be split up into "cmd1", "hello" and "all".
The only exception is that cmd2 "hello all" will be split up in "cmd2" and "hello all" because, "hello all" is entered as one string by enclosing them in quotes.
To get a part of the command you should use et.trap_Argv(partnumber)
partnumber 0 is the actual command and, partnumber 1 is the first parameter of the command
so in our example above we would get:
et.trap_Argv(0) = "cmd1"
et.trap_Argv(1) = "hello"
et.trap_Argv(2) = "all"
3. At line 2 we will write local cmd = et.trap_Argv(0) --load out the first parameter of the test typed in console (the command itself)
The commands are sent the same way they were entered, so if you enter cMd3 you will get cMd3.
To detect all variations, we will convert the string to lowercase using a normal Lua function.
4. To make it lower case we will write cmd = string.lower(cmd) --convert it to lowercase so it is easier to match in our if statements at line 3
Now we can use a simple if statement to check if the command is lol.
5. At line 4 write if cmd == "lol" then --run our code if the command was "lol"
If thats true then the script should print "hihi".
6. To do this, at line 5 write et.G_Print("hihi\n") --print out "hihi"
Now that we have handled the command in our ETPro Lua script, we do not need to send it to the normal ETPro code since that will return "Unknown Command" anyway.
We can let ETPro ignore the command by returning 1 out of our function.
7. So at line 6 we will write return 1 --return 1 to make ETPro ignore the command so you wont get an 'invalid command' warning
Thats all we need to do for this command so we can start closing our function
8. At line 7 we end our if statement of line 4 so we will write end --close the if at line 4
Now we get to the code that gets executed when the command was not lol.
We got nothing todo here so we will return 0 to make ETPro handle it.
9. To make ETPro handle all other commands, write return 0 --if the command wasnt 'lol' then we will get here and return 0 to make ETPro handle it at line 8
Now we are almost done just end our function.
10. So at line 9 we will write end --close function et_ConsoleCommand() at line 1
Now if you did it right you should have something like this:
function et_ConsoleCommand() --called when someone types a cokmmand in conosle or uses sa todo a server command
    local cmd = et.trap_Argv(0) --load out the first parameter of the test typed in console (the command itself)
    cmd = string.lower(cmd) --convert it to lower case so its easyer to match in our if statements
    if cmd == "lol" then --run our code if the command was 'lol'
        et.G_Print("hihi\n") --print out 'hihi'
        return 1 --return 1 to make etpro ignore the command so u wont get an 'invalid command' warning
    end --close the if at line 7
    return 0 --if the command wasnt 'lol' then we will get here and return 0 to make etpro handle it
end -- close et_ConsoleCommand()
Now save and load your script and you will be able to use lol as a server command.

Server Command Dumpuserid

Here we will show how to make a new server command that will simply preform a the dumpuser cmd on the name of the client slot we enter.
Just follow the steps and read the comments.
1. First we need to create a new file for the script. Create a new file and name it ServerCmdDumpuserid.lua.
To start we need an ETPro Lua function that will be called automatically by ETPro when a certain server command has been entered.
To do this we will use et_ConsoleCommand().
It is called for every server command but not for engine commands like say,broadcast,echo.
2. Inside our file at line 1 we will write function et_ConsoleCommand() --called when someone types a command in conosle or uses sa todo a server command
Now the first thing we need to know is what command was entered.
Commands that are entered will be split up by spaces, so cmd1 hello all will be split up into "cmd1", "hello" and "all".
The only exception is that cmd2 "hello all" will be split up in "cmd2" and "hello all" because, "hello all" is entered as one string by enclosing them in quotes.
To get a part of the command you should use et.trap_Argv(partnumber)
partnumber 0 is the actual command and, partnumber 1 is the first parameter of the command
so in our example above we would get:
et.trap_Argv(0) = "cmd1"
et.trap_Argv(1) = "hello"
et.trap_Argv(2) = "all"
3. At line 2 we will write local cmd = et.trap_Argv(0) --load out the first parameter of the test typed in console (the command itself)
The commands are sent the same way they were entered, so if you enter cMd3 you will get cMd3.
To detect all variations, we will convert the string to lowercase using a normal Lua function.
4. To make it lower case we will write cmd = string.lower(cmd) --convert it to lowercase so it is easier to match in our if statements at line 3
Now we can use a simple if statement to check if the command is dumpuserid.
5. At line 4 write if cmd == "dumpuserid" then --run our code if the command was "dumpuserid"
If thats true then we need to know witch client id to dump the userinfo from, therefor we just load in the 2nd comand parameter whit et.trap_Argv(1).
6. To do this, at line 5 write local id = et.trap_Argv(1) --load out the first parameter the command (the userid to dump)
now we got the 2nd parameter as string, the first thing we do now is check if it isnt an empty string ("")
7. So at line 6 write if id ~= "" then --check if parameter1 isnt empty
if its not an empty string then we wil contiune but if it is we will print back an error. We will get to the error later at line 17. Now we will go on whit the next step. We will convert our string to a number this way, we not only get it as a number but, we can also get a nil if it can be coverted so, we can see if the 2nd parameter of the command is a real number and not a word.
8. so at line 7 write local idnumber = tonumber(id) --get a number out of the string
Now we will check if its a real number and not a nil. Todo this we can simpely check if its 'true' since only 'nil' and 'false' are 'false' in lua. If its 'false' we will print back an error but we will handle that at line 15.
9. Todo this we will write at line 8 if idnumber then --check if its not a nil
Now we go on assuming we got a normal client slot id so we will try to parse his name. there are 3 ways to parse a name but i use the most simpel one. the other ways are to get it out of a configstring or userinfo. but we will use the et.gentity_get() on the 'pers.netname'
10. So at line 9 we write local idnickname = et.gentity_get(id,"pers.netname") --get the player name for player slot "id"
Now if the person entered a wrong number where there is no client connected then we get an enpty string so first we now check if our string is not empty. if its empty we will print an error but we handle that at line 13
11. At line 10 write if idnickname ~= "" then --check if the username isnt empty
Now we go on. We got a username so wut we can do next is make a server command whit it
12. At line 11 write local servercommand = "dumpuser ".. idnickname --create the command to send back to the server
Oke now its ready to send to the server as a command this is done by et.trap_SendConsoleCommand()
13. So at line 12 write et.trap_SendConsoleCommand(et.EXEC_APPEND,servercommand) --send our command to the server tobe executed
Now we are done all that left now is to close the stuff up and add the error messages for when one of our if statements return false. first we add the error message for the ifstatement of line 10. we make an else whit a et.G_Print()
14. at line 13 write else et.G_Print("Player ".. id .." is not on the server\n") --warning message if the used a wrong slot number
Now Close the if at line 10
15. at line 14 write end --close the if at line 10
Now the error message for the if at line 8
16. at line 15 write else et.G_Print("invalid player slot, useage: dumpuserid <player slot>\n") --print out a warning that they have to enter player slot
Now Close the if at line 8
17. at line 16 write end --close the if at line 12
Now the error message for the if at line 6'
18. at line 17 write else et.G_Print("invalid player slot, useage: dumpuserid <player slot>\n") --print out a warning that they have to enter player slot
Close the if at line 18
19. at line 18 write 18 write end --close the if at line 6
If u look carefulle u will see that all the thing we did so far are all whitin the first if statement that checks if the command is "dumpuserid". We are about to close that if statement but first we got to make sure this command does not get handled by the server since, we already handled and the server would just say "Uknown Command dumpuserid" anyway. in order to stop it from going to the server its command list we will return 1
20. So at line 19 u write return 1 --return 1 to make etpro ignore the command so u wont get an 'invalid command' warning
Now we can close the if at line '4'
21. At line 20 write end --close the if at line 8
For all other commands we want the server to decide wut todo whit it not our script there we will return 0 to just let the server handle it
22. At line 21 write return 0 --if the command wasnt 'dumpuserid' then we will get here and return 0 to make etpro handle it
Now all that left is to close the function
23. At the line 22 write end --close function et_ConsoleCommand() at line 5
Now if you did it right you should have something like this:
function et_ConsoleCommand()--called when someone types a command in conosle or uses sa todo a server command
    local cmd = et.trap_Argv(0) --load out the first parameter of the test typed in console (the command itself)
    cmd = string.lower(cmd) --convert it to lower case so its easyer to match in our if statements
    if cmd == "dumpuserid" then --run our code if the command was 'dumpuserid'
        local id = et.trap_Argv(1) --load out the first parameter the command (the userid to dump)
        if id ~= "" then --check if parameter1 isnt empty
            local idnumber = tonumber(id) --get a number out of the string
            if idnumber then --check if its not a nil
                local idnickname = et.gentity_get(id,"pers.netname") --get the player name for player slot "id"
                if idnickname ~= "" then --check if the username isnt empty
                    local servercommand = "dumpuser ".. idnickname --create the command to send back to the server
                    et.trap_SendConsoleCommand(et.EXEC_APPEND,servercommand) --send our command to the server tobe executed
                else et.G_Print("Player ".. id .." is not on the server\n") --warning message if the used a wrong slot number             
                end --close the if at line 14
            else et.G_Print("invalid player slot, useage: dumpuserid <player slot>\n") --print out a warning that they have to enter player slot
            end --close the if at line 12
        else et.G_Print("invalid player slot, useage: dumpuserid <player slot>\n") --print out a warning that they have to enter player slot
        end --close the if at line 10
    return 1 --return 1 to make etpro ignore the command so u wont get an 'invalid command' warning
    end --close the if at line 8
return 0 --if the command wasnt 'dumpuserid' then we will get here and return 0 to make etpro handle it
end --close function et_ConsoleCommand() at line 5
Now save and load your script and you will be able to use dumpuserid as a server command.