home *** CD-ROM | disk | FTP | other *** search
- //==============================================================================
- // Scn17p2: AI Scenario Script for scenario 17 player 2
- //==============================================================================
- /*
- AI owner: Mike Kidd
- Scenario owner: Jeff Brown
- With hacker by: Greg Street
-
- Overview:
- The player needs to break in and destroy a fortified CP base.
-
- The CP attacks with waves of units, with a special focus on including some
- priests to counter the player's myth-heavy armies.
-
- If the player ignores the objectives and moves a significant army to the
- area (west) near the prison, the CP swarms his armies over there.
-
- What Greg tried to add: When CP Migdol is lost, pull in everyone and play
- defensive so that HP can head to the prison.
-
- God Powers: Rain and Locust Swarm
- Minor gods: Ptah, Hathor, Osiris
-
- Difficulty: Not implemented.
-
- 7/31/2002: Added rule to retreat when migdol destroyed. Beefed up attack army
- sizes.
-
- 8/01/2002: Added difficulty levels, added patrol for defense
-
- 8/05/2002: Increased difficulty level by speeding unit train times, army sizes.
- Greg changed CP to start in age 3.
-
- 9/20/2002: Expanded attack plan gather distance from 10 to 20.
- Fixed Migdol rule to self-disable.
- Delayed initial attack on hard from 20 seconds to 60 seconds.
-
-
- */
- //==============================================================================
-
-
- include "scn lib.xs";
-
-
- // *****************************************************************************
- //
- // Globals
- //
- // *****************************************************************************
-
- // Attack routes and queries
- int routeLeft = -1;
- int routeCenter = -1;
- int routeRight = -1;
-
- int queryP1Units = -1;
- int queryP1Buildings = -1;
- int queryP1Farms = -1;
- int queryP1Monuments = -1;
- int queryP1Citadels = -1;
-
- // Army control
- int nextAttackTime = 240000; // Will be adjusted for the wakeup time
- int attackInterval = 300000; // Attack every 5:00 on easy
- float attackSize = 6;
- float attackSizeMultiplier = 1.2;
- int maxAttackSize = 16;
-
-
-
- int lastAttackPlan = -1; // Used to find "my army" for god power position info
- int defendPlan = -1;
-
- int barracksMaintainID = -1; // Plan for maintaining population of barracks units
- int barracksMaintainQty = 15; // How many to maintain
- int barracksUnit = cUnitTypeSpearman; // Which unit type
- int barracksMaintainDelay = 45; // How many seconds between training units
-
- int migdolMaintainID = cUnitTypeWarElephant;
- int migdolMaintainQty = 6;
- int migdolMaintainDelay = 90;
- int migdolUnit = -1;
-
- int priestMaintainID = -1;
- int priestMaintainQty = 1;
- int priestUnit = cUnitTypePriest;
- int priestMaintainDelay = 120;
-
- int mythMaintainID = -1;
- int mythMaintainQty = 1;
- int mythUnit = -1;
- int mythMaintainDelay = 150;
-
- int siegeTowerMaintainID = cUnitTypeSiegeTower;
- int siegeTowerMaintainQty = 0;
- int siegeTowerUnit = -1;
- int siegeTowerMaintainDelay = 150;
-
-
- // Cinematic blocks
- const string cbAttackGather = "7959";
- const string cbTownLocation = "9497";
- const string cbRouteLeft1 = "7961";
- const string cbRouteLeft2 = "7962";
- const string cbRouteCenter1 = "7963";
- const string cbRouteCenter2 = "7964";
- const string cbRouteRight1 = "7965";
- const string cbRouteRight2 = "7966";
- const string cbNearPrison = "7967";
- const string cbPriestGather = "7968";
- const string cbMythGather = "7969";
- const string cbMigdolGather = "7970";
- const string cbBarracksGather = "7971";
- //const string cbNearMigdol = "1081";
- const string cbRetreatCenter = "7960";
- const string cbPatrol0 = "7968";
- const string cbPatrol1 = "9497";
- const string cbPatrol2 = "7960";
-
- // Misc.
- int age2Time = 0;
- int age3Time = 0;
- int age4Time = 2100000;
- int startTime = -1; // Time of the wakeup() function...will be added to the age times.
-
-
-
- // *****************************************************************************
- //
- // FUNCTIONS
- //
- // *****************************************************************************
-
-
-
- // Used to delete units that are being replaced by a new type.
- void deleteObsoleteUnits(int unitType=cUnitTypeUnit, int player=2, vector center=vector(-1,-1,-1), float radius = 20.0, float percent=1.00)
- {
- // Make query
- int query = -1;
- int count = -1;
-
- query = kbUnitQueryCreate("Unit deletion query");
- if ( configQuery(query, unitType, -1, cUnitStateAlive, player, center, false, radius) == false)
- return;
- kbUnitQueryResetResults(query);
- count = kbUnitQueryExecute(query);
-
- // Iterate list, deleting percentage indicated
- float remainder=0.0; // Used to handle percentages, when this gets >= 1, it's time to delete a unit.
-
- for (i=0; <count)
- {
- remainder = remainder + percent;
- if (remainder >= 1.0) // time to delete one
- {
- aiTaskUnitDelete(kbUnitQueryGetResult(query,i));
- remainder = remainder - 1.0;
- }
- }
- }
-
-
- void age2EventHandler(int bogus=-1)
- {
- xsEnableRule("goToAge3");
- xsEnableRule("getAge2UnitUpgrades");
- xsEnableRule("getAge2ArmoryUpgrades");
- int oldUnit = cUnitTypeSpearman;
-
- switch(aiRandInt(3)) // Select a rax unit
- {
- case 0:
- {
- barracksUnit = cUnitTypeSlinger;
- break;
- }
- case 1:
- {
- barracksUnit = cUnitTypeSpearman;
- break;
- }
- case 2:
- {
- barracksUnit = cUnitTypeAxeman;
- break;
- }
- }
- aiEcho("Barracks unit is "+kbGetProtoUnitName(barracksUnit));
- barracksMaintainID = maintainUnit(barracksUnit, barracksMaintainQty, kbGetBlockPosition(cbBarracksGather), barracksMaintainDelay);
- if (barracksUnit != oldUnit)
- {
- deleteObsoleteUnits(oldUnit, 2, kbGetBlockPosition(cbTownLocation), 40, .5); // Delete half of the old units
- aiEcho("Deleting units: "+kbGetProtoUnitName(oldUnit));
- }
- }
-
-
-
- void age3EventHandler(int bogus=-1)
- {
- xsEnableRule("useLocustSwarm");
- xsEnableRule("goToAge4");
- xsEnableRule("getAge2UnitUpgrades");
- xsEnableRule("getAge2ArmoryUpgrades");
- xsEnableRule("getAge3UnitUpgrades");
- xsEnableRule("getAge3ArmoryUpgrades");
-
- int oldUnit = barracksUnit;
- switch(aiRandInt(3)) // Re-select a rax unit
- {
- case 0:
- {
- barracksUnit = cUnitTypeSlinger;
- break;
- }
- case 1:
- {
- barracksUnit = cUnitTypeSpearman;
- break;
- }
- case 2:
- {
- barracksUnit = cUnitTypeAxeman;
- break;
- }
- }
- aiEcho("Barracks unit is "+kbGetProtoUnitName(barracksUnit));
- aiPlanSetVariableInt(barracksMaintainID, cTrainPlanUnitType, 0, barracksUnit);
- if (barracksUnit != oldUnit)
- {
- deleteObsoleteUnits(oldUnit, 2, kbGetBlockPosition(cbTownLocation), 40, .5); // Delete half of the old units
- aiEcho("Deleting units: "+kbGetProtoUnitName(oldUnit));
- }
-
- switch(aiRandInt(3)) // Select a migdol unit
- {
- case 0:
- {
- migdolUnit = cUnitTypeWarElephant;
- break;
- }
- case 1:
- {
- migdolUnit = cUnitTypeWarElephant;
- break;
- }
- case 2:
- {
- migdolUnit = cUnitTypeWarElephant;
- break;
- }
- }
- aiEcho("Migdol unit is "+kbGetProtoUnitName(migdolUnit));
- migdolMaintainID = maintainUnit(migdolUnit, migdolMaintainQty, kbGetBlockPosition(cbMigdolGather), migdolMaintainDelay);
-
- switch(aiRandInt(2)) // Select a myth unit
- {
- case 0:
- {
- mythUnit = cUnitTypeScorpionMan;
- break;
- }
- case 1:
- {
- mythUnit = cUnitTypeWadjet;
- break;
- }
- }
- aiEcho("Myth unit is "+kbGetProtoUnitName(mythUnit));
- mythMaintainID = maintainUnit(mythUnit, mythMaintainQty, kbGetBlockPosition(cbMythGather), mythMaintainDelay);
-
- }
-
-
-
- void age4EventHandler(int bogus=-1)
- {
- xsEnableRule("getAge4UnitUpgrades");
- xsEnableRule("getAge4ArmoryUpgrades");
-
- mythUnit = cUnitTypePhoenix;
- aiPlanSetVariableInt(mythMaintainID, cTrainPlanUnitType, 0, mythUnit);
- aiEcho("Myth unit is Phoenix.");
-
- int oldUnit = barracksUnit;
- switch(aiRandInt(3)) // Re-select a rax unit
- {
- case 0:
- {
- barracksUnit = cUnitTypeSlinger;
- break;
- }
- case 1:
- {
- barracksUnit = cUnitTypeSpearman;
- break;
- }
- case 2:
- {
- barracksUnit = cUnitTypeAxeman;
- break;
- }
- }
- aiEcho("Barracks unit is "+kbGetProtoUnitName(barracksUnit));
- aiPlanSetVariableInt(barracksMaintainID, cTrainPlanUnitType, 0, barracksUnit);
- if (barracksUnit != oldUnit)
- {
- deleteObsoleteUnits(oldUnit, 2, kbGetBlockPosition(cbTownLocation), 40, .5); // Delete half of the old units
- aiEcho("Deleting units: "+kbGetProtoUnitName(oldUnit));
- }
-
- oldUnit = migdolUnit;
- switch(aiRandInt(3)) // Re-select a migdol unit
- {
- case 0:
- {
- migdolUnit = cUnitTypeWarElephant;
- break;
- }
- case 1:
- {
- migdolUnit = cUnitTypeWarElephant;
- break;
- }
- case 2:
- {
- migdolUnit = cUnitTypeWarElephant;
- break;
- }
- }
- aiEcho("Migdol unit is "+kbGetProtoUnitName(migdolUnit));
- aiPlanSetVariableInt(migdolMaintainID, cTrainPlanUnitType, 0, migdolUnit);
- if (migdolUnit != oldUnit)
- {
- deleteObsoleteUnits(oldUnit, 2, kbGetBlockPosition(cbBarracksGather), 20, .5); // Delete half of the old units
- aiEcho("Deleting units: "+kbGetProtoUnitName(oldUnit));
- }
-
-
- siegeTowerMaintainID = maintainUnit(cUnitTypeSiegeTower, siegeTowerMaintainQty, kbGetBlockPosition(cbMigdolGather), siegeTowerMaintainDelay);
-
- }
-
-
- // Called by trigger when the cinematics are done
- void wakeup(int parm=-1)
- {
- static bool alreadyRun = false;
- aiEcho("Wakeup running at "+timeString()+".");
- if (alreadyRun == true)
- return;
- alreadyRun = true;
-
- startTime = xsGetTime();
- age2Time = age2Time + startTime;
- xsEnableRule("goToAge4");
- age3Time = age3Time + startTime; // Adjust for delay in wakeup.
- age4Time = age4Time + startTime;
- nextAttackTime = nextAttackTime + startTime;
-
- // Make sure the event handlers get called if we start in a higher age.
- if (kbGetAge() >= cAge2)
- age2EventHandler(0);
- if (kbGetAge() >= cAge3)
- age3EventHandler(0);
- if (kbGetAge() >= cAge4)
- age4EventHandler();
-
- // Init age 1 maintain plan
- priestMaintainID = maintainUnit(cUnitTypePriest, priestMaintainQty, kbGetBlockPosition(cbPriestGather), priestMaintainDelay);
-
- xsEnableRule("useRain");
- xsEnableRule("scout");
- xsEnableRule("attackGenerator");
- xsEnableRule("armyNearPrison");
-
- // Init low-priority defend plan to manage all extra mil units
- defendPlan = aiPlanCreate("Defend Plan", cPlanDefend);
- if (defendPlan >= 0)
- {
- aiPlanAddUnitType(defendPlan, cUnitTypeMilitary, 0, 200, 200); // All unassigned mil units
- aiPlanSetDesiredPriority(defendPlan, 10); // Way low, below scouting and attack
- aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbTownLocation));
- // aiPlanSetVariableInt(defendPlan, cDefendPlanDefendTargetID, 0, 1410);
- aiPlanSetVariableFloat(defendPlan, cDefendPlanEngageRange, 0, 25);
- aiPlanSetVariableBool(defendPlan, cDefendPlanPatrol, 0, false);
- aiPlanSetVariableFloat(defendPlan, cDefendPlanGatherDistance, 0, 25.0);
-
- aiPlanSetVariableInt(defendPlan, cDefendPlanRefreshFrequency, 0, 5);
- aiPlanSetNumberVariableValues(defendPlan, cDefendPlanAttackTypeID, 2, true);
- aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 0, cUnitTypeUnit);
- aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 1, cUnitTypeBuilding);
-
- // Start with a simple 3-point patrol
- aiPlanSetNumberVariableValues(defendPlan, cDefendPlanPatrolWaypoint, 3, true);
- aiPlanSetVariableVector(defendPlan, cDefendPlanPatrolWaypoint, 0, kbGetBlockPosition(cbPatrol0));
- aiPlanSetVariableVector(defendPlan, cDefendPlanPatrolWaypoint, 1, kbGetBlockPosition(cbPatrol1));
- aiPlanSetVariableVector(defendPlan, cDefendPlanPatrolWaypoint, 2, kbGetBlockPosition(cbPatrol2));
- aiPlanSetVariableBool(defendPlan, cDefendPlanPatrol, 0, true);
-
-
- // vector pointA=gTownLocation;
- // pointA=xsVectorSetX(pointA, xsVectorGetX(gTownLocation)-50.0);
- // vector pointB=gTownLocation;
- // pointB=xsVectorSetZ(pointB, xsVectorGetZ(gTownLocation)-50.0);
- //aiPlanSetNumberVariableValues(defendPlan, cDefendPlanPatrolWaypoint, 2, true);
- //aiPlanSetVariableVector(defendPlan, cDefendPlanPatrolWaypoint, 0, pointA);
- //aiPlanSetVariableVector(defendPlan, cDefendPlanPatrolWaypoint, 1, pointB);
- aiPlanSetInitialPosition(defendPlan, kbGetBlockPosition(cbAttackGather));
- aiPlanSetActive(defendPlan);
- aiEcho("Creating defend plan");
- }
- }
-
-
-
-
-
- void attack(int size=0)
- {
- int attackID=aiPlanCreate("Attack at "+timeString(true)+" ", cPlanAttack);
- if (attackID < 0)
- return;
-
- if (aiPlanSetVariableInt(attackID, cAttackPlanPlayerID, 0, 1) == false)
- return;
-
- if (aiPlanSetNumberVariableValues(attackID, cAttackPlanTargetTypeID, 2, true) == false)
- return;
-
- // aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 0, cUnitTypeUnit);
- // aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 1, cUnitTypeBuilding);
-
- switch(aiRandInt(3)) // Pick a random path
- {
- case 0:
- {
- aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeLeft);
- break;
- }
- case 1:
- {
- aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeCenter);
- break;
- }
- case 2:
- {
- aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeRight);
- break;
- }
- }
-
- aiPlanSetVariableVector(attackID, cAttackPlanGatherPoint, 0, kbGetBlockPosition(cbAttackGather));
- aiPlanSetVariableFloat(attackID, cAttackPlanGatherDistance, 0, 20.0);
-
- switch(kbGetAge()) // Set the targets and unit composition
- {
- case cAge1:
- { // Spearmen and one priest, to attack units
- aiPlanAddUnitType(attackID, cUnitTypeSpearman, 1, size-1, size-1);
- aiPlanAddUnitType(attackID, cUnitTypePriest, 1, 1, 1);
- aiPlanSetVariableInt(attackID, cAttackPlanQueryID, 0, queryP1Units);
- break;
- }
- case cAge2:
- { // Rax unit and priests, to attack farms, units
- aiPlanAddUnitType(attackID, barracksUnit, 1, (3*size)/4, (3*size)/4);
- aiPlanAddUnitType(attackID, cUnitTypePriest, 1, size/4, size/4);
- aiPlanSetNumberVariableValues(attackID, cAttackPlanQueryID, 2);
- aiPlanSetVariableInt(attackID, cAttackPlanQueryID, 0, queryP1Farms);
- aiPlanSetVariableInt(attackID, cAttackPlanQueryID, 1, queryP1Units);
- break;
- }
- case cAge3:
- { // Rax, one priest, myth, midgol, to attack monuments, units, buildings
- aiPlanAddUnitType(attackID, barracksUnit, 1, size/2, size/2);
- aiPlanAddUnitType(attackID, migdolUnit, 1, size/4, size/4);
- aiPlanAddUnitType(attackID, cUnitTypePriest, 0, 1, 1);
- aiPlanAddUnitType(attackID, cUnitTypeMythUnit, 0, size/4, size/4);
- aiPlanSetNumberVariableValues(attackID, cAttackPlanQueryID, 3);
- aiPlanSetVariableInt(attackID, cAttackPlanQueryID, 0, queryP1Monuments);
- aiPlanSetVariableInt(attackID, cAttackPlanQueryID, 1, queryP1Units);
- aiPlanSetVariableInt(attackID, cAttackPlanQueryID, 2, queryP1Buildings);
- break;
- }
- case cAge4:
- { // Rax, few priests, myth, migdol, to attack Citadel, units, buildings
- aiPlanAddUnitType(attackID, barracksUnit, 1, size/3, size/3);
- aiPlanAddUnitType(attackID, migdolUnit, 1, size/3, size/3);
- aiPlanAddUnitType(attackID, cUnitTypePriest, 0, size/10, size/10);
- aiPlanAddUnitType(attackID, cUnitTypeMythUnit, 0, size/4, size/4);
- aiPlanAddUnitType(attackID, cUnitTypeSiegeTower, 0, size/2, size/10);
- aiPlanSetNumberVariableValues(attackID, cAttackPlanQueryID, 3);
- aiPlanSetVariableInt(attackID, cAttackPlanQueryID, 0, queryP1Citadels);
- aiPlanSetVariableInt(attackID, cAttackPlanQueryID, 1, queryP1Units);
- aiPlanSetVariableInt(attackID, cAttackPlanQueryID, 2, queryP1Buildings);
- break;
- }
- }
-
- aiPlanSetInitialPosition(attackID, kbGetBlockPosition(cbAttackGather));
- aiPlanSetRequiresAllNeedUnits(attackID, false);
- aiPlanSetActive(attackID);
- aiEcho("Activating attack plan "+attackID+" with appx "+size+" units.");
- lastAttackPlan = attackID; // update the global var
- }
-
-
-
-
- void main()
- {
- aiEcho("Starting Scn17p2.xs");
-
-
- //Calculate some areas.
- kbAreaCalculate(1200.0);
- aiRandSetSeed();
- aiSetAttackResponseDistance(20.0);
- kbSetTownLocation(kbGetBlockPosition(cbTownLocation));
-
- aiSetAgeEventHandler(cAge2, "age2EventHandler");
- aiSetAgeEventHandler(cAge3, "age3EventHandler");
- aiSetAgeEventHandler(cAge4, "age4EventHandler");
-
-
-
- // Init attack routes
- routeLeft = attackRoute("Left Attack Route",cbAttackGather, cbRouteLeft1, cbRouteLeft2);
- routeCenter = attackRoute("Center Attack Route",cbAttackGather, cbRouteCenter1, cbRouteCenter2);
- routeRight = attackRoute("Right Attack Route",cbAttackGather, cbRouteRight1, cbRouteRight2);
-
- // Initialize the target queries
- queryP1Units = kbUnitQueryCreate("Player 1 Units");
- configQuery(queryP1Units, cUnitTypeUnit, -1, cUnitStateAlive, 1);
-
- queryP1Buildings = kbUnitQueryCreate("Player 1 Buildings");
- configQuery(queryP1Buildings, cUnitTypeBuilding, -1, cUnitStateAliveOrBuilding, 1);
-
- queryP1Farms = kbUnitQueryCreate("Player 1 Farms");
- configQuery(queryP1Farms, cUnitTypeFarm, -1, cUnitStateAliveOrBuilding, 1);
-
- queryP1Monuments = kbUnitQueryCreate("Player 1 Monuments");
- configQuery(queryP1Monuments, cUnitTypeAbstractMonument, -1, cUnitStateAliveOrBuilding, 1);
-
- queryP1Citadels = kbUnitQueryCreate("Player 1 Citadels");
- configQuery(queryP1Citadels, cUnitTypeCitadelCenter, -1, cUnitStateAliveOrBuilding, 1);
-
- aiEcho("Difficulty = "+aiGetWorldDifficulty());
- switch(aiGetWorldDifficulty())
- {
- case 1: // Moderate
- {
- nextAttackTime = 120000;
- attackInterval = 240000;
- attackSize = 9.0;
- attackSizeMultiplier = 1.2;
- maxAttackSize = 25;
- barracksMaintainQty = 20;
- barracksMaintainDelay = 40;
- migdolMaintainQty = 9;
- migdolMaintainDelay = 60;
- priestMaintainQty = 3;
- priestMaintainDelay = 80;
- mythMaintainQty = 2;
- mythMaintainDelay = 100;
- siegeTowerMaintainQty = 1;
- age4Time = 9*60*1000;
- break;
- }
- case 2: // Hard
- {
- nextAttackTime = 60000;
- attackInterval = 192000;
- attackSize = 14.0;
- attackSizeMultiplier = 1.2;
- maxAttackSize = 40;
- barracksMaintainQty = 25;
- barracksMaintainDelay = 35;
- migdolMaintainQty = 15;
- migdolMaintainDelay = 45;
- priestMaintainQty = 9;
- priestMaintainDelay = 45;
- mythMaintainQty = 4;
- mythMaintainDelay = 45;
- siegeTowerMaintainQty = 3;
- age4Time = 6*60*1000;
- break;
- }
- case 3: // Nightmare
- {
- nextAttackTime = 20000;
- attackInterval = 120000;
- attackSize = 21.0;
- attackSizeMultiplier = 1.3;
- maxAttackSize = 50;
- barracksMaintainQty = 30;
- barracksMaintainDelay = 30;
- migdolMaintainQty = 25;
- migdolMaintainDelay = 35;
- priestMaintainQty = 12;
- priestMaintainDelay = 30;
- mythMaintainQty = 8;
- mythMaintainDelay = 30;
- siegeTowerMaintainQty = 6;
- age4Time = 3*60*1000;
- break;
- }
- }
- }
-
-
-
-
-
-
-
- // *****************************************************************************
- //
- // RULES
- //
- // *****************************************************************************
-
- rule scout
- inactive
- minInterval 5
- {
- // just set up an explore plan
- int exploreID = aiPlanCreate("Explore", cPlanExplore);
- if(exploreID >= 0)
- {
- aiPlanSetVariableFloat( exploreID, cExplorePlanLOSMultiplier, 0, 4.0 );
- aiPlanAddUnitType(exploreID, cUnitTypeSpearman, 1, 1, 1);
- aiPlanSetActive(exploreID);
- }
- xsDisableSelf();
- }
-
- rule goToAge2
- inactive
- minInterval 10
- {
- if ( xsGetTime() < age2Time)
- return;
- researchTech(cTechAge2Ptah);
- xsDisableSelf();
- }
-
-
-
- rule goToAge3
- inactive
- mininterval 20
- {
- if ( xsGetTime() < age3Time )
- return;
- researchTech(cTechAge3Hathor);
- xsDisableSelf();
- }
-
-
- rule goToAge4
- inactive
- mininterval 20
- {
- if ( xsGetTime() < age4Time )
- return;
- researchTech(cTechAge4Thoth);
- xsDisableSelf();
- }
-
-
-
- rule getAge2UnitUpgrades
- inactive
- minInterval 20
- {
- if ( xsGetTime() < (age3Time+10000) )
- return;
- researchTech(cTechMediumAxemen);
- researchTech(cTechMediumSlingers);
- researchTech(cTechMediumSpearmen);
- xsDisableSelf();
- }
-
- rule getAge2ArmoryUpgrades
- inactive
- minInterval 20
- {
- if ( xsGetTime() < (age3Time+12000) )
- return;
- aiEcho("Getting age 2 armory upgrades");
- researchTech(cTechCopperWeapons);
- researchTech(cTechCopperMail);
- researchTech(cTechCopperShields);
- xsDisableSelf();
- }
-
- rule getAge3UnitUpgrades
- inactive
- minInterval 20
- {
- if ( xsGetTime() < (age3Time+30000) )
- return;
- researchTech(cTechHeavyAxemen);
- researchTech(cTechHeavySlingers);
- researchTech(cTechHeavySpearmen);
- researchTech(cTechHeavyElephants);
- xsDisableSelf();
- }
-
- rule getAge3ArmoryUpgrades
- inactive
- minInterval 20
- {
- if ( xsGetTime() < (age3Time+120000) )
- return;
- researchTech(cTechBronzeWeapons);
- researchTech(cTechBronzeMail);
- researchTech(cTechBronzeShields);
- xsDisableSelf();
- }
-
- rule getAge4UnitUpgrades
- inactive
- minInterval 20
- {
- if ( xsGetTime() < (age4Time+480000) )
- return;
- researchTech(cTechChampionAxemen);
- researchTech(cTechChampionSlingers);
- researchTech(cTechChampionSpearmen);
- researchTech(cTechChampionElephants);
- xsDisableSelf();
- }
-
- rule getAge4ArmoryUpgrades
- inactive
- minInterval 20
- {
- if ( xsGetTime() < (age4Time+720000) )
- return;
- researchTech(cTechIronWeapons);
- researchTech(cTechIronMail);
- researchTech(cTechIronShields);
- xsDisableSelf();
- }
-
-
-
- rule attackGenerator
- minInterval 10
- inactive
- {
- //aiEcho("attack check running, next time is "+nextAttackTime);
- if ( xsGetTime() < nextAttackTime )
- return;
-
- attack(attackSize);
- nextAttackTime = xsGetTime() + attackInterval;
- attackSize = attackSize + attackSizeMultiplier;
- if (attackSize > maxAttackSize)
- attackSize = maxAttackSize;
- aiEcho("Next attack size will be "+attackSize+".");
- }
-
- // Checks to see if a large P1 army is near the prison, if so, set off a swarm attack.
- rule armyNearPrison
- inactive
- minInterval 15
- {
- static int queryPrison=-1; // Used for unit count and targeting.
- int count=0;
- int attackID=-1;
-
- if (queryPrison < 0)
- {
- // Create query
- queryPrison = kbUnitQueryCreate("Prison query");
- if ( configQuery(queryPrison, cUnitTypeUnit, -1, cUnitStateAlive, 1, kbGetBlockPosition(cbNearPrison), false, 50) == false)
- return;
- }
-
- // Check for enemies
- kbUnitQueryResetResults(queryPrison);
- count = kbUnitQueryExecute(queryPrison);
-
- if (count < 6)
- return;
-
-
-
- // Rally units to defend...all units within 100 meters, to a maximum of 30 units
- aiEcho("Outer wall emergency.");
- attackID = aiPlanCreate("Prison Attack", cPlanAttack);
- count = getUnassignedUnitCount(kbGetBlockPosition(cbAttackGather), 100.0, 2, cUnitTypeMilitary);
- if (count > 30)
- count = 30;
-
- if (attackID < 0)
- return;
-
- if (aiPlanSetVariableInt(attackID, cAttackPlanPlayerID, 0, 1) == false)
- return;
-
- aiPlanSetNumberVariableValues(attackID, cAttackPlanQueryID, 2);
- aiPlanSetVariableInt(attackID, cAttackPlanQueryID, 0, queryPrison); // Attack units near prison, then
- aiPlanSetVariableInt(attackID, cAttackPlanQueryID, 1, queryP1Units); // Attack any units
-
- aiPlanSetVariableVector(attackID, cAttackPlanGatherPoint, 0, kbGetBlockPosition(cbAttackGather));
- aiPlanSetVariableFloat(attackID, cAttackPlanGatherDistance, 0, 10.0);
-
- aiPlanAddUnitType(attackID, cUnitTypeMilitary, 1, count, count );
-
- aiEcho("Responding with "+count+" units.");
- aiPlanSetInitialPosition(attackID, kbGetBlockPosition(cbAttackGather));
- aiPlanSetRequiresAllNeedUnits(attackID, true);
- aiPlanSetActive(attackID);
- xsDisableSelf();
- }
-
- // Once the Migdol is destroyed, bring everyone inside the base so that HP can sneak around to prison
- rule migdolLost /* GTS added */
- active
- minInterval 15
- {
- static int queryMigdol=-1;
-
- if (queryMigdol < 0)
- {
- // Create query
- queryMigdol = kbUnitQueryCreate("Query to see if P2 Migdol alive");
- if (configQuery(queryMigdol, cUnitTypeMigdolStronghold, -1, cUnitStateAlive, cMyID) == false)
- return;
- }
-
- kbUnitQueryResetResults(queryMigdol);
- int targetCount = kbUnitQueryExecute(queryMigdol);
-
- if (targetCount > 0)
- return;
-
- aiEcho("Migdol lost. Move to center of town");
-
-
- /*
- aiPlanSetVariableBool(defendPlan, cDefendPlanPatrol, 0, false);
- aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbRetreatCenter)); // Move them all away
- aiPlanSetVariableFloat(defendPlan, cDefendPlanEngageRange, 0, 20.0); // Tighten the engage range
- */
- // Destroy defend plan, create new one for retreat location
- aiPlanDestroy(defendPlan);
- defendPlan = aiPlanCreate("Defend Plan, Take Two", cPlanDefend);
- if (defendPlan >= 0)
- {
- aiPlanAddUnitType(defendPlan, cUnitTypeMilitary, 0, 200, 200); // All unassigned mil units
- aiPlanSetDesiredPriority(defendPlan, 10); // Way low, below scouting and attack
- aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbRetreatCenter));
- aiPlanSetVariableFloat(defendPlan, cDefendPlanEngageRange, 0, 20);
- aiPlanSetVariableBool(defendPlan, cDefendPlanPatrol, 0, false);
- aiPlanSetVariableFloat(defendPlan, cDefendPlanGatherDistance, 0, 20.0);
-
- aiPlanSetVariableInt(defendPlan, cDefendPlanRefreshFrequency, 0, 5);
- aiPlanSetNumberVariableValues(defendPlan, cDefendPlanAttackTypeID, 2, true);
- aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 0, cUnitTypeUnit);
- aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 1, cUnitTypeBuilding);
-
- //aiPlanSetNumberVariableValues(defendPlan, cDefendPlanPatrolWaypoint, 2, true);
- //aiPlanSetVariableVector(defendPlan, cDefendPlanPatrolWaypoint, 0, pointA);
- //aiPlanSetVariableVector(defendPlan, cDefendPlanPatrolWaypoint, 1, pointB);
- aiPlanSetInitialPosition(defendPlan, kbGetBlockPosition(cbRetreatCenter));
- aiPlanSetActive(defendPlan);
- aiEcho("Recreating defend plan");
- }
-
- aiPlanDestroy(lastAttackPlan); // Kill active attack plan, if any
- xsDisableRule("attackGenerator"); // And no more attacks, please
- xsDisableSelf();
- }
-
-
-
- rule useRain
- minInterval 10
- inactive
- {
- if (xsGetTime() < startTime+300)
- return;
-
- if (aiRandInt(10) > 0)
- return;
-
- aiCastGodPowerAtPosition(cTechRain, kbGetTownLocation());
- aiEcho("Casting rain at "+timeString()+".");
- xsDisableSelf();
- }
-
-
-
-
-
- rule useLocustSwarm // Look for 6 farms near my army
- minInterval 5
- inactive
- {
- int targetUnit = -1;
- int attackArmyID = -1;
-
- if (lastAttackPlan < 0)
- return;
- vector pVec = aiPlanGetLocation(lastAttackPlan);
- if (xsVectorGetX(pVec)<0)
- return;
-
- static int tempQuery = -1;
- if (tempQuery < 0)
- { // Doesn't exist, set it up
- tempQuery = kbUnitQueryCreate("useLocustSwarm");
-
- if ( configQuery(tempQuery, cUnitTypeFarm, -1, cUnitStateAliveOrBuilding, 1, pVec, true, 50) == false)
- return;
- }
- else
- kbUnitQuerySetPosition(tempQuery, pVec); // Because pVec changes as army moves
-
- kbUnitQueryResetResults(tempQuery);
- int targetCount = kbUnitQueryExecute(tempQuery);
-
- if (targetCount < 6)
- return;
- targetUnit = kbUnitQueryGetResult(tempQuery, targetCount/2); // grab middle farm
-
- // confirm LOS
- if ( kbUnitVisible(targetUnit) != true )
- {
- aiEcho("Don't have LOS for locust swarm on unit "+targetUnit);
- return;
- }
-
- aiEcho("Using Locust Swarm");
- if ( aiCastGodPowerAtPosition(cTechLocustSwarm, kbUnitGetPosition(targetUnit)) == true)
- xsDisableSelf();
- else
- aiEcho("Locust swarm failed at "+kbUnitGetPosition(targetUnit));
- }
-
-
-
-
-