aom ai script help file.rtf

(207 KB) Pobierz

AI Help File Document

Age of Mythology

 

© 2002, Microsoft Corporation. All rights reserved.

 

Important: Age of Mythology allows you to create your own AI scripts. You may share these custom AI scripts for the purposes of gameplay, but you may not sell or make other commercial uses of the custom AI scripts. Microsoft® reserves all other rights to the editors and files.

 

AI Script Help File Document

 

The AoM AI scripting system is a very powerful system that allows the user to craft the AI using the same language as the folks at Ensemble Studios.  While this is a useful enduser feature, it is officially unsupported.

 

The high level overview for creating your own random map AI scripts is as follows:

·              Write your random map script.

·              Add an XML file into your AI directory following the format of default.xml, defaultboom.xml, or defaultrush.xml.

·              See your AI appear in the list of dropdown choices when you run the game.

·              Debug it using the ingame debugging facilities:

o              Add “aiDebug” to your user.cfg file in the startup directory.

o              When the game is running, hit ALT+SHIFT+D to bring up the debugger.

For a scenario, the steps are largely the same, except that you need to associate the AI script filename with the right player via the scenario editor (Player Data dialog).

 

A list of the type enumerations and function calls that can be made from the AI scripts is included at the end of this document.

 

AoM includes a source debugger for your XS scripts.  This is accessed by including a line with “aiDebug” on it in the user.cfg in the Startup directory of your AoM installation.  If you do not have a user.cfg file, create one with any text editor.  Once this is in your user.cfg, hitting ALT+SHIFT+D will bring up the debugger.  Different XS runtimes (AI for each player, triggers, etc.) will be available for debugging.  The debugger is an unsupported feature.

 

You can also use the “aiEcho(…)” syscall (see the syscall reference at the end of this document) to print out debugging strings, etc. during the execution of your AI.  To see these, you must put a “showAIEchoes” line in your user.cfg.


Sample AOM Scripts

The following script code is a sample script from one of the AoM single-player scenarios.  As such, it does not demonstrate everything that is possible with the AI scripting system, but it does provide a working example.  More examples (including all of the script code for the Random Map AI for AoM) can be found in the “AI” subdirectory of your AoM installation.

 

 

I. Sample Script File

 

//==============================================================================

// Scn08p2: AI Scenario Script for scenario 8 player 2

//==============================================================================

/*

   Overview:

   The human player rescues Ajax from the Trojan army, then joins forces at the

   allied TC.  His goal is to build up and take out the red town to the north, without

   the availability of siege units.

 

   The CP sends one trivial attack early, which dies hopelessly to the HP's huge

   army left over from the start.  Several of the following attack rules are currently

   implemented by triggers which attempt to build military buildings near

   the HP's town.

  

   The CP attacks down any one of three channels, with the west channel reserved for

   higher difficulty levels.

 

   No attempt is made to train units out of the forward buildings, even if the

   feeble attempt to build succeeds.  If the forward building concept stays in, we should

   add rules to make a local army out of each building and use them for extra attacks.  

 

   CP starts as age 2 with Animal Magnet (not used) and Pestilence.

   Age 3: Aphrodite: Curse

   Age 4: Hephaestus: Plenty

 

*/

//==============================================================================

 

 

include "scn lib.xs";

 

// Globals

int         lastAttackPlanID = -1; // Updated with plan ID as each attack is launched

int         defendPlan = -1;

 

int         reservePlan = -1; // Extra defend plan, higher priority, for final resistance

int         startTime = -1;               // Updated with start time when cinematic is done. 

                              // In seconds.

              

int         age3Time = 1500;              // Time (in seconds) to go to age 3

int         age4Time = 10000;

int         siegeMaintainPlan = -1;

int         mythMaintainPlan = -1;

int         hopliteMaintainPlan = -1;

int         toxotesMaintainPlan = -1;

int         hippikonMaintainPlan = -1;

int         villagerMaintainPlan = -1;

 

