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

  1. //==============================================================================
  2. // ScnEBp2: AI Scenario Script for EB scenario player 2
  3. //==============================================================================
  4. /*
  5.    AI owner:  Mike Kidd
  6.    Scenario owner: Jerome Jones
  7.  
  8.    Overview:
  9.    The player's goal is to find and destroy the four gates to the underworld.  The
  10.    CP periodically teleports new units into the fray at these locations, avoiding
  11.    portals that have been destroyed.  The CP uses minions, wolves, shades and 
  12.    Fire Giants.  
  13.  
  14.    Based on difficulty level, the CP chooses attack group sizes and intervals.  
  15.    Certain units, like a fire giant, count as several "units".  Each attack group
  16.    is made up of a homogenous set of units, it doesn't do mixed fire giant/wolf 
  17.    groups.
  18.  
  19.    Difficulty:  Implemented.  
  20.  
  21.    No age-ups or god powers.
  22.      
  23.  
  24. */
  25. //==============================================================================
  26.  
  27.  
  28. include "scn lib.xs";
  29.  
  30. // Globals
  31.  
  32. // Attack control...initialized in main() based on difficulty level
  33. int   nextAttackTime = -1;
  34. int   attackInterval = -1;
  35. float attackSize = -1.0; // The float has the "real" value so I can use % increases
  36. //int   attackSize = -1;        // This one is actually used by the attack algorithms, must be set whenever float is changed.
  37. float attackMultiplier = -1.0;   // Typically like 1.10, which would increase each attack by 10%.
  38. float maxAttackSize = -1;
  39. int   lastAttackPlan = -1;
  40.  
  41. int difficulty = -1;
  42. // Cinematic block markers
  43. const string cbNorthSpawn = "6144";
  44. const string cbNorthEastSpawn = "6145";
  45. const string cbEastSpawn = "6146";
  46. const string cbWestSpawn = "6147";
  47. const string cbP1TC = "6148";
  48. const string cbWestSettlement = "6149";
  49. const string cbCenterSettlement = "6150";
  50. const string cbEastSettlement = "6151";
  51.  
  52. // *****************************************************************************
  53. //
  54. //                                FUNCTIONS
  55. //
  56. // *****************************************************************************
  57.  
  58.  
  59. void attack()
  60. {
  61.    // Pick a unit type
  62.    int unitType = -1;
  63.    int rand = -1;
  64.    int unitQty = -1;
  65.  
  66.    if (attackSize > 8.0)   // consider fire giant
  67.       rand = aiRandInt(4);
  68.    else                    // just wolf, minion, shade
  69.       rand = aiRandInt(3);
  70.  
  71.    if (rand == 0)
  72.    {
  73.       unitType = cUnitTypeWolf;
  74.       unitQty = attackSize;    // Counts as 1 unit for toughness
  75.       aiEcho("Will send wolves ("+unitQty+").");
  76.    }
  77.    if (rand == 1)
  78.    {
  79.       unitType = cUnitTypeMinion;
  80.       unitQty = attackSize;      // Counts as 1
  81.       aiEcho("Will send minions ("+unitQty+").");
  82.    }
  83.    if (rand == 2)
  84.    {
  85.       unitType = cUnitTypeShadeofHades;
  86.       unitQty = attackSize/2;
  87.       aiEcho("Will send shades ("+unitQty+").");
  88.    }
  89.    if (rand == 3)
  90.    {
  91.       unitType = cUnitTypeFireGiant;
  92.       unitQty = attackSize/6;
  93.       aiEcho("Will send fire giants ("+unitQty+").");
  94.    }
  95.  
  96.    vector location = vector(-1, -1, -1);
  97.    int i=0;
  98.  
  99.    for (i=0; < 100)  // Shouldn't be possible to have no valid sites, but this will prevent infinite loop
  100.    {
  101.       rand = aiRandInt(4);
  102.       switch(rand)
  103.       {  // Pick a location, bail if tunnel is gone
  104.          case 0:
  105.          {     // North, check tunnel
  106.             if ( kbUnitGetCurrentHitpoints(kbGetBlockID("5949")) > 0.1 )
  107.             {
  108.                location = kbGetBlockPosition(cbNorthSpawn);
  109.                aiEcho("Location: North");
  110.             }
  111.             break;
  112.          }
  113.          case 1:
  114.          {  // Northeast
  115.             if ( kbUnitGetCurrentHitpoints(kbGetBlockID("5952")) > 0.1 )
  116.             {
  117.                location = kbGetBlockPosition(cbNorthEastSpawn);
  118.                aiEcho("Location: NorthEast");
  119.             }
  120.             break;
  121.          }
  122.          case 2:
  123.          {  // East
  124.             if ( kbUnitGetCurrentHitpoints(kbGetBlockID("5953")) > 0.1 )
  125.             {
  126.                location = kbGetBlockPosition(cbEastSpawn);
  127.                aiEcho("Location: East");
  128.             }
  129.             break;
  130.          }
  131.          case 3:
  132.          {  // West
  133.             if ( kbUnitGetCurrentHitpoints(kbGetBlockID("5950")) > 0.1 )
  134.             {
  135.                location = kbGetBlockPosition(cbWestSpawn);
  136.                aiEcho("Location: West");
  137.             }
  138.             break;
  139.          }
  140.       }
  141.       if (xsVectorGetX(location) >= 0)
  142.          break;
  143.    }
  144.  
  145.  
  146.    if (xsVectorGetX(location) < 0)
  147.          return;
  148.  
  149.    // Spawn the units
  150.    aiUnitCreateCheat( 2, unitType, location, "Attack group", unitQty); 
  151.  
  152.  
  153.    // Make the attack plan
  154.    int   attackID=aiPlanCreate("Attack at "+timeString(), cPlanAttack);
  155.    if (attackID < 0)
  156.    {
  157.       return;
  158.    }
  159.  
  160.    if (aiPlanSetVariableInt(attackID, cAttackPlanPlayerID, 0, 1) == false)
  161.    {
  162.       return;
  163.    }
  164.  
  165.    if (aiPlanSetNumberVariableValues(attackID, cAttackPlanTargetTypeID, 3, true) == false)
  166.    {
  167.       return;
  168.    }
  169.  
  170. /*   // Set up the attack query with the appropriate vector
  171.    if (attackQuery < 0)
  172.    {
  173.       attackQuery = kbUnitQueryCreate("Attack Query");
  174.       configQuery(attackQuery, cUnitTypeUnit, -1, cUnitStateAlive, 1, kbGetBlockPosition(cHPTown), false, 50.0);
  175.             //vector center = vector(-1,-1,-1), bool sort = false, float radius = -1 )
  176.    }
  177.    aiPlanSetVariableInt(attackID, cAttackPlanQueryID, 0, attackQuery);
  178.  
  179.  
  180.    if (attackMode == cAttackModeWest)
  181.       aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeWest);
  182.    else if (attackMode == cAttackModeEast)
  183.       aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeEast);
  184.    else if (aiRandInt(2) > 0)
  185.       aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeEast);
  186.    else
  187.       aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeWest);
  188. */
  189.    aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 0, cUnitTypeMilitary);
  190.    aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 1, cUnitTypeBuilding);
  191.    aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 2, cUnitTypeUnit);
  192.  
  193.  
  194.    aiPlanSetVariableVector(attackID, cAttackPlanGatherPoint, 0, location);
  195.    aiPlanSetVariableFloat(attackID, cAttackPlanGatherDistance, 0, 100.0);  // REAL wide in case of mega-spawn traffic
  196.  
  197.    aiPlanAddUnitType(attackID, unitType, 0, unitQty, unitQty);
  198.  
  199.    aiPlanSetInitialPosition(attackID, location);
  200.    aiPlanSetRequiresAllNeedUnits(attackID, true);
  201.    aiPlanSetActive(attackID);
  202.    aiEcho("Activating attack plan "+attackID);
  203. //   if (lastAttackPlan >= 0)
  204. //     aiPlanDestroy(lastAttackPlan);   // free up last set of units?
  205.    lastAttackPlan = attackID; // update the global var
  206. }
  207.  
  208.  
  209.  
  210. void wakeup(int parm=-1)
  211. {
  212.    nextAttackTime = nextAttackTime + xsGetTime();
  213.    xsEnableRule("spawnScout");
  214.    xsEnableRule("scout");
  215.    xsEnableRule("attackGenerator");
  216.    aiEcho("Wakeup running at "+timeString());
  217. }
  218.  
  219.  
  220. rule spoofWakeup
  221.    active
  222.    minInterval 35
  223. {
  224.    wakeup(0);
  225.    xsDisableSelf();
  226. }
  227.  
  228.  
  229. void main()
  230. {
  231.    aiEcho("Starting ScnEBp2.xs");
  232. //   kbSetTownLocation(kbGetBlockPosition(cCenter));
  233.    aiRandSetSeed();
  234.  
  235.    //Calculate some areas.
  236.    kbAreaCalculate(1200.0);
  237.  
  238.    difficulty = aiGetWorldDifficulty();
  239.    
  240.    switch(difficulty)
  241.    {
  242.    case 0:     // Easy
  243.       {
  244.          nextAttackTime = 300000;
  245.          attackInterval = 300000;
  246.          attackSize = 3.0;
  247.          attackMultiplier = 1.1;    // 10% per 5 min
  248.          maxAttackSize = 7;
  249.          break;
  250.       }
  251.    case 1:     // Moderate
  252.       {
  253.          nextAttackTime = 240000;
  254.          attackInterval = 240000;
  255.          attackSize = 3.0;
  256.          attackMultiplier = 1.2;    // 20% per 4 min
  257.          maxAttackSize = 15;
  258.          break;
  259.       }
  260.    case 2:     // Hard
  261.       {
  262.          nextAttackTime = 120000;
  263.          attackInterval = 240000;
  264.          attackSize = 6.0;
  265.          attackMultiplier = 1.3;    // 30% per 4 min
  266.          maxAttackSize = 30;
  267.          break;
  268.       }
  269.    case 3:     // Unfair
  270.       {
  271.          nextAttackTime = 60000;
  272.          attackInterval = 180000;
  273.          attackSize = 6.0;
  274.          attackMultiplier = 1.4;    // 40% per 3 min
  275.          maxAttackSize = 60;
  276.          break;
  277.       }
  278.    }
  279.  
  280.  
  281. /* Sample query setup
  282.    donkeyQueryEast = kbUnitQueryCreate("Idle Donkey East");
  283.    configQuery(donkeyQueryEast, cUnitTypeCaravanGreek, cActionIdle, cUnitStateAlive, 2, kbGetBlockPosition(cEastTown), false, 20.0);
  284. */
  285. }
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293. // *****************************************************************************
  294. //
  295. // RULES
  296. //
  297. // *****************************************************************************
  298.  
  299. rule spawnScout
  300.    inactive
  301.    minInterval 10
  302. {
  303.    int count = kbUnitCount(2, cUnitTypeWolf, cUnitStateAlive); // Count my scouts
  304.    if (count >= 2)
  305.       return;
  306.    aiUnitCreateCheat( 2, cUnitTypeWolf, kbGetBlockPosition("6144"), "Name", 2-count);  // Build to total of 2
  307.    aiEcho("Making wolves.");
  308. }
  309.  
  310.  
  311. rule scout
  312.    inactive
  313.    minInterval 10
  314. {
  315.    // just set up an explore plan
  316.    int exploreID = aiPlanCreate("Explore", cPlanExplore);
  317.    if(exploreID >= 0)
  318.    {
  319.       aiPlanSetVariableFloat( exploreID, cExplorePlanLOSMultiplier,  0, 4.0 );
  320.       aiPlanAddUnitType(exploreID, cUnitTypeWolf, 1, 2, 2);
  321.       aiPlanSetDesiredPriority(exploreID, 90);
  322.       aiPlanSetActive(exploreID);
  323.    }
  324.    xsDisableSelf();
  325. }
  326.  
  327.  
  328.  
  329.  
  330. rule attackGenerator
  331.    minInterval 10
  332.    active
  333. {
  334.    //aiEcho("attack check running, next time is "+nextAttackTime);
  335.    if ( xsGetTime() < nextAttackTime )
  336.       return;
  337.  
  338.    attack();
  339.    nextAttackTime = xsGetTime() + attackInterval;
  340.    attackSize = attackSize * attackMultiplier;
  341.    if (attackSize > maxAttackSize)
  342.       attackSize = maxAttackSize;
  343.    aiEcho("Next attack size will be "+attackSize+".");
  344. }
  345.  
  346.  
  347.  
  348.  
  349.  
  350.  
  351.