Scenario Tool

1. What is the scenario tool?

This is a tool used to create triggers and set up various parameters for user made missions for the game Cossacks. Essentially, it is used for the same purpose as the newer Scenario Editor that came bundled with Cossacks The difference is that the new Scenario Editor has a user interface, and more integrated with the map editor. This makes the process of making a scenario easier and more intuitive. Scenario Tool on the other hand has no user interface at all. In fact, it would be wrong to call it a tool. It is no more than a few example source codes in C++. The code then has to be compiled before you can use it in the game. It is anything but user friendly. There is a documentation that came with it but unfortunately (for us English speaking mob), it is in Russian.
 
You can download it at our download section

So why do we need the Scenario Tool?

There are simply too many bugs and missing features in the new Scenario Editor rendering it frustrating to use. In Scenario Tool, everything works. Power is also an advantage that Scenario Tool has over the Scenario Editor. As it is essentially a program source code, you can code it to do almost anything that you want. Including things that are not neccessarily originally included or intended for the game. Here the limit is your imagination ... well almost!

2. Requirements

As I have mentioned it above, Scenario Tool consists of source code examples in Visual C++, you therefore need Visual C++ 6 to use it. Obviously you also need Windows, the game Cossacks +/- AoW. And you will need to have some programming knowledge. It would also be essential that you are familiar with the Scenario Editor that came bundled with Cossacks Art of War as well. You do not need to have full knowledge C++ to use it, but essential if you want to fully utilize its power. As I am neither a professional programmer nor familiar with any other C++ utilities, I am writing this guide based on Visual C++ 6 from Microsoft.

3. How to use

Now that we are done with all the formalities, lets get down to business.

Assuming that you have had Visual C++ installed, I would now like to direct you to open up the subfolder Work01 of Russia folder. In Work01, you should find a file called Mission.dsw. This is the workspace file. Double clicking on this should open up Visual C++ and put you in the thick of a coding frenzy. Another option would be to open Visual C++ first and then go to menu File -> Open Workspace to open this file.

At this point, I would ask you to go to the menu Project -> Settings. Choose Win 32 Release option from the drop down menu. Then go to the Link tab on the right and you should see a textbox below. Scroll this textbox until you see /out:"Release/Mission.dll". This setting specifies where your file is going to be generated and under what name. You can change the text within the double brackets to a more appropriate Folder name, File name if you so wish. You would do the same for Win 32 Debug as well. Remember to set the drop down menu back to Win 32 Release option when you are done.

Here, I'd direct your attention to the window on the left hand side. You should see 2 tabs underneath it, ClassView and FileView. Choose FileView. Going up from there you should see a treeview. Expanding Header Files, you should see Mission.h. Clicking this would give you the codes for this file in the main window. This is where all the main functions for the scenario are defined. Have a browse through to familiarise yourself with them.

This is where we take a break and have ourselves a cuppa & a smoko...

Are we back from our break yet?

Good, lets continue.

Now that we are recharged, let move on to Source Files. Expanding this and you will see Mission.cpp. This is the nerve center of your program. This is where you do your programming. So lets start.

For those of you who are not familiar with C++, let me give you a few pointers.

Libraries

Because C++ has only a very limited number of intrinsic functions, this is expanded by the inclusion of additional external libraries. This is stated in the first line #include "mission.h". You can of course use other libraries for maths, strings, etc if you wish but for our purpose, mission.h (.h = header file) is all we need.

Variables

If you are familiar with programming, you are familiar with the concept of variables. This is a value holder, and the values of course can be changed from within the program either at design-time or at run-time. So the next lot of statements after #include are variable declarations. Because we are working within the constraints of Cossacks, there are only one type of variable that you would need to worry about and this is GAMEOBJ.

This variable refers to all unit, unit types, upgrades, groups and zones. Names can be anything you want but be careful as C++ is case sensitive, and do try to avoid key words. Of course you would want to keep your naming convention logical for easier later reference to your codes. Declare all necessary variables that you might need here.

Another important pointer : REMEMBER THE SEMICOLON ; It tells C++ that it's the end of the line. Simply pressing ENTER to go to the next line will not do!.

One more thing for the uninitiated: // is the comment tag for a single line. Anything after this tag is ignored by C++ until it gets to the next line. You do not have to put a semicolon after this tag however. /* and */ tags (in this order) are comment block tags and anything multiple lines that is placed between these tags will be ignored by C++. Comments should be used liberally as you will find it a nightmare going back to your codes at a later time, trying to decipher what you have done without adequate comments.

 

How are we doing so far?

Lets press on if you dare.

Dysfunctional Functions

This is the real juicy bit as we are getting into the actual programming bit, so get your itchy fingers ready.