int         routeWestPass = -1;

int         routeNorthPass = -1;

int         routeEastPass = -1;

 

// Initial settings are for the easiest difficulty level, others are set in main().

int         nextAttackTime = 480000;     // 8 minutes

float       attackSize = 4.0;

float       maxAttackSize = 9.0;

float       attackSizeMultiplier = 1.2;

int         attackInterval = 300000;      // 5 minutes

float       reserveSize = 15.0;           // Army to keep in reserve

int         attackCount = 0;

int         trainDelay = 30;

int         cavTrainDelay = 30;

int         archerTrainDelay = 15;

int         infantryTrainDelay = 20;

 

int builderQty = 1;     // For forward building

int defendQty = 0;      // For escort group

 

// Cinematic block markers

const string cbVillagerGather = "1872";

const string cbSiegeGather = "1873";

const string cbArcherGather = "1878";

const string cbCavalryGather = "1874";

const string cbInfantryGather = "1875";

const string cbP2TC = "1876";

const string cbGateEast = "1826";

const string cbGateWest = "1827";

const string cbWestPass1 = "1833";

const string cbWestPass2 = "1832";

const string cbNorthWestPlateau = "1834";

const string cbNorthEastPlateau = "1835";

const string cbP1Gold = "1831";

const string cbP1Granary = "1830";

const string cbSouthField = "1877";

const string cbEastPass1 = "1828";

const string cbEastPass2 = "1829";

const string cbP1TC = "1836";

const string cbNorthPass = "2272";

const string cbAttack2Stable = "1882";

const string cbAttack2Army = "1883";

const string cbAttack5Tower = "1880";

const string cbAttack3Army = "1881";

 

// Econ

int   maxVills = 20;        // Will scale with difficulty

int   maxFishBoats = 0;    // Including one to scout

float goldPercent = 0.25;

float woodPercent = 0.15;

float foodPercent = 0.60;

int   gathererTypeID = -1;

int   fishGatherer = -1;

int   mainBase = -1;

float mainRadius = 100.0;

 

 


// *****************************************************************************

//

// Building plan support for forward building

//

// *****************************************************************************

int buildPlan = -1;

int buildDefend = -1;

// Set the following four vars, then just enable testBuildPlan.

int buildUnit = cUnitTypeTower;

vector buildVec = cInvalidVector;

vector startPoint = cInvalidVector;

 

rule buildPlanRule

   inactive

{

 

   buildPlan = aiPlanCreate("Build Plan", cPlanBuild);

   if(buildPlan >= 0)

   {

      aiPlanSetVariableInt(buildPlan, cBuildPlanBuildingTypeID, 0, buildUnit);

      aiPlanSetDesiredPriority(buildPlan, 40);

      aiPlanSetVariableVector(buildPlan, cBuildPlanCenterPosition, 0, buildVec);

      aiPlanSetInitialPosition(buildPlan, startPoint);

      aiPlanSetVariableFloat(buildPlan, cBuildPlanCenterPositionDistance, 0, 12);

      aiPlanAddUnitType(buildPlan,

                        kbTechTreeGetUnitIDTypeByFunctionIndex(cUnitFunctionBuilder, 0),

                        1, builderQty, builderQty);

      aiPlanSetEscrowID(buildPlan, cRootEscrowID);

      aiPlanSetInitialPosition(buildPlan, buildVec);

      aiPlanSetActive(buildPlan);

   }

 

   buildDefend =aiPlanCreate("Build Defend Plan", cPlanDefend);

   if (buildDefend >= 0)

   {

      aiPlanAddUnitType(buildDefend, cUnitTypeMilitary, 0, defendQty, defendQty);

      aiPlanSetDesiredPriority(buildDefend, 60); // Above other defend plans

      aiPlanSetVariableVector(buildDefend, cDefendPlanDefendPoint, 0, buildVec);

      aiPlanSetVariableFloat(buildDefend, cDefendPlanEngageRange, 0, 15);

      aiPlanSetVariableBool(buildDefend, cDefendPlanPatrol, 0, false);

      aiPlanSetVariableFloat(buildDefend, cDefendPlanGatherDistance, 0, 8.0);

      aiPlanSetInitialPosition(buildDefend, kbGetBlockPosition(cbInfantryGather));

      aiPlanSetUnitStance(buildDefend, cUnitStanceDefensive);

 

      aiPlanSetVariableInt(buildDefend, cDefendPlanRefreshFrequency, 0, 5);

      aiPlanSetNumberVariableValues(buildDefend, cDefendPlanAttackTypeID, 2, true);

      aiPlanSetVariableInt(buildDefend, cDefendPlanAttackTypeID, 0, cUnitTypeUnit);

      aiPlanSetVariableInt(buildDefend, cDefendPlanAttackTypeID, 1, cUnitTypeBuilding);

     

      aiPlanSetActive(buildDefend);

      aiEcho("Creating defend plan");

   }

   xsEnableRule("endBuildDefend");

   xsDisableSelf();

}

 

