home *** CD-ROM | disk | FTP | other *** search
- //==============================================================================
- // ScnEBp2: AI Scenario Script for EB scenario player 2
- //==============================================================================
- /*
- AI owner: Mike Kidd
- Scenario owner: Jerome Jones
-
- Overview:
- The player's goal is to find and destroy the four gates to the underworld. The
- CP periodically teleports new units into the fray at these locations, avoiding
- portals that have been destroyed. The CP uses minions, wolves, shades and
- Fire Giants.
-
- Based on difficulty level, the CP chooses attack group sizes and intervals.
- Certain units, like a fire giant, count as several "units". Each attack group
- is made up of a homogenous set of units, it doesn't do mixed fire giant/wolf
- groups.
-
- Difficulty: Implemented.
-
- No age-ups or god powers.
-
-
- */
- //==============================================================================
-
-
- include "scn lib.xs";
-
- // Globals
-
- // Attack control...initialized in main() based on difficulty level
- int nextAttackTime = -1;
- int attackInterval = -1;
- float attackSize = -1.0; // The float has the "real" value so I can use % increases
- //int attackSize = -1; // This one is actually used by the attack algorithms, must be set whenever float is changed.
- float attackMultiplier = -1.0; // Typically like 1.10, which would increase each attack by 10%.
- float maxAttackSize = -1;
- int lastAttackPlan = -1;
-
- int difficulty = -1;
- // Cinematic block markers
- const string cbNorthSpawn = "6144";
- const string cbNorthEastSpawn = "6145";
- const string cbEastSpawn = "6146";
- const string cbWestSpawn = "6147";
- const string cbP1TC = "6148";
- const string cbWestSettlement = "6149";
- const string cbCenterSettlement = "6150";
- const string cbEastSettlement = "6151";
-
- // *****************************************************************************
- //
- // FUNCTIONS
- //
- // *****************************************************************************
-
-
- void attack()
- {
- // Pick a unit type
- int unitType = -1;
- int rand = -1;
- int unitQty = -1;
-
- if (attackSize > 8.0) // consider fire giant
- rand = aiRandInt(4);
- else // just wolf, minion, shade
- rand = aiRandInt(3);
-
- if (rand == 0)
- {
- unitType = cUnitTypeWolf;
- unitQty = attackSize; // Counts as 1 unit for toughness
- aiEcho("Will send wolves ("+unitQty+").");
- }
- if (rand == 1)
- {
- unitType = cUnitTypeMinion;
- unitQty = attackSize; // Counts as 1
- aiEcho("Will send minions ("+unitQty+").");
- }
- if (rand == 2)
- {
- unitType = cUnitTypeShadeofHades;
- unitQty = attackSize/2;
- aiEcho("Will send shades ("+unitQty+").");
- }
- if (rand == 3)
- {
- unitType = cUnitTypeFireGiant;
- unitQty = attackSize/6;
- aiEcho("Will send fire giants ("+unitQty+").");
- }
-
- vector location = vector(-1, -1, -1);
- int i=0;
-
- for (i=0; < 100) // Shouldn't be possible to have no valid sites, but this will prevent infinite loop
- {
- rand = aiRandInt(4);
- switch(rand)
- { // Pick a location, bail if tunnel is gone
- case 0:
- { // North, check tunnel
- if ( kbUnitGetCurrentHitpoints(kbGetBlockID("5949")) > 0.1 )
- {
- location = kbGetBlockPosition(cbNorthSpawn);
- aiEcho("Location: North");
- }
- break;
- }
- case 1:
- { // Northeast
- if ( kbUnitGetCurrentHitpoints(kbGetBlockID("5952")) > 0.1 )
- {
- location = kbGetBlockPosition(cbNorthEastSpawn);
- aiEcho("Location: NorthEast");
- }
- break;
- }
- case 2:
- { // East
- if ( kbUnitGetCurrentHitpoints(kbGetBlockID("5953")) > 0.1 )
- {
- location = kbGetBlockPosition(cbEastSpawn);
- aiEcho("Location: East");
- }
- break;
- }
- case 3:
- { // West
- if ( kbUnitGetCurrentHitpoints(kbGetBlockID("5950")) > 0.1 )
- {
- location = kbGetBlockPosition(cbWestSpawn);
- aiEcho("Location: West");
- }
- break;
- }
- }
- if (xsVectorGetX(location) >= 0)
- break;
- }
-
-
- if (xsVectorGetX(location) < 0)
- return;
-
- // Spawn the units
- aiUnitCreateCheat( 2, unitType, location, "Attack group", unitQty);
-
-
- // Make the attack plan
- int attackID=aiPlanCreate("Attack at "+timeString(), cPlanAttack);
- if (attackID < 0)
- {
- return;
- }
-
- if (aiPlanSetVariableInt(attackID, cAttackPlanPlayerID, 0, 1) == false)
- {
- return;
- }
-
- if (aiPlanSetNumberVariableValues(attackID, cAttackPlanTargetTypeID, 3, true) == false)
- {
- return;
- }
-
- /* // Set up the attack query with the appropriate vector
- if (attackQuery < 0)
- {
- attackQuery = kbUnitQueryCreate("Attack Query");
- configQuery(attackQuery, cUnitTypeUnit, -1, cUnitStateAlive, 1, kbGetBlockPosition(cHPTown), false, 50.0);
- //vector center = vector(-1,-1,-1), bool sort = false, float radius = -1 )
- }
- aiPlanSetVariableInt(attackID, cAttackPlanQueryID, 0, attackQuery);
-
-
- 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, cAttackPlanTargetTypeID, 0, cUnitTypeMilitary);
- aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 1, cUnitTypeBuilding);
- aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 2, cUnitTypeUnit);
-
-
- aiPlanSetVariableVector(attackID, cAttackPlanGatherPoint, 0, location);
- aiPlanSetVariableFloat(attackID, cAttackPlanGatherDistance, 0, 100.0); // REAL wide in case of mega-spawn traffic
-
- aiPlanAddUnitType(attackID, unitType, 0, unitQty, unitQty);
-
- aiPlanSetInitialPosition(attackID, location);
- 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 wakeup(int parm=-1)
- {
- nextAttackTime = nextAttackTime + xsGetTime();
- xsEnableRule("spawnScout");
- xsEnableRule("scout");
- xsEnableRule("attackGenerator");
- aiEcho("Wakeup running at "+timeString());
- }
-
-
- rule spoofWakeup
- active
- minInterval 35
- {
- wakeup(0);
- xsDisableSelf();
- }
-
-
- void main()
- {
- aiEcho("Starting ScnEBp2.xs");
- // kbSetTownLocation(kbGetBlockPosition(cCenter));
- aiRandSetSeed();
-
- //Calculate some areas.
- kbAreaCalculate(1200.0);
-
- difficulty = aiGetWorldDifficulty();
-
- switch(difficulty)
- {
- case 0: // Easy
- {
- nextAttackTime = 300000;
- attackInterval = 300000;
- attackSize = 3.0;
- attackMultiplier = 1.1; // 10% per 5 min
- maxAttackSize = 7;
- break;
- }
- case 1: // Moderate
- {
- nextAttackTime = 240000;
- attackInterval = 240000;
- attackSize = 3.0;
- attackMultiplier = 1.2; // 20% per 4 min
- maxAttackSize = 15;
- break;
- }
- case 2: // Hard
- {
- nextAttackTime = 120000;
- attackInterval = 240000;
- attackSize = 6.0;
- attackMultiplier = 1.3; // 30% per 4 min
- maxAttackSize = 30;
- break;
- }
- case 3: // Unfair
- {
- nextAttackTime = 60000;
- attackInterval = 180000;
- attackSize = 6.0;
- attackMultiplier = 1.4; // 40% per 3 min
- maxAttackSize = 60;
- break;
- }
- }
-
-
- /* Sample query setup
- donkeyQueryEast = kbUnitQueryCreate("Idle Donkey East");
- configQuery(donkeyQueryEast, cUnitTypeCaravanGreek, cActionIdle, cUnitStateAlive, 2, kbGetBlockPosition(cEastTown), false, 20.0);
- */
- }
-
-
-
-
-
-
-
- // *****************************************************************************
- //
- // RULES
- //
- // *****************************************************************************
-
- rule spawnScout
- inactive
- minInterval 10
- {
- int count = kbUnitCount(2, cUnitTypeWolf, cUnitStateAlive); // Count my scouts
- if (count >= 2)
- return;
- aiUnitCreateCheat( 2, cUnitTypeWolf, kbGetBlockPosition("6144"), "Name", 2-count); // Build to total of 2
- aiEcho("Making wolves.");
- }
-
-
- rule scout
- inactive
- minInterval 10
- {
- // just set up an explore plan
- int exploreID = aiPlanCreate("Explore", cPlanExplore);
- if(exploreID >= 0)
- {
- aiPlanSetVariableFloat( exploreID, cExplorePlanLOSMultiplier, 0, 4.0 );
- aiPlanAddUnitType(exploreID, cUnitTypeWolf, 1, 2, 2);
- aiPlanSetDesiredPriority(exploreID, 90);
- aiPlanSetActive(exploreID);
- }
- xsDisableSelf();
- }
-
-
-
-
- rule attackGenerator
- minInterval 10
- active
- {
- //aiEcho("attack check running, next time is "+nextAttackTime);
- if ( xsGetTime() < nextAttackTime )
- return;
-
- attack();
- nextAttackTime = xsGetTime() + attackInterval;
- attackSize = attackSize * attackMultiplier;
- if (attackSize > maxAttackSize)
- attackSize = maxAttackSize;
- aiEcho("Next attack size will be "+attackSize+".");
- }
-
-
-
-
-
-
-