|  | LUA Scripting Guidefor Blitzkrieg® Maps
   
 by kaoz MMXI
 
 
 |  | 
   
    |  | 
 
 
 |  | 
   
    |  | 01. IntroductionThis guide is an attempt to make the Lua 
        Script file, added to a Blitzkrieg map, understandable for mappers. It 
        is not an explanation of the script language itself. Therefore, all Lua 
        references are only in relation to a Blitzkrieg map.
 This guide will show a lot of examples, but it does not claim to hold 
        all the answers and/or solutions. Undoubtedly, more experienced scripters 
        could come up with a thousand more ingenious possibilities, however, for 
        the beginner, none of these make it easier to understand. The given examples 
        in this guide, however, will add flavour to a map, because even with a 
        simple script, the map possibilities are still interesting and providing 
        more fun to play the map.
 
 Make it easy on yourself and use the program SciTE 
        to create or open Lua files; not only does 
        it provide a recognizable icon to your Lua 
        files, but through the use of different colours, the script simply shows 
        more lucid. Also included, is a search and replace function that come 
        in very useful. You can download it here: SciTE
 
 Included in this guide, are also explanations that handle about map making, 
        rather than Lua, but I consider these essential, 
        because they are needed to see the complete picture.
 
 I would not have been able to create this without those who created earlier 
        guides. Therefore, I need to thank hitandrun, [BKP], Wespex, Rémy, Tangram 
        and Leon. Besides, I studied and learned a lot from other Lua 
        files, therefore, I would also need to thank Dimitry M., Kristallagent, 
        CC_Commander, Milknova, Zigfrid and so many others.
 
 Return to index
 
 
 |  | 
   
    |  | 02. Map StructureObviously, there's two important things to create a map: the MapEditor 
        and a Lua script.
 The MapEditor is used to create this map 
        graphically, to place objects and units, set planes and map tools, create 
        reinforcements, add start commands and so on. The map is saved as a bzm-file 
        or xml-file in the folder: Blitzkrieg\Run\data\maps. 
        In case of a mod, this would be: Blitzkrieg\Run\Mods\MyMod\data\maps.
 
 The Lua-file is used to 
        create functions, conditions, counters, troop reinforcements and behaviors 
        for the map that cannot be achieved through the MapEditor. 
        This Lua-file also needs 
        to be saved in the folder: Blitzkrieg\Run\data\maps. (Admitted, you could 
        put this file somewhere else and link to it, but keeping the map-file 
        and lua-file together 
        gives you less headaches afterwards).
 
 
 The Lua-file must be attached to the 
        map through the MapEditor.To attach this file, in the MapEditor, press 
        the Set Script File button and browse to 
        the specific Lua-file.
 
 
 A third important thing to finalize the map, is to create a folder 
        in the Blitzkrieg\Run\data\scenarios\Custom\Missions directory with the 
        name of the map. In this map are placed the txt-files 
        for the ingame objectives and one 1.xml-file 
        that holds map info, map settings and map markers. These files can be 
        created with the ResEditor, but can also 
        be copied from an existing map and then changed.
 
  Make sure to save the txt-files in 
        Unicode format, if not, it will only show 
        square digits.Open txt-files and 1.xml-file 
        from existing maps to learn from it!
 
 Return to index
 
 
 |  | 
   
    |  | 03. Lua Basic AknowledgementsLua scripting allows you to use some powerful 
        tools that bring action to a map. The main tool being a function, 
        which will "do" something. Within a function, 
        you can start another function or set a condition and moreover, various 
        functions after the condition. This way it is possible to let specific 
        things happen, accordingly to the player's or AI's behavior and that's 
        where it becomes very interesting.
 Every Lua script needs a initializing function; 
        the function Init().
 Look at it as if it's the ignition of the script: when the map loads in 
        the game, it will always start reading this (regardless of where this 
        is placed within the script).
 
 
         
          |  |  
  In the above picture, the function Init() 
        will start the function RevealObjective0 
        after 1 second. Next, the function Info, 
        will start after 19 seconds. (1000ms being 1 second). The pre-defined 
        command RunScript will call the function 
        only by its title. There are several pre-defined so called keywords 
        for the Lua language itself and several especially for the Blitzkrieg 
        engine. The latter are summarized in Calvin's 
        Lua Scripting Guide (which should always be next to you when you are 
        map scripting) and we'll deal with most of them in this guide. (I sometimes 
        refer to these keywords as commands).
 Notice that a script-line ends with a ; 
        (semicolon) and that a function needs to be closed with end;.
 
 Personally, i believe typing a script character by character, is a waste 
        of time and more vulnerable to typos. Use copy/paste 
        and simply change the concerning parameters. This doesn't mean you shouldn't 
        copy without care of course. When a script becomes larger, it's easy to 
        lose focus. For this same reason, it is better to cluster or group the 
        script functions logically.
 
 The Lua language is case-sensitive, meaning that it will see a difference 
        between upper and lower cases. Therefore, writing Function 
        init() will not work!
 
 Using -- (dashes) allows you to put comments 
        in a script. Any line preceded with 2 dashes 
        will be ignored by the engine reading the script. This can also be used 
        to temporarely switch on or off a certain line.
 
 
         
          |  |  
 The example above shows a function with the name DebugView 
        that is handy when testing your map. Unlike the function 
        Init(), you can specify the function names yourself, but it is 
        advised to keep this also logical. If the name shows what it does or wants 
        to execute, it just makes more sense.
 Let's run through the script above:
 The function Init() would start the function 
        DebugView after a second, if it wasn't preceded 
        by the 2 dashes. This is what i mean by switching on/off a specific line. 
        Imagine that it did start; it will first set the Password 
        Panzerklein, which enables other keywords like ShowActiveScripts, 
        ChangeWarFog and God.
 After this, DisplayTrace will show the string 
        Test123 in the upper left corner of the 
        game screen. This is used so you get informed whether the script is loaded 
        and running or not.
 Next, the ShowActiveScripts() function shows 
        the current functions executed by the RunScript() 
        functions of the script. Again, you get informed in Console mode during 
        a game whether the specific RunScript is 
        executed or not.
 Next, the ChangeWarFog is set to player 
        1 (the AI), so in testing mode, you'll be able to see the enemy movements.
 Next, God is set to player 0 and to mode 
        2, in which the player is invulnerable and the opponents are killed at 
        the first contact. In this example the keyword God 
        is also disabled by the 2 dashes and will not work. Using God mode can 
        be handy in the beginning of testing maps, but it is advised to test in 
        normal mode in later stages also, especially when you need to test balances 
        in strenght.
 
 Notice that, the function DebugView() uses 
        the keyword Suicide(). Unlike the function 
        Init(), all other functions need this to prevent the function from 
        re-executing itself infinitely.
 
 When a function is made to check a specific condition, 
        you need to also close this condition with 
        another end;.
 
 
         
          |  |  
  The above function ToLose states that 
        if the player 0 has less than 5 units, then 
        a screen message will be displayed and another function Lost 
        will run after 9 seconds. The if/then is 
        a condition within the function ToLose. 
        From the moment this function has started, it will check the keyword GetNUnitsInSide 
        and proceed once the condition is true, in this case less than 5 units. 
        But for now, remember that with a condition 
        you need another end;.
 Return to index
 
 
 |  | 
   
    |  | 04. Setting Map MarkersOkay, imagine you, me or we have created a map with the MapEditor. So 
        we have a .bzm (or .xml) 
        file in our maps folder. (Always keep a backup copy in case something 
        happens...!). Now before starting to script the .lua 
        file, you will probably have a good idea what the objective(s) of your 
        map should be like. To describe the objective(s), set map markers for 
        them and setting up the map for the BK engine to find it, we need the 
        files in the folder Blitzkrieg\Run\data\scenarios\Custom\Missions\MyNewMap.
 
         
          |  |  
 You'll see a few txt-files and one 
        1.xml file.What is written in the header.txt is what 
        will appear as a title in the game missions overview, so you want to keep 
        this short and informative. Long titles make the missions list unreadable.
 The description.txt is used to describe 
        the map's background, obviously. It is however, only shown in the game 
        when it is part of a chapter. So even there's no real use of it in a single 
        mission, you should still describe your map as some players might open 
        and read the file to get a better idea what the map is about.
 Same for the subheader.txt: it isn't really 
        shown in the game, but it is mostly used to write the author's name into 
        it.
 Then there's the objectives: in this example MyNewMap, there's 2 objectives, 
        being 0.txt and 1txt. 
        These objectives have both a title or header, being 0h.txt 
        and 1h.txt.
 
 
         
          |  |  
  So, if you need more objectives, keep counting and create 2.txt 
        - 2h.txt - 3.txt - 3h.txt and so on.
 Now, let's take a look to the 1.xml. This 
        file can be made with the ResEditor, but it's easier to copy one and adapt 
        it.
 In xml-language, you will mainly see tags, like <base></base>. 
        Some tags are placed inbetween tags and some tags require a reference 
        to a specific file. Don't worry if you don't understand xml, this is just 
        how it works, but you should be able to read it and understand which particular 
        reference you need to change.
 
 Everything between <History></History> 
        tags isn't really necessary. It only holds information about the path, 
        time and date, author, etc. when the file was created (through the ResEditor). 
        You could if you want, change the date and author to your desire.
 
 On the other hand, the tags between <RPG></RPG> 
        are very important! Let's look at the first part:
 
 
         
          |  |  
  So when the game loads, it will load and read this 1.xml 
        file. The path between the <HeaderText></HeaderText> 
        tags needs to point to the specific header.txt 
        file in your mission folder. If, for example, you have copied this 1.xml 
        and you have a mission folder called Belgium1940, 
        then you simply change all the MyNewMap's 
        into Belgium1940.
 
  Okay, let's move on further through the xml:
 
 The <FinalMap></FinalMap> 
        tags are also very important and refer to the name of your map, being 
        the .bzm file. The game will look in the 
        maps folder and search for the name. If, for example, you have a map Ardennes.bzm, 
        you refer to it in the 1.xml as <FinalMap>Ardennes</FinalMap>.
 Next, you can set the music for the map. Some tags, like these, have items. 
        If, for instance, you want more music, you could add items, 
        so it would look this:
 
 
 In case you don't want any music, just leave it empty between the 
        tags, like <CombatMusics></CombatMusics>. 
        Or you can also write <CombatMusics/> which 
        is the same, but shorter than <CombatMusics></CombatMusics>. 
        It's not of that great importance though.
 Next important part of the 1.xml are the 
        objectives:
 
 
         
          |  |  
 So again, you will see reference paths to the txt-files 
        in your mission folder. Again, change the MyNewMap 
        into the name of the mission folder.
 As you can see, these 2 objectives are items 
        between the <Objectives></Objectives> 
        tags. The item Secret can be set to 0 
        or 1, where 0 
        will show the objective from the beginning of the game, in contrast to 
        1, that will keep the objective secret until 
        you call upon it through the lua script. If you need more objectives, 
        copy/paste more items and change them.
 
 Now take a good look to the part that says: <PosOnMap 
        x="96" y="419"/>
 These coordinates are used to place the map marker on the minimap for 
        the objective. In case you don't want any map marker, but still the objective, 
        simply set their value to zero.
 
 How to find the correct coordinates for your map markers?
 These could be set with the ResEditor, but there's an easier way. When 
        your map is loaded in the MapEditor and in the editor, you would press 
        the Create button on the bottom left, a 
        minimap will be created. These files are then created in your Blitzkrieg\Run\data\maps. 
        There you will find 2 .tga files and some 
        .dds files. Open MyMap_large.tga 
        with Photoshop or Gimp.
 
 
         
          |  |  
  This large .tga file is always 512 pixels 
        on 512 pixels, no matter the measures of the actual map. In the picture 
        above, you see a .tga loaded in Photoshop. 
        Going over the picture, the mouse pointer will show the exact xy coordinates 
        in the info panel.
 So logically, <PosOnMap x="0" y="0"/> 
        would be the upper left corner, <PosOnMap x="512" 
        y="512"/> the bottom right corner and <PosOnMap 
        x="256" y="256"/> the middle. There is however, a small glitch 
        as many times I noticed it wasn't shown exact. To solve this, you just 
        add 8 or 10 pixels to the value and you get a better result. Thus <PosOnMap 
        x="266" y="266"/> would be the exact middle (shown on the minimap 
        in the game that is). You will notice this glitch very clear when you 
        for example want a map marker upon a bridge or a house. In Gimp or Photoshop 
        you get the exact xy coordinates, but in the game the marker is not exactly 
        on top of the bridge or house. Like I said, add 8 or 10 pixels and it 
        will shown correct.
 
 Return to index
 
 
 |  | 
   
    |  | 05. ObjectivesThe following picture shows a basic example with one 
        objective and one reinforcement.
 
         
          |  Let's 
              "drive" through the script: 
 At the bottom, the function Init() 
              starts the function RevealObjective0() 
              after 1 second and function Info after 
              19 seconds.
 
 Jump to the function RevealObjective0() 
              and notice it will first set the keyword ObjectiveChanged 
              to (0, 0) and then start the function 
              Objective0(), after again 1 second.
 For the ObjectiveChanged: (0=objective#, 
              0=not accomplished)
 
 From the function RevealObjective0(), 
              let's jump further to the function Objective0().
 This function holds a condition: if 
              all units from ScriptGroup 119 of 
              player 1 (enemy AI) is less 
              or equal to 1, then the ObjectiveChanged 
              is set to (0, 1), thus accomplished, 
              and next, the keyword LandReinforcement 
              will start and drop units with GroupScriptID 
              0 into the game.
 
 |  
  In later chapters, we'll go deeper into reinforcements 
        and ScriptID's. For now, if you were able 
        to follow and read the script, then you should have gotten a basic idea 
        of how a Lua script is running. Which is only very logical in fact.
 So, let's try more objectives:
 
 
         
          |  This 
              script has 3 objectives that follow one another. Setting the secrecy 
              to the flag (in the 1.xml or Mission 
              Editor), the next objective and flag will only appear after a particular 
              objective is completed. 
 Again at the bottom, the function Init() 
              will start the function RevealObjective0() 
              after 1 second.
 Next, the function RevealObjective0() 
              sets the ObjectiveChanged and then 
              runs the function Objective0() that 
              states if the units with ScriptID 
              200 of player 1 are equal 
              to zero, then the ObjectiveChanged 
              is accomplished and the next function RevealObjective1() 
              will start running after 19 seconds.
 
 The same happens for the second objective: function 
              RevealObjective1() sets the ObjectiveChanged 
              of objective #1 to not accomplished and then runs Objective1. 
              When enemy units of ScriptID 201 are 
              all dead, the objective is accomplished and function 
              RevealObjective2() will be called.
 
 The last objective states that if 
              all units of player 1 in Area 
              "totalMap" is less or equal 
              to 3, then player 0 
              will win.
 
 |  
 Of course, you don't want the player to wait 19 seconds for the 
        next objective, but it should show that you can play around with timings. 
        And alternatively, in case you don't want the objectives one after another, 
        you can start more or all of them at the same time, whenever you like 
        this to happen.In the following example, when the objective is reached, it will set off 
        3 other objectives with different time intervals.
 
 In fact, you can start various functions at various time intervals:
 
 
  At this point, you should start to see the possibilities that you 
        are able to call any function at a specific time whenever you desire, 
        in this case, after an objective is reached.
 In case you want all objectives at the start, you could also script:
 
 or even:
 
 
  Do not "overscript" the function 
        Init() though; if you would script a dozen RunScript's 
        or more that would start running at the same time, you might ask for trouble. 
        Avoid script failures and try to set up a logical time schedule.
 Return to index
 
 
 |  | 
   
    |  | 06. Win or LoseThe 2 keywords Win and Loose 
        of course are of great importance in determining the game's outcome. Determining 
        when a player should win is mostly very easy, but the Loose 
        command, imho, is being very underestimated by most mappers. True, some 
        maps may not need this at all, but personally I think that if the player 
        has a chance to be beaten by f.e. an AI enemy attack, the game becomes 
        more challenging.
 
         
          |  Let's 
              imagine a map where you have to defend a certain Area and capture 
              one. Player 0 has units with ScriptID 101 
              at the Area "warehouse" 
              and units with ScriptID 100 to attack 
              the Area "station". The 
              enemy player 1 has units with whatever ScriptID and some of them 
              will attack the Area "Warehouse". 
 The function Init() starts the function 
              ToWin() and function ToLose(). 
              Player 0 will win if more or equal to 6 of units with ScriptID 
              100 are in the Area "station" 
              or will lose if less then 6 units with ScriptID 
              101 are present in the Area "warehouse".
 
 |  
 
         
          |  Or 
              imagine a map where the player will lose if the general of his forces 
              gets killed. 
 The script doesn't show everything, but the function 
              Trigger01() states that if 
              unit with ScriptID 19 of player 0 
              is equal to zero (thus killed), then 
              a screen message will explain why. The keyword Loose 
              is put in a separate function and only starts after 7 seconds, so 
              the player gets the time for reading the onscreen message.
 
 |  
 
         
          |  Or 
              in this example, the player will lose if he has less then 5 units 
              left. 
 Of course, this example also doesn't show the complete script. The 
              function Trigger01() must be called 
              upon into the function Init() or somewhere 
              else in the script...
 
 |  
  How to create AI enemy attacks and Area's will be explained in 
        later chapters, but I wanted to focus on Win/Loose 
        first. Experiment with these to add spice to your scenario.
 Return to index
 
 
 |  | 
   
    |  | 07. ScriptIDAnother important thing is the ScriptID. 
        In the MapEditor you can give any unit, building or object a ScriptID, 
        which can be referred to in the Lua script. 
        Double click to open the Properties window of any object. By default, 
        the value -1 is given by the editor.
 
  There exists a suggestion to use the ScriptID's 
        as follows:ScriptIDs 0 - 999 for terrain objects and buildings
 ScriptIDs 1000 - 1999 for AI (enemy) units
 ScriptIDs 2000 - 2999 for player units
 However, this is not a written law, instead it is an advise to maintain 
        order over chaos.
 
 From the moment you have defined ScriptID's, 
        you can do remarkable things in the Lua script:
 
 
         
          |  The 
              function Trux() will change the units 
              with ScriptID 200 to player 0. You 
              are able to let units switch from sides, player 0, enemy or neutral. 
              I used this function a lot where the player gains enemy trucks when 
              a specific area is taken. 
 The function FrostBite() will damage 
              the object with ScriptID 100. Using 
              the following parameter 0 will cause 
              to completely destroy it. This object can be anything, a tank, a 
              squad, a building, a group of objects, etc.
 
 The function EnterHouse() will give 
              a command to the (infantry) unit with ScriptID 
              300 to enter the house/building with ScriptID 
              10.
 
 |  
 So, at this point, you should understand that ScriptID's 
        are a necessary thing in order to be able to let things happen to them. 
        This will bring action to your map in every way. 
 Return to index
 
 
 |  | 
   
    |  | 08. Area'sLet's go back to the MapEditor for a moment; on the left side you'll 
        see the Map Tools panel. With this tool, 
        you can draw retangular or round Area's 
        upon the map. Hold the left mouse button and use the keyboard arrows to 
        enlarge the Area, if needed. When you release 
        the mouse button, you'll be prompted to set a name for the Area. 
        Take care, because this is case-sensitive!Later on in the Lua script, you'll be able 
        to refer to these Area names.
 
 
 
  In earlier examples, you have already seen some examples where 
        an Area was used. It's really handy to create 
        triggers and thus things will happen from the moment a specific unit or 
        units come in or leave a certain Area.
 Here are 2 more examples:
 
 
         
          |  The 
              function Objective2() states that 
              if more or equal than 2 units with 
              ScriptID 100 or more or equal than 
              2 units with ScriptID 102 are present 
              in Area "Fuel Dump", then 
              the objective is reached and it will start to rain ("RainyDay") 
              after 30 seconds. 
 |  
 
         
          |  The 
              function Trigger08() states that if 
              more than 0 units from Player 0 are 
              present in Area "zone1", 
              then a command will be given to unit 
              with ScriptID 111 (which in this case 
              is a artillery gun) to start shelling the Area 
              "zone1". After approximately 2 minutes it will 
              run the function HoldFire() and stop 
              shelling. 
 |  
 These examples should give a good idea of what is possible with 
        Area's in combination with the amount of 
        units in or out them. There's also a few keywords/commands that return 
        the number of mines, fences and trenches from a specific Area. 
        Check out Calvin's 
        Lua Scripting Guide for this.
 Return to index
 
 
 |  | 
   
    |  | 09. Start CommandsIn the MapEditor, one can use the Add Start Command 
        function to command a certain, selected unit or even a group.Select a unit, click on the icon and the Unit Start 
        Command Property window will open.
 
 
 
  From a drop-down list, there's quite some choices of command. Select 
        one and next, with the window still open, you can click on any spot in 
        the map to set the x,y positions (notice the pink circle). Or you could 
        set these manually if you'd like.
 You are able to set multiple commands in a row.
 
 
         
          |  |  
 Use these commands logically; some commands work only in combination 
        with a specific unit. Although you can set the command, it might not work. 
        A tank cannot heal infantry and a truck cannot use a spyglass, and so 
        forth.
 Some of these commands can also be achieved through a Lua 
        script, but not all and vice versa, there are commands within Lua 
        that cannot be found in the Add Start Command 
        from the MapEditor. It demands a little practice to know what is where. 
        Again, check out Calvin's 
        Lua Scripting Guide for the possibilities in Lua.
 
 In Lua, the keywords Cmd 
        and QCmd are used to command specific units.
 Pre-defined actions like MOVE_TO, SWARM_TO, CALL_BOMBERS, etc. are used 
        to specify the command. These actions are connected to numbers, which 
        can also be used instead. All actions are summorized in Calvin's 
        Lua Scripting Guide.
 
 Let's show a few examples:
 
 
         
          |  Imagine 
              you have a tank with ScriptID 100. 
              From the moment you call upon the function 
              Attack01(), the Cmd will move 
              the tank to the given coordinates. Next, the QCmd 
              will let the tank swarm to the given coordinates and finally the 
              next QCmd will let the tank attack 
              the unit with ScriptID 200 . 
 |  
 
         
          |  Here, 
              I have changed the actions with their corresponding numbers, so 
              this function will do exactly the same as the one in the previous 
              example. MOVE_TO = 0
 SWARM_TO = 3
 ATTACK_UNIT = 1
 
 |  
 
         
          |  This 
              example shows a simple function that calls an enemy scout plane 
              with ScriptID 999. It will fly and 
              scout (action = 21) to the given coordinates in the different command 
              lines. 
 |  
 
         
          |  This 
              example shows, let's say an infantry unit with ScriptID 
              19. After 1 second, it will enter the building with ScriptID 
              1000.
 After 2 minutes, the same unit will leave the building and go to 
              the given coordinates.
 From there, it will start to swarm to the new given coordinates.
 
 |  
  All these commands can be set for the AI enemy, but also for the player. 
        However, a player can chose to select the specific unit and change its 
        purpose; in that case, any given command will get cancelled. It may also 
        happen that you command a plane and then it suddenly starts to rain, cancelling 
        any given commands to it.
 At this point, you should have a serious idea of command possibilities. 
        Again, these will bring action to your map. Beware although and always 
        test your given commands. In a lot of cases, the given commands might 
        react in the game different as expected. If you, for example, connect 
        a trigger to a certain action and when the action gets blocked or cancelled 
        in some way in the game, your trigger will also not work anymore. The 
        more complicated you make this, the more testing it will need, from various 
        points of view.
 
 Return to index
 
 
 |  | 
   
    |  | 10. ReinforcementsLet's return again to the MapEditor, where on the left side, you'll notice 
        the Reinforcement Groups panel.
 
         
          |  First, 
              click on New Group and the Reinforcement 
              Group ID window opens. There, set the number you desire and 
              click ok. In this picture, I have already made a group called 0 
              and the Reinforcement Group ID window 
              shows I am making a second called 1. 
 When you select a group in the upper window, like Group 
              N:0 which is blue lined, then in the lower window, you can 
              click the Add group with scriptID 
              button. As the picture shows, I have already added ScriptID 
              1000, ScriptID 1001 and ScriptID 
              2000 to this group.
 
 So, it is possible to create one group that gives reinforcements 
              to both the player and the AI enemy. In Lua, 
              you'll need to use the keyword/command LandReinforcement(0). 
              The parameter of the command refers to the GroupID, 
              in this case 0. Thus, not to the individual 
              ScriptID's!
 
 If you have a map where you have lots of groups of units that you 
              want to "control" more separately, you could give the 
              same GroupID like the ScriptID, 
              which makes it a little easier to remember who's who when you are 
              scripting. So, GroupID 1000 holds 
              the units with ScriptID 1000, GroupID 
              1001 holds units with ScriptID 1001, 
              and so forth.
 Then in Lua, when you use LandReinforcement(1001), 
              you see the concerning units more directly.
 
 By the way, clicking and checking the small white square before 
              Group N:0 will hide all units belonging 
              to that group from the map in the editor, which is handy in some 
              cases.
 
 |  
  We've seen the command earlier in an example, but here's a few 
        more:
 
         
          |  When 
              function Ambush() is running, it will 
              check the Area "ambush" 
              and if there's more than 2 units of 
              player 0 present, then 
              the reinforcements of GroupID 0 will 
              immediatly take place. 
 |  
 
         
          |  In 
              case you want to have more control over the timing of your reinforcements, 
              it's better to put the LandReinforcement() 
              in a separate function, like in the example, function 
              Reinforce0 and function Reinforce1. 
 When function Objective0() is reached, 
              it will run RevealObjective1 after 
              1 second. Next, LandReinforcement(1001) 
              will happen after 3 minutes and LandReinforcement(1002) 
              will happen after 5 minutes.
 
 |  
  There is one thing you need to pay attention to, when you combine 
        actions to reinforcements. Reinforcements do take some time to take place. 
        If a group of tanks would land, they'll do this in an unpredictable way, 
        one by one. It will not land all the tanks at the same time.Have a look to the following function:
 
 
         
          |  This 
              function makes perfect sense, but will perform poorly in the game. 
              So, imagine that group of tanks with ScriptID 
              1001; they will land, but the following command Cmd 
              will only apply to the first landed unit. Because it takes time 
              for the other units to land, they will completely miss the following 
              command and they won't do anything. 
 |  
 
         
          |  One 
              way to solve this, is using the Add Start 
              Command in the MapEditor and add it manually. These commands 
              work fine from the moment the units land. 
 However, if you need to set the commands in Lua, 
              then put the command in a separate function, which takes place after 
              a certain amount of time (at least the time that is needed to land 
              all concerning units).
 So, in the example, when function Trigger_01() 
              is reached, it will land that group of tanks with ScriptID 
              1001 and after 1 minute it will start the function 
              Attack_01() so that the whole group of tanks start swarming 
              to Area "zone1".
 
 |  
 Well, that's pretty much it concerning reinforcements. There is 
        still the keyword DeleteReinforcement(), 
        which you obviously, can use to remove reinforcements with GroupID 
        x.
 Return to index
 
 
 |  | 
   
    |  | 11. AviationAviation works a bit the same like reinforcements. Back again, in the 
        MapEditor, pressing the little plane icon in the menu, will enable you 
        to set plane types, appear points and such. You ought to do this before 
        anything else, I think btw.
 
  Once that is set, you have a little more options to "control" 
        the aviation through Lua: some Lua 
        script commands let you play with their appearance and behavior.
 
         
          |  In 
              this script, the function Init() disables 
              all aviation (-1) for both parties 
              and starts function Objective0() after 
              1 second and function AirForce() after 
              2 minutes. 
 The function Objective0() states that 
              if more than 2 units of player 0 
              enter the "facility" 
              area, then both players receive recon 
              planes (0).
 
 Next after 2 minutes, the function AirForce() 
              will check the "facility" 
              area and if there are more than 2 
              units of ScriptID 19 in there, then 
              both parties receive paratrooper planes (2).
 
 For all the iTypes of Aviation, please refer to Calvin's 
              Lua Scripting Guide.
 
 |  
 
         
          |  In 
              this next example, both parties start with no aviation. 
 After 10 seconds, the function BomberPlanez() 
              will enable this type for player 1 
              and fly to the given coordinates in the Cmd 
              command.
 
 50 seconds later the function Attackplanez() 
              again will enable attack planes for player 1 
              that fly to the same coordinates.
 
 iAction 19 = CALL_BOMBERS
 iAction 36 = CALL_GROUND_ATTACK
 
 |  
 
         
          |  I've 
              used this one in maps where the player has to conquer an enemy airfield. 
              It would only be logical that from that moment, enemy aviation becomes 
              disabled. 
 The function Objective_00 (the given 
              function name may seem a little odd, but never mind that) states 
              that if there is less than 1 enemy 
              in the "airport" area, then 
              aviation will become disabled for player 1.
 
 |  Return to index
 
 
 |  | 
   
    |  | 12. WeatherSetting the weather is really easy in Lua, 
        and especially handy when you need good weather to call (enemy) planes 
        or when you need rain in case you surely don't want any aviation to happen 
        (for a specific time).
 
         
          |  I 
              often use these 2 functions because they give me exactly what I 
              need. 
 When I call upon function Holiday(), 
              it will switch the weather to good (0). 
              It will NOT switch the weather automatically (0), 
              so sunny days remain infinite until I call upon function 
              RainyDay().
 
 When I call upon function RainyDay(), 
              it will switch the weather to bad (1). 
              And it will switch the weather automatically (1), 
              back to random.
 
 
 |  
 This works fine for me, but you could change it any way you want.
 Return to index
 
 
 |  | 
   
    |  | 13. VariablesIn Lua (as in other script languages), 
        you can assign a decimal, an integer or a string value to a global 
        or local variable. Using a function, you 
        can then check whether it's value corresponds to a certain condition or 
        not. And this can be extremely handy!
 Global means that this variable is set, 
        covering the whole script. Local means that 
        the variable is set and covering a part of the script. I can't explain 
        variables fully detailed here, because I don't consider myself such a 
        great scripter and so this task isn't up to me really. However, I hope 
        the following examples may show some of the possibilities.
 
 
         
          |  In 
              this script example, each time an objective is reached, a SetIGlobalVar() 
              with a particular name (temp.template00.objective.1) 
              is given the integer value 1. 
 Next, using the GetIGlobalVar(), the 
              function ToWin() will check if 
              all variables are equal to 1 (and 
              then the player will win).
 
 Again, the script is not complete and of course, the functions need 
              to be running/triggered in order to work!
 
 |  
 
         
          |  In 
              this example, the variable is being used as a counter. 
 Setting a local variable i, one can 
              add a +1 value to a global variable 
              ("numbMissionDone", i).
 
 So, when the first objective is reached, it will take the local 
              i (which is 0). 
              It will also take the global variable (which is also 0) 
              and add +1, thus, it will set the 
              global variable to 1.
 
 After the second objective is reached, it will again take the local 
              i, but it will also get the global 
              variable (which is now 1) and add 
              +1, so now the global variable is 
              2.
 
 When the function ToWin() realizes 
              the value of the global variable is 2, 
              the player will win...
 
 I know, when you see this for the first time, it seems a bit like 
              rocket science, but if you practice this more, you will get to understand 
              it.
 
 |  Return to index
 
 
 |  | 
  
    |  | 14. A Few More TricksIn this final chapter, you'll find a few examples of more complex situations 
        or goals, achievable through Lua. These 
        were not invented by myself, but I have adapted them and I often use them 
        when a particular situation asks for them.
 
         
          |  This 
              script shows how to use a neutral 
              plane (which will not get shot down by the AI enemy) and drop a 
              para-squad that will change sides from the moment it enters a specific 
              Area. 
 The function Init() will set the global 
              variable "ParadropSquad.ScriptID" 
              to 2019, so the para-squad will have 
              ScriptID 2019 right from the start.
 
 Two seconds later, a transport plane with ScriptID 
              999 of player 2 (neutral) will 
              paradrop (22) the squad at the given 
              coordinates. And calls the function MoveIt().
 
 GetUnitState() will check whether 
              unit(s) 2019 are waiting. If so, they 
              receive the command to move to the "LandingZone" 
              area.
 
 The function ChangePara() will check 
              if units with ScriptID 2019 are present 
              in the "LandingZone" area, 
              and if so, it will change the player side of with ScriptID 
              2019 to 0.
 
 Thx to Leon.
 
 |  
 
         
          |  This 
              script is again, not complete, but imagine the functions are running. 
 In this scenario, we have an enemy group of units with ScriptID 
              101. They have commands added and they are attacking the 
              player within an Area "Town". 
              When they are all dead, they will respawn and start attacking again. 
              Look at the function Respawn_00() and 
              function Reinforce_00() and notice 
              they keep on triggering each other infinitely.
 
 However, from the moment where the player has more than 3 units 
              (thus 4), the KillScript() will stop 
              the respawning of the enemy units.
 
 You can use the KillScript() for other 
              purposes as well; it can stop any named function.
 
 Thx to GordonCZ.
 
 |  
 
         
          |  In this scenario, we have a fort that needs to be defended by the 
              player, while the AI enemy is attacking with a group of units with 
              ScriptID 100, 101, 102. 
 What's important here, is the elseif. 
              The objective may have two outcomes; if 
              the player has no more units within the "fort" 
              area and the AI enemy has more than 3 units in the "nibeiwa" 
              area, then the player will lose and 
              the objective has failed (0, 2).
 
 Otherwise (elseif), when all AI enemy 
              units with ScriptID 100, 101, 102 
              are less than 1 (meaning dead), the 
              objective is reached (0, 1) and the 
              player wins.
 
 Thx to runrum for pointing at the 2 Suicide()'s.
 
 |  
 
         
          |  This function MissionTimer() can be 
              used to display the time and so call upon the global variables when 
              you need to time something. 
 Thx to danzig70.
 
 |  
 
         
          |  The keyword AskClient("SetCamera(x,y)") 
              will move the camera view to the given coordinates. To move the 
              camera to a more or less correct point, try to divide the coordinates 
              seen in the MapEditor by a value of 1.4 (meaning that if the place 
              is located in 3000,15000 in the MapEditor, then divide 
              both values by 1.4 and you will get 
              coordinates 2143,10714 for the script file). 
 Thx to [BKP], GordonCZ, cc_commander, runrum.
 
 |  Return to index
 
 
 |  | 
   
    |  | created by kaoz - MMXI
 
 |  |