home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2003 January / maximum-cd-2003-01.iso / Software / Games / AoM / mtrial.exe / AOM / AI / SCN29P2.XS < prev    next >
Encoding:
Text File  |  2002-09-11  |  15.7 KB  |  477 lines

  1. //==============================================================================
  2. // Scn29p2: AI Scenario Script for scenario 29 player 2
  3. //==============================================================================
  4. /*
  5.    AI owner:  Dave Leary
  6.    Scenario owner: Joe Gillum/Jerome Jones
  7.  
  8.     Difficulty level stuff: adds ballistae on higher levels (hard/titan) and
  9.     generally increases the size of attacks on higher levels.
  10. */
  11. //==============================================================================
  12. // Difficulty Level check predeclared.
  13. //==============================================================================
  14. int difflevel=-1;        
  15.  
  16. // Variable for main base.
  17. int gMainBaseID=-1;
  18.  
  19. //Shared variables.
  20. int numberAttacks=0;
  21. int attackPlayerID=-1;
  22.  
  23. //Attack 1 vars.
  24. int attackPlan1ID=-1;
  25. int maintainPlan1ID=-1;
  26. int maintainPlan2ID=-1;
  27. int maintainPlan3ID=-1;
  28. int maintainPlan4ID=-1;
  29.  
  30. int defendPlan1ID=-1;
  31.  
  32. // Route and path vars.
  33. int attackRoute1ID=-1;
  34. int attackPath1ID=-1;
  35.  
  36. // Unit types
  37. int attackerUnitTypeID1=cUnitTypeMountainGiant;
  38. int attackerUnitTypeID2=cUnitTypeFrostGiant;
  39. int attackerUnitTypeID3=cUnitTypeFireGiant;
  40. int attackerUnitTypeID4=cUnitTypeBallista;
  41.  
  42. //==============================================================================
  43. // Set Town Location
  44. //==============================================================================
  45. void setTownLocation(void)
  46. {
  47.    //Look for the "Town Location" marker.
  48.    kbSetTownLocation(kbGetBlockPosition("365582"));
  49. }
  50.  
  51. //==============================================================================
  52. // miscStartup
  53. //==============================================================================
  54. void miscStartup(void)
  55. {
  56.     // Get the difficulty level.
  57.     difflevel=aiGetWorldDifficulty();
  58.  
  59.    //Startup message(s).
  60.    aiEcho("");
  61.    aiEcho("");
  62.    aiEcho("Scn29P2 AI Start, filename='"+cFilename+"'.");
  63.    //Spit out the map size.
  64.    aiEcho("Map size is ("+kbGetMapXSize()+", "+kbGetMapZSize()+").");
  65.     aiEcho("Difficulty Level="+difflevel+".");
  66.  
  67.    //Cheat like a bastard.  Once only, though.
  68.    kbLookAtAllUnitsOnMap();
  69.    //Calculate some areas.
  70.    kbAreaCalculate(1200.0);
  71.    //Set our town location.
  72.    setTownLocation();
  73.     
  74.     //Allocate all resources to the root escrow by setting percentage of military/economy to 0.
  75.     kbEscrowSetPercentage( cEconomyEscrowID, cAllResources, 0.0 );
  76.     kbEscrowSetPercentage( cMilitaryEscrowID, cAllResources, 0.0 );
  77.  
  78.     //Allocate all resources 
  79.    kbEscrowAllocateCurrentResources();
  80.  
  81.     //Reset random seed
  82.     aiRandSetSeed();
  83.  
  84.     // Diff level adjustments
  85.     if ( difflevel > 0 )
  86.     {
  87.         attackerUnitTypeID2=cUnitTypeMountainGiant;
  88.     }
  89.  
  90.     if ( difflevel > 1 )
  91.     {
  92.         attackerUnitTypeID1=cUnitTypeMountainGiant;
  93.         attackerUnitTypeID2=cUnitTypeFireGiant;
  94.     }
  95.  
  96.     if ( difflevel == 3 )
  97.     {
  98.         attackerUnitTypeID1=cUnitTypeFireGiant;
  99.         attackerUnitTypeID2=cUnitTypeFrostGiant;
  100.     }
  101. }
  102.  
  103. //==============================================================================
  104. //==============================================================================
  105. // Attack stuff.
  106. //==============================================================================
  107. //==============================================================================
  108.  
  109. //==============================================================================
  110. // initAttack: Creates attack routes, etc.
  111. //==============================================================================
  112. void initAttack(int playerID=-1)
  113. {
  114.    //Destroy all previous attacks (if this isn't the player we're already attacking.
  115.    if (playerID != attackPlayerID)
  116.    {
  117.       //Reset the attack player ID.
  118.       attackPlayerID=-1;
  119.       //Destroy any previous attack plan.
  120.       aiPlanDestroy(attackPlan1ID);
  121.       attackPlan1ID=-1;
  122.  
  123.       //Destroy our previous attack paths.
  124.       kbPathDestroy(attackPath1ID);
  125.       attackPath1ID=-1;
  126.  
  127.       //Destroy our previous attack routes.  
  128.       attackRoute1ID=-1;
  129.  
  130.       //Reset the number of attacks.
  131.       numberAttacks=0;
  132.    }
  133.  
  134.    //Save the player to attack.
  135.    attackPlayerID=playerID;
  136.  
  137.    vector gatherPoint=kbGetBlockPosition("365589");
  138.    
  139.     //Setup attack path 1 - go left
  140.    attackPath1ID=kbPathCreate("Attack Path 1");
  141.    kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("365577"));
  142.     kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("365578"));
  143.     kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("365579"));
  144.     kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("365580"));
  145.    //Create attack route 1.
  146.    attackRoute1ID=kbCreateAttackRouteWithPath("Attack Route 1", gatherPoint, kbGetBlockPosition("365581"));
  147.    
  148.     if (attackRoute1ID >= 0)
  149.       kbAttackRouteAddPath(attackRoute1ID, attackPath1ID);
  150.  
  151. }
  152.  
  153. //==============================================================================
  154. // setupBaseAttack - the primary attack setup.
  155. // Prioritizes enemy units instead of buildings.
  156. //==============================================================================
  157. bool setupBaseAttack(int playerID=-1)
  158. {
  159.     difflevel=aiGetWorldDifficulty();
  160.  
  161.    // If we have enough unassigned military units of the core type, bail.
  162.    int numberAvailableUnits1=aiNumberUnassignedUnits(attackerUnitTypeID1);
  163.     vector gatherPoint=kbGetBlockPosition("365589");
  164.    
  165.     // Bail if there aren't at least two mountain giants around.
  166.     aiEcho("There are "+numberAvailableUnits1+" base giants available for a new attack.");
  167.     if (numberAvailableUnits1 < 1)
  168.         return( false );
  169.        
  170.     //Info.
  171.     aiEcho("Attacking Player "+playerID+".");
  172.  
  173.    //If the player to attack doesn't match, init the attack.
  174.    if (attackPlayerID != playerID)
  175.    {
  176.       initAttack(playerID);
  177.       if (attackPlayerID < 0)
  178.          return(false);
  179.    }
  180.  
  181.    //Create an attack plan.
  182.    int newAttackPlanID=aiPlanCreate("Attack Player"+attackPlayerID+" Attempt"+numberAttacks, cPlanAttack);
  183.    if (newAttackPlanID < 0)
  184.       return(false);
  185.  
  186.    //Target player (required).  This must work.
  187.    if (aiPlanSetVariableInt(newAttackPlanID, cAttackPlanPlayerID, 0, attackPlayerID) == false)
  188.       return(false);
  189.  
  190.     //Set the target type.  This must work.
  191.    if (aiPlanSetNumberVariableValues(newAttackPlanID, cAttackPlanTargetTypeID, 2, true) == false)
  192.       return(false);
  193.  
  194.    //Unit types to attack.
  195.    aiPlanSetVariableInt(newAttackPlanID, cAttackPlanTargetTypeID, 0, cUnitTypeBuilding);
  196.     aiPlanSetVariableInt(newAttackPlanID, cAttackPlanTargetTypeID, 1, cUnitTypeUnit);
  197.  
  198.     aiPlanSetVariableInt(newAttackPlanID, cAttackPlanAttackRouteID, 0, attackRoute1ID);
  199.     aiPlanSetVariableVector(newAttackPlanID, cAttackPlanGatherPoint, 0, gatherPoint);
  200.    aiPlanSetInitialPosition(newAttackPlanID, gatherPoint);
  201.  
  202.    //Set the gather point distance
  203.    aiPlanSetVariableFloat(newAttackPlanID, cAttackPlanGatherDistance, 0, 100.0);
  204.  
  205.    //Set up the attack route usage pattern
  206.    aiPlanSetVariableInt(newAttackPlanID, cAttackPlanAttackRoutePattern, 0, cAttackPlanAttackRoutePatternRandom);
  207.    
  208.     //Add the unit types to the plan
  209.     if ( difflevel < 2 )
  210.     {
  211.         aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID1, 2, 2, 2);
  212.         aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID2, 0, 1, 1);
  213.     }
  214.     else if ( difflevel == 2 )
  215.     {
  216.         aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID1, 2, 4, 4);
  217.         aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID2, 0, 4, 4);
  218.         aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID4, 0, 2, 2);
  219.     }
  220.     else
  221.     {
  222.         aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID1, 2, 4, 4);
  223.         aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID2, 0, 4, 4);
  224.         aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID4, 0, 4, 4);
  225.     }
  226.     
  227.    //Plan requires all need units to work (can be false)
  228.    aiPlanSetRequiresAllNeedUnits(newAttackPlanID, true);
  229.    //Activate the plan.
  230.    aiPlanSetActive(newAttackPlanID);
  231.  
  232.    //Now, save the attack plan ID appropriately
  233.    aiPlanSetOrphan(attackPlan1ID, true);
  234.    attackPlan1ID=newAttackPlanID;
  235.  
  236.    //Increment our overall number of attacks
  237.    numberAttacks++;
  238. }
  239.  
  240. //==============================================================================
  241. // Attack Generator 1 - Base attack, every two minutes, once activated.
  242. //==============================================================================
  243. rule attackGenerator1
  244.    minInterval 150
  245.    inactive
  246.    group AttackRules
  247. {
  248.    // See how many "idle" attack plans we have.  Don't create any more if we have
  249.    // idle plans.
  250.    int numberIdleAttackPlans=aiGetNumberIdlePlans(cPlanAttack);
  251.  
  252.    if (numberIdleAttackPlans > 0)
  253.       return;
  254.  
  255.     setupBaseAttack(1);
  256. }
  257.  
  258. //==============================================================================
  259. // Favor cheat - grant 30 favor every 45 seconds.
  260. //==============================================================================
  261. rule favorCheat
  262.    minInterval 40
  263.    inactive
  264.    group AttackRules
  265. {
  266.     difflevel=aiGetWorldDifficulty();
  267.     // Cheat for favor.  It's tough to be Norse.
  268.     if ( difflevel < 2 )
  269.     {
  270.         aiResourceCheat( 2, cResourceFavor, 50.0 );
  271.     }
  272.     else
  273.     {
  274.         aiResourceCheat( 2, cResourceFavor, 100.0 );
  275.     }
  276. }
  277.  
  278. // Wall upgrade.
  279. rule upgradeWalls
  280.    minInterval 10
  281.    inactive
  282. {
  283.    int planID=aiPlanCreate("Upgrading Walls", cPlanResearch);
  284.    if (planID < 0)
  285.       return;
  286.  
  287.    aiPlanSetVariableInt(planID, cResearchPlanTechID, 0, cTechStoneWall);
  288.    aiPlanSetVariableInt(planID, cResearchPlanBuildingTypeID, 0, cUnitTypeWallLong);
  289.    aiPlanSetActive(planID);
  290.    
  291.     //Done.
  292.    xsDisableSelf();
  293. }
  294.  
  295. // Tower upgrade.
  296. rule upgradeTowers
  297.    minInterval 90
  298.    inactive
  299. {
  300.    int planID=aiPlanCreate("Upgrading Towers", cPlanResearch);
  301.    if (planID < 0)
  302.       return;
  303.  
  304.    aiPlanSetVariableInt(planID, cResearchPlanTechID, 0, cTechWatchTower);
  305.    aiPlanSetVariableInt(planID, cResearchPlanBuildingTypeID, 0, cUnitTypeTower);
  306.    aiPlanSetActive(planID);
  307.    
  308.     //Done.
  309.    xsDisableSelf();
  310. }
  311.  
  312. //==============================================================================
  313. // initiateAttacks - triggered with an AI FUNC to get everything rolling.
  314. //==============================================================================
  315. void initiateAttacks( int parameter=-1 )
  316. {
  317.     aiEcho("*** PLAYER 2 AI: Attacks now being sent.");
  318.     
  319.     // Enable favor generation and other fun..
  320.     xsEnableRule("attackGenerator1");
  321.     xsEnableRule("favorCheat");
  322.     xsEnableRule("upgradeWalls");
  323.     xsEnableRule("upgradeTowers");
  324. }
  325.  
  326. //==============================================================================
  327. // settlementDestroyed - if P2's settlement is destroyed, defend plan backs
  328. // up to the rear.
  329. //==============================================================================
  330. void settlementDestroyed( int parameter=-1 )
  331. {
  332.     aiEcho("*** PLAYER 2 AI: Now defending the rear.");
  333.     vector rearDefend=kbGetBlockPosition("365582");
  334.     
  335.     aiPlanSetVariableVector(defendPlan1ID, cDefendPlanDefendPoint, 0, rearDefend);
  336. }
  337.  
  338. //==============================================================================
  339. // MAIN
  340. //==============================================================================
  341. void main(void)
  342. {
  343.    //Startup.
  344.    miscStartup();
  345.  
  346.     difflevel=aiGetWorldDifficulty();
  347.  
  348.    //Share a common gather point.
  349.    vector gatherPoint1=kbGetBlockPosition("365574");
  350.     vector gatherPoint2=kbGetBlockPosition("365575");
  351.     vector gatherPoint3=kbGetBlockPosition("367252");
  352.  
  353.    //Maintain 4 of the first giant type.
  354.    maintainPlan1ID=aiPlanCreate("Maintain "+kbGetProtoUnitName(attackerUnitTypeID1), cPlanTrain);
  355.    if (maintainPlan1ID >= 0)
  356.    {
  357.         //Must set the type of unit to train.
  358.       aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanUnitType, 0, attackerUnitTypeID1);
  359.       //You can limit the number of units that are ever trained by this plan with this call.
  360.       //aiPlanSetVariableInt(maintainPlanID, cTrainPlanNumberToTrain, 0, 25);
  361.       //Set the number of units to maintain in the world at one time, based
  362.         if ( difflevel == 2 )
  363.         {
  364.             aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanNumberToMaintain, 0, 8);
  365.         }
  366.         else if ( difflevel == 3 )
  367.         {
  368.             aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanNumberToMaintain, 0, 10);
  369.         }
  370.         else
  371.         {
  372.             aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanNumberToMaintain, 0, 4);
  373.         }
  374.       //Don't train units too fast
  375.         if ( difflevel < 2 )
  376.         {
  377.             aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanFrequency, 0, 60);
  378.         }
  379.         else
  380.         {
  381.             aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanFrequency, 0, 30);
  382.         }
  383.       //Set a gather point.
  384.       aiPlanSetVariableVector(maintainPlan1ID, cTrainPlanGatherPoint, 0, gatherPoint1);
  385.       //Activate the plan.
  386.       aiPlanSetActive(maintainPlan1ID);
  387.    }
  388.  
  389.     //Maintain 2 of the second giant type (though we only ever send one in an attack group).
  390.    maintainPlan2ID=aiPlanCreate("Maintain 2 "+kbGetProtoUnitName(attackerUnitTypeID2), cPlanTrain);
  391.    if (maintainPlan2ID >= 0)
  392.    {
  393.         //Must set the type of unit to train.
  394.       aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanUnitType, 0, attackerUnitTypeID2);
  395.       //You can limit the number of units that are ever trained by this plan with this call.
  396.       //aiPlanSetVariableInt(maintainPlanID, cTrainPlanNumberToTrain, 0, 25);
  397.       //Set the number of units to maintain in the world at one time.
  398.       
  399.         if ( difflevel > 1 )
  400.         {
  401.             aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanNumberToMaintain, 0, 6);
  402.         }
  403.         else
  404.         {
  405.             aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanNumberToMaintain, 0, 2);
  406.         }
  407.  
  408.       //Don't train units too fast
  409.         if ( difflevel < 2 )
  410.         {
  411.             aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanFrequency, 0, 90);
  412.         }
  413.         else
  414.         {
  415.             aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanFrequency, 0, 45);
  416.         }
  417.  
  418.       //Set a gather point.
  419.       aiPlanSetVariableVector(maintainPlan2ID, cTrainPlanGatherPoint, 0, gatherPoint2);
  420.       //Activate the plan.
  421.       aiPlanSetActive(maintainPlan2ID);
  422.    }
  423.  
  424.     // If the difficulty is higher than moderate, maintain two (or four) ballista.
  425.     if ( difflevel > 1 )
  426.     {
  427.         maintainPlan4ID=aiPlanCreate("Maintain "+kbGetProtoUnitName(attackerUnitTypeID1), cPlanTrain);
  428.         if (maintainPlan4ID >= 0)
  429.         {
  430.             //Must set the type of unit to train.
  431.             aiPlanSetVariableInt(maintainPlan4ID, cTrainPlanUnitType, 0, attackerUnitTypeID4);
  432.             //You can limit the number of units that are ever trained by this plan with this call.
  433.             //aiPlanSetVariableInt(maintainPlanID, cTrainPlanNumberToTrain, 0, 25);
  434.             //Set the number of units to maintain in the world at one time, based
  435.             if ( difflevel == 2 )
  436.             {
  437.                 aiPlanSetVariableInt(maintainPlan4ID, cTrainPlanNumberToMaintain, 0, 2);
  438.                 aiPlanSetVariableInt(maintainPlan4ID, cTrainPlanFrequency, 0, 60);
  439.             }
  440.             else if ( difflevel == 3 )
  441.             {
  442.                 aiPlanSetVariableInt(maintainPlan4ID, cTrainPlanNumberToMaintain, 0, 4);
  443.                 aiPlanSetVariableInt(maintainPlan4ID, cTrainPlanFrequency, 0, 30);
  444.             }
  445.             //Set a gather point.
  446.             aiPlanSetVariableVector(maintainPlan4ID, cTrainPlanGatherPoint, 0, gatherPoint3);
  447.             //Activate the plan.
  448.             aiPlanSetActive(maintainPlan4ID);
  449.         }
  450.     }
  451.  
  452.     // Defense at the gate.
  453.    defendPlan1ID=aiPlanCreate("Gate Defense", cPlanDefend);
  454.    if (defendPlan1ID >= 0)
  455.    {
  456.       //Main gate location
  457.       vector theGate=kbGetBlockPosition("365576");
  458.  
  459.       //Add the unit(s)
  460.         if ( difflevel < 2 )
  461.         {
  462.             aiPlanAddUnitType(defendPlan1ID, attackerUnitTypeID1, 2, 2, 2);
  463.             aiPlanAddUnitType(defendPlan1ID, attackerUnitTypeID2, 0, 1, 1);
  464.         }
  465.         else
  466.         {
  467.             aiPlanAddUnitType(defendPlan1ID, attackerUnitTypeID1, 4, 4, 4);
  468.             aiPlanAddUnitType(defendPlan1ID, attackerUnitTypeID2, 0, 2, 2);
  469.         }
  470.         
  471.       //Setup the vars.
  472.       aiPlanSetDesiredPriority(defendPlan1ID, 90);
  473.         aiPlanSetVariableVector(defendPlan1ID, cDefendPlanDefendPoint, 0, theGate);
  474.       aiPlanSetVariableFloat(defendPlan1ID, cDefendPlanEngageRange, 0, 30);
  475.       aiPlanSetActive(defendPlan1ID);
  476.     }
  477. }