Scripting: Invasions

Invasions are the hardest to set up in the scripting file: adding them requires adding code to four places in the script file.

Variables
We have to add two variables to the script: one for storing the invasions themselves, and one for managing the military AI: the engine that decides what the enemies should do. Add the following bit of code to the variables section:

  // Military AI and invasion list required for invasions
  private TMilitaryAI mMilitaryAI = null;
  private InvasionSetup[] mInvasions;

OnTick()
The following lines have to be added to the OnTick method in your script:

  // Update military AI (for invasions)
  mMilitaryAI.Update(game, 0.1);

The 0.1 in the call to Update denotes the percentage of buildings that will be destroyed by raiders or pillagers before they leave your city. This is usually set to 0.1 (10%), but can be increased or decreased to your liking.

Adding invasions to OnBeginScenario()

We have to do two things in the OnBeginScenario method: initializing the two variables we've added to the variables section, and setting up the invasions themselves.

Initializing the variables
Add the following code to the OnBeginScenario method, where you have to replace <NUMBER_OF_INVASIONS> with, you guessed it, the number of invasions you'll be setting up:

  mMilitaryAI = new TMilitaryAI(game);
  mInvasions = new InvasionSetup[<NUMBER_OF_INVASIONS>];

Setting up the invasions
Setting up an invasion consists of three steps:

  1. Creating the invasion
  2. Adding cohorts to the invasion
  3. Adding the invasion to the game

In the code below, you'll see references to <NUM>: you have to replace this with the sequence number of the invasion. The first invasion has number 0, the second has number 1, and so on.

For creating an invasion, you have to enter quite a few variables:

Invasion id
A unique string for the invasion. Is usually of the form "conquest2", "raid0", etc.
Enemy faction
The "nationality" of the invading army. A list of factions can be consulted on the scripting constants page
Invasion type
Whether the invasion is a conquest, a raid or pillage, where there's virtually no difference between a "raid" and a "pillage". For a raid, the invaders will leave when 10% of the buildings have been torched. For conquests, the invaders will try to destroy everything. A list of invasion types can be looked up on the scripting constants page
Buy-off cost
The amount of denarii the player can pay to buy the enemy off. This can be set to zero to disable bribing the enemy.
Start week
The starting week of the invasion, calculated from the start of the scenario. Note that the "start" of the invasion is when the one-year warning message shows up. This means that the actual invasion happens one year after the start week
Start week variance
The variance in the starting week: for example, when set to 4, the invasion can happen up to 4 weeks before or after the actual starting week.

The code for creating an invasion is as follows: (where the names between <...> are placeholders you have to fill in):

  mInvasions[<NUM>] = new InvasionSetup("<INVASION_ID>", <FACTION>,
    <INVASION_TYPE>, <BUYOFF>, <START_WEEK>, <VARIANCE>);

Adding cohorts to the invasion is similar to how it is done for military requests. The only difference is that you have to add waypoint IDs where the enemy will enter and leave the map. You must ensure that you have placed waypoints with that same ID on the map in the editor. If you have placed multiple waypoints with the same ID in the editor, the game will randomly choose one waypoint for each of the cohorts.

As with the military requests, you can look up the cohort type on the scripting constants page.

The code for adding a cohort is as follows; you can add multiple lines to add more cohort types to the invasion:

  mInvasions[<NUM>].AddCohort(<COHORT_TYPE>, <NUM_COHORTS>,
    <ENTRY_WAYPOINT>, <EXIT_WAYPOINT>);

Finally, we come to adding the invasion to the game. Here you can also tell the game to repeat the invasion every n weeks. Set it to zero for a one-time invasion. The code:

  mInvasions[<NUM>].CreateInvasion(game, <NUM>, <REPEAT_WEEK>);

Example
A full example of setting up an invasion which repeats every 4 years:

  mInvasions[0] = new InvasionSetup("conquest0",sInvasionFactions.kGreek,
    eInvasionType.kInvasion, 13000, 360, 4);
  mInvasions[0].AddCohort(sCohortDbIDs.kParth_Hvy, 3, 3, 3);
  mInvasions[0].AddCohort(sCohortDbIDs.kParth_Aux, 2, 3, 3);
  mInvasions[0].AddCohort(sCohortDbIDs.kParth_Catapult, 6, 3, 3);
  mInvasions[0].CreateInvasion(game, 0, 192);

Replacing the Run() method

To get the military invasions working properly, the Run method will be called by the game for two more reasons than usual: when an invasion arrives and when the target of the enemy is destroyed. The easiest way to get this working is by replacing the entire Run() method with the following code snippet:

// This is the main script loop
public void Run(object gameInterface)
{
  IGameQueryInterface gameQueryInterface =
    (IGameQueryInterface)gameInterface;
  switch (gameQueryInterface.RunReason)
  {
    case RunReason.kTick:
      OnTick(gameQueryInterface);
      break;

    case RunReason.kOnBeginScenario:
      OnBeginScenario(gameQueryInterface);
      break;

    case RunReason.kOnInvasionArrival:
      OnInvasionArrival(gameQueryInterface);
      break;

    case RunReason.kOnCohortTargetDestroyed:
      OnCohortTargetDestroyed(gameQueryInterface);
      break;

    case RunReason.kOnLoadScenario:
      OnScenarioLoad(gameQueryInterface);
      break;
  }
}

void OnInvasionArrival(IGameQueryInterface game)
{
  // let's find out which invasion we are...
  foreach (InvasionSetup inv in mInvasions)
  {
    if (game.RunInvasion == inv.GetInvasionName())
    {
      // hook into military AI
      eInvasionType invType = inv.GetInvasionType();
      mMilitaryAI.InvasionBegin(invType, game);
      break;
    }
  }
}

void OnCohortTargetDestroyed(IGameQueryInterface game)
{
  // see what we should be doing next
  String nextOrders = 
    mMilitaryAI.InvasionTargetDestroyed(game.RunCohortID, game);
  game.SetCohortOrders(game.RunCohortID, ref nextOrders);
}

Message texts in XML

Once you've set up the invasions in the script, don't forget to add messages to the XML file!

< Previous: scripting military requests | Editor Home | Next: scripting: constants >