home *** CD-ROM | disk | FTP | other *** search
Text File | 2002-09-17 | 37.9 KB | 1,060 lines |
- //==============================================================================
- // Scn18p2: AI Scenario Script for scenario 18 player 2.
- //==============================================================================
- /*
- AI owner: Dave Leary
- Scenario owner: Joe "The Golem" Gillum
-
- Overview:
-
- *** DIFFICULTY LEVEL NOTES ***
-
- Easy level - Red player has fewer defenses. Additional resources granted to
- the player.
-
- Moderate level - Smallest of starting three gold mines goes away.
-
- Difficult - Only one gold mine near player's starting base. Increased frequency
- and severity of naval attacks.
-
- Nightmare - Only one gold mine near player's starting base, and it changes to
- a tiny one. Very few trees.around player's base. Purple (allied) town has only
- a town center. Large and painful naval attacks, including Leviathans.
- */
- //==============================================================================
- // Need scn lib for some stuff here.
- include "scn lib.xs";
-
- // Variable for main base.
- int gMainBaseID=-1;
-
- //==============================================================================
- // Set Town Location
- //==============================================================================
- void setTownLocation(void)
- {
- //Look for the "Town Location" marker.
- kbSetTownLocation(kbGetBlockPosition("9976"));
- }
-
- //==============================================================================
- // miscStartup
- //==============================================================================
- void miscStartup(void)
- {
- // Difficulty Level check.
- int difflevel=-1;
- difflevel=aiGetWorldDifficulty();
-
- //Startup message(s).
- aiEcho("");
- aiEcho("");
- aiEcho("Scn18P2 AI Start, filename='"+cFilename+"'.");
- aiEcho("Difficulty Level="+difflevel+".");
- //Spit out the map size.
- aiEcho(" Map size is ("+kbGetMapXSize()+", "+kbGetMapZSize()+").");
- //Cheat like a bastard. Once only, though.
- kbLookAtAllUnitsOnMap();
- //Calculate some areas.
- kbAreaCalculate(1200.0);
- //Set our town location.
- setTownLocation();
- //Reset random seed
- aiRandSetSeed();
-
- //Set the base location.
- gMainBaseID=kbBaseGetMainID(cMyID);
-
- // Drop the AI attack response distance for this player to 5 meters, to simulate the surprise thing
- aiSetAttackResponseDistance(10.0);
- }
-
- //==============================================================================
- //==============================================================================
- // Attack stuff.
- //==============================================================================
- //==============================================================================
- //Shared variables.
- int numberAttacks=0;
- int attackPlayerID=-1;
-
- //TODO: Decide how to rep attack group size.
- int attackMinimumGroupSize=3;
- int attackMaximumGroupSize=5;
-
- //Attack 1 vars.
- int attackPlan1ID=-1;
-
- //Attack 2 vars.
- int attackPlan2ID=-1;
-
- // Defend plans.
- int defendPlan1ID=-1;
- int defendPlan2ID=-1;
-
- int shipDefendPlanID=-1;
-
- // Route and path vars
- int attackRoute1ID=-1;
- int attackPath1ID=-1;
- int attackRoute2ID=-1;
- int attackPath2ID=-1;
-
- // Saved plan IDs
- int maintainPlan1ID=-1;
- int maintainPlan2ID=-1;
-
- int maintainMyth1ID=-1;
- int maintainMyth2ID=-1;
-
- int maintainShip1ID=-1;
- int maintainShip2ID=-1;
-
- int maintainMythSeaID=-1;
-
- int maintainPlanVillagerID=-1;
-
- int exploreID=-1;
-
- int attackerUnitTypeID1=cUnitTypeSpearman;
- int attackerUnitTypeID2=cUnitTypeChariotArcher;
-
- int attackerShipTypeID1=cUnitTypeSiegeShipEgyptian;
- int attackerShipTypeID2=cUnitTypeRammingShipEgyptian;
-
- int attackerMythSeaTypeID=cUnitTypeLeviathan;
-
- int mythUnitTypeID1=cUnitTypeWadjet;
- int mythUnitTypeID2=cUnitTypeScorpionMan;
-
- // Initial gather percentages
- float totalFoodGathererPercentage = 0.3;
- float totalWoodGathererPercentage = 0.3;
- float totalGoldGathererPercentage = 0.4;
- float totalFavorGathererPercentage = 0.0;
-
- //==============================================================================
- // initMainBase - Mike's spiffy function to relocate the main base.
- //==============================================================================
- void initMainBase()
- {
- vector basePosition=kbGetBlockPosition("9976");
-
- // Nuke bases, add one base to rule them all
- kbBaseDestroyAll(cMyID);
-
- gMainBaseID = kbBaseCreate(cMyID, "Base "+kbBaseGetNextID(), basePosition, 50.0);
-
- if (gMainBaseID < 0)
- aiEcho("***** Main base creation failed. *****");
-
- vector baseFront=xsVectorNormalize(kbGetMapCenter()-basePosition); // Set front
- kbBaseSetFrontVector(cMyID, gMainBaseID, baseFront);
- kbBaseSetMaximumResourceDistance(cMyID, gMainBaseID, 50.0);
- kbBaseSetMain(cMyID, gMainBaseID, true); // Make this the main base
-
- // Add the buildings
- int buildingQuery = -1;
- int count = 0;
- buildingQuery = kbUnitQueryCreate("Building Query"); // All buildings in the base
- configQuery(buildingQuery, cUnitTypeBuilding, -1, cUnitStateAliveOrBuilding, cMyID, basePosition, false, 50.0);
- kbUnitQueryResetResults(buildingQuery);
- count = kbUnitQueryExecute(buildingQuery);
-
- int i = 0;
- int buildingID = -1;
- echoQuery(buildingID);
- for (i=0; < count)
- {
- buildingID = kbUnitQueryGetResult(buildingQuery, i);
- // Add it to the base
- kbBaseAddUnit( cMyID, gMainBaseID, buildingID );
- }
- }
-
- //==============================================================================
- // initEcon
- //
- // Set Up the initial Economy.
- //==============================================================================
- void initEcon()
- {
- aiEcho("Economy Init.");
-
- /* Don't need this for what we're doing here.
- // Set our update resource handler.
- aiSetUpdateResourceEventHandler("updateResourceHandler");
- */
-
- //-- Setup AI Cost weights.
- kbSetAICostWeight(cResourceFood, 1.5);
- kbSetAICostWeight(cResourceWood, 1.0);
- kbSetAICostWeight(cResourceGold, 1.5);
- kbSetAICostWeight(cResourceFavor, 10.0);
-
- //-- Dont auto gather favor
- //totalFavorGathererPercentage = 0;
-
- //-- Set initial gatherer percentages.
- aiSetResourceGathererPercentage(cResourceFood, totalFoodGathererPercentage, false, cRGPScript);
- aiSetResourceGathererPercentage(cResourceWood, totalWoodGathererPercentage, false, cRGPScript);
- aiSetResourceGathererPercentage(cResourceGold, totalGoldGathererPercentage, false, cRGPScript);
- aiSetResourceGathererPercentage(cResourceFavor, totalFavorGathererPercentage, false, cRGPScript);
- aiNormalizeResourceGathererPercentages(cRGPScript);
-
- aiSetResourceGathererPercentageWeight(cRGPScript, 1);
- aiSetResourceGathererPercentageWeight(cRGPCost, 0);
-
- //-- Set up the initial resource subtype breakdowns - all farming, all the time.
- // aiSetResourceBreakdown(cResourceFood, cAIResourceSubTypeEasy, 1, 50, 0.0, gMainBaseID);
- // aiSetResourceBreakdown(cResourceFood, cAIResourceSubTypeHunt, 1, 50, 0.1, gMainBaseID);
- aiSetResourceBreakdown(cResourceFood, cAIResourceSubTypeFarm, 1, 50, 1.0, gMainBaseID);
- // aiSetResourceBreakdown(cResourceFood, cAIResourceSubTypeFish, 1, 50, 1.0, gMainBaseID);
- aiSetResourceBreakdown(cResourceWood, cAIResourceSubTypeEasy, 1, 50, 1.0, gMainBaseID);
- aiSetResourceBreakdown(cResourceGold, cAIResourceSubTypeEasy, 1, 50, 1.0, gMainBaseID);
- aiSetResourceBreakdown(cResourceFavor, cAIResourceSubTypeEasy, 1, 50, 1.0, gMainBaseID);
-
- //-- Set up auto-gather escrows
- aiSetAutoGatherEscrowID(cRootEscrowID);
- aiSetAutoFarmEscrowID(cRootEscrowID);
-
- //Allocate all resources to the root escrow by setting percentage of military/economy to 0.
- kbEscrowSetPercentage( cEconomyEscrowID, cAllResources, 0.0 );
- kbEscrowSetPercentage( cMilitaryEscrowID, cAllResources, 0.0 );
-
- //-- create a herd plan to gather any herdables that we encounter.
- int herdPlanID=aiPlanCreate("HerdThings", cPlanHerd);
- if (herdPlanID >= 0)
- {
- aiPlanAddUnitType(herdPlanID, cUnitTypeHerdable, 0, 100, 100);
- aiPlanSetVariableInt(herdPlanID, cHerdPlanBuildingTypeID, 0, cUnitTypeSettlementLevel1);
- aiPlanSetActive(herdPlanID);
- }
-
- //Allocate all resources
- kbEscrowAllocateCurrentResources();
-
- // Don't gather too far away from the main base.
- // kbBaseSetMaximumResourceDistance( 2, gMainBaseID, 50.0 );
- }
-
- //==============================================================================
- // initAttack: Creates attack routes, etc.
- //==============================================================================
- void initAttack(int playerID=-1)
- {
- //Destroy all previous attacks (if this isn't the player we're already attacking.
- if (playerID != attackPlayerID)
- {
- //Reset the attack player ID.
- attackPlayerID=-1;
- //Destroy any previous attack plan.
- aiPlanDestroy(attackPlan1ID);
- attackPlan1ID=-1;
- aiPlanDestroy(attackPlan2ID);
- attackPlan2ID=-1;
-
- //Destroy our previous attack paths.
- kbPathDestroy(attackPath1ID);
- attackPath1ID=-1;
- kbPathDestroy(attackPath2ID);
- attackPath2ID=-1;
-
- //Destroy our previous attack routes.
- attackRoute1ID=-1;
- attackRoute2ID=-1;
-
- //Reset the number of attacks.
- numberAttacks=0;
- }
-
- //Save the player to attack.
- attackPlayerID=playerID;
-
- vector gatherPoint=kbGetBlockPosition("6451");
- vector waterGatherPoint=kbGetBlockPosition("9971");
-
- /*
- //Setup attack path 1
- attackPath1ID=kbPathCreate("Attack Path Land");
- // kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("6456"));
- kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("6457"));
-
- //Create attack route 1.
- attackRoute1ID=kbCreateAttackRouteWithPath("Attack Route 1", gatherPoint, kbGetBlockPosition("6458"));
-
- if (attackRoute1ID >= 0)
- kbAttackRouteAddPath(attackRoute1ID, attackPath1ID);
- */
-
- //Setup attack path 2 - water attack
- attackPath2ID=kbPathCreate("Attack Path Water");
-
- kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("9972"));
- kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("9973"));
-
- //Create attack route 2.
- attackRoute2ID=kbCreateAttackRouteWithPath("Attack Route 2", waterGatherPoint, kbGetBlockPosition("9974"));
-
- if (attackRoute2ID >= 0)
- kbAttackRouteAddPath(attackRoute2ID, attackPath2ID);
- }
-
- //==============================================================================
- // setupAttack
- //==============================================================================
- bool setupLandAttack(int playerID=-1)
- {
- // int randomPath=aiRandInt(2);
-
- //Info.
- aiEcho("Attacking Player "+playerID+".");
-
- //If the player to attack doesn't match, init the attack.
- if (attackPlayerID != playerID)
- {
- initAttack(playerID);
- if (attackPlayerID < 0)
- return(false);
- }
-
- //Create an attack plan.
- int newAttackPlanID=aiPlanCreate("Attack Player"+attackPlayerID+" Attempt"+numberAttacks, cPlanAttack);
- if (newAttackPlanID < 0)
- return(false);
-
- //Target player (required). This must work.
- if (aiPlanSetVariableInt(newAttackPlanID, cAttackPlanPlayerID, 0, attackPlayerID) == false)
- return(false);
-
- //Gather point.
- vector gatherPoint=kbGetBlockPosition("6451");
-
- //Set the target type. This must work.
- if (aiPlanSetNumberVariableValues(newAttackPlanID, cAttackPlanTargetTypeID, 2, true) == false)
- return(false);
-
- aiPlanSetNumberVariableValues(newAttackPlanID, cAttackPlanTargetTypeID, 2, true);
-
- //Unit types to attack.
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanTargetTypeID, 0, cUnitTypeUnit);
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanTargetTypeID, 1, cUnitTypeBuilding);
-
- // aiPlanSetVariableInt(newAttackPlanID, cAttackPlanAttackRouteID, 0, attackRoute1ID);
-
- //Set the gather point and gather point distance.
- aiPlanSetVariableVector(newAttackPlanID, cAttackPlanGatherPoint, 0, gatherPoint);
- aiPlanSetVariableFloat(newAttackPlanID, cAttackPlanGatherDistance, 0, 30.0);
-
- //Set up the attack route usage pattern.
- // aiPlanSetVariableInt(newAttackPlanID, cAttackPlanAttackRoutePattern, 0, cAttackPlanAttackRoutePatternRandom);
-
- //Add the unit types to the plan, as long as there's enough axemen.
- aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID1, 6, 12, 12);
- aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID2, 0, 6, 6);
- aiPlanAddUnitType(newAttackPlanID, mythUnitTypeID1, 0, 4, 4);
- aiPlanAddUnitType(newAttackPlanID, mythUnitTypeID2, 0, 3, 3);
-
- //Set the initial position.
- aiPlanSetInitialPosition(newAttackPlanID, gatherPoint);
-
- //Plan requires all need units to work (can be false).
- aiPlanSetRequiresAllNeedUnits(newAttackPlanID, true);
- //Activate the plan.
- aiPlanSetActive(newAttackPlanID);
-
- //Now, save the attack plan ID appropriately.
- aiPlanSetOrphan(attackPlan1ID, true);
- attackPlan1ID=newAttackPlanID;
-
- //Increment our overall number of attacks.
- numberAttacks++;
- }
-
- //==============================================================================
- // setupWaterAttack
- //==============================================================================
- bool setupWaterAttack(int playerID=-1)
- {
- // int randomPath=aiRandInt(2);
- int difflevel=-1;
- difflevel=aiGetWorldDifficulty();
-
- //Info.
- aiEcho("Attacking Player "+playerID+".");
-
- //If the player to attack doesn't match, init the attack.
- if (attackPlayerID != playerID)
- {
- initAttack(playerID);
- if (attackPlayerID < 0)
- return(false);
- }
-
- //Create an attack plan.
- int newAttackPlanID=aiPlanCreate("Attack Player"+attackPlayerID+" Attempt"+numberAttacks, cPlanAttack);
- if (newAttackPlanID < 0)
- return(false);
-
- //Target player (required). This must work.
- if (aiPlanSetVariableInt(newAttackPlanID, cAttackPlanPlayerID, 0, attackPlayerID) == false)
- return(false);
-
- //Gather point.
- vector gatherPoint=kbGetBlockPosition("3081");
-
- //Set the target type. This must work.
- if (aiPlanSetNumberVariableValues(newAttackPlanID, cAttackPlanTargetTypeID, 2, true) == false)
- return(false);
-
- aiPlanSetNumberVariableValues(newAttackPlanID, cAttackPlanTargetTypeID, 2, true);
-
- //Unit types to attack.
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanTargetTypeID, 0, cUnitTypeBuilding);
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanTargetTypeID, 1, cUnitTypeUnit);
-
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanAttackRouteID, 0, attackRoute2ID);
-
- //Set the gather point and gather point distance.
- aiPlanSetVariableVector(newAttackPlanID, cAttackPlanGatherPoint, 0, gatherPoint);
- aiPlanSetVariableFloat(newAttackPlanID, cAttackPlanGatherDistance, 0, 30.0);
-
- //Set up the attack route usage pattern.
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanAttackRoutePattern, 0, cAttackPlanAttackRoutePatternRandom);
-
- //Add the unit types to the plan
- aiPlanAddUnitType(newAttackPlanID, attackerShipTypeID1, 2, 2, 6);
-
- // On Titan, add Leviathans to the attack.
- if ( difflevel == 3 )
- {
- aiPlanAddUnitType(newAttackPlanID, attackerMythSeaTypeID, 1, 2, 2);
- }
-
- //Set the initial position.
- aiPlanSetInitialPosition(newAttackPlanID, gatherPoint);
- //Plan requires all need units to work (can be false).
- aiPlanSetRequiresAllNeedUnits(newAttackPlanID, true);
- //Activate the plan.
- aiPlanSetActive(newAttackPlanID);
-
- //Now, save the attack plan ID appropriately.
- aiPlanSetOrphan(attackPlan1ID, true);
- attackPlan2ID=newAttackPlanID;
-
- //Increment our overall number of attacks.
- numberAttacks++;
- }
-
- //==============================================================================
- // createUnitProgression
- //==============================================================================
- int createUnitProgression(int unitTypeID=-1, string name="BUG")
- {
- int pID=aiPlanCreate(name, cPlanProgression);
-
- if (pID < 0)
- return(-1);
-
- //This is a military plan.
- //aiPlanSetMilitary(pID, true);
- //Set it for the building that we get our unit from.
- aiPlanSetVariableInt(pID, cProgressionPlanGoalUnitID, 0, kbTechTreeGetUnitIDByTrain(unitTypeID));
-
- //Build it in our main base using the root escrow.
- aiPlanSetBaseID(pID, gMainBaseID);
- aiPlanSetEscrowID(pID, cRootEscrowID);
-
- //Go.
- aiPlanSetActive(pID);
- return(pID);
- }
-
- //==============================================================================
- // createTechProgression
- //==============================================================================
- int createTechProgression(int techID=-1, string name="BUG", int researchFromProto=-1)
- {
- //Check for old plan.
- int oldPlanID=aiPlanGetIDByTypeAndVariableType(cPlanProgression, cProgressionPlanGoalTechID, techID);
- if(oldPlanID != -1)
- {
- aiEcho("createTechProgression: already have a plan("+oldPlanID+") for this Tech("+techID+").");
- return(oldPlanID);
- }
-
- //Create a new one.
- int pID=aiPlanCreate(name, cPlanProgression);
- if (pID < 0)
- {
- aiEcho("createTechProgression: couldn't create Progression.");
- return(-1);
- }
- //This is a military plan.
- //aiPlanSetMilitary(pID, true);
- aiPlanSetVariableInt(pID, cProgressionPlanGoalTechID, 0, techID);
- aiPlanSetVariableInt(pID, cProgressionPlanBuildingPref, 0, researchFromProto);
-
- //Build it in our main base using the root escrow.
- aiPlanSetBaseID(pID, gMainBaseID);
- aiPlanSetEscrowID(pID, cRootEscrowID);
-
- //Go.
- aiPlanSetActive(pID);
- aiEcho("createTechProgression: creating Tech Progression("+name+") to TechID("+techID+").");
- return(pID);
- }
-
- //==============================================================================
- // Queryin' for enemies landing in the logical spots
- //==============================================================================
- int checkForEnemiesLeft(void)
- {
- static int enemyQueryID=-1;
- vector leftSide=kbGetBlockPosition("9967");
- int enemyCount=-1;
-
- if (enemyQueryID < 0)
- {
- // Doesn't exist, set it up
- enemyQueryID = kbUnitQueryCreate("Enemy Query 1");
-
- // Get the number
- if ( configQuery( enemyQueryID, cUnitTypeMilitary, -1, cUnitStateAlive, 1, leftSide, false, 20 ) == false )
- return(-1);
- }
-
- kbUnitQueryResetResults(enemyQueryID);
- enemyCount = kbUnitQueryExecute(enemyQueryID);
- return(enemyCount);
- }
-
- int checkForEnemiesRight(void)
- {
- static int enemyQueryID=-1;
- vector rightSide=kbGetBlockPosition("9969");
- int enemyCount=-1;
-
- if (enemyQueryID < 0)
- {
- // Doesn't exist, set it up
- enemyQueryID = kbUnitQueryCreate("Enemy Query 2");
-
- // Get the number
- if ( configQuery( enemyQueryID, cUnitTypeMilitary, -1, cUnitStateAlive, 1, rightSide, false, 20 ) == false )
- return(-1);
- }
-
- kbUnitQueryResetResults(enemyQueryID);
- enemyCount = kbUnitQueryExecute(enemyQueryID);
- return(enemyCount);
- }
-
- //==============================================================================
- // Attack Generator Land - Send dudes now! Or, well, soon,
- //==============================================================================
- rule attackGeneratorLand
- minInterval 90
- inactive
- group AttackRules
- {
- //See how many "idle" attack plans we have. Don't create any more if we have
- //idle plans.
- int numberIdleAttackPlans=aiGetNumberIdlePlans(cPlanAttack);
-
- if (numberIdleAttackPlans > 0)
- return;
-
- //If we have enough unassigned military units, create a new attack plan.
- int numberAvailableUnits=aiNumberUnassignedUnits(attackerUnitTypeID1);
- aiEcho("There are "+numberAvailableUnits+" spearmen available for a new attack.");
-
- if (numberAvailableUnits >= 6)
- setupLandAttack(1);
- }
-
- //==============================================================================
- // Attack Generator Boat - Send siege ships when you have them.
- //==============================================================================
- rule attackGeneratorBoat
- minInterval 90
- inactive
- group AttackRules
- {
- int difflevel=-1;
- difflevel=aiGetWorldDifficulty();
-
- //See how many "idle" attack plans we have. Don't create any more if we have
- //idle plans.
- int numberIdleAttackPlans=aiGetNumberIdlePlans(cPlanAttack);
-
- if (numberIdleAttackPlans > 0)
- return;
-
- //If we have enough unassigned military units, create a new attack plan.
- int numberAvailableUnits=aiNumberUnassignedUnits(attackerShipTypeID1);
- aiEcho("There are "+numberAvailableUnits+" siege ships available for a new attack.");
-
-
- if ( difflevel < 2 )
- {
- if (numberAvailableUnits >= 2)
- setupWaterAttack(1);
- }
- else
- {
- if (numberAvailableUnits >= 4)
- setupWaterAttack(1);
- }
- }
-
- //==============================================================================
- // Maintain Myth Units, starting four minutes after being alerted.
- //==============================================================================
- rule maintainMythUnits
- minInterval 240
- inactive
- {
- vector gatherPointWadjet=kbGetBlockPosition("6649");
- vector gatherPointScorpionMan=kbGetBlockPosition("10038");
-
- // Lots more villagers maintained now.
- aiPlanSetVariableInt(maintainPlanVillagerID, cTrainPlanNumberToMaintain, 0, 20);
-
- // Maintain the two myth units. These will be added to attacks.
- maintainMyth1ID=aiPlanCreate("Maintain "+kbGetProtoUnitName(mythUnitTypeID1), cPlanTrain);
- if (maintainMyth1ID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainMyth1ID, cTrainPlanUnitType, 0, mythUnitTypeID1);
- //You can limit the number of units that are ever trained by this plan with this call.
- //aiPlanSetVariableInt(maintainPlanID, cTrainPlanNumberToTrain, 0, 25);
- //Set the number of units to maintain in the world at one time.
- aiPlanSetVariableInt(maintainMyth1ID, cTrainPlanNumberToMaintain, 0, 4);
- //Don't train units too fast
- aiPlanSetVariableInt(maintainMyth1ID, cTrainPlanFrequency, 0, 90);
- //Set a gather point.
- aiPlanSetVariableVector(maintainMyth1ID, cTrainPlanGatherPoint, 0, gatherPointWadjet);
- //Activate the plan.
- aiPlanSetActive(maintainMyth1ID);
- }
-
- maintainMyth2ID=aiPlanCreate("Maintain "+kbGetProtoUnitName(mythUnitTypeID2), cPlanTrain);
- if (maintainMyth2ID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainMyth2ID, cTrainPlanUnitType, 0, mythUnitTypeID2);
- //You can limit the number of units that are ever trained by this plan with this call.
- //aiPlanSetVariableInt(maintainPlanID, cTrainPlanNumberToTrain, 0, 25);
- //Set the number of units to maintain in the world at one time.
- aiPlanSetVariableInt(maintainMyth2ID, cTrainPlanNumberToMaintain, 0, 3);
- //Don't train units too fast
- aiPlanSetVariableInt(maintainMyth2ID, cTrainPlanFrequency, 0, 120);
- //Set a gather point.
- aiPlanSetVariableVector(maintainMyth2ID, cTrainPlanGatherPoint, 0, gatherPointScorpionMan);
- //Activate the plan.
- aiPlanSetActive(maintainMyth2ID);
- }
- xsDisableSelf();
- }
-
- //==================================================================================
- // More ramming boats, fifteen minutes after being alerted (except on Easy/Moderate)
- //==================================================================================
- rule moreBoats
- minInterval 900
- inactive
- {
- int difflevel=-1;
- difflevel=aiGetWorldDifficulty();
-
- if ( difflevel > 1 )
- {
- aiPlanSetVariableInt(maintainShip2ID, cTrainPlanNumberToMaintain, 0, 4);
- }
- xsDisableSelf();
- }
-
- //==============================================================================
- // Rules to check for enemies landing on the peninsulae left and right
- //==============================================================================
- rule enemiesLandLeft
- minInterval 10
- active
- {
- int difflevel=-1;
- difflevel=aiGetWorldDifficulty();
-
- int numEnemies=-1;
- numEnemies=checkForEnemiesLeft();
-
- if (numEnemies > 2)
- {
- aiEcho("*** P2: ENEMY HAS LANDED ON THE LEFT ***");
- xsEnableRule("attackGeneratorLand");
- xsDisableRule("enemiesLandRight");
-
- // Destroy the defend plans
- aiPlanDestroy( defendPlan1ID );
- aiPlanDestroy( defendPlan2ID );
-
- // Cheat a little. Okay, a lot. Different on lower levels.
- if ( difflevel < 2 )
- {
- aiResourceCheat( 2, cResourceFood, 100.0 );
- aiResourceCheat( 2, cResourceWood, 400.0 );
- aiResourceCheat( 2, cResourceGold, 250.0 );
- aiResourceCheat( 2, cResourceFavor, 10.0 );
- }
- else
- {
- aiResourceCheat( 2, cResourceFood, 200.0 );
- aiResourceCheat( 2, cResourceWood, 600.0 );
- aiResourceCheat( 2, cResourceGold, 500.0 );
- aiResourceCheat( 2, cResourceFavor, 20.0 );
- }
- xsDisableSelf();
- }
- }
-
- rule enemiesLandRight
- minInterval 10
- active
- {
- int difflevel=-1;
- difflevel=aiGetWorldDifficulty();
-
- int numEnemies=-1;
- numEnemies=checkForEnemiesRight();
-
- if (numEnemies > 2)
- {
- aiEcho("*** P2: ENEMY HAS LANDED ON THE RIGHT ***");
- xsEnableRule("attackGeneratorLand");
- xsDisableRule("enemiesLandLeft");
-
- // Destroy the defend plans.
- aiPlanDestroy( defendPlan1ID );
- aiPlanDestroy( defendPlan2ID );
-
- // Cheat a little. Okay, a lot. Different on lower levels.
- if ( difflevel < 2 )
- {
- aiResourceCheat( 2, cResourceFood, 100.0 );
- aiResourceCheat( 2, cResourceWood, 400.0 );
- aiResourceCheat( 2, cResourceGold, 250.0 );
- aiResourceCheat( 2, cResourceFavor, 10.0 );
- }
- else
- {
- aiResourceCheat( 2, cResourceFood, 200.0 );
- aiResourceCheat( 2, cResourceWood, 600.0 );
- aiResourceCheat( 2, cResourceGold, 500.0 );
- aiResourceCheat( 2, cResourceFavor, 20.0 );
- }
- xsDisableSelf();
- }
- }
-
- //==============================================================================
- // armoryUpgrades, oh yeah! Six minutes after AI is alerted, if it's still got
- // an armory. And if it doesn't, it should rebuild one, even!
- //==============================================================================
- /*
- rule armoryUpgrades
- minInterval 360
- inactive
- {
- aiEcho("*** GETTING ARMORY UPGRADES ***");
- createTechProgression(cTechBronzeWeapons, "Research Bronze Weapons", cUnitTypeArmory);
- createTechProgression(cTechBronzeMail, "Research Bronze Mail", cUnitTypeArmory);
- createTechProgression(cTechCopperShields, "Research Copper Shields", cUnitTypeArmory);
-
- xsDisableSelf();
- }
- */
-
- //==============================================================================
- // cheatResources - for Titan level only.
- //==============================================================================
- rule cheatResources
- minInterval 60
- inactive
- group TitanRules
- {
- // Cheat for favor and gold, to keep the Leviathans rolling.
- aiResourceCheat( 2, cResourceFavor, 25.0 );
- aiResourceCheat( 2, cResourceGold, 250.0 );
- }
-
- //==============================================================================
- // playerLands - fires when the player initially lands.
- //==============================================================================
- void playerLands( int parameter=-1 )
- {
- int difflevel=-1;
- difflevel=aiGetWorldDifficulty();
-
- aiEcho("*** P2 Attacks now Possible ***");
-
- // Maintain ships.
- vector gatherPointShip1=kbGetBlockPosition("9971");
- vector gatherPointShip2=kbGetBlockPosition("9975");
- vector defendPlanSpot=kbGetBlockPosition("9968");
-
- // Cheat and have some wood
- aiResourceCheat( 2, cResourceWood, 750.0 );
-
- // Defend plan on each peninsula.
- defendPlan1ID=aiPlanCreate("West Defense", cPlanDefend);
- if (defendPlan1ID >= 0)
- {
- //Main gate location
- defendPlanSpot=kbGetBlockPosition("9968");
-
- //Add the unit(s).
- aiPlanAddUnitType(defendPlan1ID, attackerUnitTypeID1, 0, 4, 4);
- aiPlanAddUnitType(defendPlan1ID, attackerUnitTypeID2, 0, 3, 3);
-
- //Setup the vars - priority is slightly higher than the attack plans.
- aiPlanSetDesiredPriority(defendPlan1ID, 60);
- aiPlanSetVariableVector(defendPlan1ID, cDefendPlanDefendPoint, 0, defendPlanSpot);
- aiPlanSetVariableFloat(defendPlan1ID, cDefendPlanEngageRange, 0, 25);
- aiPlanSetActive(defendPlan1ID);
- }
-
- // Defend plan on each peninsula.
- defendPlan2ID=aiPlanCreate("West Defense", cPlanDefend);
- if (defendPlan2ID >= 0)
- {
- //Main gate location
- defendPlanSpot=kbGetBlockPosition("9969");
-
- //Add the unit(s).
- aiPlanAddUnitType(defendPlan2ID, attackerUnitTypeID1, 0, 4, 4);
- aiPlanAddUnitType(defendPlan2ID, attackerUnitTypeID2, 0, 3, 3);
-
- //Setup the vars - priority is slightly higher than the attack plans.
- aiPlanSetDesiredPriority(defendPlan2ID, 60);
- aiPlanSetVariableVector(defendPlan2ID, cDefendPlanDefendPoint, 0, defendPlanSpot);
- aiPlanSetVariableFloat(defendPlan2ID, cDefendPlanEngageRange, 0, 15);
- aiPlanSetActive(defendPlan2ID);
- }
-
- // Defend plan on each peninsula.
- shipDefendPlanID=aiPlanCreate("Ship Defense", cPlanDefend);
- if (shipDefendPlanID >= 0)
- {
- //Main gate location
- defendPlanSpot=kbGetBlockPosition("9972");
-
- //Add the unit(s).
- aiPlanAddUnitType(shipDefendPlanID, attackerShipTypeID2, 0, 4, 4);
-
- //Setup the vars - priority is slightly higher than the attack plans.
- aiPlanSetDesiredPriority(shipDefendPlanID, 60);
- aiPlanSetVariableVector(shipDefendPlanID, cDefendPlanDefendPoint, 0, defendPlanSpot);
- aiPlanSetVariableFloat(shipDefendPlanID, cDefendPlanEngageRange, 0, 20);
- aiPlanSetActive(shipDefendPlanID);
- }
-
- maintainShip1ID=aiPlanCreate("Maintain "+kbGetProtoUnitName(attackerShipTypeID1), cPlanTrain);
- if (maintainShip1ID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainShip1ID, cTrainPlanUnitType, 0, attackerShipTypeID1);
- //You can limit the number of units that are ever trained by this plan with this call.
- //aiPlanSetVariableInt(maintainPlanID, cTrainPlanNumberToTrain, 0, 25);
-
- //Set the number of units to maintain in the world at one time (based on difficulty)
- if ( difflevel < 2 )
- {
- aiPlanSetVariableInt(maintainShip1ID, cTrainPlanNumberToMaintain, 0, 2);
- }
- else if ( difflevel == 2 )
- {
- aiPlanSetVariableInt(maintainShip1ID, cTrainPlanNumberToMaintain, 0, 5);
- aiResourceCheat( 2, cResourceWood, 400.0 );
- aiResourceCheat( 2, cResourceGold, 400.0 );
- }
- else
- {
- aiPlanSetVariableInt(maintainShip1ID, cTrainPlanNumberToMaintain, 0, 6);
- aiResourceCheat( 2, cResourceWood, 600.0 );
- aiResourceCheat( 2, cResourceGold, 600.0 );
- }
-
- //Don't train units too fast
- if ( difflevel < 2 )
- {
- aiPlanSetVariableInt(maintainShip1ID, cTrainPlanFrequency, 0, 120);
- }
- else
- {
- aiPlanSetVariableInt(maintainShip1ID, cTrainPlanFrequency, 0, 50);
- }
-
- //Set a gather point.
- aiPlanSetVariableVector(maintainShip1ID, cTrainPlanGatherPoint, 0, gatherPointShip1);
- //Activate the plan.
- aiPlanSetActive(maintainShip1ID);
- }
-
- maintainShip2ID=aiPlanCreate("Maintain "+kbGetProtoUnitName(attackerShipTypeID2), cPlanTrain);
- if (maintainShip2ID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainShip2ID, cTrainPlanUnitType, 0, attackerShipTypeID2);
- //You can limit the number of units that are ever trained by this plan with this call.
- //aiPlanSetVariableInt(maintainPlanID, cTrainPlanNumberToTrain, 0, 25);
- //Set the number of units to maintain in the world at one time.
- aiPlanSetVariableInt(maintainShip2ID, cTrainPlanNumberToMaintain, 0, 2);
- //Don't train units too fast
- aiPlanSetVariableInt(maintainShip2ID, cTrainPlanFrequency, 0, 105);
- //Set a gather point.
- aiPlanSetVariableVector(maintainShip2ID, cTrainPlanGatherPoint, 0, gatherPointShip2);
- //Activate the plan.
- aiPlanSetActive(maintainShip2ID);
- }
-
- // Enable attacks and activate some other long-term rules
- xsEnableRule("attackGeneratorBoat");
- xsEnableRule("maintainMythUnits");
- xsEnableRule("moreBoats");
-
- // xsEnableRule("armoryUpgrades");
-
- // Mmm, unit upgrades. Let's go!
- // createTechProgression(cTechHeavySpearmen, "Research up to Heavy Spearmen", cUnitTypeBarracks);
- // createTechProgression(cTechHeavySlingers, "Research up to Medium Slingers", cUnitTypeBarracks);
-
- // Attack response range increases to 40.
- aiSetAttackResponseDistance(40.0);
- }
-
- //==============================================================================
- // MAIN.
- //==============================================================================
- void main(void)
- {
- int difflevel=-1;
- difflevel=aiGetWorldDifficulty();
-
- //Startup.
- miscStartup();
- initMainBase();
- initEcon();
-
- //Gather Points
- vector gatherPointVillager=kbGetBlockPosition("9976");
- vector gatherPointMilitary1=kbGetBlockPosition("9966");
- vector gatherPointMilitary2=kbGetBlockPosition("10033");
-
- vector gatherPointLeviathan=kbGetBlockPosition("9975");
-
- maintainPlanVillagerID=aiPlanCreate("Maintain Villagers", cPlanTrain);
- if (maintainPlanVillagerID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainPlanVillagerID, cTrainPlanUnitType, 0, cUnitTypeVillagerEgyptian);
- //You can limit the number of units that are ever trained by this plan with this call.
- //aiPlanSetVariableInt(maintainPlanID, cTrainPlanNumberToTrain, 0, 25);
- //Set the number of units to maintain in the world at one time.
- aiPlanSetVariableInt(maintainPlanVillagerID, cTrainPlanNumberToMaintain, 0, 10);
- //Don't train units faster than every 20 seconds
- aiPlanSetVariableInt(maintainPlanVillagerID, cTrainPlanFrequency, 0, 15);
- //Set a gather point.
- aiPlanSetVariableVector(maintainPlanVillagerID, cTrainPlanGatherPoint, 0, gatherPointVillager);
- //Activate the plan.
- aiPlanSetActive(maintainPlanVillagerID);
- }
-
- maintainPlan1ID=aiPlanCreate("Maintain "+kbGetProtoUnitName(attackerUnitTypeID1), cPlanTrain);
- if (maintainPlan1ID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanUnitType, 0, attackerUnitTypeID1);
- //You can limit the number of units that are ever trained by this plan with this call.
- //aiPlanSetVariableInt(maintainPlanID, cTrainPlanNumberToTrain, 0, 25);
- //Set the number of units to maintain in the world at one time.
- aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanNumberToMaintain, 0, 6);
- //Don't train units too fast
- aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanFrequency, 0, 30);
- //Set a gather point.
- aiPlanSetVariableVector(maintainPlan1ID, cTrainPlanGatherPoint, 0, gatherPointMilitary1);
- //Activate the plan.
- aiPlanSetActive(maintainPlan1ID);
- }
-
- maintainPlan2ID=aiPlanCreate("Maintain "+kbGetProtoUnitName(attackerUnitTypeID2), cPlanTrain);
- if (maintainPlan2ID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanUnitType, 0, attackerUnitTypeID2);
- //You can limit the number of units that are ever trained by this plan with this call.
- //aiPlanSetVariableInt(maintainPlanID, cTrainPlanNumberToTrain, 0, 25);
- //Set the number of units to maintain in the world at one time.
- aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanNumberToMaintain, 0, 6);
-
- //Don't train units too fast
- aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanFrequency, 0, 45);
- //Set a gather point.
- aiPlanSetVariableVector(maintainPlan2ID, cTrainPlanGatherPoint, 0, gatherPointMilitary2);
- //Activate the plan.
- aiPlanSetActive(maintainPlan2ID);
- }
-
- if ( difflevel == 3 )
- {
- maintainMythSeaID=aiPlanCreate("Maintain "+kbGetProtoUnitName(attackerMythSeaTypeID), cPlanTrain);
- if (maintainMythSeaID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainMythSeaID, cTrainPlanUnitType, 0, attackerMythSeaTypeID);
- //You can limit the number of units that are ever trained by this plan with this call.
- //aiPlanSetVariableInt(maintainPlanID, cTrainPlanNumberToTrain, 0, 25);
- //Set the number of units to maintain in the world at one time.
- aiPlanSetVariableInt(maintainMythSeaID, cTrainPlanNumberToMaintain, 0, 2);
- //Don't train units too fast
- aiPlanSetVariableInt(maintainMythSeaID, cTrainPlanFrequency, 0, 55);
- //Set a gather point.
- aiPlanSetVariableVector(maintainMythSeaID, cTrainPlanGatherPoint, 0, gatherPointLeviathan);
- //Activate the plan.
- aiPlanSetActive(maintainMythSeaID);
- }
- xsEnableRule("cheatResources");
- }
-
- // Create a fishing plan.
- int fishGatherer = kbTechTreeGetUnitIDTypeByFunctionIndex(cUnitFunctionFish, 0);
- int fishPlanID=aiPlanCreate("FishPlan", cPlanFish);
-
- if (fishPlanID >= 0)
- {
- aiEcho("Setting up the Fishing Plan.");
- aiPlanSetDesiredPriority(fishPlanID, 70);
- aiPlanSetVariableVector(fishPlanID, cFishPlanLandPoint, 0, kbBaseGetLocation(cMyID, gMainBaseID));
-
- //-- If you don't explicitly set the water point, the plan will find one for you.
- aiPlanSetVariableBool(fishPlanID, cFishPlanAutoTrainBoats, 0, false); // I'm going to have a maintain plan for fishing + scouting combined
- aiPlanSetEscrowID(fishPlanID, cRootEscrowID);
-
- aiPlanAddUnitType(fishPlanID, fishGatherer, 3, 3, 3);
- aiPlanSetActive(fishPlanID);
- }
-
- // Empower a Wood Choppery with Mr. Pharoah
- int empowerPlan1ID=aiPlanCreate("EmpowerPlan", cPlanEmpower);
- if (empowerPlan1ID >= 0)
- {
- aiPlanSetDesiredPriority(empowerPlan1ID, 50);
- aiPlanAddUnitType(empowerPlan1ID, cUnitTypePharaoh, 1, 1, 1);
- aiPlanSetVariableInt(empowerPlan1ID, cEmpowerPlanTargetTypeID, 0, cUnitTypeLumberCamp);
- aiPlanSetActive(empowerPlan1ID);
- }
-
- // Basic tech progressions to upgrade our operations (better gold mining, wood chopping, and farms)
- createTechProgression(cTechShaftMine, "Research up to Shaft Mine", cUnitTypeMiningCamp);
- createTechProgression(cTechIrrigation, "Research up to Irrigation", cUnitTypeGranary);
- createTechProgression(cTechBowSaw, "Research up to Bow Saw", cUnitTypeLumberCamp);
- }