rule endBuildDefend

   inactive

   minInterval 7

{

   aiEcho("Build Plan state is "+aiPlanGetState(buildPlan));

   if (aiPlanGetState(buildPlan) == -1)

   {

      aiPlanDestroy(buildDefend);

      aiEcho("Destroying build defend plan");

      xsDisableSelf();

   }

}

 

 

 

// *****************************************************************************

//

//                                FUNCTIONS

//

// *****************************************************************************

 

 

void age2EventHandler(int bogus=-1)

{

   xsEnableRule("usePestilence");

   xsEnableRule("goToAge3");

   xsEnableRule("getAge2UnitUpgrades");

   xsEnableRule("getAge2ArmoryUpgrades");

}

 

 

 

void age3EventHandler(int bogus=-1)

{

   xsEnableRule("useCurse");

   siegeMaintainPlan = maintainUnit(cUnitTypePetrobolos, reserveSize/8,

                                    kbGetBlockPosition(cbSiegeGather), 60);

   xsEnableRule("getAge3UnitUpgrades");

   xsEnableRule("getAge3ArmoryUpgrades");

}

 

 

void age4EventHandler(int bogus=-1)

{

   xsEnableRule("usePlenty");

   xsEnableRule("getAge4UnitUpgrades");

   xsEnableRule("getAge4ArmoryUpgrades");

   xsEnableRule("usePlenty");

}

 

 

// Called by a trigger, to let AI know that the game has started

void wakeup(int parm=-1)

{

   startTime = xsGetTime()/1000;

   aiEcho("Wakeup running at "+startTime);

 

   if (kbGetAge() >= cAge2)

      age2EventHandler(0);

   if (kbGetAge() >= cAge3)

      age3EventHandler(0);

   if (kbGetAge() >= cAge4)

      age4EventHandler(0);

 

   xsEnableRule("attackGenerator");

   xsEnableRule("scout");

   hippikonMaintainPlan = maintainUnit(cUnitTypeHippikon, reserveSize/3,

                                       kbGetBlockPosition(cbCavalryGather),

                                       cavTrainDelay);

 

   toxotesMaintainPlan = maintainUnit(cUnitTypeToxotes, reserveSize/3,

                                      kbGetBlockPosition(cbArcherGather),

                                      archerTrainDelay);

 

   hopliteMaintainPlan = maintainUnit(cUnitTypeHoplite, reserveSize/3,

                                      kbGetBlockPosition(cbInfantryGather),

                                      infantryTrainDelay);

 

   // Init low-priority defend plan to manage spare units

   defendPlan =aiPlanCreate("Defend Plan", cPlanDefend);

   if (defendPlan >= 0)

   {

      // All unassigned mil units

      aiPlanAddUnitType(defendPlan, cUnitTypeMilitary, 0, 200, 200);

     


...

Zgłoś jeśli naruszono regulamin