home *** CD-ROM | disk | FTP | other *** search
Text File | 2002-09-10 | 33.0 KB | 1,013 lines |
- //==============================================================================
- // Scn07p2: AI Scenario Script for scenario 7 player 2
- //==============================================================================
- /*
- AI owner: Mike Kidd
- Scenario owner: Jeff Brown
-
- Overview:
- The player's challenge is to take down the main gate at Troy, starting
- from the south end of the map. The main gate is behind several layers of
- walls. Near the map center, just inside the outer walls, is a Trojan
- market. Trade units travel from this market to town centers at the east
- and west map ends, and these trade units generate "income" for Troy.
-
- Every time a trade unit completes a trip, Troy gets "income"...a counter
- is incremented. As this counter advances, Troy is allowed to research
- unit line upgrades, attack and armor upgrades, and age advances. If the
- player is effective at suppressing or eliminating this trade, he will
- face a rather weak army when assaulting Troy. Killed trade units will
- gradually be replaced, but replacement is slow enough to make killing
- worthwhile. If the market is destroyed, trade unit activity and replacement
- is suspended. A trickle of "income" is provided to Troy so that even with
- all trade suspended, it will eventually age up.
-
- Attacking the trade is also good because Troy will devote its armies to
- defense, rather than raiding the player's town. Troy's priorities are:
- 1) Guard the market
- 2) Guard and replace the trade units
- 3) Raid the player's town
-
- When the player reaches the inner walls, other reserve units will appear
- to help defend the walls, including cyclopses, catapults, etc. These units
- will not be used offensively. The reserve units are kept in two defense plans,
- one for hoplites near the gate, and one for cavalry further back. The
- defense plan radii should be such that the units respond appropriately.
-
- In addition to the entity-AI-only units scattered around the map, the
- CP trains hoplites and hippikons behind the innermost wall, attempting to
- maintain a target population. At attackInterval times, the CP drafts an army
- of attackSize units, and sends them at the target indicated by attackMode.
-
- AttackMode is set to the market if an army is within the outer walls. If an
- enemy army has been detected near either trade route in the last few minutes,
- the armies select targets based on a query centered on that area and restricted
- in radius to avoid the CP town. If the center is clear, and no enemy unit
- groups have been seen on the trade routes recently, then Troy goes offensive
- and attacks the HP's town.
-
- CP starts as Zeus in age 2, with Bolt and Cease Fire available.
- Age3: Dionysos (Bronze).
- Age 4: Hera (lightning storm).
-
- Difficulty: Implemented 7/17/2002
-
- 7/18/2002: Changed effect of killing donkeys. In addition to delaying upgrades,
- the attack group size is modified downward if the number of donkeys remaining isn't
- at the desired level. That is, by killing donkeys, the player reduces the size
- of attack groups.
-
- 7/24/2002: Totally removing the effects of trade on age upgrade times. Will
- make the trickle trade the only thing that counts, it will come in at a higher rate.
- Fixing a bug where the target unit type for the attack plans is set to -1. (Only matters when
- the query is empty.) Totally removing the queries for attack groups, we're not
- limiting the attack range any more based on trade damage.
-
- 7/31/2002: Tweaked the difficulty down a bit, to compensate for the added threat on the water.
- Decreased trade point accumulation (slower age upgrades) and reduced frequency of attacks.
-
- 8/20/2002: Fixed the side effects of age2EventHandler no longer firing on startup.
-
- 8/20/2002: Difficulty feedback. Made the following changes:
-
- Killing trade carts affects number of hoplite in attack group. Normally half the cav number,
- the number will be 1/2 cav times % trade carts remaining.
-
- Trade carts will not be replaced.
-
- Starting attack group size, and max size are reduced for hard and nightmare.
-
- 9/03/2002: Reduced attack size, maxAttackSize and defend qty's for easy and moderate.
- Slowed attack frequency on easy.
-
- 9/06/2002: Added check for the existance of the market. If it doesn't exist, leave donkeys at corner TCs.
- Also reduced attack group size by 15% on easy. Added seige to attack groups on hard/titan.
-
- 9/07/2002: Changed "need" from 0 to 1 for hoplites and hippikons in attack plan, to avoid weirdness in the unit selection.
- */
- //==============================================================================
-
-
- include "scn lib.xs";
-
- float tradePoints = 0.0; // Variable used to track how much trade Troy has been able to keep going.
- // Used to activate upgrades for this CP.
- float tradePointIncrement = 1.0; // Used to adjust difficulty level
-
- int routeWest=-1; // Attack route for west side
- int routeEast=-1; // Attack route for east side
- int routeCenter=-1; // Attack route to market area
-
- int lastAttackPlan=-1; // ID of the most recent attack plan, for god power monitoring
- int attackQuery=-1; // Query used for target selection in all attack plans
- int defendPlan = -1;
- int defendPlan2 = -1; // Extra for hippikons
-
- vector attackVector = vector(-1,-1,-1); // Defines the center of the area in which attack plans look for targets.
- float attackRadius = 75.0; // How far away from the vector can it select targets?
-
-
- int attackInterval=360000; // Seconds between attacks
- int nextAttackTime=360000; // Time for next attack
- float attackSize=2.55; // Number of units
- float attackMultiplier = 1.2;
- int maxAttackSize=6;
- int hopliteQty = 7;
- int hippikonQty = 9;
- int trainInterval = 20; // Seconds between training hoplites, hippikons
-
- int lastWestAttack=-600000; // Last time west trade route was attacked.
- int lastEastAttack=-600000;
-
- bool okToUseLightning = false; // Set to true in the lightning() aiFunc.
-
- /* This functionality suppressed 7/24/2002
- int attackMode=0; // Attack mode. Determines CP AI priorities. Values:
- const int cAttackModeHPTown = 0; // 0: Hasn't been attacked, primary focus is HP city.
- const int cAttackModeDefense = 1; // 1: Deep attack, enemy units inside fortification...all-out defense
- const int cAttackModeWest = 2; // 2: Defending west side trade route
- const int cAttackModeEast = 3; // 3: Defending east side trade route
- */
-
- const string cWestSide="3470"; // Cinematic block markers
- const string cCenter="3469";
- const string cEastSide="3471";
- const string cWestGate="3514";
- const string cEastGate="3515";
- const string cHPTown="3516";
- const string cInfGather="3472";
- const string cCavGather="3473";
- const string cMarket="3660";
- const string cWestTown="3661";
- const string cEastTown="3662";
- const string cAttackGather="7673";
-
- int donkeyQueryMiddle=-1; // Checks for idle donkeys at market
- int donkeyQueryWest=-1; // Checks for idle donkeys at west town
- int donkeyQueryEast=-1; // Checks for idle donkeys at east town
- int donkeyQueryIdleOther=-1;
- bool donkeyGoEast=false; // Flip-flop controller for donkey direction from center market
- int TCQueryWest=-1; // Query to find out if west TC is still CP-owned
- int TCQueryEast=-1; // Ditto east
- int marketQuery=-1; // Ditto market
-
- int donkeyQty = 8;
-
- // *****************************************************************************
- //
- // FUNCTIONS
- //
- // *****************************************************************************
-
-
-
- void age2EventHandler(int bogus=-1)
- {
-
- }
-
- void age3EventHandler(int bogus=-1)
- {
- xsEnableRule("useBronze");
- }
-
- void age4EventHandler(int bogus=-1)
- {
- xsEnableRule("useLightningStorm");
- }
-
-
- void lightning(int ignore = 0)
- {
- aiEcho("Lightning func called, it is now OK to use lightning when available.");
- okToUseLightning = true;
- }
-
-
- void tradePoint(int parm=1) // Called via a trigger each time a caravan finishes a trade route.
- // On 7/24, changed it so that trickleTrade is the only thing that calls this.
- {
- tradePoints = tradePoints+tradePointIncrement;
- //aiEcho("TradePoint firing, total is "+tradePoints);
- }
-
-
- /* Disabled 7/24/2002
- void attack(int side=-1) // Called via a trigger (actually, now a rule) when a caravan is attacked, 0 for west, 1 for east
- {
- if (xsGetTime() < 10000)
- return; // avoid initial false alarms
- //aiEcho("I'm being attacked! ("+side+")");
-
- if (side == 0)
- lastWestAttack = xsGetTime();
-
- if (side == 1)
- lastEastAttack = xsGetTime();
- }
- */
-
-
-
-
- void testAttack()
- {
- int attackID=aiPlanCreate("Test Attack "+timeString()+" ", cPlanAttack);
- if (attackID < 0)
- {
- return;
- }
-
- if (aiPlanSetVariableInt(attackID, cAttackPlanPlayerID, 0, 1) == false)
- {
- return;
- }
-
- if (aiPlanSetNumberVariableValues(attackID, cAttackPlanTargetTypeID, 2, true) == false)
- {
- return;
- }
-
- float adjustedAttackSize = -1; // Adjusts attack size to account for number of donkeys MIA
- float donkeyActual = 0.0;
- float donkeyRatio = 0.0;
- donkeyActual = kbUnitCount(2, cUnitTypeCaravanGreek, cUnitStateAlive);
- donkeyRatio = donkeyActual/donkeyQty;
- adjustedAttackSize = donkeyRatio*attackSize; // Used to modify number of hoplites.
-
- if ( donkeyRatio < .75)
- {
- aiEcho("Donkey ratio "+donkeyRatio);
- aiEcho("Attack group reduced from "+attackSize+" to "+adjustedAttackSize+".");
- }
-
- // Query disabled 7/24/2002 aiPlanSetVariableInt(attackID, cAttackPlanQueryID, 0, attackQuery);
-
- // add "unit" and "building" to attack list
- aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 0, cUnitTypeUnit);
- aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 1, cUnitTypeBuilding);
-
- /* Attack modes disabled 7/24/2002
- if (attackMode == cAttackModeWest)
- aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeWest);
- else if (attackMode == cAttackModeEast)
- aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeEast);
- else */if (aiRandInt(2) > 0)
- aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeEast);
- else
- aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeWest);
-
- aiPlanSetVariableInt(attackID, cAttackPlanLastRefreshTime, 0, 30);
-
- aiPlanSetVariableVector(attackID, cAttackPlanGatherPoint, 0, kbGetBlockPosition(cAttackGather));
- aiPlanSetVariableFloat(attackID, cAttackPlanGatherDistance, 0, 15.0);
-
- aiPlanAddUnitType(attackID, cUnitTypeHippikon, 1, (2*attackSize+1)/3, (2*attackSize+1)/3);
- aiPlanAddUnitType(attackID, cUnitTypeHoplite, 1, (adjustedAttackSize+2)/3, (adjustedAttackSize+2)/3);
- if (aiGetWorldDifficulty() > 1) // We're on hard or nightmare
- aiPlanAddUnitType(attackID, cUnitTypePetrobolos, 0, aiGetWorldDifficulty()-1, aiGetWorldDifficulty()-1);
-
- aiPlanSetInitialPosition(attackID, kbGetBlockPosition(cAttackGather));
- aiPlanSetRequiresAllNeedUnits(attackID, true);
- aiPlanSetActive(attackID);
- aiEcho("Activating attack plan "+attackID);
- // if (lastAttackPlan >= 0)
- // aiPlanDestroy(lastAttackPlan); // free up last set of units?
- lastAttackPlan = attackID; // update the global var
- }
-
-
-
-
-
- void main()
- {
-
- aiEcho("Starting Scn07p2.xs");
- aiRandSetSeed();
- kbSetTownLocation(kbGetBlockPosition(cCenter));
- //Calculate some areas.
- kbAreaCalculate(1200.0);
-
- aiSetAttackResponseDistance(20.0);
-
- // Kill escrows
- kbEscrowSetPercentage( cEconomyEscrowID, cAllResources, 0.0);
- kbEscrowSetPercentage( cMilitaryEscrowID, cAllResources, 0.0);
- kbEscrowAllocateCurrentResources();
-
- aiSetAgeEventHandler(cAge2, "age2EventHandler");
- aiSetAgeEventHandler(cAge3, "age3EventHandler");
- aiSetAgeEventHandler(cAge4, "age4EventHandler");
-
-
- routeWest = attackRoute("West Attack Route",cInfGather,cCenter,cWestGate);
- routeEast = attackRoute("East Attack Route",cInfGather,cCenter,cEastGate);
- routeCenter = attackRoute("Center Attack Route",cInfGather,cCenter);
-
- attackVector = kbGetBlockPosition(cHPTown); // in HP's town
- attackRadius = 75.0;
-
- // Set up the attack query with the appropriate vector
- /* Query disabled 7/24/2002
- if (attackQuery < 0)
- {
- attackQuery = kbUnitQueryCreate("Attack Query");
- configQuery(attackQuery, cUnitTypeUnit, -1, cUnitStateAlive, 1, kbGetBlockPosition(cHPTown), false, 200.0); // really anywhere
- }
- */
-
- aiEcho("Difficulty = "+aiGetWorldDifficulty());
- switch(aiGetWorldDifficulty())
- {
- case 1:
- {
- attackInterval = 300000;
- nextAttackTime = 240000;
- attackSize = 4;
- attackMultiplier = 1.2;
- maxAttackSize = 10;
- hopliteQty = 8;
- hippikonQty = 12;
- trainInterval = 20;
- tradePointIncrement = 1.8;
- break;
- }
- case 2:
- {
- attackInterval = 230000;
- nextAttackTime = 120000;
- attackSize = 6;
- attackMultiplier = 1.2;
- maxAttackSize = 20;
- hopliteQty = 15;
- hippikonQty = 20;
- trainInterval = 15;
- tradePointIncrement = 2.5;
- break;
- }
- case 3:
- {
- attackInterval = 180000;
- nextAttackTime = 30000;
- attackSize = 6;
- attackMultiplier = 1.2;
- maxAttackSize = 30;
- hopliteQty = 20;
- hippikonQty = 30;
- trainInterval = 8;
- tradePointIncrement = 4.0;
- break;
- }
- }
-
- // Init low-priority defend plan to manage hoplites
- defendPlan =aiPlanCreate("Defend Plan", cPlanDefend);
- if (defendPlan >= 0)
- {
- aiPlanAddUnitType(defendPlan, cUnitTypeHoplite, 0, 200, 200); // All unassigned mil units
- aiPlanSetDesiredPriority(defendPlan, 10); // Way low, below scouting and attack
- aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cInfGather));
- aiPlanSetVariableFloat(defendPlan, cDefendPlanEngageRange, 0, 40);
- aiPlanSetVariableBool(defendPlan, cDefendPlanPatrol, 0, false);
- aiPlanSetVariableFloat(defendPlan, cDefendPlanGatherDistance, 0, 10.0);
- aiPlanSetInitialPosition(defendPlan, kbGetBlockPosition(cInfGather));
- aiPlanSetUnitStance(defendPlan, cUnitStanceDefensive);
-
- aiPlanSetVariableInt(defendPlan, cDefendPlanRefreshFrequency, 0, 5);
- aiPlanSetNumberVariableValues(defendPlan, cDefendPlanAttackTypeID, 2, true);
- aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 0, cUnitTypeUnit);
- aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 1, cUnitTypeBuilding);
-
- aiPlanSetActive(defendPlan);
- aiEcho("Creating defend plan");
- }
-
- // Extra one for cav
- defendPlan2 =aiPlanCreate("Hippikon Defend Plan", cPlanDefend);
- if (defendPlan2 >= 0)
- {
- aiPlanAddUnitType(defendPlan2, cUnitTypeHippikon, 0, 200, 200); // All unassigned mil units
- aiPlanSetDesiredPriority(defendPlan2, 10); // Way low, below scouting and attack
- aiPlanSetVariableVector(defendPlan2, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cCavGather));
- aiPlanSetVariableFloat(defendPlan2, cDefendPlanEngageRange, 0, 50);
- aiPlanSetVariableBool(defendPlan2, cDefendPlanPatrol, 0, false);
- aiPlanSetVariableFloat(defendPlan2, cDefendPlanGatherDistance, 0, 10.0);
- aiPlanSetInitialPosition(defendPlan2, kbGetBlockPosition(cCavGather));
- aiPlanSetUnitStance(defendPlan2, cUnitStanceDefensive);
-
- aiPlanSetVariableFloat(defendPlan2, cDefendPlanRefreshFrequency, 0, 5);
- aiPlanSetNumberVariableValues(defendPlan2, cDefendPlanAttackTypeID, 2, true);
- aiPlanSetVariableInt(defendPlan2, cDefendPlanAttackTypeID, 0, cUnitTypeUnit);
- aiPlanSetVariableInt(defendPlan2, cDefendPlanAttackTypeID, 1, cUnitTypeBuilding);
-
- aiPlanSetActive(defendPlan2);
- aiEcho("Creating defend plan");
- }
-
-
- // Set up the queries for idle donkeys
- donkeyQueryWest = kbUnitQueryCreate("Idle Donkey West");
- donkeyQueryMiddle = kbUnitQueryCreate("Idle Donkey Middle");
- donkeyQueryEast = kbUnitQueryCreate("Idle Donkey East");
- donkeyQueryIdleOther = kbUnitQueryCreate("Idle Donkeys Elsewhere");
-
- configQuery(donkeyQueryWest, cUnitTypeCaravanGreek, cActionIdle, cUnitStateAlive, 2, kbGetBlockPosition(cWestTown), false, 20.0);
- configQuery(donkeyQueryEast, cUnitTypeCaravanGreek, cActionIdle, cUnitStateAlive, 2, kbGetBlockPosition(cEastTown), false, 20.0);
- configQuery(donkeyQueryMiddle, cUnitTypeCaravanGreek, cActionIdle, cUnitStateAlive, 2, kbGetBlockPosition(cMarket), false, 20.0);
- configQuery(donkeyQueryIdleOther, cUnitTypeCaravanGreek, cActionIdle, cUnitStateAlive, 2);
-
- // See if the CP still owns outlying settlements
- TCQueryWest = kbUnitQueryCreate("West Town");
- TCQueryEast = kbUnitQueryCreate("East Town");
- marketQuery = kbUnitQueryCreate("Market query");
- configQuery(TCQueryWest, cUnitTypeSettlementLevel1, -1, cUnitStateAlive, 2, kbGetBlockPosition(cWestTown), false, 10.0);
- configQuery(TCQueryEast, cUnitTypeSettlementLevel1, -1, cUnitStateAlive, 7, kbGetBlockPosition(cEastTown), false, 10.0); // Player 7 owns it
- configQuery(marketQuery, cUnitTypeMarket, -1, cUnitStateAlive, 2, kbGetBlockPosition(cMarket), false, 10.0);
-
- xsEnableRule("useCeaseFire");
- }
-
-
-
-
-
-
-
- // *****************************************************************************
- //
- // RULES
- //
- // *****************************************************************************
-
-
- // See what the attack query says
- rule dumpAttack
- inactive
- minInterval 30
- {
- int query=-1;
- int count = -1;
- int i=-1;
-
- if (lastAttackPlan < 0)
- return;
-
- query = aiPlanGetVariableInt(lastAttackPlan, cAttackPlanQueryID, 0);
-
- if (query < 0)
- {
- aiEcho("Last attack plan has bad query ID");
- return;
- }
-
- kbUnitQueryResetResults(query);
- count = kbUnitQueryExecute(query);
- aiEcho("Attack Query found "+count+" results:");
- for (i=0; < count)
- aiEcho(" "+kbUnitQueryGetResult(query, i));
-
-
- }
-
-
-
- rule seeDonkeyRun
- active
- minInterval 10
- { // Look for idle donkeys at the market or side towns, and get them moving.
- int count = -1;
- int donkey = -1;
-
- bool westTC = false;
- bool eastTC = false;
- bool market = false;
-
- kbUnitQueryResetResults(TCQueryWest);
- if (kbUnitQueryExecute(TCQueryWest) > 0)
- westTC = true;
- kbUnitQueryResetResults(TCQueryEast);
- if (kbUnitQueryExecute(TCQueryEast) > 0)
- eastTC = true;
- kbUnitQueryResetResults(marketQuery);
- if (kbUnitQueryExecute(marketQuery) > 0)
- market = true;
-
-
- // Check middle
- kbUnitQueryResetResults(donkeyQueryMiddle);
- count = kbUnitQueryExecute(donkeyQueryMiddle);
- if (count > 0)
- {
- for (i=0; <count) // Find each donkey, scoot them alternately east or west, subject to TC availability
- {
- donkey = kbUnitQueryGetResult(donkeyQueryMiddle, i);
- if (donkeyGoEast == true)
- {
- if (eastTC == true)
- {
- aiTaskUnitMove(donkey,kbGetBlockPosition(cEastTown));
- }
- donkeyGoEast = false;
- }
- else
- {
- if (westTC == true)
- {
- aiTaskUnitMove(donkey,kbGetBlockPosition(cWestTown));
- }
- donkeyGoEast = true;
- }
- }
- }
-
- // Check west
- kbUnitQueryResetResults(donkeyQueryWest);
- count = kbUnitQueryExecute(donkeyQueryWest);
- if (count > 0)
- {
- if (market == true)
- {
- for (i=0; <count) // Find each donkey, scoot them to the market
- {
- donkey = kbUnitQueryGetResult(donkeyQueryWest, i);
- aiTaskUnitMove(donkey,kbGetBlockPosition(cMarket));
- //tradePoint(1); // Count it as a complete run...counting this end to avoid credit for newly trained donkeys at market
- }
- }
- }
-
-
- // Check east
- kbUnitQueryResetResults(donkeyQueryEast);
- count = kbUnitQueryExecute(donkeyQueryEast);
- if (count > 0)
- {
- if (market == true)
- {
- for (i=0; <count) // Find each donkey, scoot them to the market
- {
- donkey = kbUnitQueryGetResult(donkeyQueryEast, i);
- aiTaskUnitMove(donkey,kbGetBlockPosition(cMarket));
- //tradePoint(1); // Count it as a complete run
- }
- }
- }
- /*
- // Check other
- kbUnitQueryResetResults(donkeyQueryIdleOther);
- count = kbUnitQueryExecute(donkeyQueryIdleOther);
- if (count > 0)
- {
- for (i=0; <count) // Find each donkey, scoot them to the market
- {
- donkey = kbUnitQueryGetResult(donkeyQueryIdleOther, i);
- aiTaskUnitMove(donkey,kbGetBlockPosition(cMarket));
- //tradePoint(1); // Count it as a complete run
- }
- }
- */
-
- }
-
-
- /* Disabled 7/24/2002
-
- rule setAttackMode // Evaluates CP's top-level attack military priorities
- active
- minInterval 5
- {
- int currentTime = 0;
-
- currentTime = xsGetTime();
-
- static int invaderQuery = -1;
- static int westArmyQuery = -1;
- static int eastArmyQuery = -1;
-
- if ( invaderQuery < 0 ) // Set up query if it doesn't exist
- {
- invaderQuery = kbUnitQueryCreate("Invader Query");
- // Enemy units within 30 meters of center mark
- configQuery(invaderQuery, cUnitTypeMilitary, -1, cUnitStateAlive, 1, kbGetBlockPosition(cCenter), false, 30.0);
- }
-
- if ( westArmyQuery < 0 ) // Set up query if it doesn't exist
- {
- westArmyQuery = kbUnitQueryCreate("West Enemy Army Query");
- // Enemy units within 50 meters of west mark
- configQuery(westArmyQuery, cUnitTypeMilitary, -1, cUnitStateAlive, 1, kbGetBlockPosition(cWestSide), false, 50.0);
- }
-
- if ( eastArmyQuery < 0 ) // Set up query if it doesn't exist
- {
- eastArmyQuery = kbUnitQueryCreate("East Enemy Army Query");
- // Enemy units within 50 meters of west mark
- configQuery(eastArmyQuery, cUnitTypeMilitary, -1, cUnitStateAlive, 1, kbGetBlockPosition(cEastSide), false, 50.0);
- }
-
-
- // Check to see if either side is invaded
- kbUnitQueryResetResults(westArmyQuery);
- if (kbUnitQueryExecute(westArmyQuery) > 3)
- attack(0); // Register a west side attack
- kbUnitQueryResetResults(eastArmyQuery);
- if (kbUnitQueryExecute(eastArmyQuery) > 3)
- attack(1); // Register an east side attack
-
- // Check for center invaders
- kbUnitQueryResetResults(invaderQuery);
- if ( kbUnitQueryExecute(invaderQuery) > 2 ) // More than two units?
- {
- if (attackMode != cAttackModeDefense)
- aiEcho("Attack mode: Defense");
- attackMode = cAttackModeDefense;
- kbUnitQuerySetPosition(attackQuery, kbGetBlockPosition(cCenter));
- kbUnitQuerySetMaximumDistance(attackQuery, 50.0);
-
- return; // Defense mode overrides others
- }
-
- // If no center attack, see if we've been attacked on the east or west side recently.
- if (lastWestAttack < lastEastAttack) // East attacked most recently
- {
- if ( lastEastAttack > (currentTime-360000) ) // East attacked within last six minutes
- {
- if (attackMode != cAttackModeEast)
- aiEcho("Attack mode: East");
- attackMode = cAttackModeEast;
- kbUnitQuerySetPosition(attackQuery, kbGetBlockPosition(cEastSide)); // East block
- kbUnitQuerySetMaximumDistance(attackQuery, 50.0);
- return;
- }
- }
- else // West attacked most recently
- {
- if ( lastWestAttack > (currentTime-360000)) // West attacked within last six minutes
- {
- if (attackMode != cAttackModeWest)
- aiEcho("Attack mode: West");
- attackMode = cAttackModeWest;
- kbUnitQuerySetPosition(attackQuery, kbGetBlockPosition(cWestSide)); // East block
- kbUnitQuerySetMaximumDistance(attackQuery, 50.0);
- return;
- }
- }
-
-
- // If we get here, attack the player.
- if (attackMode != cAttackModeHPTown)
- aiEcho("Attack mode: HP Town");
- attackMode = cAttackModeHPTown;
- kbUnitQuerySetPosition(attackQuery, kbGetBlockPosition(cHPTown)); // HP town
- kbUnitQuerySetMaximumDistance(attackQuery, 200.0);
-
- }
- */
-
-
-
- rule testArmy
- active
- minInterval 20
- {
- maintainUnit(cUnitTypeHoplite, hopliteQty, kbGetBlockPosition(cInfGather), trainInterval);
- maintainUnit(cUnitTypeHippikon, hippikonQty, kbGetBlockPosition(cCavGather), trainInterval);
- maintainUnit(cUnitTypePegasus, 1, kbGetBlockPosition(cAttackGather), 20);
- if (aiGetWorldDifficulty() > 1) // We're hard or titan
- maintainUnit(cUnitTypePetrobolos, aiGetWorldDifficulty(), kbGetBlockPosition(cAttackGather), 30);
- xsDisableSelf();
- }
-
-
- rule maintainDonkeys
- active
- minInterval 30
- {
- //maintainUnit(cUnitTypeCaravanGreek, donkeyQty, kbGetBlockPosition(cMarket), 60); // Keep 8 donkeys, 1 minute between respawns, rebuild at market
- xsDisableSelf();
- }
-
-
- rule trickleTrade
- active
- minInterval 30
- {
- tradePoint(); // Give a minimal trickle of trade points even if the CP loses all donkeys.
- // 7/24/2000: This is the only source of trade points
- }
-
-
- // Research chain...get progressively more upgrades as the trade points pile up
-
- rule firstUnitUpgrades
- active
- minInterval 5
- {
- if (tradePoints < 15)
- return;
- researchTech(cTechMediumCavalry);
- researchTech(cTechMediumInfantry);
- tradePoints = 0;
- xsDisableSelf();
- xsEnableRule("firstAttackUpgrade");
- }
-
- rule firstAttackUpgrade
- inactive
- minInterval 5
- {
- if (tradePoints < 15)
- return;
- researchTech(cTechCopperWeapons);
- researchTech(cTechCopperMail);
- researchTech(cTechCopperShields);
- tradePoints = 0;
- xsDisableSelf();
- xsEnableRule("age3Upgrade");
- }
-
- rule age3Upgrade
- inactive
- minInterval 5
- {
- if (tradePoints < 30)
- return;
- researchTech(cTechAge3Dionysos);
- tradePoints = 0;
- xsDisableSelf();
- xsEnableRule("secondUnitUpgrades");
- }
-
- rule secondUnitUpgrades
- inactive
- minInterval 5
- {
- if (tradePoints < 15)
- return;
- researchTech(cTechHeavyInfantry);
- researchTech(cTechHeavyCavalry);
- tradePoints = 0;
- xsDisableSelf();
- xsEnableRule("secondAttackUpgrade");
- }
-
- rule secondAttackUpgrade
- inactive
- minInterval 5
- {
- if (tradePoints < 15)
- return;
- researchTech(cTechBronzeWeapons);
- researchTech(cTechBronzeMail);
- researchTech(cTechBronzeShields);
- tradePoints = 0;
- xsDisableSelf();
- xsEnableRule("age4Upgrade");
- }
-
- rule age4Upgrade
- inactive
- minInterval 5
- {
- if (tradePoints < 30)
- return;
- researchTech(cTechAge4Hera);
- tradePoints = 0;
- xsDisableSelf();
- xsEnableRule("thirdUnitUpgrades");
- }
-
- rule thirdUnitUpgrades
- inactive
- minInterval 5
- {
- if (tradePoints < 15)
- return;
- researchTech(cTechChampionCavalry);
- researchTech(cTechChampionInfantry);
- tradePoints = 0;
- xsDisableSelf();
- xsEnableRule("thirdAttackUpgrade");
- }
-
- rule thirdAttackUpgrade
- inactive
- minInterval 5
- {
- if (tradePoints < 15)
- return;
- researchTech(cTechIronWeapons);
- researchTech(cTechIronMail);
- researchTech(cTechIronShields);
- tradePoints = 0;
- xsDisableSelf();
- // xsEnableRule("next");
- }
-
-
-
- rule scout
- active
- {
- // just set up an explore plan
- int exploreID = aiPlanCreate("Explore", cPlanExplore);
- if(exploreID >= 0)
- {
- //aiPlanAddVariableFloat( exploreID, cExplorePlanLOSMultiplier, "LOS Multiplier", 1);
- aiPlanSetVariableFloat( exploreID, cExplorePlanLOSMultiplier, 0, 4.0 );
- aiPlanAddUnitType(exploreID, cUnitTypeScout, 1, 1, 1);
- aiPlanSetActive(exploreID);
- }
- // Add a pegasus plan
- int exploreAirID = aiPlanCreate("Air Explore", cPlanExplore);
- if(exploreAirID >= 0)
- {
- //aiPlanAddVariableFloat( exploreID, cExplorePlanLOSMultiplier, "LOS Multiplier", 1);
- aiPlanSetVariableFloat( exploreAirID, cExplorePlanLOSMultiplier, 0, 4.0 );
- aiPlanAddUnitType(exploreAirID, cUnitTypePegasus, 1, 1, 1);
- aiPlanSetActive(exploreAirID);
- }
- xsDisableSelf();
- }
-
-
-
-
- rule useBolt
- minInterval 5
- active
- {
- if (xsGetTime() < (13*60*1000) )
- return; // Don't bolt until 13:00
-
- static int tempQuery = -1;
- if (tempQuery < 0)
- { // Doesn't exist, set it up
- tempQuery = kbUnitQueryCreate("useBolt");
- if ( configQuery(tempQuery, cUnitTypeHippikon, -1, cUnitStateAlive, 1) == false)
- return;
- }
- kbUnitQueryResetResults(tempQuery);
- int targetCount = kbUnitQueryExecute(tempQuery);
-
- if (targetCount < 1)
- return;
-
- int targetUnit = kbUnitQueryGetResult(tempQuery, 0); // grab first unit
-
- // confirm LOS
- if ( kbUnitVisible(targetUnit) != true )
- return;
-
- // whoop 'em
- if (aiCastGodPowerAtUnit(cTechBolt, targetUnit) == true)
- xsDisableSelf();
- }
-
-
-
-
- rule useLightningStorm
- minInterval 5
- inactive
- {
- if (okToUseLightning == false)
- return;
-
- // look for a group of 8 enemy units, at my main army's location
- int targetUnit = -1;
- int attackArmyID = -1;
-
- vector pVec = aiPlanGetLocation(lastAttackPlan);
- if (xsVectorGetX(pVec)<0)
- return;
-
- static int tempQuery = -1;
- if (tempQuery < 0)
- { // Doesn't exist, set it up
- tempQuery = kbUnitQueryCreate("useLightningStorm");
-
- if ( configQuery(tempQuery, cUnitTypeMilitary, -1, cUnitStateAlive, 1, pVec, true, 50) == false)
- return;
- }
- else
- kbUnitQuerySetPosition(tempQuery, pVec); // Because pVec changes as army moves
- kbUnitQueryResetResults(tempQuery);
- int targetCount = kbUnitQueryExecute(tempQuery);
- if (targetCount < 8)
- return;
-
- targetUnit = kbUnitQueryGetResult(tempQuery, 0); // grab first unit
-
- // confirm LOS
- if ( kbUnitVisible(targetUnit) != true )
- {
- aiEcho("Don't have LOS to unit "+targetUnit);
- // return;
- }
-
- aiEcho("Using Lightning Storm");
- if ( aiCastGodPowerAtPosition(cTechLightningStorm, kbUnitGetPosition(targetUnit)) == true)
- xsDisableSelf();
-
- }
-
-
- rule useBronze
- minInterval 5
- inactive
- {
- // look for a group of 6 enemy units, at my main army's location
- int attackArmyID = -1;
-
- vector pVec = aiPlanGetLocation(lastAttackPlan);
- if (xsVectorGetX(pVec)<0)
- return;
-
- static int tempQuery = -1;
- if (tempQuery < 0)
- { // Doesn't exist, set it up
- tempQuery = kbUnitQueryCreate("useBronze");
-
- if ( configQuery(tempQuery, cUnitTypeMilitary, -1, cUnitStateAlive, 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;
-
- aiEcho("Using Bronze");
- if ( aiCastGodPowerAtPosition(cTechBronze, pVec) == true)
- {
- aiEcho("Deactivating UseBronze");
- xsDisableSelf();
- }
- }
-
-
-
- rule useCeaseFire
- minInterval 5
- inactive
- {
- // look for a group of 6 enemy units at my town
- int targetUnit = -1;
- int attackArmyID = -1;
-
-
- static int tempQuery = -1;
- if (tempQuery < 0)
- { // Doesn't exist, set it up
- tempQuery = kbUnitQueryCreate("useCeaseFire");
- if ( configQuery(tempQuery, cUnitTypeMilitary, -1, cUnitStateAlive, 1, kbGetTownLocation(), true, 30) == false)
- return;
- }
- kbUnitQueryResetResults(tempQuery);
- int targetCount = kbUnitQueryExecute(tempQuery);
-
- if (targetCount < 6)
- return;
- targetUnit = kbUnitQueryGetResult(tempQuery, 0); // grab first unit
-
- // confirm LOS
- if ( kbUnitVisible(targetUnit) != true )
- {
- aiEcho("Don't have LOS to unit "+targetUnit);
- // return;
- }
-
- aiEcho("Using Cease Fire");
- if ( aiCastGodPowerAtPosition(cTechCeaseFire, kbUnitGetPosition(targetUnit)) == true)
- xsDisableSelf();
- }
-
-
-
-
-
- rule attackGenerator
- minInterval 10
- active
- {
- //aiEcho("attack check running, next time is "+nextAttackTime);
- if ( xsGetTime() < nextAttackTime )
- return;
-
- testAttack();
- nextAttackTime = xsGetTime() + attackInterval;
- attackSize = attackSize * attackMultiplier;
- if (attackSize > maxAttackSize)
- attackSize = maxAttackSize;
- aiEcho("Next attack size will be "+attackSize+".");
- }
-
-
-
-
-
-