home *** CD-ROM | disk | FTP | other *** search
- //==============================================================================
- // mc02p2.xs
- //==============================================================================
- /*
- AI owner: Dave Leary
- Scenario owner: Dave Leary
-
- This AI handles "Bjarnar's Brigands" - one of two primarily naval-based AIs that
- bother the player (and each other) in the second scenario of the free
- minicampaign. It cheats like mad.
- */
- //==============================================================================
- // Need scn lib for some stuff here.
- include "scn lib.xs";
-
- // Predefined Stuff.
- // Ship types
- int attackerUnitTypeIDBoat1=cUnitTypeSiegeShipNorse;
- int attackerUnitTypeIDBoat2=cUnitTypeRammingShipNorse;
-
- // Land unit types
- int attackerUnitTypeID1=cUnitTypeUlfsark;
- int attackerUnitTypeID2=cUnitTypeJarl;
-
- // Defend plans.
- int defendPlan1ID=-1;
- int defendPlan2ID=-1;
- int defendPlan3ID=-1;
-
- // One attack plan for the landing troops.
- int attackPlan1ID=-1;
-
- // Functions to check to see what's hanging around the point.
- int checkForMilitary(vector point = vector(-1,-1,-1))
- {
- return(getUnassignedUnitCount(point, 30.0, cMyID, cUnitTypeLogicalTypeLandMilitary));
- }
-
- //==============================================================================
- // Set Town Location
- //==============================================================================
- void setTownLocation(void)
- {
- //Look for the "Town Location" marker.
- kbSetTownLocation(kbGetBlockPosition("859"));
- }
-
- //==============================================================================
- // miscStartup
- //==============================================================================
- void miscStartup(void)
- {
- // Difficulty Level check.
- int difflevel=-1;
- difflevel=aiGetWorldDifficulty();
-
- //Startup message(s).
- aiEcho("");
- aiEcho("");
- aiEcho("mc02p2 AI Start, filename='"+cFilename+"'.");
- aiEcho("Difficulty Level="+difflevel+".");
- //Spit out the map size.
- aiEcho(" Map size is ("+kbGetMapXSize()+", "+kbGetMapZSize()+").");
- //Cheat like a bastard. Once only, though.
- kbLookAtAllUnitsOnMap();
- //Calculate some areas.
- kbAreaCalculate(1200.0);
- //Set our town location.
- setTownLocation();
- //Reset random seed
- aiRandSetSeed();
- //Allocate all resources to the root escrow.
- kbEscrowAllocateCurrentResources();
-
- // Large AI attack response distance for this player
- aiSetAttackResponseDistance(50.0);
- }
-
- //==============================================================================
- // Favor cheat.
- //==============================================================================
- rule favorCheat
- minInterval 60
- active
- group AttackRules
- {
- // Cheat for favor - 20 every minute
- aiResourceCheat( 2, cResourceFavor, 20.0 );
- }
-
-
- //==============================================================================
- // Move Defend Plans - changes (randomly) the water location the AI defends.
- //==============================================================================
- rule moveDefendPlans
- minInterval 65
- inactive
- group AttackRules
- {
- int randomDefendPoint1=aiRandInt(3);
- int randomDefendPoint2=aiRandInt(3);
-
- // Set up defend points for crazy AI behavior.
- vector defendPoint1=kbGetBlockPosition("842");
- vector defendPoint2=kbGetBlockPosition("845");
- vector defendPoint3=kbGetBlockPosition("844");
-
-
- // First Defend Plan - choose a point.
- if ( randomDefendPoint1 == 0 )
- {
- aiPlanSetVariableVector(defendPlan1ID, cDefendPlanDefendPoint, 0, defendPoint1);
- }
- else if ( randomDefendPoint1 == 1 )
- {
- aiPlanSetVariableVector(defendPlan1ID, cDefendPlanDefendPoint, 0, defendPoint2);
- }
- else
- {
- aiPlanSetVariableVector(defendPlan1ID, cDefendPlanDefendPoint, 0, defendPoint3);
- }
-
- // Second Defend Plan - choose a point.
- if ( randomDefendPoint2 == 0 )
- {
- aiPlanSetVariableVector(defendPlan2ID, cDefendPlanDefendPoint, 0, defendPoint1);
- }
- else if ( randomDefendPoint2 == 1 )
- {
- aiPlanSetVariableVector(defendPlan2ID, cDefendPlanDefendPoint, 0, defendPoint2);
- }
- else
- {
- aiPlanSetVariableVector(defendPlan2ID, cDefendPlanDefendPoint, 0, defendPoint3);
- }
- }
-
- // Secondary rule to send one ship to annoy the player.
- rule annoyPlayer
- minInterval 80
- inactive
- group AttackRules
-
- {
- int randomBotherPlayer=aiRandInt(2);
-
- vector annoyPoint1=kbGetBlockPosition("863");
- vector annoyPoint2=kbGetBlockPosition("862");
-
- // Activate the "annoy the player" defend plan.
- if ( randomBotherPlayer == 0 )
- {
- aiPlanSetVariableVector(defendPlan3ID, cDefendPlanDefendPoint, 0, annoyPoint1);
- }
- else
- {
- aiPlanSetVariableVector(defendPlan3ID, cDefendPlanDefendPoint, 0, annoyPoint2);
- }
- }
-
-
- // Send transport every three minutes.
- rule activateTransport
- minInterval 180
- inactive
- group AttackRules
- {
- int transportPlanID=aiPlanCreate("Transport Group", cPlanTransport);
- int randomUnits=aiRandInt(2);
-
- // Difficulty Level check.
- int difflevel=-1;
- difflevel=aiGetWorldDifficulty();
-
- vector gatherPoint=kbGetBlockPosition("892");
- vector targetPoint=kbGetBlockPosition("893");
-
- // Only send the transport on difficulty levels greater than moderate.
- if ( difflevel > 1 )
- {
- if (transportPlanID >= 0)
- {
- aiEcho("*** PLAYER 3 SENDING TRANSPORT ***");
-
- aiPlanAddUnitType(transportPlanID, cUnitTypeTransportShipNorse, 1, 1, 1);
- aiPlanAddUnitType(transportPlanID, cUnitTypeUlfsark, 0, 5, 5);
-
- aiPlanAddUnitType(transportPlanID, cUnitTypeJarl, 0, 3, 3);
- aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportTypeID, 0, cUnitTypeTransportShipNorse);
-
- aiPlanSetVariableBool(transportPlanID, cTransportPlanMaximizeXportMovement, 0, true);
-
- aiPlanSetVariableVector(transportPlanID, cTransportPlanGatherPoint, 0, gatherPoint);
- aiPlanSetVariableVector(transportPlanID, cTransportPlanTargetPoint, 0, targetPoint);
-
- aiPlanSetDesiredPriority(transportPlanID, 75);
-
- // Don't return when finished.
- // aiPlanSetVariableBool(transportPlanID, cTransportPlanReturnWhenDone, 0, false);
-
- // Specific transport hackery
- // aiPlanAddUnit(transportPlanID, whichTransport);
- aiPlanSetActive(transportPlanID);
- }
- }
- }
-
- //==============================================================================
- // Check the landing spot for unassigned dudes.
- //==============================================================================
- rule pollForMilitary
- minInterval 15
- inactive
- {
- vector landingBeach=kbGetBlockPosition("893");
-
- int attackPlanSize = -1;
- attackPlanSize = checkForMilitary(landingBeach);
- if (attackPlanSize > 0)
- {
- aiEcho("P3 Attack Plan: Found "+attackPlanSize+" units on the beach.");
- int newAttackPlanID=aiPlanCreate("Beach Attack", cPlanAttack);
- if (newAttackPlanID >= 0)
- {
- //Target player.
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanPlayerID, 0, 1);
-
- aiPlanSetVariableVector(newAttackPlanID, cAttackPlanGatherPoint, 0, landingBeach);
- aiPlanSetVariableFloat(newAttackPlanID, cAttackPlanGatherDistance, 0, 40.0);
-
- //Add the unit(s).
- aiPlanAddUnitType(newAttackPlanID, cUnitTypeUlfsark, 0, 4, 4);
- aiPlanAddUnitType(newAttackPlanID, cUnitTypeJarl, 0, 3, 3);
-
- aiPlanSetNumberVariableValues(newAttackPlanID, cAttackPlanTargetTypeID, 2, true);
-
- //Unit types to attack.
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanTargetTypeID, 0, cUnitTypeBuilding);
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanTargetTypeID, 1, cUnitTypeUnit);
-
- aiPlanSetInitialPosition(newAttackPlanID, landingBeach);
-
- //Setup the vars.
- aiPlanSetDesiredPriority(newAttackPlanID, 40);
- aiPlanSetActive(newAttackPlanID);
-
- //Save this off and orphan the previous attack.
- aiPlanSetOrphan(attackPlan1ID, true);
- attackPlan1ID=newAttackPlanID;
- }
- }
- }
-
- // Rule to activate some other rules after an extra three minutes.
- rule threeMinuteWarning
- minInterval 180
- inactive
- group AttackRules
- {
- vector annoyPoint1=kbGetBlockPosition("863");
-
- // The "annoy player" plan.
- defendPlan3ID=aiPlanCreate("Annoy Player Defense Plan", cPlanDefend);
- if (defendPlan3ID >= 0)
- {
- // Add the unit(s).
- aiPlanAddUnitType(defendPlan3ID, attackerUnitTypeIDBoat2, 0, 1, 1);
-
- // Set up the vars.
- aiPlanSetDesiredPriority(defendPlan3ID, 40);
- // Starts at the first point, for grins.
- aiPlanSetVariableVector(defendPlan3ID, cDefendPlanDefendPoint, 0, annoyPoint1);
- aiPlanSetVariableFloat(defendPlan3ID, cDefendPlanEngageRange, 0, 30);
- aiPlanSetActive(defendPlan3ID);
- }
-
- xsEnableRule("annoyPlayer");
- xsEnableRule("activateTransport");
- xsEnableRule("pollForMilitary");
-
- xsDisableSelf();
- }
-
- //==============================================================================
- // Player Builds Dock - first objective. Called when the player builds his
- // first dock (a prerequisite for what comes later). This gets the AI exploring
- // and causes all kinds of mayhem.
- //==============================================================================
- void playerBuildsDock(int scriptCall = -1)
- {
- // Declare the vectors for the defend plan.
- vector defendPoint1=kbGetBlockPosition("842");
- vector defendPoint2=kbGetBlockPosition("845");
-
- // Create two explore plans with different patterns (one doing loops,
- // the other not doing loops).
- aiEcho("*** PLAYER BUILDS A DOCK ***");
-
- int explorePlan1ID=aiPlanCreate("Siege Explore 1", cPlanExplore);
- if (explorePlan1ID >= 0)
- {
- aiPlanAddUnitType(explorePlan1ID, attackerUnitTypeIDBoat1, 1, 1, 1);
- aiPlanSetDesiredPriority(explorePlan1ID, 1);
- aiPlanSetVariableBool(explorePlan1ID, cExplorePlanDoLoops, 0, false);
- aiPlanSetActive(explorePlan1ID);
- }
-
- // Set up two crazy defend plans.
- defendPlan1ID=aiPlanCreate("Ship Defense Plan 1", cPlanDefend);
- if (defendPlan1ID >= 0)
- {
- // Add the unit(s).
- aiPlanAddUnitType(defendPlan1ID, attackerUnitTypeIDBoat1, 0, 2, 2);
- aiPlanAddUnitType(defendPlan1ID, attackerUnitTypeIDBoat2, 0, 2, 2);
-
- // Set up the vars.
- aiPlanSetDesiredPriority(defendPlan1ID, 50);
- // Starts at the first point, for grins.
- aiPlanSetVariableVector(defendPlan1ID, cDefendPlanDefendPoint, 0, defendPoint1);
- aiPlanSetVariableFloat(defendPlan1ID, cDefendPlanEngageRange, 0, 40);
- aiPlanSetActive(defendPlan1ID);
- }
-
- defendPlan2ID=aiPlanCreate("Ship Defense Plan 2", cPlanDefend);
- if (defendPlan2ID >= 0)
- {
- // Add the unit(s).
- aiPlanAddUnitType(defendPlan2ID, attackerUnitTypeIDBoat1, 0, 2, 2);
- aiPlanAddUnitType(defendPlan2ID, attackerUnitTypeIDBoat2, 0, 2, 2);
-
- // Set up the vars.
- aiPlanSetDesiredPriority(defendPlan2ID, 50);
- // Starts at the second point, for grins
- aiPlanSetVariableVector(defendPlan2ID, cDefendPlanDefendPoint, 0, defendPoint2);
- aiPlanSetVariableFloat(defendPlan2ID, cDefendPlanEngageRange, 0, 40);
- aiPlanSetActive(defendPlan2ID);
- }
-
- // Activate the rules that changes where the defend plans are defending, and annoying
- // attacks are sent at the player.
- xsEnableRule("moveDefendPlans");
- xsEnableRule("threeMinuteWarning");
- }
-
- //==============================================================================
- // MAIN
- //==============================================================================
- void main(void)
- {
- //Startup.
- miscStartup();
-
- //Gather points - ships
- vector gatherPointSiegeShip=kbGetBlockPosition("860");
- vector gatherPointRammingShip=kbGetBlockPosition("861");
-
- //Gather point for land units.
- vector gatherPointLandUnits=kbGetBlockPosition("891");
-
- // Set up defend points for crazy AI behavior.
- vector defendPoint1=kbGetBlockPosition("842");
- vector defendPoint2=kbGetBlockPosition("845");
- vector defendPoint3=kbGetBlockPosition("844");
-
- //Maintain seven siege ships.
- int maintainPlan1ID=aiPlanCreate("Maintain 7 "+kbGetProtoUnitName(attackerUnitTypeIDBoat1), cPlanTrain);
- if (maintainPlan1ID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanUnitType, 0, attackerUnitTypeIDBoat1);
- //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.
- aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanNumberToMaintain, 0, 7);
- aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanFrequency, 0, 20);
- //Turn off training from multiple buildings.
- aiPlanSetVariableBool(maintainPlan1ID, cTrainPlanUseMultipleBuildings, 0, false);
- //Set a gather target ID.
- //aiPlanSetVariableInt(maintainPlanID, cTrainPlanGatherTargetID, 0, 1234);
- //Set a gather point.
- aiPlanSetVariableVector(maintainPlan1ID, cTrainPlanGatherPoint, 0, gatherPointSiegeShip);
- //Activate the plan.
- aiPlanSetActive(maintainPlan1ID);
- }
-
- //Maintain four ramming ships.
- int maintainPlan2ID=aiPlanCreate("Maintain 4 "+kbGetProtoUnitName(attackerUnitTypeIDBoat2), cPlanTrain);
- if (maintainPlan2ID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanUnitType, 0, attackerUnitTypeIDBoat2);
- //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.
- aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanNumberToMaintain, 0, 4);
- aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanFrequency, 0, 30);
- //Turn off training from multiple buildings.
- aiPlanSetVariableBool(maintainPlan2ID, cTrainPlanUseMultipleBuildings, 0, false);
- //Set a gather target ID.
- //aiPlanSetVariableInt(maintainPlanID, cTrainPlanGatherTargetID, 0, 1234);
- //Set a gather point.
- aiPlanSetVariableVector(maintainPlan2ID, cTrainPlanGatherPoint, 0, gatherPointRammingShip);
- //Activate the plan.
- aiPlanSetActive(maintainPlan2ID);
- }
-
- // Maintain a transport for a little transport-guys action.
- int maintainPlan3ID=aiPlanCreate("Maintain 1 Transport", cPlanTrain);
- if (maintainPlan3ID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainPlan3ID, cTrainPlanUnitType, 0, cUnitTypeTransportShipNorse);
- //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.
- aiPlanSetVariableInt(maintainPlan3ID, cTrainPlanNumberToMaintain, 0, 1);
- aiPlanSetVariableInt(maintainPlan3ID, cTrainPlanFrequency, 0, 45);
- //Turn off training from multiple buildings.
- aiPlanSetVariableBool(maintainPlan3ID, cTrainPlanUseMultipleBuildings, 0, false);
- //Set a gather target ID.
- //aiPlanSetVariableInt(maintainPlanID, cTrainPlanGatherTargetID, 0, 1234);
- //Set a gather point.
- aiPlanSetVariableVector(maintainPlan3ID, cTrainPlanGatherPoint, 0, gatherPointSiegeShip);
- //Activate the plan.
- aiPlanSetActive(maintainPlan3ID);
- }
-
- // Maintain some military units...Jarls and Ulfsarks.
- int maintainPlan4ID=aiPlanCreate("Maintain Ulfsarks", cPlanTrain);
- if (maintainPlan4ID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainPlan4ID, 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.
- aiPlanSetVariableInt(maintainPlan4ID, cTrainPlanNumberToMaintain, 0, 6);
- aiPlanSetVariableInt(maintainPlan4ID, cTrainPlanFrequency, 0, 15);
- //Turn off training from multiple buildings.
- //aiPlanSetVariableBool(maintainPlan4ID, cTrainPlanUseMultipleBuildings, 0, false);
- //Set a gather target ID.
- //aiPlanSetVariableInt(maintainPlanID, cTrainPlanGatherTargetID, 0, 1234);
- //Set a gather point.
- aiPlanSetVariableVector(maintainPlan4ID, cTrainPlanGatherPoint, 0, gatherPointLandUnits);
- //Activate the plan.
- aiPlanSetActive(maintainPlan4ID);
- }
-
- int maintainPlan5ID=aiPlanCreate("Maintain Jarls", cPlanTrain);
- if (maintainPlan5ID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainPlan5ID, 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.
- aiPlanSetVariableInt(maintainPlan5ID, cTrainPlanNumberToMaintain, 0, 4);
- aiPlanSetVariableInt(maintainPlan5ID, cTrainPlanFrequency, 0, 20);
- //Turn off training from multiple buildings.
- //aiPlanSetVariableBool(maintainPlan4ID, cTrainPlanUseMultipleBuildings, 0, false);
- //Set a gather target ID.
- //aiPlanSetVariableInt(maintainPlanID, cTrainPlanGatherTargetID, 0, 1234);
- //Set a gather point.
- aiPlanSetVariableVector(maintainPlan5ID, cTrainPlanGatherPoint, 0, gatherPointLandUnits);
- //Activate the plan.
- aiPlanSetActive(maintainPlan5ID);
- }
- }