Again for those with lesser knowledge of programming, a Function is a block of codes that does something - calculation, drawing, play sound - just something. The beauty of a function is that you can call it again and again without having to rewrite the whole code again and again. In C++, functions can either return a value or ... not ...! A function starts at the open bracket { and ends at this end bracket }. Within a function, you might wish to use If logical blocks. This block also starts with { and ends with }. So you need to be careful and make sure that you have all the necessary brackets or the code will not compile.

In Cossacks, for our purpose, there are only two functions and they both do NOT return a value. They are OnInit() and ProcessScenary(). The word void before the function name indicate that the function does not return a value. Other "intrinsic" functions are available from the header file mission.h. Note the date type that may be returned by these functions. For example, int GetGlobalTime(); returns an integer. This returned value can later be used in your codes, for example, in a decision structure to test it against a certain value. Functions that do not return values simply just carry out an action with no returned values. I suggest you might have another go at reading this mission.h file again and try to commit some of the more common functions that you are likely to use to your memory.

OnInit()

This is where you would want to load your variables with values from the maps using the appropriate Register* function (these are functions declared in mission.h). For example you would want to load GAMEOBJ GROUP1 with a group from the map named StartGroup by entering this RegisterUnits(&GROUP1,"StartGroup"); The ampersand &, in C++, means by reference. You declare GROUP1 without the ampersand as GAMEOBJ and load the value to it with the ampersand in Register*() function. Just know this and use it. Full explannation is outside the scope of this manual.

Within this function, you should also set the player's name and set the players' alliance. You can do everything else in the next function.

About player's alliance: This is done by using ChangeFriend(Player as byte,Flag as byte) function. A byte has 8 bits and this equates to values of integer in the range of 0 to 255. Of course, there are only 8 players in Cossacks so the Player value is in the range of 0 to 7. (Note C++ start at 0 so in the script, 0 means Player 1 in the game. Confused?). From here, I will use C++ notation for Player. The integer Flag is used to set the player's alliance. You work out the value for the flag as followed:

Each player 0 - 7can either be an ally or enemy to the player that you are setting the alliance for. If its an enemy, the value is zero. If it's a friend:

Player 0 value is 1

Player 1 value is 2

Player 2 value is 4

Player 3 value is 8

Player 4 value is 16

Player 5 value is 32

Player 6 value is 64

Player 7 value is 128

So for example if you want to set alliance for Player 0 as friend to Player 2 and 3, then you set it as ChangeFriend(0,13). Breaking this down, value 13 is derived from : Player 0 value + Player 2 value + ... + Player 7 value. Of course, you are friendly to yourself so Player 0 value is 1. Player 2 value for a friend is 4 and Player 3 is 8. So 1 + 4 + 8 = 13.

Special value of 0 = enemy to everyone, and 255 = friend to everyone. 0 is the default value so you don't need to code for this if that's what you want in the scenario.

Take note that this makes you friend to Players 2 and 3 but they are not your friends. This means that Player 0 units will not attack Player 2 and 3 but Player 2 and 3 will attack Player 0. So you need to also code for these to be friend with Player 0 as well by ChangeFriend(2,13) and ChangeFriend(3,13).

So you can see that this feature is a lot more powerful than the simple feature of Change Relation in Scenario Editor.

ProcessScenary()

This is where the real fun starts. In this function, you code the flow for your scenario. Of all the different decision structures, you will only need to know one and that is if(){ }. Basically this tell the scenario to test for certain condition and if the conditions are met, you then go to the next statement within the if block. If the conditions are not met, the scenario will parse through to the next block of statements. Each block of statement commences at the open bracket { and ends at close bracket }. I will now introduce you to the different syntax of C++ needed to use this tool.

&& is AND

|| is OR

== is Logical comparator EQUAL

> is Logical comparotor GREATER THAN

< is Logical comparator SMALLER THAN

and finally >= and <= (you guess these two).

Triggers are defined as Trigg. Each has an identifying number, starting at 0. I do not know the actual limit for the number of triggers that you can have.

In each scenario, triggers start as being activated. After you have satisfied the condition and gone into an IF block for that trigger, you will need to turn it off by doing this : SetTrigg(whatevertriggernumber,0). If you want to have this trigger remaining active (ie. the equivalent of Activate Current Trigger of the Scenario Editor), you simply omit doing this.

Did you know that the function Patrol existed in Cossacks EW - GSC simply did not give it a button!.

Now you need to go through the list of available functions in Mission.h file and see which of those that you will need. Most of them are very much self explanatory. Then start coding.

After finishing coding, you need to build your DLL file. You can do so by going to the menu again and under Build, you choose Build Whatevermission.dll. You will find your DLL file in the folder that you have specified previously.

Copy this file to the UserMission folder of Cossacks. You can even put it in a subfolder if you so wish. Then you need to specify where path for this in the map editor under Set Starting Parameters. Now we are done. Load up the map and test it out.

It's unwieldy and sounds complicated, but it's really good fun, once you get the hang of it.