home *** CD-ROM | disk | FTP | other *** search
- //==============================================================================
- // Scn29p2: AI Scenario Script for scenario 29 player 2
- //==============================================================================
- /*
- AI owner: Dave Leary
- Scenario owner: Joe Gillum/Jerome Jones
-
- Difficulty level stuff: adds ballistae on higher levels (hard/titan) and
- generally increases the size of attacks on higher levels.
- */
- //==============================================================================
- // Difficulty Level check predeclared.
- //==============================================================================
- int difflevel=-1;
-
- // Variable for main base.
- int gMainBaseID=-1;
-
- //Shared variables.
- int numberAttacks=0;
- int attackPlayerID=-1;
-
- //Attack 1 vars.
- int attackPlan1ID=-1;
- int maintainPlan1ID=-1;
- int maintainPlan2ID=-1;
- int maintainPlan3ID=-1;
- int maintainPlan4ID=-1;
-
- int defendPlan1ID=-1;
-
- // Route and path vars.
- int attackRoute1ID=-1;
- int attackPath1ID=-1;
-
- // Unit types
- int attackerUnitTypeID1=cUnitTypeMountainGiant;
- int attackerUnitTypeID2=cUnitTypeFrostGiant;
- int attackerUnitTypeID3=cUnitTypeFireGiant;
- int attackerUnitTypeID4=cUnitTypeBallista;
-
- //==============================================================================
- // Set Town Location
- //==============================================================================
- void setTownLocation(void)
- {
- //Look for the "Town Location" marker.
- kbSetTownLocation(kbGetBlockPosition("365582"));
- }
-
- //==============================================================================
- // miscStartup
- //==============================================================================
- void miscStartup(void)
- {
- // Get the difficulty level.
- difflevel=aiGetWorldDifficulty();
-
- //Startup message(s).
- aiEcho("");
- aiEcho("");
- aiEcho("Scn29P2 AI Start, filename='"+cFilename+"'.");
- //Spit out the map size.
- aiEcho("Map size is ("+kbGetMapXSize()+", "+kbGetMapZSize()+").");
- aiEcho("Difficulty Level="+difflevel+".");
-
- //Cheat like a bastard. Once only, though.
- kbLookAtAllUnitsOnMap();
- //Calculate some areas.
- kbAreaCalculate(1200.0);
- //Set our town location.
- setTownLocation();
-
- //Allocate all resources to the root escrow by setting percentage of military/economy to 0.
- kbEscrowSetPercentage( cEconomyEscrowID, cAllResources, 0.0 );
- kbEscrowSetPercentage( cMilitaryEscrowID, cAllResources, 0.0 );
-
- //Allocate all resources
- kbEscrowAllocateCurrentResources();
-
- //Reset random seed
- aiRandSetSeed();
-
- // Diff level adjustments
- if ( difflevel > 0 )
- {
- attackerUnitTypeID2=cUnitTypeMountainGiant;
- }
-
- if ( difflevel > 1 )
- {
- attackerUnitTypeID1=cUnitTypeMountainGiant;
- attackerUnitTypeID2=cUnitTypeFireGiant;
- }
-
- if ( difflevel == 3 )
- {
- attackerUnitTypeID1=cUnitTypeFireGiant;
- attackerUnitTypeID2=cUnitTypeFrostGiant;
- }
- }
-
- //==============================================================================
- //==============================================================================
- // Attack stuff.
- //==============================================================================
- //==============================================================================
-
- //==============================================================================
- // initAttack: Creates attack routes, etc.
- //==============================================================================
- void initAttack(int playerID=-1)
- {
- //Destroy all previous attacks (if this isn't the player we're already attacking.
- if (playerID != attackPlayerID)
- {
- //Reset the attack player ID.
- attackPlayerID=-1;
- //Destroy any previous attack plan.
- aiPlanDestroy(attackPlan1ID);
- attackPlan1ID=-1;
-
- //Destroy our previous attack paths.
- kbPathDestroy(attackPath1ID);
- attackPath1ID=-1;
-
- //Destroy our previous attack routes.
- attackRoute1ID=-1;
-
- //Reset the number of attacks.
- numberAttacks=0;
- }
-
- //Save the player to attack.
- attackPlayerID=playerID;
-
- vector gatherPoint=kbGetBlockPosition("365589");
-
- //Setup attack path 1 - go left
- attackPath1ID=kbPathCreate("Attack Path 1");
- kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("365577"));
- kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("365578"));
- kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("365579"));
- kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("365580"));
- //Create attack route 1.
- attackRoute1ID=kbCreateAttackRouteWithPath("Attack Route 1", gatherPoint, kbGetBlockPosition("365581"));
-
- if (attackRoute1ID >= 0)
- kbAttackRouteAddPath(attackRoute1ID, attackPath1ID);
-
- }
-
- //==============================================================================
- // setupBaseAttack - the primary attack setup.
- // Prioritizes enemy units instead of buildings.
- //==============================================================================
- bool setupBaseAttack(int playerID=-1)
- {
- difflevel=aiGetWorldDifficulty();
-
- // If we have enough unassigned military units of the core type, bail.
- int numberAvailableUnits1=aiNumberUnassignedUnits(attackerUnitTypeID1);
- vector gatherPoint=kbGetBlockPosition("365589");
-
- // Bail if there aren't at least two mountain giants around.
- aiEcho("There are "+numberAvailableUnits1+" base giants available for a new attack.");
- if (numberAvailableUnits1 < 1)
- return( false );
-
- //Info.
- aiEcho("Attacking Player "+playerID+".");
-
- //If the player to attack doesn't match, init the attack.
- if (attackPlayerID != playerID)
- {
- initAttack(playerID);
- if (attackPlayerID < 0)
- return(false);
- }
-
- //Create an attack plan.
- int newAttackPlanID=aiPlanCreate("Attack Player"+attackPlayerID+" Attempt"+numberAttacks, cPlanAttack);
- if (newAttackPlanID < 0)
- return(false);
-
- //Target player (required). This must work.
- if (aiPlanSetVariableInt(newAttackPlanID, cAttackPlanPlayerID, 0, attackPlayerID) == false)
- return(false);
-
- //Set the target type. This must work.
- if (aiPlanSetNumberVariableValues(newAttackPlanID, cAttackPlanTargetTypeID, 2, true) == false)
- return(false);
-
- //Unit types to attack.
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanTargetTypeID, 0, cUnitTypeBuilding);
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanTargetTypeID, 1, cUnitTypeUnit);
-
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanAttackRouteID, 0, attackRoute1ID);
- aiPlanSetVariableVector(newAttackPlanID, cAttackPlanGatherPoint, 0, gatherPoint);
- aiPlanSetInitialPosition(newAttackPlanID, gatherPoint);
-
- //Set the gather point distance
- aiPlanSetVariableFloat(newAttackPlanID, cAttackPlanGatherDistance, 0, 100.0);
-
- //Set up the attack route usage pattern
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanAttackRoutePattern, 0, cAttackPlanAttackRoutePatternRandom);
-
- //Add the unit types to the plan
- if ( difflevel < 2 )
- {
- aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID1, 2, 2, 2);
- aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID2, 0, 1, 1);
- }
- else if ( difflevel == 2 )
- {
- aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID1, 2, 4, 4);
- aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID2, 0, 4, 4);
- aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID4, 0, 2, 2);
- }
- else
- {
- aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID1, 2, 4, 4);
- aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID2, 0, 4, 4);
- aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID4, 0, 4, 4);
- }
-
- //Plan requires all need units to work (can be false)
- aiPlanSetRequiresAllNeedUnits(newAttackPlanID, true);
- //Activate the plan.
- aiPlanSetActive(newAttackPlanID);
-
- //Now, save the attack plan ID appropriately
- aiPlanSetOrphan(attackPlan1ID, true);
- attackPlan1ID=newAttackPlanID;
-
- //Increment our overall number of attacks
- numberAttacks++;
- }
-
- //==============================================================================
- // Attack Generator 1 - Base attack, every two minutes, once activated.
- //==============================================================================
- rule attackGenerator1
- minInterval 150
- inactive
- group AttackRules
- {
- // See how many "idle" attack plans we have. Don't create any more if we have
- // idle plans.
- int numberIdleAttackPlans=aiGetNumberIdlePlans(cPlanAttack);
-
- if (numberIdleAttackPlans > 0)
- return;
-
- setupBaseAttack(1);
- }
-
- //==============================================================================
- // Favor cheat - grant 30 favor every 45 seconds.
- //==============================================================================
- rule favorCheat
- minInterval 40
- inactive
- group AttackRules
- {
- difflevel=aiGetWorldDifficulty();
- // Cheat for favor. It's tough to be Norse.
- if ( difflevel < 2 )
- {
- aiResourceCheat( 2, cResourceFavor, 50.0 );
- }
- else
- {
- aiResourceCheat( 2, cResourceFavor, 100.0 );
- }
- }
-
- // Wall upgrade.
- rule upgradeWalls
- minInterval 10
- inactive
- {
- int planID=aiPlanCreate("Upgrading Walls", cPlanResearch);
- if (planID < 0)
- return;
-
- aiPlanSetVariableInt(planID, cResearchPlanTechID, 0, cTechStoneWall);
- aiPlanSetVariableInt(planID, cResearchPlanBuildingTypeID, 0, cUnitTypeWallLong);
- aiPlanSetActive(planID);
-
- //Done.
- xsDisableSelf();
- }
-
- // Tower upgrade.
- rule upgradeTowers
- minInterval 90
- inactive
- {
- int planID=aiPlanCreate("Upgrading Towers", cPlanResearch);
- if (planID < 0)
- return;
-
- aiPlanSetVariableInt(planID, cResearchPlanTechID, 0, cTechWatchTower);
- aiPlanSetVariableInt(planID, cResearchPlanBuildingTypeID, 0, cUnitTypeTower);
- aiPlanSetActive(planID);
-
- //Done.
- xsDisableSelf();
- }
-
- //==============================================================================
- // initiateAttacks - triggered with an AI FUNC to get everything rolling.
- //==============================================================================
- void initiateAttacks( int parameter=-1 )
- {
- aiEcho("*** PLAYER 2 AI: Attacks now being sent.");
-
- // Enable favor generation and other fun..
- xsEnableRule("attackGenerator1");
- xsEnableRule("favorCheat");
- xsEnableRule("upgradeWalls");
- xsEnableRule("upgradeTowers");
- }
-
- //==============================================================================
- // settlementDestroyed - if P2's settlement is destroyed, defend plan backs
- // up to the rear.
- //==============================================================================
- void settlementDestroyed( int parameter=-1 )
- {
- aiEcho("*** PLAYER 2 AI: Now defending the rear.");
- vector rearDefend=kbGetBlockPosition("365582");
-
- aiPlanSetVariableVector(defendPlan1ID, cDefendPlanDefendPoint, 0, rearDefend);
- }
-
- //==============================================================================
- // MAIN
- //==============================================================================
- void main(void)
- {
- //Startup.
- miscStartup();
-
- difflevel=aiGetWorldDifficulty();
-
- //Share a common gather point.
- vector gatherPoint1=kbGetBlockPosition("365574");
- vector gatherPoint2=kbGetBlockPosition("365575");
- vector gatherPoint3=kbGetBlockPosition("367252");
-
- //Maintain 4 of the first giant type.
- maintainPlan1ID=aiPlanCreate("Maintain "+kbGetProtoUnitName(attackerUnitTypeID1), cPlanTrain);
- if (maintainPlan1ID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanUnitType, 0, attackerUnitTypeID1);
- //You can limit the number of units that are ever trained by this plan with this call.
- //aiPlanSetVariableInt(maintainPlanID, cTrainPlanNumberToTrain, 0, 25);
- //Set the number of units to maintain in the world at one time, based
- if ( difflevel == 2 )
- {
- aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanNumberToMaintain, 0, 8);
- }
- else if ( difflevel == 3 )
- {
- aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanNumberToMaintain, 0, 10);
- }
- else
- {
- aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanNumberToMaintain, 0, 4);
- }
- //Don't train units too fast
- if ( difflevel < 2 )
- {
- aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanFrequency, 0, 60);
- }
- else
- {
- aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanFrequency, 0, 30);
- }
- //Set a gather point.
- aiPlanSetVariableVector(maintainPlan1ID, cTrainPlanGatherPoint, 0, gatherPoint1);
- //Activate the plan.
- aiPlanSetActive(maintainPlan1ID);
- }
-
- //Maintain 2 of the second giant type (though we only ever send one in an attack group).
- maintainPlan2ID=aiPlanCreate("Maintain 2 "+kbGetProtoUnitName(attackerUnitTypeID2), cPlanTrain);
- if (maintainPlan2ID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanUnitType, 0, attackerUnitTypeID2);
- //You can limit the number of units that are ever trained by this plan with this call.
- //aiPlanSetVariableInt(maintainPlanID, cTrainPlanNumberToTrain, 0, 25);
- //Set the number of units to maintain in the world at one time.
-
- if ( difflevel > 1 )
- {
- aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanNumberToMaintain, 0, 6);
- }
- else
- {
- aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanNumberToMaintain, 0, 2);
- }
-
- //Don't train units too fast
- if ( difflevel < 2 )
- {
- aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanFrequency, 0, 90);
- }
- else
- {
- aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanFrequency, 0, 45);
- }
-
- //Set a gather point.
- aiPlanSetVariableVector(maintainPlan2ID, cTrainPlanGatherPoint, 0, gatherPoint2);
- //Activate the plan.
- aiPlanSetActive(maintainPlan2ID);
- }
-
- // If the difficulty is higher than moderate, maintain two (or four) ballista.
- if ( difflevel > 1 )
- {
- maintainPlan4ID=aiPlanCreate("Maintain "+kbGetProtoUnitName(attackerUnitTypeID1), cPlanTrain);
- if (maintainPlan4ID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainPlan4ID, cTrainPlanUnitType, 0, attackerUnitTypeID4);
- //You can limit the number of units that are ever trained by this plan with this call.
- //aiPlanSetVariableInt(maintainPlanID, cTrainPlanNumberToTrain, 0, 25);
- //Set the number of units to maintain in the world at one time, based
- if ( difflevel == 2 )
- {
- aiPlanSetVariableInt(maintainPlan4ID, cTrainPlanNumberToMaintain, 0, 2);
- aiPlanSetVariableInt(maintainPlan4ID, cTrainPlanFrequency, 0, 60);
- }
- else if ( difflevel == 3 )
- {
- aiPlanSetVariableInt(maintainPlan4ID, cTrainPlanNumberToMaintain, 0, 4);
- aiPlanSetVariableInt(maintainPlan4ID, cTrainPlanFrequency, 0, 30);
- }
- //Set a gather point.
- aiPlanSetVariableVector(maintainPlan4ID, cTrainPlanGatherPoint, 0, gatherPoint3);
- //Activate the plan.
- aiPlanSetActive(maintainPlan4ID);
- }
- }
-
- // Defense at the gate.
- defendPlan1ID=aiPlanCreate("Gate Defense", cPlanDefend);
- if (defendPlan1ID >= 0)
- {
- //Main gate location
- vector theGate=kbGetBlockPosition("365576");
-
- //Add the unit(s)
- if ( difflevel < 2 )
- {
- aiPlanAddUnitType(defendPlan1ID, attackerUnitTypeID1, 2, 2, 2);
- aiPlanAddUnitType(defendPlan1ID, attackerUnitTypeID2, 0, 1, 1);
- }
- else
- {
- aiPlanAddUnitType(defendPlan1ID, attackerUnitTypeID1, 4, 4, 4);
- aiPlanAddUnitType(defendPlan1ID, attackerUnitTypeID2, 0, 2, 2);
- }
-
- //Setup the vars.
- aiPlanSetDesiredPriority(defendPlan1ID, 90);
- aiPlanSetVariableVector(defendPlan1ID, cDefendPlanDefendPoint, 0, theGate);
- aiPlanSetVariableFloat(defendPlan1ID, cDefendPlanEngageRange, 0, 30);
- aiPlanSetActive(defendPlan1ID);
- }
- }