home *** CD-ROM | disk | FTP | other *** search
- //==============================================================================
- // Scn22p2: AI Scenario Script for scenario 22 player 2 (revised)
- //==============================================================================
- /*
- AI owner: Dave Leary
- Scenario owner: Joe "The Golem" Gillum
-
- Overview: Basic AI script for the enemy main town in 22.
-
- *** DIFFICULTY LEVEL NOTES ***
-
- Note that most of the difficulty here is handled via trigger - the timing of
- the AI's initial attacks after the player lands is the primary difficulty
- level adjustment for this scenario.
-
- Easy level - Smaller groups in general.
-
- Moderate level - Base level.
-
- Difficult - Larger groups. More towers.
-
- Nightmare - Lots more elephants and scarabs. More towers. Faster upgrades.
- Will go for heavy elephants (ow).
- */
- //==============================================================================
- // 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("1851"));
- }
-
- //==============================================================================
- // miscStartup
- //==============================================================================
- void miscStartup(void)
- {
- // Difficulty Level check.
- int difflevel=-1;
- difflevel=aiGetWorldDifficulty();
-
- //Startup message(s).
- aiEcho("");
- aiEcho("");
- aiEcho("Scn22P2 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(5.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;
-
- // 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 maintainPlan3ID=-1;
- int maintainPlan4ID=-1;
- int maintainPlanVillagerID=-1;
- int exploreID=-1;
-
- int attackerUnitTypeID1=cUnitTypeSpearman;
- int attackerUnitTypeID2=cUnitTypeSlinger;
- int attackerUnitTypeID3=cUnitTypeWarElephant;
- int attackerUnitTypeID4=cUnitTypeScarab;
-
- // Initial gather percentages
- float totalFoodGathererPercentage = 0.35;
- float totalWoodGathererPercentage = 0.25;
- float totalGoldGathererPercentage = 0.4;
- float totalFavorGathererPercentage = 0.0;
-
- //==============================================================================
- // initMainBase - Mike's spiffy function to relocate the main base.
- //==============================================================================
- void initMainBase()
- {
- vector basePosition=kbGetBlockPosition("3090");
-
- // 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, 55, 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 all herdables that we encounter.
- int herdPlanID=aiPlanCreate("HerdTest", cPlanHerd);
- if (herdPlanID >= 0)
- {
- aiPlanAddUnitType(herdPlanID, cUnitTypeHerdable, 0, 100, 100);
- aiPlanSetVariableInt(herdPlanID, cHerdPlanBuildingTypeID, 0, cUnitTypeSettlementLevel1);
- aiPlanSetActive(herdPlanID);
- }
-
- //Allocate all resources
- kbEscrowAllocateCurrentResources();
- }
-
- //==============================================================================
- // 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("3081");
-
- //Setup attack path 1 - go north
- attackPath1ID=kbPathCreate("Attack Path North");
- kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("3078"));
- kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("3079"));
- kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("3080"));
- kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("3073"));
-
- //Create attack route 1.
- attackRoute1ID=kbCreateAttackRouteWithPath("Attack Route 1", gatherPoint, kbGetBlockPosition("3075"));
-
- if (attackRoute1ID >= 0)
- kbAttackRouteAddPath(attackRoute1ID, attackPath1ID);
-
- //Setup attack path 2 - go south
- attackPath2ID=kbPathCreate("Attack Path South");
-
- kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("1851"));
- kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("1853"));
- kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("1849"));
- kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("3080"));
- kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("3073"));
-
- //Create attack route 2.
- attackRoute2ID=kbCreateAttackRouteWithPath("Attack Route 2", gatherPoint, kbGetBlockPosition("3075"));
-
- if (attackRoute2ID >= 0)
- kbAttackRouteAddPath(attackRoute2ID, attackPath2ID);
- }
-
- //==============================================================================
- // setupAttack
- //==============================================================================
- bool setupAttack(int playerID=-1)
- {
- // Difficulty Level check.
- int difflevel=-1;
- difflevel=aiGetWorldDifficulty();
-
- 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("3081");
-
- //Set the target type. This must work.
- if (aiPlanSetNumberVariableValues(newAttackPlanID, cAttackPlanTargetTypeID, 2, true) == false)
- return(false);
-
- //Unit types to attack.
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanTargetTypeID, 0, cUnitTypeUnit);
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanTargetTypeID, 1, cUnitTypeBuilding);
-
- //Attack route.
- if (randomPath == 0)
- {
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanAttackRouteID, 0, attackRoute1ID);
- }
- else
- {
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanAttackRouteID, 0, attackRoute2ID);
- }
-
- //Set the gather point and gather point distance.
- aiPlanSetVariableVector(newAttackPlanID, cAttackPlanGatherPoint, 0, gatherPoint);
- aiPlanSetVariableFloat(newAttackPlanID, cAttackPlanGatherDistance, 0, 20.0);
-
- //Set up the attack route usage pattern.
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanAttackRoutePattern, 0, cAttackPlanAttackRoutePatternRandom);
-
- //Add the unit types to the plan
- aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID1, 4, 4, 12);
- aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID2, 0, 4, 6);
-
- // Elephants if you got 'em
- aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID3, 0, 4, 8);
-
- // Scarabs! More on higher levels.
- if ( difflevel < 3 )
- {
- aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID4, 0, 2, 2);
- }
- else
- {
- aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID4, 0, 2, 4);
- }
-
- //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++;
- }
-
- //==============================================================================
- // 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);
- }
-
- //==============================================================================
- // Attack Generator 1 - Send dudes now! Or, well, soon,
- //==============================================================================
- rule attackGenerator1
- minInterval 90
- inactive
- group AttackRules
- {
- // Difficulty Level check.
- 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(attackerUnitTypeID1);
- aiEcho("There are "+numberAvailableUnits+" spearmen available for a new attack.");
-
- if ( difflevel < 2 )
- {
- if (numberAvailableUnits >= 4)
- setupAttack(1);
- }
- else
- {
- if (numberAvailableUnits >= 6)
- setupAttack(1);
- }
- }
-
-
- //==============================================================================
- // Maintain Scarabs, starting four minutes after being alerted.
- //==============================================================================
- rule maintainScarabs
- minInterval 240
- inactive
- {
- // Difficulty Level check.
- int difflevel=-1;
- difflevel=aiGetWorldDifficulty();
-
- vector gatherPointMyth=kbGetBlockPosition("1853");
-
- // Two should be plenty.
- maintainPlan4ID=aiPlanCreate("Maintain "+kbGetProtoUnitName(attackerUnitTypeID4), cPlanTrain);
- if (maintainPlan4ID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainPlan4ID, cTrainPlanUnitType, 0, attackerUnitTypeID4);
- //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.
- if ( difflevel < 3 )
- {
- aiPlanSetVariableInt(maintainPlan4ID, cTrainPlanNumberToMaintain, 0, 2);
- aiPlanSetVariableInt(maintainPlan4ID, cTrainPlanFrequency, 0, 90);
- }
- else
- {
- aiPlanSetVariableInt(maintainPlan4ID, cTrainPlanNumberToMaintain, 0, 4);
- aiPlanSetVariableInt(maintainPlan4ID, cTrainPlanFrequency, 0, 45);
- }
-
- //Set a gather point.
- aiPlanSetVariableVector(maintainPlan4ID, cTrainPlanGatherPoint, 0, gatherPointMyth);
- //Activate the plan.
- aiPlanSetActive(maintainPlan4ID);
- }
-
- // While we're here, destroy the defend plan at the gate. It should have been
- // there long enough to cover the builders.
- aiPlanDestroy(defendPlan1ID);
- 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
- {
- // Difficulty Level check.
- int difflevel=-1;
- difflevel=aiGetWorldDifficulty();
-
- aiEcho("*** GETTING ARMORY UPGRADES ***");
- createTechProgression(cTechBronzeWeapons, "Research Bronze Weapons", cUnitTypeArmory);
- createTechProgression(cTechBronzeMail, "Research Bronze Mail", cUnitTypeArmory);
-
- if ( difflevel == 3 )
- {
- createTechProgression(cTechBronzeShields, "Research Bronze Shields", cUnitTypeArmory);
- createTechProgression(cTechHeavyElephants, "Research Heavy Elephants", cUnitTypeMigdolStronghold);
- }
- else
- {
- createTechProgression(cTechCopperShields, "Research Copper Shields", cUnitTypeArmory);
- }
-
- xsDisableSelf();
- }
-
-
- //==============================================================================
- // Resource cheat for Titan.
- //==============================================================================
- rule cheatResources
- minInterval 120
- inactive
- group TitanRules
- {
- // Cheat, cheat, cheat...
- aiResourceCheat( 2, cResourceFood, 300.0 );
- aiResourceCheat( 2, cResourceFavor, 30.0 );
- }
-
-
- //==============================================================================
- // alertEnemy - fired with an AI FUNC when the player kills an anubite, or
- // builds a dock of his own.
- //
- // This causes the AI to wall up and then to start attacking.
- //==============================================================================
- void alertEnemy( int parameter=-1 )
- {
- // Difficulty Level check.
- int difflevel=-1;
- difflevel=aiGetWorldDifficulty();
-
- aiEcho("*** ENEMY ALERTED ***");
- vector WallPointA=kbGetBlockPosition("3086");
- vector WallPointB=kbGetBlockPosition("3087");
-
- vector WallPointC=kbGetBlockPosition("3088");
- vector WallPointD=kbGetBlockPosition("3089");
-
- aiWallFromAToB("Build Wall", WallPointA, WallPointB, 1, 1, 1, cRootEscrowID, 1 );
- aiWallFromAToB("Build Wall", WallPointC, WallPointD, 1, 1, 1, cRootEscrowID, 1 );
-
- vector TowerPoint=kbGetBlockPosition("1853");
-
- vector gatherPointElephants=kbGetBlockPosition("3101");
-
- // Difficulty level resource cheats.
- if ( difflevel > 1 )
- {
- aiResourceCheat( 2, cResourceFood, 500.0 );
- aiResourceCheat( 2, cResourceWood, 300.0 );
- aiResourceCheat( 2, cResourceGold, 500.0 );
- }
-
- // Even more on Titan, plus enable a semiconstant stream of stuff.
- if ( difflevel > 2 )
- {
- aiResourceCheat( 2, cResourceFood, 300.0 );
- aiResourceCheat( 2, cResourceWood, 200.0 );
- aiResourceCheat( 2, cResourceGold, 300.0 );
- xsEnableRule("cheatResources");
- }
-
- // Maintain four elephants (eight on higher levels)
- maintainPlan3ID=aiPlanCreate("Maintain 4 "+kbGetProtoUnitName(attackerUnitTypeID3), cPlanTrain);
- if (maintainPlan3ID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainPlan3ID, cTrainPlanUnitType, 0, attackerUnitTypeID3);
- //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(maintainPlan3ID, cTrainPlanNumberToMaintain, 0, 4);
- //Don't train units too fast
- aiPlanSetVariableInt(maintainPlan3ID, cTrainPlanFrequency, 0, 90);
-
- // Modifiers based on difficulty level.
- if ( difflevel > 1 )
- {
- aiPlanSetVariableInt(maintainPlan3ID, cTrainPlanFrequency, 0, 50);
- }
-
- if ( difflevel == 3)
- {
- aiPlanSetVariableInt(maintainPlan3ID, cTrainPlanNumberToMaintain, 0, 8);
- }
-
- //Set a gather point.
- aiPlanSetVariableVector(maintainPlan3ID, cTrainPlanGatherPoint, 0, gatherPointElephants);
- //Activate the plan.
- aiPlanSetActive(maintainPlan3ID);
- }
-
- // Lots more villagers maintained.
- if ( difflevel < 2 )
- {
- aiPlanSetVariableInt(maintainPlanVillagerID, cTrainPlanNumberToMaintain, 0, 16);
- }
- else
- {
- aiPlanSetVariableInt(maintainPlanVillagerID, cTrainPlanNumberToMaintain, 0, 20);
- }
-
- // Defend plan at the main gate
- defendPlan1ID=aiPlanCreate("Gate Defense", cPlanDefend);
- if (defendPlan1ID >= 0)
- {
- //Main gate location
- vector defendPlanSpot=kbGetBlockPosition("3080");
-
- // On higher difficulty levels, more.
- if ( difflevel > 1 )
- {
- //Add the unit(s).
- aiPlanAddUnitType(defendPlan1ID, attackerUnitTypeID1, 0, 7, 7);
- aiPlanAddUnitType(defendPlan1ID, attackerUnitTypeID2, 0, 6, 6);
- }
- else
- {
- //Add the unit(s).
- aiPlanAddUnitType(defendPlan1ID, attackerUnitTypeID1, 0, 3, 3);
- aiPlanAddUnitType(defendPlan1ID, attackerUnitTypeID2, 0, 2, 2);
- }
-
- //Setup the vars - priority is slightly higher than the attack plans.
- aiPlanSetDesiredPriority(defendPlan1ID, 60);
- aiPlanSetVariableVector(defendPlan1ID, cDefendPlanDefendPoint, 0, defendPlanSpot);
- aiPlanSetVariableFloat(defendPlan1ID, cDefendPlanEngageRange, 0, 15);
- aiPlanSetActive(defendPlan1ID);
- }
-
- // Create an explore plan with a single spearman.
- /*
- exploreID = aiPlanCreate("Explore", cPlanExplore);
- if(exploreID >= 0)
- {
- aiPlanAddUnitType(exploreID, attackerUnitTypeID1, 1, 1);
- aiPlanSetActive(exploreID);
- }
- */
-
- //-- Build a tower near the center of the lower route.
- int buildTower = aiPlanCreate("Build Tower", cPlanBuild);
- if(buildTower >= 0)
- {
- //BP Type and Priority.
- aiPlanSetVariableInt(buildTower, cBuildPlanBuildingTypeID, 0, cUnitTypeTower);
- aiPlanSetDesiredPriority(buildTower, 75);
- aiPlanSetVariableVector(buildTower, cBuildPlanCenterPosition, 0, TowerPoint);
- aiPlanSetVariableFloat(buildTower, cBuildPlanCenterPositionDistance, 0, 5);
- aiPlanAddUnitType(buildTower, kbTechTreeGetUnitIDTypeByFunctionIndex(cUnitFunctionBuilder, 0), 2, 2, 2);
- aiPlanSetEscrowID(buildTower, cRootEscrowID);
- aiPlanSetActive(buildTower);
- }
-
- // Enable attacks, and set up for maintaining Scarabs in a few minutes.
- xsEnableRule("attackGenerator1");
- xsEnableRule("maintainScarabs");
-
- if ( difflevel > 0 )
- {
- xsEnableRule("armoryUpgrades");
- }
-
- // Mmm, unit upgrades. Let's go!
- createTechProgression(cTechHeavySpearmen, "Research up to Heavy Spearmen", cUnitTypeBarracks);
- createTechProgression(cTechHeavySlingers, "Research up to Heavy Slingers", cUnitTypeBarracks);
-
- // Attack response range increases to 20.
- aiSetAttackResponseDistance(20.0);
- }
-
- //==============================================================================
- // MAIN.
- //==============================================================================
- void main(void)
- {
- // Difficulty Level check.
- int difflevel=-1;
- difflevel=aiGetWorldDifficulty();
-
- //Startup.
- miscStartup();
- initMainBase();
- initEcon();
-
- //Gather Points
- vector gatherPointVillager=kbGetBlockPosition("1851");
- vector gatherPointMilitary1=kbGetBlockPosition("3076");
- vector gatherPointMilitary2=kbGetBlockPosition("3077");
-
- // On Titan difficulty level, Scarabs start getting cranked out right away, and he gets
- // armory upgrades faster.
- if ( difflevel == 3 )
- {
- xsSetRuleMinInterval("maintainScarabs", 30 );
- xsSetRuleMinInterval("armoryUpgrades", 60 );
- }
-
- 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, 8);
- //Don't train units faster than every 20 seconds
- aiPlanSetVariableInt(maintainPlanVillagerID, cTrainPlanFrequency, 0, 20);
- //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);
- // On higher difficulty levels, more.
- if ( difflevel > 1 )
- {
- aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanNumberToMaintain, 0, 20);
- aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanFrequency, 0, 25);
- }
- else
- {
- aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanNumberToMaintain, 0, 12);
- aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanFrequency, 0, 40);
- }
- //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.
- // On higher difficulty levels, more.
- if ( difflevel > 1 )
- {
- aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanNumberToMaintain, 0, 12);
- aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanFrequency, 0, 40);
- }
- else
- {
- aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanNumberToMaintain, 0, 8);
- aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanFrequency, 0, 60);
- }
-
- //Set a gather point.
- aiPlanSetVariableVector(maintainPlan2ID, cTrainPlanGatherPoint, 0, gatherPointMilitary2);
- //Activate the plan.
- aiPlanSetActive(maintainPlan2ID);
- }
-
- // 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 the mining camp.
- int empowerPlan1ID=aiPlanCreate("EmpowerPlan", cPlanEmpower);
- if (empowerPlan1ID >= 0)
- {
- aiPlanSetDesiredPriority(empowerPlan1ID, 50);
- aiPlanAddUnitType(empowerPlan1ID, cUnitTypePharaoh, 1, 1, 1);
- aiPlanSetVariableInt(empowerPlan1ID, cEmpowerPlanTargetTypeID, 0, cUnitTypeMiningCamp);
- aiPlanSetActive(empowerPlan1ID);
- }
-
- // Empower a Migdol.
- int empowerPlan2ID=aiPlanCreate("EmpowerPlan", cPlanEmpower);
- if (empowerPlan2ID >= 0)
- {
- aiPlanSetDesiredPriority(empowerPlan2ID, 50);
- aiPlanAddUnitType(empowerPlan2ID, cUnitTypePriest, 1, 1, 1);
- aiPlanSetVariableInt(empowerPlan2ID, cEmpowerPlanTargetTypeID, 0, cUnitTypeMigdolStronghold);
- aiPlanSetActive(empowerPlan2ID);
- }
-
-
- // Basic tech progressions to upgrade our operations.
- createTechProgression(cTechShaftMine, "Research up to Shaft Mine", cUnitTypeMiningCamp);
- createTechProgression(cTechIrrigation, "Research up to Irrigation", cUnitTypeGranary);
- }
-