home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2003 January / maximum-cd-2003-01.iso / Software / Games / AoM / mtrial.exe / AOM / AI / SCN12P2.XS < prev    next >
Encoding:
Text File  |  2002-07-30  |  25.9 KB  |  714 lines

  1. //==============================================================================
  2. // Scn12p2: AI Scenario Script for scenario 12 player 2
  3. //==============================================================================
  4. /*
  5.    AI owner:  Mike Kidd
  6.    Scenario owner: Jeff Brown
  7.  
  8.    Overview:
  9.    The human player starts with a small army and three heroes,and regularly 
  10.    receives reinforcements at the starting position.  His goal is to destroy
  11.    the giant ram before the gates are broken down.
  12.  
  13.    The AI operates by taking units that are trigger-spawned, and then sending 
  14.    them to defend the ram (75%) or intercept the HP's units at the "bridge" (25%).  
  15.  
  16.    Many of the unit spawnings are based on the percent damage to the ram, with the
  17.    intent being to provide more and more opposition as the player gets closer 
  18.    to winning.
  19.  
  20.    Each time a set of units are spawned, a trigger calls the spawn() function and
  21.    passes an int that indicates which of three spawning areas has the new units.
  22.  
  23.    The CP can use God Powers to support its armies, but curse is not allowed for
  24.    the first 5 minutes of the game.  The CP does not age up.
  25.  
  26.    Difficulty: Controlled by triggers.
  27.      
  28.  
  29. */
  30. //==============================================================================
  31.  
  32.  
  33. include "scn lib.xs";
  34.  
  35. // Globals
  36.  
  37. bool  creatingDefendPlan = false;      // flipped to true while defend plan is gathering initial units.
  38. int   currentDefendPlan = -1;          // Used to monitor the most recent defend plan until it has its initial units
  39. int   defendPlanSize = -1;             // Number of units wanted for this plan
  40.  
  41. // Cinematic block markers
  42. const string cbNorthStart = "1923";
  43. const string cbEastStart = "1924";
  44. const string cbSouthStart = "1925";
  45. const string cbSouthPass = "1922";
  46. const string cbGate = "1921";
  47.  
  48.  
  49.  
  50. // *****************************************************************************
  51. //
  52. //                                FUNCTIONS
  53. //
  54. // *****************************************************************************
  55.  
  56.  
  57.  
  58. /*
  59. void launchAttack(vector start=vector(-1,-1,-1), int query=-1, int count=-1)
  60. {
  61.    static int attackQuery = -1;     // Attack at gate
  62.    static int attackQuery2 = -1;    // Attack at pass
  63.    int attackID = aiPlanCreate("Attack at "+(xsGetTime()/1000), cPlanAttack);
  64.    if (attackID < 0)
  65.       return;
  66.    if (aiPlanSetVariableInt(attackID, cAttackPlanPlayerID, 0, 1) == false)
  67.       return;
  68.    if (attackQuery < 0)
  69.    {
  70.       attackQuery = kbUnitQueryCreate("Attack Gate");
  71.       configQuery(attackQuery, cUnitTypeUnit, -1, cUnitStateAlive, 1, kbGetBlockPosition(cbGate), false, 75.0);
  72.    }
  73.    if (attackQuery2 < 0)
  74.    {
  75.       attackQuery2 = kbUnitQueryCreate("Attack Pass");
  76.       configQuery(attackQuery2, cUnitTypeUnit, -1, cUnitStateAlive, 1, kbGetBlockPosition(cbSouthPass), false, 50.0);
  77.    }
  78.  
  79.    aiPlanSetVariableVector(attackID, cAttackPlanGatherPoint, 0, start);
  80.    aiPlanSetVariableFloat(attackID, cAttackPlanGatherDistance, 0, 50.0); 
  81.    aiPlanSetInitialPosition( attackID, start);
  82.    aiPlanAddUnitType(attackID, cUnitTypeMilitary, 1, count, count);
  83.  
  84.    // 75% odds of getting gate, 25% at pass
  85.    if (aiRandInt(4) > 0)
  86.    {
  87.       aiPlanSetVariableInt(attackID, cAttackPlanQueryID, 0, attackQuery);  // Query for units within 75m of the ram
  88. //      aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeGate);
  89.       aiPlanSetInitialPosition(attackID, start);
  90.       aiEcho("Plan "+attackID+" will attack the gate starting from "+start+".");
  91. kbUnitQueryExecute(attackQuery);
  92. echoQuery(attackQuery);
  93.    }
  94.    else
  95.    {
  96.       aiPlanSetVariableInt(attackID, cAttackPlanQueryID, 0, attackQuery2);    // Query for units within 50m of the south pass
  97. //      aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeSouthPass);
  98.       aiPlanSetInitialPosition(attackID, start);
  99.       aiEcho("Plan "+attackID+" will attack the south pass starting from "+start+".");
  100. kbUnitQueryExecute(attackQuery2);
  101. echoQuery(attackQuery2);
  102.    }
  103.  
  104.    aiPlanSetRequiresAllNeedUnits(attackID, true);
  105.    aiPlanSetActive(attackID);
  106.    aiEcho("Activating attack plan "+attackID);
  107. }
  108. */
  109.  
  110. /*
  111. void checkNorthStart()   // Defend plan version
  112. {
  113.    int targetCount = 0;
  114.    targetCount = getUnassignedUnitCount(kbGetBlockPosition(cbNorthStart), 50.0, cMyID, cUnitTypeMilitary);
  115.    int vilCount = 0;
  116.  
  117.    int query=-1;           // Query to find the villagers, if any.
  118.  
  119.    query = kbUnitQueryCreate("Villagers");
  120.    if (query < 0)
  121.       return();
  122.  
  123.    configQuery(query, cUnitTypeVillagerGreek, -1, cUnitStateAlive, cMyID, kbGetBlockPosition(cbNorthStart), true, 50.0);
  124.    kbUnitQueryResetResults(query);
  125.    vilCount = kbUnitQueryExecute(query);
  126.  
  127.    aiEcho("Found "+targetCount+" units in North pass.");
  128.    int defendPlan =aiPlanCreate("Defend Plan", cPlanDefend);
  129.    if (defendPlan >= 0)
  130.    {
  131.       aiPlanAddUnitType(defendPlan, cUnitTypeMilitary, 0, targetCount, targetCount);    // Unassigned mil units
  132.       aiPlanSetDesiredPriority(defendPlan, 50);                       // Way low, below scouting and attack
  133.       aiPlanSetVariableFloat(defendPlan, cDefendPlanEngageRange, 0, 60);
  134.       aiPlanSetVariableBool(defendPlan, cDefendPlanPatrol, 0, false);
  135.       aiPlanSetVariableFloat(defendPlan, cDefendPlanGatherDistance, 0, 20.0);
  136.       aiPlanSetInitialPosition(defendPlan, kbGetBlockPosition(cbNorthStart));
  137.       aiPlanSetUnitStance(defendPlan, cUnitStanceDefensive);
  138.  
  139.       aiPlanSetVariableInt(defendPlan, cDefendPlanRefreshFrequency, 0, 5);
  140.  
  141.       if (vilCount < 1) // No vills, just get units
  142.       {
  143.          if (aiRandInt(4) > 0)   // 1 in 4
  144.            aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbSouthPass));
  145.          else
  146.             aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbGate));
  147.          aiPlanSetNumberVariableValues(defendPlan, cDefendPlanAttackTypeID, 2, true);
  148.          aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 0, cUnitTypeUnit);
  149.          aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 1, cUnitTypeBuilding);
  150.       }
  151.       else
  152.       {     // Protect the villagers
  153.          aiPlanSetNumberVariableValues(defendPlan, cDefendPlanDefendTargetID, vilCount, true);
  154.          aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbNorthStart));
  155.  
  156.          int i = 0;
  157.          for (i=0; < vilCount)
  158.          {
  159.             aiPlanSetVariableInt(defendPlan, cDefendPlanDefendTargetID, i, kbUnitQueryGetResult(query, i)); // Add this vill to the list
  160.          }
  161.          aiEcho("Added "+vilCount+" villagers to defend list.");
  162.          aiPlanSetNumberVariableValues(defendPlan, cDefendPlanAttackTypeID, 2, true);
  163.          aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 0, cUnitTypeUnit);
  164.          aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 1, cUnitTypeBuilding);      }
  165.  
  166.       aiPlanSetActive(defendPlan); 
  167. //    aiPlanSetNoMoreUnits(defendPlan, true);
  168.       aiEcho("Creating defend plan");
  169.    }
  170. }
  171.  
  172.  
  173.  
  174. void checkEastStart()   // Defend plan version
  175. {
  176.    int targetCount = 0;
  177.    targetCount = getUnassignedUnitCount(kbGetBlockPosition(cbEastStart), 50.0, cMyID, cUnitTypeMilitary);
  178.    int vilCount = 0;
  179.  
  180.    int query=-1;           // Query to find the villagers, if any.
  181.  
  182.    query = kbUnitQueryCreate("Villagers");
  183.    if (query < 0)
  184.       return();
  185.  
  186.    configQuery(query, cUnitTypeVillagerGreek, -1, cUnitStateAlive, cMyID, kbGetBlockPosition(cbEastStart), true, 50.0);
  187.    kbUnitQueryResetResults(query);
  188.    vilCount = kbUnitQueryExecute(query);
  189.  
  190.    aiEcho("Found "+targetCount+" units in East pass.");
  191.    int defendPlan =aiPlanCreate("Defend Plan", cPlanDefend);
  192.    if (defendPlan >= 0)
  193.    {
  194.       aiPlanAddUnitType(defendPlan, cUnitTypeMilitary, 0, targetCount, targetCount);    
  195.       aiPlanSetDesiredPriority(defendPlan, 50);                       
  196.       aiPlanSetVariableFloat(defendPlan, cDefendPlanEngageRange, 0, 60);
  197.       aiPlanSetVariableBool(defendPlan, cDefendPlanPatrol, 0, false);
  198. //      aiPlanSetVariableVector(defendPlan, cDefendPlanGatherPoint, 0, kbGetBlockPosition(cbEastStart));
  199.       aiPlanSetVariableFloat(defendPlan, cDefendPlanGatherDistance, 0, 20.0);
  200.       aiPlanSetInitialPosition(defendPlan, kbGetBlockPosition(cbEastStart));
  201.       aiPlanSetUnitStance(defendPlan, cUnitStanceDefensive);
  202.  
  203.       aiPlanSetVariableInt(defendPlan, cDefendPlanRefreshFrequency, 0, 5);
  204.  
  205.       if (vilCount < 1) // No vills, just get units
  206.       {
  207.          if (aiRandInt(4) > 0)   // 1 in 4
  208.            aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbSouthPass));
  209.          else
  210.             aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbGate));         
  211.          aiPlanSetNumberVariableValues(defendPlan, cDefendPlanAttackTypeID, 2, true);
  212.          aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 0, cUnitTypeUnit);
  213.          aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 1, cUnitTypeBuilding);
  214.       }
  215.       else
  216.       {
  217.          aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbEastStart));
  218.          aiPlanSetNumberVariableValues(defendPlan, cDefendPlanDefendTargetID, vilCount, true);
  219.          int i = 0;
  220.          for (i=0; < vilCount)
  221.          {
  222.             aiPlanSetVariableInt(defendPlan, cDefendPlanDefendTargetID, i, kbUnitQueryGetResult(query, i)); // Add this vill to the list
  223.          }
  224.          aiEcho("Added "+vilCount+" villagers to defend list.");
  225.          aiPlanSetNumberVariableValues(defendPlan, cDefendPlanAttackTypeID, 2, true);
  226.          aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 0, cUnitTypeUnit);
  227.          aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 1, cUnitTypeBuilding);
  228.       }
  229.  
  230.       aiPlanSetActive(defendPlan); 
  231. //    aiPlanSetNoMoreUnits(defendPlan, true);
  232.       aiEcho("Creating defend plan");
  233.    }
  234. }
  235.  
  236.  
  237.  
  238. void checkSouthStart()   // Defend plan version
  239. {
  240.    int targetCount = 0;
  241.    targetCount = getUnassignedUnitCount(kbGetBlockPosition(cbSouthStart), 50.0, cMyID, cUnitTypeMilitary);
  242.    int vilCount = 0;
  243.  
  244.    int query=-1;           // Query to find the villagers, if any.
  245.  
  246.    query = kbUnitQueryCreate("Villagers");
  247.    if (query < 0)
  248.       return();
  249.  
  250.    configQuery(query, cUnitTypeVillagerGreek, -1, cUnitStateAlive, cMyID, kbGetBlockPosition(cbSouthStart), true, 50.0);
  251.    kbUnitQueryResetResults(query);
  252.    vilCount = kbUnitQueryExecute(query);
  253.  
  254.    aiEcho("Found "+targetCount+" units in South pass.");
  255.    int defendPlan =aiPlanCreate("Defend Plan", cPlanDefend);
  256.    if (defendPlan >= 0)
  257.    {
  258.       aiPlanAddUnitType(defendPlan, cUnitTypeMilitary, 0, targetCount, targetCount);    // Unassigned mil units
  259.       aiPlanSetDesiredPriority(defendPlan, 50);                       // Way low, below scouting and attack
  260.       aiPlanSetVariableFloat(defendPlan, cDefendPlanEngageRange, 0, 60);
  261.       aiPlanSetVariableBool(defendPlan, cDefendPlanPatrol, 0, false);
  262.       aiPlanSetVariableFloat(defendPlan, cDefendPlanGatherDistance, 0, 20.0);
  263.       aiPlanSetInitialPosition(defendPlan, kbGetBlockPosition(cbSouthStart));
  264.       aiPlanSetUnitStance(defendPlan, cUnitStanceDefensive);
  265.  
  266.       aiPlanSetVariableInt(defendPlan, cDefendPlanRefreshFrequency, 0, 5);
  267.  
  268.       if (vilCount < 1) // No vills, just get units
  269.       {
  270.          if (aiRandInt(4) > 0)   // 1 in 4
  271.            aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbSouthPass));
  272.          else
  273.             aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbGate));         aiPlanSetNumberVariableValues(defendPlan, cDefendPlanAttackTypeID, 2, true);
  274.          aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 0, cUnitTypeUnit);
  275.          aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 1, cUnitTypeBuilding);
  276.       }
  277.       else
  278.       {
  279.          aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbSouthStart));
  280.          aiPlanSetNumberVariableValues(defendPlan, cDefendPlanDefendTargetID, vilCount, true);
  281.          int i = 0;
  282.          for (i=0; < vilCount)
  283.          {
  284.             aiPlanSetVariableInt(defendPlan, cDefendPlanDefendTargetID, i, kbUnitQueryGetResult(query, i)); // Add this vill to the list
  285.          }
  286.          aiEcho("Added "+vilCount+" villagers to defend list.");
  287.          aiPlanSetNumberVariableValues(defendPlan, cDefendPlanAttackTypeID, 2, true);
  288.          aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 0, cUnitTypeUnit);
  289.          aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 1, cUnitTypeBuilding);      }
  290.  
  291.       aiPlanSetActive(defendPlan); 
  292. //    aiPlanSetNoMoreUnits(defendPlan, true);
  293.       aiEcho("Creating defend plan");
  294.    }
  295. }
  296. */
  297. /*
  298. void checkNorthStart()
  299. //   inactive
  300. //   minInterval 15
  301. {
  302. //   static int northStartQuery = -1;
  303. //   static int lastTime = -30000;
  304.    int targetCount = -1;
  305.  
  306. //   if (xsGetTime() < (lastTime+25000) )
  307. //      return;     // suppress if we've picked up units here in the last 25 seconds, to avoid multiple tasking
  308.  
  309.    targetCount = getUnassignedUnitCount(kbGetBlockPosition(cbNorthStart), 50.0, cMyID, cUnitTypeMilitary);
  310.  
  311.    aiEcho("Found "+targetCount+" units in North pass.");
  312.    if (targetCount > 0)
  313.    {
  314.       launchAttack(kbGetBlockPosition(cbNorthStart), northStartQuery, targetCount);
  315. //      lastTime = xsGetTime();
  316.    }
  317. }*/
  318.  
  319.  
  320.  
  321. /*
  322. void checkEastStart()
  323. //   inactive
  324. //   minInterval 15
  325. {
  326. //   static int eastStartQuery = -1;
  327. //   static int lastTime = -30000;
  328.    int targetCount = -1;
  329.  
  330. //   if (xsGetTime() < (lastTime+25000) )
  331. //      return;     // suppress if we've picked up units here in the last 25 seconds, to avoid multiple tasking
  332.  
  333.    targetCount = getUnassignedUnitCount(kbGetBlockPosition(cbEastStart), 50.0, cMyID, cUnitTypeMilitary);
  334.  
  335.  
  336.    aiEcho("Found "+targetCount+" units in East pass.");
  337.    if (targetCount > 0)
  338.    {
  339.       launchAttack(kbGetBlockPosition(cbEastStart), eastStartQuery, targetCount);
  340. //      lastTime = xsGetTime();
  341.    }
  342. }
  343.  
  344.  
  345. void checkSouthStart()
  346. //   inactive
  347. //   minInterval 15
  348. {
  349. //  static int southStartQuery = -1;
  350. //   static int lastTime = -30000;
  351.    int targetCount = -1;
  352.  
  353. //   if (xsGetTime() < (lastTime+25000) )
  354. //      return;     // suppress if we've picked up units here in the last 25 seconds, to avoid multiple tasking
  355.  
  356.    targetCount = getUnassignedUnitCount(kbGetBlockPosition(cbSouthStart), 50.0, cMyID, cUnitTypeMilitary);
  357.  
  358.    aiEcho("Found "+targetCount+" units in South pass.");
  359.    if (targetCount > 0)
  360.    {
  361.       launchAttack(kbGetBlockPosition(cbSouthStart), southStartQuery, targetCount);
  362. //      lastTime = xsGetTime();
  363.    }
  364. }
  365. */
  366.  
  367. /*
  368. // Called via trigger when an army is available in one of the channels.  ChannelID indicates which channel has the units.
  369. void spawn(int channelID=-1)
  370. {     
  371.    aiEcho("Spawn firing, channelID = "+channelID);
  372.    switch(channelID)
  373.    {
  374.    case 0:
  375.       {
  376.          checkSouthStart();
  377.          break;
  378.       }
  379.    case 1:
  380.       {
  381.          checkEastStart();
  382.          break;
  383.       }
  384.    case 2:
  385.       {
  386.          checkNorthStart();
  387.          break;
  388.       }
  389.    }
  390. }
  391. */
  392.  
  393.  
  394. // Called by a trigger, to let AI know that the game has started
  395. void wakeup(int parm=-1)
  396. {
  397.    xsDisableRule("spoofWakeup");       // No need for rule to fire, the trigger woke us up.
  398.    aiEcho("Wakeup running at "+xsGetTime()/1000);
  399.    xsEnableRule("checkNorthStart");
  400.    xsEnableRule("checkEastStart");
  401.    xsEnableRule("checkSouthStart");
  402.    xsEnableRule("taskBuilders");
  403.    //xsEnableRule("useCurse");  Disabled because Ian doesn't like it.  ;-)
  404.    xsEnableRule("useRestoration");
  405.    xsEnableRule("pollForMilitary");
  406. }
  407.  
  408.  
  409. int createDefendPlan(vector point = vector(-1,-1,-1))       // Make a defend plan gathering units at this point, return plan ID
  410. {
  411.    int planID = -1;
  412.    int vilCount = 0;       // How many villagers in the neighborhood?
  413.  
  414.    int query=-1;           // Query to find the villagers, if any.
  415.  
  416.    query = kbUnitQueryCreate("Villagers");
  417.    if (query < 0)
  418.       return(-1);
  419.  
  420.    configQuery(query, cUnitTypeVillagerGreek, -1, cUnitStateAlive, cMyID, point, true, 30.0);
  421.    kbUnitQueryResetResults(query);
  422.    vilCount = kbUnitQueryExecute(query);
  423.  
  424.  
  425.    int defendPlan =aiPlanCreate("Defend Plan "+timeString(), cPlanDefend);
  426.    if (defendPlan >= 0)
  427.    {
  428.       aiPlanAddUnitType(defendPlan, cUnitTypeMilitary, 0, defendPlanSize, defendPlanSize);    // Unassigned mil units
  429.       aiPlanSetDesiredPriority(defendPlan, 50);                       // Way low, below scouting and attack
  430.       aiPlanSetVariableFloat(defendPlan, cDefendPlanEngageRange, 0, 50);
  431.       aiPlanSetVariableBool(defendPlan, cDefendPlanPatrol, 0, false);
  432.       aiPlanSetVariableFloat(defendPlan, cDefendPlanGatherDistance, 0, 5.0);
  433.       aiPlanSetInitialPosition(defendPlan, point);
  434.       aiPlanSetUnitStance(defendPlan, cUnitStanceDefensive);
  435.  
  436.       aiPlanSetVariableInt(defendPlan, cDefendPlanRefreshFrequency, 0, 5);
  437.       aiEcho("Creating defend plan "+defendPlan+".");
  438.  
  439.       if (vilCount < 1) // No vills, just get units
  440.       {
  441.          if (aiRandInt(4) == 0)   // 1 in 4
  442.          {
  443.             aiEcho("  will defend bridge.");
  444.             aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbSouthPass));
  445.          }
  446.          else
  447.          {
  448.             aiEcho("  will defend ram.");
  449.             aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbGate));
  450.          }
  451.          aiPlanSetNumberVariableValues(defendPlan, cDefendPlanAttackTypeID, 2, true);
  452.          aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 0, cUnitTypeUnit);
  453.          aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 1, cUnitTypeBuilding);
  454.       }
  455.       else
  456.       {                          // Escort the villagers
  457.          aiEcho("  will escort "+vilCount+" villagers.");
  458.          aiPlanSetVariableFloat(defendPlan, cDefendPlanEngageRange, 0, 20);    // ultra-close cover?
  459.          aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, point);
  460.          aiPlanSetNumberVariableValues(defendPlan, cDefendPlanDefendTargetID, vilCount, true);
  461.          int i = 0;
  462.          for (i=0; < vilCount)
  463.          {
  464.             aiPlanSetVariableInt(defendPlan, cDefendPlanDefendTargetID, i, kbUnitQueryGetResult(query, i)); // Add this vill to the list
  465.          }
  466.          aiEcho("Added "+vilCount+" villagers to defend list.");
  467.          aiPlanSetNumberVariableValues(defendPlan, cDefendPlanAttackTypeID, 2, true);
  468.          aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 0, cUnitTypeUnit);
  469.          aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 1, cUnitTypeBuilding);
  470.       }
  471.  
  472.       aiPlanSetActive(defendPlan); 
  473. //    aiPlanSetNoMoreUnits(defendPlan, true);
  474.       return(defendPlan);
  475.    }
  476.    else
  477.       return(-1);
  478. }
  479.  
  480. int checkForMilitary(vector point = vector(-1,-1,-1))
  481. {
  482.    return( getUnassignedUnitCount(point, 30.0, cMyID, cUnitTypeMilitary) );
  483. }
  484.  
  485.  
  486. void main()
  487. {
  488.    aiEcho("Starting Scn12p2.xs");
  489.    kbSetTownLocation(kbGetBlockPosition(cbGate));
  490.    aiSetAttackResponseDistance(20.0);
  491.  
  492.    //Calculate some areas.
  493.    kbAreaCalculate(1200.0);
  494.  
  495.    aiRandSetSeed();
  496.  
  497. }
  498.  
  499. // *****************************************************************************
  500. //
  501. // RULES
  502. //
  503. // *****************************************************************************
  504. rule bigBrother         // Look over the defend plan's shoulder, set it to not take new units as soon as it has its initial army.
  505.    inactive 
  506.    runImmediately
  507. {
  508.    static int startTime = -1;      // Used to set a time limit for this plan's initial staffing
  509.  
  510.    if (startTime == -1)
  511.       startTime = xsGetTime();     // 30 second max
  512.    else
  513.    {
  514.       if ( xsGetTime() > (startTime+10000) )     // Check time limit, 10 seconds max
  515.       {
  516.          aiEcho("  Time limit exceeded on defend plan "+currentDefendPlan);
  517.          aiPlanSetNoMoreUnits( currentDefendPlan, true );
  518.          xsDisableSelf();
  519.          creatingDefendPlan = false;
  520.          currentDefendPlan = -1;
  521.          defendPlanSize = -1;
  522.          startTime = -1;
  523.          return;
  524.       }
  525.    }
  526.  
  527.    int actualSize = -1;
  528.    actualSize = aiPlanGetNumberUnits(currentDefendPlan, cUnitTypeMilitary);
  529.       
  530.    if (actualSize >= defendPlanSize)   // we're done!
  531.    {
  532.       aiEcho("  Defend plan has "+actualSize+" units.");
  533.       aiPlanSetNoMoreUnits( currentDefendPlan, true );
  534.       xsDisableSelf();
  535.       creatingDefendPlan = false;
  536.       currentDefendPlan = -1;
  537.       defendPlanSize = -1;
  538.       startTime = -1;
  539.       return;
  540.    }
  541.  
  542.    // Otherwise, keep waiting
  543. }
  544.  
  545.  
  546.  
  547. rule pollForMilitary       // Check all three spawn locations looking for unassigned units
  548.    minInterval 5
  549.    inactive
  550. {
  551.    if (creatingDefendPlan == true)
  552.       return;     // Do not start new groups until current one is done
  553.  
  554.    defendPlanSize = checkForMilitary(kbGetBlockPosition(cbNorthStart));
  555.    if (defendPlanSize > 0)
  556.    {
  557.       aiEcho("Found "+defendPlanSize+" units in the north tunnel.");
  558.       creatingDefendPlan = true;    // Blocks createion of others until big brother clears it.
  559.       currentDefendPlan = createDefendPlan(kbGetBlockPosition(cbNorthStart));
  560.       xsEnableRule("bigBrother");
  561.       return;
  562.    }
  563.  
  564.    defendPlanSize = checkForMilitary(kbGetBlockPosition(cbEastStart));
  565.    if (defendPlanSize > 0)
  566.    {
  567.       aiEcho("Found "+defendPlanSize+" units in the east tunnel.");
  568.       creatingDefendPlan = true;    // Blocks createion of others until big brother clears it.
  569.       currentDefendPlan = createDefendPlan(kbGetBlockPosition(cbEastStart));
  570.       xsEnableRule("bigBrother");
  571.       return;
  572.    }
  573.  
  574.    defendPlanSize = checkForMilitary(kbGetBlockPosition(cbSouthStart));
  575.    if (defendPlanSize > 0)
  576.    {
  577.       aiEcho("Found "+defendPlanSize+" units in the south tunnel.");
  578.       creatingDefendPlan = true;    // Blocks createion of others until big brother clears it.
  579.       currentDefendPlan = createDefendPlan(kbGetBlockPosition(cbSouthStart));
  580.       xsEnableRule("bigBrother");
  581.       return;
  582.    }
  583. }
  584.  
  585.  
  586.  
  587. rule useCurse 
  588.    minInterval 5
  589.    inactive
  590. {
  591.    if (xsGetTime() < 300000)
  592.       return;  // Not before five minutes!
  593.  
  594.    // look for a group of 6 enemy military units, at the gate or the pass
  595.    int targetUnit = -1;
  596.  
  597.    
  598.    static int tempQuery = -1;
  599.    if (tempQuery < 0)
  600.    {  // Doesn't exist, set it up
  601.       tempQuery = kbUnitQueryCreate("useCurseHome");
  602.       if ( configQuery(tempQuery, cUnitTypeMilitary, -1, cUnitStateAlive, 1, kbGetBlockPosition(cbGate), true, 50) == false)
  603.          return;
  604.    }
  605.    kbUnitQueryResetResults(tempQuery);
  606.    int targetCount = kbUnitQueryExecute(tempQuery);  
  607.  
  608.    if (targetCount < 6)
  609.    {
  610.       vector pVec = kbGetBlockPosition(cbSouthPass);
  611.       if (xsVectorGetX(pVec)>=0)
  612.       {
  613.          static int tempQuery2 = -1;
  614.          if (tempQuery2 < 0)
  615.          {  // Doesn't exist, set it up
  616.             tempQuery2 = kbUnitQueryCreate("useCurseArmy");
  617.             if ( configQuery(tempQuery2, cUnitTypeMilitary, -1, cUnitStateAlive, 1, pVec, true, 50) == false)
  618.                return;
  619.          }
  620.          else
  621.             kbUnitQuerySetPosition(tempQuery, pVec); // Because pVec changes as army moves
  622.          kbUnitQueryResetResults(tempQuery2);
  623.          targetCount = kbUnitQueryExecute(tempQuery2);  
  624.          if (targetCount < 6)
  625.             return;
  626.          else
  627.             targetUnit = kbUnitQueryGetResult(tempQuery2, targetCount/2);  // grab middle unit
  628.       }
  629.    } 
  630.    else
  631.       targetUnit = kbUnitQueryGetResult(tempQuery, targetCount/2);  // grab middle unit
  632.  
  633.  
  634.    aiEcho("Using Curse at "+kbUnitGetPosition(targetUnit));
  635.    if ( aiCastGodPowerAtPosition(cTechCurse, kbUnitGetPosition(targetUnit)) == true)
  636.       xsDisableSelf();
  637.  
  638. }
  639.  
  640.  
  641.  
  642. rule useRestoration // Check gate area, use when there are >= 10 CP units and >=10 HP units in area
  643.    minInterval 5
  644.    inactive
  645. {
  646.    
  647.    int targetUnit = -1;
  648.  
  649.    static int tempQuery = -1;
  650.    if (tempQuery < 0)
  651.    {  // Doesn't exist, set it up
  652.       tempQuery = kbUnitQueryCreate("useRestoration1");     // Look for my units
  653.       if ( configQuery(tempQuery, cUnitTypeMilitary, -1, cUnitStateAlive, 2, kbGetBlockPosition(cbGate), true, 50) == false)
  654.          return;
  655.    }
  656.    kbUnitQueryResetResults(tempQuery);
  657.    int targetCount = kbUnitQueryExecute(tempQuery); 
  658.    if (targetCount < 10)
  659.       return;     // Not enough, wait
  660.    else
  661.       targetUnit = kbUnitQueryGetResult(tempQuery, targetCount/2);  // grab middle unit
  662.  
  663.    
  664.  
  665.    static int tempQuery2 = -1;
  666.    if (tempQuery2 < 0)
  667.    {  // Doesn't exist, set it up
  668.       tempQuery2 = kbUnitQueryCreate("useRestoration2");    // Look for HP units
  669.       if ( configQuery(tempQuery2, cUnitTypeMilitary, -1, cUnitStateAlive, 1, kbGetBlockPosition(cbGate), true, 50) == false)
  670.          return;
  671.    }
  672.    kbUnitQueryResetResults(tempQuery2);
  673.    targetCount = kbUnitQueryExecute(tempQuery2); 
  674.    if (targetCount < 10)
  675.       return;
  676.  
  677.  
  678.  
  679.  
  680.    aiEcho("Using Restoration at "+kbUnitGetPosition(targetUnit));
  681.    if ( aiCastGodPowerAtPosition(cTechRestoration, kbUnitGetPosition(targetUnit)) == true)
  682.       xsDisableSelf();
  683.    else
  684.       aiEcho("Restoration failed at "+kbUnitGetPosition(targetUnit));
  685. }
  686.  
  687.  
  688. rule taskBuilders
  689.    inactive
  690.    minInterval 10
  691. {
  692.    static int villQuery = -1;
  693.    int villCount = -1;
  694.  
  695.    if (villQuery < 0) // need to define query
  696.    {
  697.       villQuery = kbUnitQueryCreate("checkBuilders");    // Look for HP units
  698.       if ( configQuery(villQuery, cUnitTypeVillagerGreek, cActionIdle, cUnitStateAlive, 2) == false)
  699.          return;
  700.    }
  701.    kbUnitQueryResetResults(villQuery);
  702.    villCount = kbUnitQueryExecute(villQuery);
  703.  
  704.    if (villCount == 0)
  705.       return;
  706.  
  707.    int vill = -1;
  708.    for (i=0; < villCount)
  709.    {
  710.       vill = kbUnitQueryGetResult(villQuery, i);
  711.       aiTaskUnitWork(vill, kbGetBlockID("312"));     // Task them to work on the ram
  712.    }
  713. }
  714.