home *** CD-ROM | disk | FTP | other *** search
- //==============================================================================
- // Scn33p2: AI Scenario Script for scenario 33 player 2
- //==============================================================================
- /*
- AI owner: Mike Kidd
- Scenario owner: Jeff Brown
-
- Overview:
-
- Player 2 is Norse, and appears to the HP to be the same as player 6 (Greek).
- Player 2's role is to steadily harrass the player continuously, from the time
- of the wakeup() call.
-
- */
- //==============================================================================
-
-
- include "scn lib.xs";
-
-
- // *****************************************************************************
- //
- // Globals
- //
- // *****************************************************************************
-
-
- // Cinematic blocks
-
- const string cbDefendPoint = "2883";
- const string cbAttackGather = "2889";
- const string cbTownCenter = "2886";
- const string cbGarg = "2898"; // Gargarensis's hideout
- const string cbRouteA1 = "2891"; // East side
- const string cbRouteA2 = "2892";
- const string cbRouteA3 = "2893";
- const string cbRouteB1 = "2891"; // Center
- const string cbRouteB2 = "2892";
- const string cbRouteB3 = "2894";
- const string cbRouteC1 = "2891"; // West
- const string cbRouteC2 = "2895";
- const string cbRouteC3 = "2896";
- const string cbUndermine = "3005";
-
-
- // Attack routes and queries
- int routeA = -1;
- int routeB = -1;
- int routeC = -1;
-
-
- // Army control
- int lastAttackPlan = -1; // Used to find "my army" for god power position info
- int penultimatePlan = -1; // Need to track 2nd last for undermine
- int defendPlan = -1;
- int explorePlan = -1;
-
- // The following are set in main() based on difficulty level.
- int nextAttackTime = 180000; // Will be adjusted for the wakeup time
- int attackInterval = 240000; // Attack every 4:00
- float attackSize = 4.0;
- float attackMultiplier = 1.2;
- int maxAttackSize = 8;
-
- // Upgrade timer control
- int startTime = -1;
- int endTime = -1;
- int undermineTime = 1500000; // 25 min on easy, i.e. never
- int undermineInterval = 240000; // 4 minutes
-
-
- 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 = cUnitTypeUlfsark;
- 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 difficulty = -1; // Global to store difficulty, set early in main.
-
-
-
- // *****************************************************************************
- //
- // 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();
- endTime = startTime + 20*60*1000; // When does the army arrive?
-
- if (age2Time > 0)
- age2Time = age2Time + startTime; // Adjust for delay in wakeup.
- if (age3Time > 0)
- age3Time = age3Time + startTime;
- if (age4Time > 0)
- age4Time = age4Time + startTime;
- if (nextAttackTime > 0)
- nextAttackTime = nextAttackTime + startTime;
-
- undermineTime = undermineTime + 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);
-
- //*** Add a few portable rams
- maintainUnit(cUnitTypePortableRam, 8, cInvalidVector, 1);
-
- // 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");
- xsEnableRule("upgradeGenerator");
- xsEnableRule("useUndermine");
- //xsEnableRule("useFimbulwinter"); // Disabled because Ian can't handle it. ;-)
- }
-
-
- void flood(int ignore=0)
- {
- aiEcho("Flood called at "+timeString());
- // aiFunc trigger: Tells us to make one uber-group for attacking.
- nextAttackTime = xsGetTime() + attackInterval;
-
- int size = -1;
- size = maxAttackSize*2;
-
- int attackID=aiPlanCreate("Final 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);
-
- aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeB);
-
- aiPlanSetVariableVector(attackID, cAttackPlanGatherPoint, 0, kbGetBlockPosition(cbAttackGather));
- aiPlanSetVariableFloat(attackID, cAttackPlanGatherDistance, 0, 20.0);
-
-
- aiPlanAddUnitType(attackID, cUnitTypeMilitary, 0, size, size); // all
-
- aiPlanSetInitialPosition(attackID, kbGetBlockPosition(cbAttackGather));
- aiPlanSetRequiresAllNeedUnits(attackID, false);
- aiPlanSetDesiredPriority(attackID, 50); // Less than scouting, more than defense
- aiPlanSetActive(attackID);
- aiEcho("Activating attack plan "+attackID+" with up to "+size+" units.");
- penultimatePlan = lastAttackPlan;
- lastAttackPlan = attackID; // update the global var
-
- }
-
-
- 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, 3, true) == false)
- return;
-
- aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 0, cUnitTypeUnit);
- aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 1, cUnitTypeBuilding);
- aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 2, cUnitTypeAbstractWall);
-
-
-
- switch(aiRandInt(3))
- {
- case 0:
- {
- aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeA);
- break;
- }
- case 1:
- {
- aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeB);
- break;
- }
- case 2:
- {
- aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeC);
- break;
- }
- }
-
- aiPlanSetVariableVector(attackID, cAttackPlanGatherPoint, 0, kbGetBlockPosition(cbAttackGather));
- aiPlanSetVariableFloat(attackID, cAttackPlanGatherDistance, 0, 20.0);
-
- aiPlanAddUnitType(attackID, maintainUnit1, 0, (size+8)/10, (size+8)/10); // boar
- aiPlanAddUnitType(attackID, maintainUnit2, 0, (size+2)/10, (size+2)/10); // wolf
- aiPlanAddUnitType(attackID, maintainUnit3, 0, (4*size+5)/10, (4*size+5)/10); // Jarl
-
- if ( (endTime - xsGetTime()) < 15*60*1000)
- {
- aiEcho(" adding seige to attack plan.");
- aiPlanAddUnitType(attackID, maintainUnit4, 0, (2*size+3)/10, (2*size+3)/10); // huskarl
- aiPlanAddUnitType(attackID, cUnitTypePortableRam, 0, (2*size+7)/10, (2*size+7)/10); // ram
- }
- else
- {
- aiPlanAddUnitType(attackID, maintainUnit4, 0, (4*size+6)/10, (4*size+6)/10); // huskarl
- }
-
- 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 Scn33p2.xs");
-
- //Calculate some areas.
- kbAreaCalculate(1200.0);
- aiRandSetSeed();
- kbSetTownLocation(kbGetBlockPosition(cbTownCenter));
-
- /*
- aiSetAgeEventHandler(cAge2, "age2EventHandler");
- aiSetAgeEventHandler(cAge3, "age3EventHandler");
- aiSetAgeEventHandler(cAge4, "age4EventHandler");
- */
- aiSetAttackResponseDistance(20.0);
-
- // Kill escrows
- kbEscrowSetPercentage( cEconomyEscrowID, cAllResources, 0.0);
- kbEscrowSetPercentage( cMilitaryEscrowID, cAllResources, 0.0);
- kbEscrowAllocateCurrentResources();
-
-
- 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
-
- // Set difficulty vars
- difficulty = aiGetWorldDifficulty();
- aiEcho("Difficulty = "+difficulty);
-
- switch(difficulty) // Set up the attack control and age-up parameters
- {
- case 0: // Easy
- {
- nextAttackTime = 120000; // 2 min
- attackInterval = 240000; // 4 min
- attackSize = 3;
- attackMultiplier = 1.3; // 30% per interval
- maxAttackSize = 8;
- age2Time = -1; // N/A
- age3Time = 1200000; // 20 min
- age4Time = 40*60*1000;
- undermineTime = 25*60*1000;
- armyReserveSize = 12;
- standardDelay = 1; // seconds
- break;
- }
- case 1: // Moderate
- {
- nextAttackTime = 90000; // 1.5 min min
- attackInterval = 162000; // 162 sec min
- attackSize = 6.0;
- attackMultiplier = 1.3; // 30% per period
- maxAttackSize = 15;
- age2Time = -1; // N/A
- age3Time = 720000; // 12 min
- age4Time = 20*60*1000;
- undermineTime = 15*60*1000;
- armyReserveSize = 16;
- standardDelay = 1; // seconds
- break;
- }
- case 2: // Difficult
- {
- nextAttackTime = 60000;
- attackInterval = 120000;
- attackSize = 8.0;
- attackMultiplier = 1.3; // 30% per period
- maxAttackSize = 20;
- age2Time = -1; // N/A
- age3Time = 4*60*1000; // 4 min
- age4Time = 12*60*1000;
- undermineTime = 9*60*1000;
- armyReserveSize = 25;
- standardDelay = 1; // seconds
- break;
- }
- case 3: // Nightmare
- {
- nextAttackTime = 60000;
- attackInterval = 120000;
- attackSize = 10.0;
- attackMultiplier = 1.4; // 40% per period
- maxAttackSize = 30;
- age2Time = -1; // N/A
- age3Time = 1*60*1000; // 1 min
- age4Time = 8*60*1000;
- undermineTime = 0;
- armyReserveSize = 40;
- standardDelay = 1; // seconds
- break;
- }
- }
-
-
-
- // Set global unit control vars
- maintainQty1 = (armyReserveSize+8)/10; // Quantity to maintain
- maintainUnit1 = cUnitTypeBattleBoar; // Unit type
- maintainDelay1 = standardDelay; // Interval between training units
- maintainGather1 = cInvalidVector;
-
- maintainQty2 = (armyReserveSize+2)/10; // Quantity to maintain
- maintainUnit2 = cUnitTypeFenrisWolf; // Unit type
- maintainDelay2 = standardDelay; // Interval between training units
- maintainGather2 = cInvalidVector;
-
- maintainQty3 = (3*armyReserveSize+2)/10; // Quantity to maintain
- maintainUnit3 = cUnitTypeJarl; // Unit type
- maintainDelay3 = standardDelay; // Interval between training units
- maintainGather3 = cInvalidVector;
-
- maintainQty4 = (3*armyReserveSize+5)/10; // Quantity to maintain
- maintainUnit4 = cUnitTypeHuskarl; // Unit type
- maintainDelay4 = standardDelay; // Interval between training units
- maintainGather4 = cInvalidVector;
-
-
- maintainQtyScout = 1;
- maintainUnitScout = cUnitTypeUlfsark;
- 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);
-
-
-
-
-
- /*
- // Initialize the target queries
- queryP1Units = kbUnitQueryCreate("Player 1 Units");
- configQuery(queryP1Units, cUnitTypeUnit, -1, cUnitStateAlive, 1);
- */
-
-
- }
-
-
-
-
-
-
-
- // *****************************************************************************
- //
- // 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 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 explorePlan = aiPlanCreate("Explore", cPlanExplore);
- if(explorePlan >= 0)
- {
- aiPlanSetVariableFloat( explorePlan, cExplorePlanLOSMultiplier, 0, 4.0 );
- aiPlanAddUnitType(explorePlan, maintainUnitScout, 1, 1, 1);
- aiPlanSetDesiredPriority(explorePlan, 90);
- aiPlanSetInitialPosition(explorePlan, kbGetBlockPosition(cbAttackGather));
- aiPlanSetActive(explorePlan);
- }
- xsDisableSelf();
- }
-
-
-
- /*
- 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
- {
- // researchTech(cTechMediumInfantry);
- // researchTech(cTechMediumCavalry);
- xsDisableSelf();
- }
-
- rule getAge2ArmoryUpgrades
- inactive
- minInterval 20
- {
-
- aiEcho("Getting age 2 armory upgrades");
- researchTech(cTechCopperWeapons);
- researchTech(cTechCopperMail);
- researchTech(cTechCopperShields);
- xsDisableSelf();
- }
-
- rule getAge3UnitUpgrades
- inactive
- minInterval 20
- {
-
- // researchTech(cTechHeavyInfantry);
- // researchTech(cTechHeavyCavalry);
- xsDisableSelf();
- }
-
- rule getAge3ArmoryUpgrades
- inactive
- minInterval 20
- {
- aiEcho("Getting age 3 armory upgrades");
- researchTech(cTechBronzeWeapons);
- researchTech(cTechBronzeMail);
- researchTech(cTechBronzeShields);
- xsDisableSelf();
- }
-
- rule getAge4UnitUpgrades
- inactive
- minInterval 20
- {
-
- // researchTech(cTechChampionInfantry);
- // researchTech(cTechChampionCavalry);
- xsDisableSelf();
- }
-
- rule getAge4ArmoryUpgrades
- inactive
- minInterval 20
- {
- aiEcho("Getting age 4 armory upgrades");
- researchTech(cTechIronWeapons);
- researchTech(cTechIronMail);
- researchTech(cTechIronShields);
- xsDisableSelf();
- }
-
-
- rule upgradeGenerator
- minInterval 10
- inactive
- {
- // Progressively get unit upgrades throughout
- // Take the time from startTime to endTime, divide into six segments.
- // At the end of each segment, get a set of unit or armory upgrades.
-
- static int interval = 0;
- static int nextTime = 0;
- static int count = 0;
-
- if (interval == 0)
- {
- interval = (endTime - startTime)/6;
- nextTime = startTime + interval;
- }
-
- if (nextTime > xsGetTime())
- return; // It is not yet our time.
-
- // It is time, do something
- switch( count ) // Activate the appropriate upgrade rule, reset nextTime timer.
- {
- case 0:
- {
- xsEnableRule("getAge2UnitUpgrades");
- count = count + 1;
- nextTime = nextTime + interval;
- break;
- }
- case 1:
- {
- xsEnableRule("getAge2ArmoryUpgrades");
- count = count + 1;
- nextTime = nextTime + interval;
- break;
- }
- case 2:
- {
- xsEnableRule("getAge3UnitUpgrades");
- count = count + 1;
- nextTime = nextTime + interval;
- break;
- }
- case 3:
- {
- xsEnableRule("getAge3ArmoryUpgrades");
- count = count + 1;
- nextTime = nextTime + interval;
- break;
- }
- case 4:
- {
- xsEnableRule("getAge4UnitUpgrades");
- count = count + 1;
- nextTime = nextTime + interval;
- break;
- }
- case 5:
- {
- xsEnableRule("getAge4ArmoryUpgrades");
- count = count + 1;
- xsDisableSelf();
- break;
- }
- }
-
-
- }
-
- 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+".");
- }
-
-
- rule useFimbulwinter
- minInterval 5
- inactive
- {
- if ( xsGetTime() < ((12*60*1000)+startTime) )
- return;
-
- aiCastGodPowerAtPosition(cTechSnowStorm, kbGetBlockPosition(cbTownCenter));
- xsDisableSelf();
- aiEcho("Invoking Fimbulwinter.");
- }
-
-
-
- rule useUndermine // Look for 3 walls near the last attack plan
- minInterval 5
- inactive
- {
- int targetUnit = -1;
- int attackArmyID = -1;
-
- if ( xsGetTime() < undermineTime )
- return;
-
- vector pVec = aiPlanGetLocation(penultimatePlan); // Try the 2nd last plan, it should be to the walls by now
- if (xsVectorGetX(pVec)<0)
- pVec = aiPlanGetLocation(lastAttackPlan); // It doesn't exist, so try the most recent plan
-
- if (xsVectorGetX(pVec)<0)
- return; // Neither plan exists, give up.
-
- 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, 20) == false)
- return;
- }
- else
- kbUnitQuerySetPosition(tempQuery, pVec); // Because pVec changes as army moves
-
- kbUnitQueryResetResults(tempQuery);
- int targetCount = kbUnitQueryExecute(tempQuery);
-
- if (targetCount < 3)
- return;
- targetUnit = kbUnitQueryGetResult(tempQuery, targetCount/2); // grab middle wall
-
- // confirm LOS
- if ( kbUnitVisible(targetUnit) != true )
- {
- aiEcho("Undermine: Don't have LOS for unit "+targetUnit+" "+kbGetProtoUnitName(targetUnit));
- // Grab the explore unit, send it here
- static int scoutQuery = -1;
- if (scoutQuery < 0)
- {
- scoutQuery = kbUnitQueryCreate("Scout Query");
- configQuery(scoutQuery, maintainUnitScout, -1, cUnitStateAlive, cMyID, aiPlanGetLocation(explorePlan), true, 10);
- }
- else
- kbUnitQuerySetPosition( scoutQuery, aiPlanGetLocation(explorePlan));
- int unit = -1;
- int count = -1;
- kbUnitQueryResetResults(scoutQuery);
- count = kbUnitQueryExecute(scoutQuery);
- if (count > 0)
- {
- unit = kbUnitQueryGetResult(scoutQuery, 0);
- aiTaskUnitMove(unit, kbGetBlockPosition(cbUndermine));
- aiEcho("Moving unit "+unit+" to location "+kbGetBlockPosition(cbUndermine));
- }
-
- return;
- }
-
- // Move the target point away from the wall, about 1 meter toward the army's location.
- float armyX = -1;
- float armyZ = -1;
- float wallX = -1;
- float wallZ = -1;
- float targetX = -1;
- float targetZ = -1;
- float dx = -1;
- float dz = -1;
- float scale = -1;
- vector targetVec = cInvalidVector;
-
- armyX = xsVectorGetX(pVec);
- armyZ = xsVectorGetZ(pVec);
- wallX = xsVectorGetX(kbUnitGetPosition(targetUnit));
- wallZ = xsVectorGetZ(kbUnitGetPosition(targetUnit));
- dx = wallX - armyX;
- dz = wallZ - armyZ; // Positive if wallZ < armyZ
- if (dx < 0)
- scale = -1.0 * dx;
- else
- scale = dx;
- if (dz < 0)
- scale = scale + (-1*dz);
- else
- scale = scale + dz;
- // Scale is now sum of absolute values of dx and dz, rough indicator of range.
-
- targetX = wallX - (dx / scale);
- targetZ = wallZ - (dz / scale);
- targetVec = pVec;
- targetVec = xsVectorSetX(targetVec, targetX);
- targetVec = xsVectorSetZ(targetVec, targetZ);
-
- aiEcho("Using Undermine at "+targetVec);
- if ( aiCastGodPowerAtPosition(cTechUndermine, targetVec) == true)
- aiEcho("Undermine succeeded at "+targetVec);
- else
- aiEcho("Undermine failed at "+targetVec);
-
- undermineTime = xsGetTime() + undermineInterval;
- }
-
-
-