home *** CD-ROM | disk | FTP | other *** search
Text File | 2002-09-19 | 31.3 KB | 1,030 lines |
- //==============================================================================
- // Scn26p2: AI Scenario Script for scenario 26 player 2
- //==============================================================================
- /*
- AI owner: Mike Kidd
- Scenario owner: Greg Street
-
- Overview:
-
- Has no economy. Just sends in waves of units for a "weather the storm".
-
- Starts fully upgraded in Age4. Does not need any techs.
-
- Player 2 should periodically attack with mostly giants while HP is building up.
- Once HP has reached the Dwarven Forge, Player 2 changes attacks to focus on that
- area and sends in large waves of giants, Trolls and Ballistae.
-
- Note to MK: Many of the "route" CBs have changed numbers below const area, and may be incorrect.
- Note to GTS: Many of these routes have been fixed, and should all be correct. ;-)
-
- 9/19/2002: Removed wakeup() call from main() as a wakeup trigger does exist.
- Reduced difficulty on Titan from this:
- nextAttackTime = 60000;
- attackInterval = 120000;
- attackSize = 8.0;
- attackMultiplier = 1.4; // 40% per period
- maxAttackSize = 25;
- age2Time = -1; // N/A
- age3Time = 1*60*1000; // 1 min
- age4Time = 5*60*1000;
- armyReserveSize = 35;
- to this:
- nextAttackTime = 120000;
- attackInterval = 132000;
- attackSize = 5.0;
- attackMultiplier = 1.2; // 20% per period
- maxAttackSize = 18;
- age2Time = -1; // N/A
- age3Time = 1*60*1000; // 1 min
- age4Time = 5*60*1000;
- armyReserveSize = 30;
- standardDelay = 1; // seconds
- also increased the hard attack interval by 20%.
-
- */
- //==============================================================================
-
-
- include "scn lib.xs";
-
-
- // *****************************************************************************
- //
- // Globals
- //
- // *****************************************************************************
-
-
- // Cinematic blocks
-
- const string cbMountainGiantGather = "2534";
- const string cbTrollGather = "2535";
- const string cbDefendPoint = "2535";
-
- const string cbAttackGather = "2558";
- const string cbP1TCNorth = "2537";
- const string cbP1TCSouth = "2538";
- const string cbP2TC = "3690";
- const string cbWalkingWoods = "2540";
-
- const string cbRouteA1 = "2546"; // Route A: West channel
- const string cbRouteA2 = "2557";
- const string cbRouteA3 = "2544";
-
- const string cbRouteB1 = "2546"; // Route B: Center channel
- const string cbRouteB2 = "2547";
- const string cbRouteB3 = "2551";
-
- const string cbRouteC1 = "2549"; // Route C: East channel (initially closed)
- const string cbRouteC2 = "2550";
- const string cbRouteC3 = "2538";
-
- const string cbRouteD1 = "2541"; // Route D: SW entrance to forge
- const string cbRouteD2 = "2539";
- const string cbRouteD3 = "1886";
-
- const string cbRouteE1 = "2536"; // Route E: NW entrance to forge
- const string cbRouteE2 = "2553";
- const string cbRouteE3 = "1886";
-
- const string cbRouteF1 = "2536"; // Route F: NE entrance to forge
- const string cbRouteF2 = "2534";
- const string cbRouteF3 = "1886";
-
- const string cbForge ="1886"; // Center of forge area
-
-
- // Attack routes and queries
- int routeA = -1;
- int routeB = -1;
- int routeC = -1;
- int routeD = -1;
- int routeE = -1;
- int routeF = -1;
-
-
- // Army control
- int lastAttackPlan = -1; // Used to find "my army" for god power position info
- int defendPlan = -1;
- int navalDefendPlan = -1;
- bool defendOnly = false; // When true, cancels last attack plan, all military go to defense
-
-
- // The following are set in main() based on difficulty level.
- int nextAttackTime = 240000; // Will be adjusted for the wakeup time
- int attackInterval = 240000; // Attack every 4:00
- float attackSize = 6.0;
- float attackMultiplier = 1.2;
- int maxAttackSize = 25;
- int armyReserveSize = -1; // Target size for total reserve army, to be adjusted for difficulty
- int standardDelay = -1; // Used to set unit-training delay times, adjusted for difficulty
-
-
- int maintainQty1 = -1; // Quantity to maintain
- int maintainUnit1 = -1; // Unit type
- int maintainDelay1 = -1; // Interval between training units
- vector maintainGather1 = cInvalidVector;
- int maintainID1 = -1; // Maintain plan for primary military unit
-
- int maintainQty2 = -1; // Quantity to maintain
- int maintainUnit2 = -1; // Unit type
- int maintainDelay2 = -1; // Interval between training units
- vector maintainGather2 = cInvalidVector;
- int maintainID2 = -1; // Maintain plan for secondary military unit
-
- int maintainQty3 = -1; // Quantity to maintain
- int maintainUnit3 = -1; // Unit type
- int maintainDelay3 = -1; // Interval between training units
- vector maintainGather3 = cInvalidVector;
- int maintainID3 = -1; // Maintain plan for tertiary military unit
-
- int maintainQty4 = -1; // Quantity to maintain
- int maintainUnit4 = -1; // Unit type
- int maintainDelay4 = -1; // Interval between training units
- vector maintainGather4 = cInvalidVector;
- int maintainID4 = -1; // Maintain plan for quatenary military unit
-
- int maintainQtyScout = 1;
- int maintainUnitScout = cUnitTypeFenrisWolf;
- int maintainDelayScout = 1;
- vector maintainGatherScout = cInvalidVector;
- int maintainIDScout = -1; // Scout unit
-
-
-
-
-
- // Misc.
- int age2Time = -1; // Will be adjusted in main() for difficulty
- int age3Time = -1;
- int age4Time = -1;
- int startTime = -1; // Time of the wakeup() function...will be added to the age times.
-
- int difficulty = -1; // Global to store difficulty, set early in main.
-
- bool forge = false; // Set to true when the AI should be attacking the forge area
- bool route3Open = false; // Set to true when the trigger tells us that the third route is open.
-
- // *****************************************************************************
- //
- // FUNCTIONS
- //
- // *****************************************************************************
-
-
- // 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();
- if (age2Time > 0)
- age2Time = age2Time + startTime; // Adjust for delay in wakeup.
- xsEnableRule("goToAge3");
- if (age3Time > 0)
- age3Time = age3Time + startTime;
- if (age4Time > 0)
- age4Time = age4Time + startTime;
- if (nextAttackTime > 0)
- nextAttackTime = nextAttackTime + startTime;
-
- // Init maintain plans
- if (maintainUnit1 > 0)
- maintainID1 = maintainUnit(maintainUnit1, maintainQty1, maintainGather1, maintainDelay1);
- if (maintainUnit2 > 0)
- maintainID2 = maintainUnit(maintainUnit2, maintainQty2, maintainGather2, maintainDelay2);
- if (maintainUnit3 > 0)
- maintainID3 = maintainUnit(maintainUnit3, maintainQty3, maintainGather3, maintainDelay3);
- if (maintainUnit4 > 0)
- maintainID4 = maintainUnit(maintainUnit4, maintainQty4, maintainGather4, maintainDelay4);
- if (maintainUnitScout > 0)
- maintainIDScout = maintainUnit(maintainUnitScout, maintainQtyScout, maintainGatherScout, maintainDelayScout);
-
-
- // 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(cbDefendPoint));
- 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);
-
- aiPlanSetInitialPosition(defendPlan, kbGetBlockPosition(cbAttackGather));
- aiPlanSetActive(defendPlan);
- aiEcho("Creating defend plan");
- }
-
- xsEnableRule("scout");
- xsEnableRule("attackGenerator");
- }
-
-
- // Called by a trigger to let the AI know that the third route is open (the boulder is gone).
- void route3IsOpen(int ignore=0)
- {
- route3Open = true;
- aiEcho("Route C is open.");
- }
-
-
- // AIFunc
- void runAway(int ignore=0)
- { // All units should run away from the forge
- aiEcho("RunAway function called at "+timeString());
- aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbDefendPoint));
- aiPlanSetVariableFloat(defendPlan, cDefendPlanEngageRange, 0, 5);
- aiSetAttackResponseDistance(5.0);
-
- aiPlanDestroy(lastAttackPlan);
- aiPlanDestroy(defendPlan);
- xsDisableRule("attackGenerator");
-
- // Force every unit to move NOW
- int query=-1;
- query = kbUnitQueryCreate("Unit list");
- configQuery(query, cUnitTypeUnit, -1, cUnitStateAlive, cMyID);
- int count = -1;
- int i = -1;
- int unit = -1;
- kbUnitQueryResetResults(query);
- count = kbUnitQueryExecute(query);
- aiEcho("Moving "+count+" units.");
- for (i=0; < count)
- {
- unit = kbUnitQueryGetResult(query, i);
- aiTaskUnitMove(unit, kbGetBlockPosition(cbDefendPoint));
- aiEcho(" "+unit);
- }
- }
-
-
- // AIFunc
- void charge(int ignore=0) // Time to have everybody attack
- {
- aiEcho("Charge function called at "+timeString());
- aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbForge));
- aiPlanSetVariableFloat(defendPlan, cDefendPlanEngageRange, 0, 5);
- aiSetAttackResponseDistance(20.0);
- }
-
-
- // Called by a trigger when the player has successfully captured the forge. The bulk of offensive attacks will be on
- // forge from this point forward,with occasional attacks on the HP's economy.
- void attackForge(int ignore=0)
- {
- forge = true; // Sets the global variable, monitored by attack function for choosing routes.
- // aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbForge));
- // xsEnableRule("restoreNormalDefense"); // When this rule fires, reset the defense to its normal position
- // if ( (nextAttackTime + 90000) > xsGetTime() ) // Make sure we don't attack until the defense goes normal
- // nextAttackTime = xsGetTime() + 90000;
- aiEcho("Starting forge attacks");
-
- switch(difficulty) // Attack more often now
- {
- case 0: // Easy
- {
- attackInterval = 120000;
- attackSize = 5;
- armyReserveSize = 12;
- }
- case 1: // Moderate
- {
- attackInterval = 90000;
- attackSize = 9;
- armyReserveSize = 18;
- }
- case 2: // Hard
- {
- attackInterval = 75000;
- attackSize = 12;
- armyReserveSize = 25;
- }
- case 3: // Titan
- {
- attackInterval = 60000;
- attackSize = 12;
- armyReserveSize = 35;
- }
- }
- if (nextAttackTime > (xsGetTime() + attackInterval))
- nextAttackTime = xsGetTime()+attackInterval;
-
- aiPlanDestroy(lastAttackPlan);
- }
-
-
-
-
- // Cancel last offensive plan and put all units on defense.
- void defend(int parm=-1)
- {
- aiEcho("Defend function called.");
- defendOnly = true;
- aiPlanDestroy(lastAttackPlan);
- }
-
-
-
-
- // 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");
-
- /* xsEnableRule("useHealingSpring"); */
- }
-
-
-
- void age3EventHandler(int bogus=-1)
- {
-
- if (age4Time > 0) // May be suppressed for difficulty
- xsEnableRule("goToAge4");
- xsEnableRule("getAge3UnitUpgrades");
- xsEnableRule("getAge3ArmoryUpgrades");
-
-
- // aiPlanSetVariableInt(navyMaintainID, cTrainPlanUnitType, 0, navyUnit);
- // if (navyUnit != oldUnit)
- // {
- // deleteObsoleteUnits(oldUnit, 2, kbGetBlockPosition(cbFinalGate), 50, .5); // Delete half of the old units
- // aiEcho("Deleting units: "+kbGetProtoUnitName(oldUnit));
- // }
-
- xsEnableRule("useWalkingWoods");
- }
-
-
-
- void age4EventHandler(int bogus=-1)
- {
- xsEnableRule("getAge4UnitUpgrades");
- xsEnableRule("getAge4ArmoryUpgrades");
-
- //xsEnableRule("useNidhogg");
- }
-
-
-
-
- void attack(int size=0)
- {
- if (defendOnly == true)
- return;
-
- int attackID=aiPlanCreate("Attack at "+timeString(true)+" ", cPlanAttack);
- if (attackID < 0)
- return;
-
- if (aiPlanSetVariableInt(attackID, cAttackPlanPlayerID, 0, 1) == false)
- return;
-
- if (aiPlanSetNumberVariableValues(attackID, cAttackPlanTargetTypeID, 3, true) == false)
- return;
-
- aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 0, cUnitTypeUnit);
- aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 1, cUnitTypeBuilding);
- aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 2, cUnitTypeAbstractWall);
-
- int rand = -1;
-
- if (forge == true)
- rand = 3 + aiRandInt(3); // 3, 4, 5, meaning routes D-F to attack forge
- else
- {
- if (route3Open == true)
- rand = aiRandInt(3); // 0, 1, 2, routes A-C
- else
- rand = aiRandInt(2); // 0, 1, just routes A or B, C is not yet open.
- }
- switch(rand) // Pick a random path
- {
- case 0:
- {
- aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeA);
- break;
- }
- case 1:
- {
- aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeB);
- break;
- }
- case 2:
- {
- aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeC);
- break;
- }
- case 3:
- {
- aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeD);
- break;
- }
- case 4:
- {
- aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeE);
- break;
- }
- case 5:
- {
- aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeF);
- break;
- }
- }
-
- aiPlanSetVariableVector(attackID, cAttackPlanGatherPoint, 0, kbGetBlockPosition(cbAttackGather));
- aiPlanSetVariableFloat(attackID, cAttackPlanGatherDistance, 0, 20.0);
-
- /* switch(kbGetAge()) // Set the targets and unit composition
- {
- case cAge1:
- {
- aiPlanAddUnitType(attackID, cUnitTypeMilitary, 1, size, size);
- break;
- }
- case cAge2:
- {
- aiPlanAddUnitType(attackID, cUnitTypeMilitary, 1, size, size);
- break;
- }
- case cAge3:
- { //
- aiPlanAddUnitType(attackID, cUnitTypeMilitary, 1, size, size);
- //aiPlanAddUnitType(attackID, navyUnit, 1, (size+1)/2, (size+1)/2);
- //aiPlanAddUnitType(attackID, barracksUnit, 1, (size+2)/4, (size+2)/4);
- //aiPlanAddUnitType(attackID, cUnitTypeMythUnit, 0, (size+2)/4, (size+2)/4);
- break;
- }
- case cAge4:
- {
- aiPlanAddUnitType(attackID, cUnitTypeMilitary, 1, size, size);
- // aiPlanAddUnitType(attackID, navyUnit, 1, (size+1)/2, (size+1)/2);
- // aiPlanAddUnitType(attackID, barracksUnit, 1, (size+2)/4, (size+2)/4);
- // aiPlanAddUnitType(attackID, cUnitTypeMythUnit, 0, (size+2)/4, (size+2)/4);
- // aiPlanSetNumberVariableValues(attackID, cAttackPlanQueryID, 3);
- // aiPlanSetVariableInt(attackID, cAttackPlanQueryID, 0, queryP1Monuments);
- // aiPlanSetVariableInt(attackID, cAttackPlanQueryID, 1, queryP1Units);
- // aiPlanSetVariableInt(attackID, cAttackPlanQueryID, 2, queryP1Buildings);
-
- break;
- }
- }*/
-
- if(kbGetAge() < cAge4)
- {
- aiPlanAddUnitType(attackID, maintainUnit1, 0, (size+1)/2, (size+1)/2); // Just trolls and mountain giants
- aiPlanAddUnitType(attackID, maintainUnit2, 0, (size)/2, (size)/2);
- }
- else
- {
- aiPlanAddUnitType(attackID, maintainUnit1, 0, (size+3)/4, (size+3)/4);
- aiPlanAddUnitType(attackID, maintainUnit2, 0, (size+2)/4, (size+2)/4);
- aiPlanAddUnitType(attackID, maintainUnit3, 0, (size+1)/4, (size+1)/4);
- aiPlanAddUnitType(attackID, maintainUnit4, 0, (size)/4, (size)/4);
-
- }
-
- aiPlanSetInitialPosition(attackID, kbGetBlockPosition(cbAttackGather));
- aiPlanSetRequiresAllNeedUnits(attackID, false);
- aiPlanSetDesiredPriority(attackID, 50); // Less than scouting, more than defense
- aiPlanSetActive(attackID);
- aiEcho("Activating attack plan "+attackID+" with appx "+size+" units.");
- lastAttackPlan = attackID; // update the global var
- }
-
-
-
-
- void main()
- {
- aiEcho("Starting Scn26p2.xs");
-
- //Calculate some areas.
- kbAreaCalculate(1200.0);
- aiRandSetSeed();
- kbSetTownLocation(kbGetBlockPosition(cbP2TC));
-
- aiSetAgeEventHandler(cAge2, "age2EventHandler");
- aiSetAgeEventHandler(cAge3, "age3EventHandler");
- aiSetAgeEventHandler(cAge4, "age4EventHandler");
-
- aiSetAttackResponseDistance(10.0);
-
- kbEscrowSetPercentage( cEconomyEscrowID, cAllResources, 0.0);
- kbEscrowSetPercentage( cMilitaryEscrowID, cAllResources, 0.0);
- kbEscrowAllocateCurrentResources();
-
-
- // Set difficulty vars
- difficulty = aiGetWorldDifficulty();
- aiEcho("Difficulty = "+difficulty);
-
- switch(difficulty) // Set up the attack control and age-up parameters
- {
- case 0: // Easy
- {
- nextAttackTime = 300000; // 5 min
- attackInterval = 390000; // 6.5 min
- attackSize = 1.3;
- attackMultiplier = 1.2; // 20% per interval
- maxAttackSize = 3;
- age2Time = -1; // N/A
- age3Time = 1200000; // 20 min
- age4Time = 40*60*1000;
- armyReserveSize = 6;
- standardDelay = 1; // seconds
- break;
- }
- case 1: // Moderate
- {
- nextAttackTime = 180000; // 3 min
- attackInterval = 300000; // 5 min
- attackSize = 3.0;
- attackMultiplier = 1.2; // 20% per period
- maxAttackSize = 6;
- age2Time = -1; // N/A
- age3Time = 720000; // 12 min
- age4Time = 20*60*1000;
- armyReserveSize = 9;
- standardDelay = 1; // seconds
- break;
- }
- case 2: // Difficult
- {
- nextAttackTime = 120000;
- attackInterval = 180000;
- attackSize = 6.0;
- attackMultiplier = 1.3; // 30% per period
- maxAttackSize = 12;
- age2Time = -1; // N/A
- age3Time = 4*60*1000; // 4 min
- age4Time = 8*60*1000;
- armyReserveSize = 20;
- standardDelay = 1; // seconds
- break;
- }
- case 3: // Nightmare
- {
- nextAttackTime = 120000;
- attackInterval = 132000;
- attackSize = 5.0;
- attackMultiplier = 1.2; // 20% per period
- maxAttackSize = 18;
- age2Time = -1; // N/A
- age3Time = 1*60*1000; // 1 min
- age4Time = 5*60*1000;
- armyReserveSize = 30;
- standardDelay = 1; // seconds
- break;
- }
- }
-
-
- // Set global unit control vars
- maintainQty1 = (armyReserveSize+2)/4; // Quantity to maintain
- maintainUnit1 = cUnitTypeTroll; // Unit type
- maintainDelay1 = standardDelay; // Interval between training units
- maintainGather1 = kbGetBlockPosition(cbTrollGather);
-
- maintainQty2 = (armyReserveSize+2)/4; // Quantity to maintain
- maintainUnit2 = cUnitTypeMountainGiant; // Unit type
- maintainDelay2 = standardDelay; // Interval between training units
- maintainGather2 = kbGetBlockPosition(cbMountainGiantGather);
-
- maintainQty3 = (armyReserveSize+2)/4; // Quantity to maintain
- maintainUnit3 = cUnitTypeFireGiant; // Unit type
- maintainDelay3 = standardDelay; // Interval between training units
- maintainGather3 = cInvalidVector;
-
- maintainQty4 = (armyReserveSize+2)/4; // Quantity to maintain
- maintainUnit4 = cUnitTypeBallista; // Unit type
- maintainDelay4 = standardDelay; // Interval between training units
- maintainGather4 = cInvalidVector;
-
- maintainQtyScout = 1;
- maintainUnitScout = cUnitTypeFenrisWolf;
- maintainDelayScout = 1;
- maintainGatherScout = cInvalidVector;
-
-
- // Init attack routes
- routeA = attackRoute("Attack Route A", cbRouteA1, cbRouteA2, cbRouteA3);
- routeB = attackRoute("Attack Route B", cbRouteB1, cbRouteB2, cbRouteB3);
- routeC = attackRoute("Attack Route C", cbRouteC1, cbRouteC2, cbRouteC3);
- routeD = attackRoute("Attack Route D", cbRouteD1, cbRouteD2, cbRouteD3);
- routeE = attackRoute("Attack Route E", cbRouteE1, cbRouteE2, cbRouteE3);
- routeF = attackRoute("Attack Route F", cbRouteF1, cbRouteF2, cbRouteF3);
-
-
-
-
- /*
- // 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);
- */
-
- // wakeup(0); // No wakeup trigger...call it immediately
-
- }
-
-
-
-
-
-
-
- // *****************************************************************************
- //
- // RULES
- //
- // *****************************************************************************
- rule cheatScout // Spawn a fenris wolf if none exist
- active
- minInterval 15
- {
- int count = -1;
- count = kbUnitCount(2, maintainUnitScout, cUnitStateAlive);
- if (count < maintainQtyScout)
- aiUnitCreateCheat( 2, maintainUnitScout, kbGetBlockPosition(cbAttackGather), "Scout group", maintainQtyScout - count);
-
- }
-
-
- rule restoreNormalDefense // Reset defense to normal after storming the forge
- inactive
- minInterval 45
- {
- aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbDefendPoint));
- aiEcho("Defend plan reset to normal location.");
- xsDisableSelf();
-
- }
-
-
- rule favorGenerator
- active
- minInterval 15
- {
- aiResourceCheat( 2, cResourceFavor, 100.0 ); // Max out the favor every 15 seconds
- kbEscrowAllocateCurrentResources(); // Make sure the escrow knows about it.
- }
-
-
- 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, maintainUnitScout, 1, 1, 1);
- aiPlanSetDesiredPriority(exploreID, 90);
- aiPlanSetInitialPosition(exploreID, kbGetBlockPosition(cbAttackGather));
- aiPlanSetActive(exploreID);
- }
- xsDisableSelf();
- }
-
-
-
-
- /*
- rule getWatchTower
- inactive
- minInterval 10
- group upgradeGroup
- {
- if (kbGetTechStatus(cTechWatchTower) == cTechStatusAvailable)
- {
- int x=-1;
- x = aiPlanCreate("WatchTower", cPlanResearch);
- aiPlanSetVariableInt(x, cResearchPlanTechID, 0, cTechWatchTower);
- aiPlanSetActive(x);
- xsDisableSelf();
- aiEcho("Getting Watch Tower");
- }
- }
- */
-
-
-
-
- rule goToAge2
- inactive
- minInterval 10
- {
- if ( xsGetTime() < age2Time)
- return;
- researchTech(cTechAge2Heimdall);
- xsDisableSelf();
- }
-
-
-
- rule goToAge3
- inactive
- mininterval 20
- {
- if ( xsGetTime() < age3Time )
- return;
- researchTech(cTechAge3Njord);
- xsDisableSelf();
- }
-
-
- rule goToAge4
- inactive
- mininterval 20
- {
- if ( xsGetTime() < age4Time )
- return;
- researchTech(cTechAge4Hel);
- xsDisableSelf();
- }
-
-
-
- rule getAge2UnitUpgrades
- inactive
- minInterval 20
- {
- if ( xsGetTime() < (age2Time + age2Time + age3Time)/3 )
- return; // Wait till 1/3 to age3
- // researchTech(cTechMediumInfantry);
- // researchTech(cTechMediumCavalry);
- xsDisableSelf();
- }
-
- rule getAge2ArmoryUpgrades
- inactive
- minInterval 20
- {
- if ( xsGetTime() < (age2Time + age3Time + age3Time)/3 )
- return; // Wait till 2/3 to age3
- // aiEcho("Getting age 2 armory upgrades");
- // researchTech(cTechCopperWeapons);
- // researchTech(cTechCopperMail);
- // researchTech(cTechCopperShields);
- xsDisableSelf();
- }
-
- rule getAge3UnitUpgrades
- inactive
- minInterval 20
- {
- if ( xsGetTime() < (age3Time+180000) )
- return;
- // researchTech(cTechHeavyInfantry);
- // researchTech(cTechHeavyCavalry);
- xsDisableSelf();
- }
-
- rule getAge3ArmoryUpgrades
- inactive
- minInterval 20
- {
- if ( xsGetTime() < (age3Time+300000) )
- return;
- // researchTech(cTechBronzeWeapons);
- // researchTech(cTechBronzeMail);
- // researchTech(cTechBronzeShields);
- xsDisableSelf();
- }
-
- rule getAge4UnitUpgrades
- inactive
- minInterval 20
- {
- if ( xsGetTime() < (age4Time+300000) )
- return;
- researchTech(cTechChampionInfantry);
- researchTech(cTechChampionCavalry);
- xsDisableSelf();
- }
-
- rule getAge4ArmoryUpgrades
- inactive
- minInterval 20
- {
- if ( xsGetTime() < (age4Time+600000) )
- 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 * attackMultiplier;
- 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();
- }
- */
-
-
- // Use walking woods as soon as we have LOS
- rule useWalkingWoods
- minInterval 5
- inactive
- {
- if (kbLocationVisible(kbGetBlockPosition(cbWalkingWoods)) == false)
- return;
-
- aiCastGodPowerAtPosition(cTechWalkingWoods, kbGetBlockPosition(cbWalkingWoods));
- aiEcho("Using walking woods at "+kbGetBlockPosition(cbWalkingWoods));
- xsDisableSelf();
- }
-
- /*
-
- // Use healing spring only after "forge" is true
- rule useHealingSpring
- minInterval 5
- inactive
- {
- if (forge == false)
- return;
-
- aiCastGodPowerAtPosition(cTechHealingSpring, kbGetBlockPosition(cbMountainGiantGather));
- aiEcho("Using Healing Spring at "+kbGetBlockPosition(cbMountainGiantGather));
- xsDisableSelf();
- } */
-
-
-
-
-
- /*
- rule useUndermine // Look for 2 walls 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("useUndermine");
-
- if ( configQuery(tempQuery, cUnitTypeAbstractWall, -1, cUnitStateAliveOrBuilding, 1, pVec, true, 25) == false)
- return;
- }
- else
- kbUnitQuerySetPosition(tempQuery, pVec); // Because pVec changes as army moves
-
- kbUnitQueryResetResults(tempQuery);
- int targetCount = kbUnitQueryExecute(tempQuery);
-
- if (targetCount < 2)
- return;
- targetUnit = kbUnitQueryGetResult(tempQuery, 0); // grab first wall
-
- // confirm LOS
- if ( kbUnitVisible(targetUnit) != true )
- {
- aiEcho("Undermine: Don't have LOS for unit "+targetUnit+" "+kbGetProtoUnitName(targetUnit));
- return;
- }
-
- aiEcho("Using Undermine at "+kbUnitGetPosition(targetUnit));
- if ( aiCastGodPowerAtPosition(cTechUndermine, kbUnitGetPosition(targetUnit)) == true)
- xsDisableSelf();
- else
- aiEcho("Undermine failed at "+kbUnitGetPosition(targetUnit));
- }
- */
-
-