How to get the AI to build walls
Posted: Mon May 27, 2013 2:25 pm
Basically, I wrote this up for somebody on HG.
DISCLAIMER: I only put this up for people who wanted to add walls to their AI without changing it, and to help them modify their AIs and stuff. I put it up here so that people who want to play AOE3 can make their computer more challenging and more NR material. Of course, I will always have the opinion that my works constitutes the best yet depiction of NR , but there is always room for being disproved.
------------------------------
It is possible to get the AI to build walls, almost always.
An answer to your question about Asian AIs, and Aztecs for that matter - the reason they don't build gates is because Gates aren't enabled for these civs in the techtreey + techtreex; they merely have the "transform gate" option available to them. Thus though humans can use this ability, computer players cannot, because they are based on scripting, not on clicking any special abilities.
So, in order to get them to build gates, you have to add Gates to their Age0Tech. The needed Age0Techs are Age0XPAztec, ypAge0IndiansBuildings, ypAge0JapaneseBuildings, and ypAge0ChineseBuildings. Here is some added stuff the the Age0XPAztec tech:
Now to the ypAge0IndianBuildings:
In hindsight, I hypothesize that this is the same for the Asian Wonder powers. The AI should research them almost as techs, or as command abilities. In fact, Minutemen are at this moment unusable by known commands, because they are "command" at the town center, thereby every town center, not a standard "techrow" upgrade.
As we come back to walls, you need to add this code to the bottom of the AImain.xs: (or just press the edit button on my post here and copy and paste the information onto a notepad document, then open the AImain.xs found in Program Files and upgrade this).
Note: AI3 is for The Asian Dynasties, AI2 is for The Warchiefs, AI is for Age of Empires III Vanilla (original game without expansion packs). The same for Protoy/Techtreey (The Asian Dynasties), Protox/Techtreex (The Warchiefs), Proto/Techtree (Vanilla).
rule delayWallsAggressive
active
minInterval 10
{
if ( (kbGetPopCap()-kbGetPop()) < 80 )
return; // Don't start walls until we have pop room
int wallPlanID=aiPlanCreate("WallInBase", cPlanBuildWall);
if (wallPlanID != -1)
{
aiPlanSetVariableInt(wallPlanID, cBuildWallPlanWallType, 0, cBuildWallPlanWallTypeRing);
aiPlanAddUnitType(wallPlanID, gEconUnit, 0, 1, 2);
aiPlanSetVariableVector(wallPlanID, cBuildWallPlanWallRingCenterPoint, 0, kbBaseGetLocation(cMyID, kbBaseGetMainID(cMyID)));
aiPlanSetVariableFloat(wallPlanID, cBuildWallPlanWallRingRadius, 0.0, 89.0);
aiPlanSetVariableInt(wallPlanID, cBuildWallPlanNumberOfGates, 0, 20);
aiPlanSetBaseID(wallPlanID, kbBaseGetMainID(cMyID));
aiPlanSetEscrowID(wallPlanID, cEconomyEscrowID);
aiPlanSetDesiredPriority(wallPlanID, 80);
aiPlanSetActive(wallPlanID, true);
//Enable our wall gap rule, too.
xsEnableRule("fillInWallGapsAggressive");
aiEcho("Enabling Wall Plan for Base ID: "+kbBaseGetMainID(cMyID));
}
xsDisableSelf();
}
//==============================================================================
// RULE fillInWallGapsAggressive
//==============================================================================
rule fillInWallGapsAggressive
minInterval 31
inactive
{
//If we're not building walls, then start.
if (gBuildWalls == false)
{
xsEnableRule("turtleUp");
return;
}
//If we already have a build wall plan, don't make another one. (We try to build a second aggressive wall after our first preliminary one now)
if(aiPlanGetIDByTypeAndVariableType(cPlanBuildWall, cBuildWallPlanWallType, cBuildWallPlanWallTypeRing, true) >= 1)
return;
int wallPlanID=aiPlanCreate("FillInWallGapsAggressive", cPlanBuildWall);
if (wallPlanID != -1)
{
aiPlanSetVariableInt(wallPlanID, cBuildWallPlanWallType, 0, cBuildWallPlanWallTypeRing);
aiPlanAddUnitType(wallPlanID, gEconUnit, 1, 1, 2);
aiPlanSetVariableVector(wallPlanID, cBuildWallPlanWallRingCenterPoint, 0, kbBaseGetLocation(cMyID, kbBaseGetMainID(cMyID)));
aiPlanSetVariableFloat(wallPlanID, cBuildWallPlanWallRingRadius, 0.0, 89.0);
aiPlanSetVariableInt(wallPlanID, cBuildWallPlanNumberOfGates, 0, 20);
aiPlanSetBaseID(wallPlanID, kbBaseGetMainID(cMyID));
aiPlanSetEscrowID(wallPlanID, cEconomyEscrowID);
aiPlanSetDesiredPriority(wallPlanID,80);
aiPlanSetActive(wallPlanID, true);
}
}
Copy and paste this to the end of your AI file. By itself, it makes the AI build walls in Deathmatch games, and occasionally in supremacy. As a reference, I will explain what some things do, especially for the second one.
gEconunit, 1, 1, 2,); - the first "1", or "true", makes it "true" to build these walls, the 2nd is the amount, or layers of wall to be build, and the 3rd is the number of workers. If you want more layers, however, you have to add something like 1, 3i+3, 2,); so as to make the second wall 3 game meters out farther than the previous one. Wall plans set too close to each other will make the AI build them over each other.
BuildWallPlanWallRingRadius, 0.0, 89.0); - Sets the radius of the computer building walls around their base. The maximum base limit is 55 game meters around their base, so 59.0-62.0 meters is generally the ideal distance for the AI main defensive wall. 59.0 Allows them to build walls that don't interfere with their allies' walls, but may leave a small gap due to a plantation sticking out of the wall gap, thus allowing for easier raiding. 60.0-62.0 meters only works on larger maps for their build radius.
cBuildWallPlanNumberOfGates, 0, 20); - self explanitory, 20 gates for the whole radius, if possible (note that on ordinary maps only 12 gates will be built, because the wall is usually a semicircle; for 59.0 radius, you need 15 gates to make the AI to pass effectively through their walls).
if (wallPlanID != -1) - this makes this wall build plan infinite - thus the computer will use it quite often, and send people to rebuild their walls. Also, "0" here means a type of randomizer, and works infinitely. So its not always defined how the AI will build walls, but they build them back slightly randomized pattern - though close enough to their previous wall that it doesn't affect their building too much.
minInterval 31 - the minimum interval in game seconds the computer will choose to send villagers to build walls.
aiPlanSetDesiredPriority(wallPlanID,80); - priority, 99-100 being the highest, 50 being medium-low, anything <50 being very low or not at all.
Of course, if you build walls, you 1) need them upgraded, and 2) need them built always from a certain age onward. So, I have these solutions.
To make them always build walls from Industrial onwards, add this:
xsEnableRule("fillInWallGapsAggressive");
to this:
rule age4Monitor
inactive
minInterval 10
{
if (kbGetAge() >= cAge4)
{
aiEcho("*** We're in age 4.");
(Insert Enable rule HERE, then press "enter" to get a space)
// Bump up settler train plan
updateSettlerCounts();
Then, add this rule to the bottom of your AImain.xs file:
rule BastionUpgradeMonitor
inactive
minInterval 90
{
int upgradePlanID = -1;
// Disable rule for native or Asian civs
if ((civIsNative() == true) TT (civIsAsian() == true))
{
xsDisableSelf();
return;
}
if ((kbTechGetStatus(cTechBastion) == cTechStatusObtainable) && (kbUnitCount(cMyID, cUnitTypeAbstractWall, cUnitStateAlive) >= 20))
{
upgradePlanID = aiPlanGetIDByTypeAndVariableType(cPlanResearch, cResearchPlanTechID, cTechBastion);
if (upgradePlanID >= 0)
aiPlanDestroy(upgradePlanID);
createSimpleResearchPlan(cTechBastion, getUnit(cUnitTypeChurch), cMilitaryEscrowID, 50);
return;
}
}
And, again, then add it to be enabled from Industrial onwards:
rule age4Monitor
inactive
minInterval 10
{
if (kbGetAge() >= cAge4)
{
aiEcho("*** We're in age 4.");
xsEnableRule("fillInWallGapsAggressive");
xsEnableRule("BastionUpgradeMonitor");
// Bump up settler train plan
updateSettlerCounts();
If you want to build a second layer of walls, then copy and paste the rules I gave you, make them a different distance other than 89.0, and rename them something other than delayWallsAggressive, and fillInWallGapsAggressive. Then enable them from the Age4Monitor and enjoy .
regards,
murdilator
DISCLAIMER: I only put this up for people who wanted to add walls to their AI without changing it, and to help them modify their AIs and stuff. I put it up here so that people who want to play AOE3 can make their computer more challenging and more NR material. Of course, I will always have the opinion that my works constitutes the best yet depiction of NR , but there is always room for being disproved.
------------------------------
It is possible to get the AI to build walls, almost always.
An answer to your question about Asian AIs, and Aztecs for that matter - the reason they don't build gates is because Gates aren't enabled for these civs in the techtreey + techtreex; they merely have the "transform gate" option available to them. Thus though humans can use this ability, computer players cannot, because they are based on scripting, not on clicking any special abilities.
So, in order to get them to build gates, you have to add Gates to their Age0Tech. The needed Age0Techs are Age0XPAztec, ypAge0IndiansBuildings, ypAge0JapaneseBuildings, and ypAge0ChineseBuildings. Here is some added stuff the the Age0XPAztec tech:
Code: Select all
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>WallStraight2</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>Plantation</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>CWallGate</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>WallConnector</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>WallStraight5</Target></Effect>
Now to the ypAge0IndianBuildings:
Code: Select all
<Tech name ='ypAge0IndiansBuildings' type ='Normal'>
<DBID>5173</DBID>
<Effects>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>YPBarracksIndian</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>ypBerryBuilding</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>ypCaravanserai</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>ypCastle</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>ypConsulate</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>YPDockAsian</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>ypSacredField</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>ypRicePaddy</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>ypMonastery</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>ypTradeMarketAsian</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>ypHouseIndian</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>ypGroveBuilding</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>CWallGate</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>WallConnector</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>WallStraight2</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>WallStraight5</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>TradingPost</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>TownCenter</Target></Effect>
<Effect type ='Data' amount ='1.00' subtype ='Enable' relativity ='Absolute'>
<Target type ='ProtoUnit'>FieldHospital</Target></Effect>
</Effects>
</Tech>
In hindsight, I hypothesize that this is the same for the Asian Wonder powers. The AI should research them almost as techs, or as command abilities. In fact, Minutemen are at this moment unusable by known commands, because they are "command" at the town center, thereby every town center, not a standard "techrow" upgrade.
As we come back to walls, you need to add this code to the bottom of the AImain.xs: (or just press the edit button on my post here and copy and paste the information onto a notepad document, then open the AImain.xs found in Program Files and upgrade this).
Note: AI3 is for The Asian Dynasties, AI2 is for The Warchiefs, AI is for Age of Empires III Vanilla (original game without expansion packs). The same for Protoy/Techtreey (The Asian Dynasties), Protox/Techtreex (The Warchiefs), Proto/Techtree (Vanilla).
rule delayWallsAggressive
active
minInterval 10
{
if ( (kbGetPopCap()-kbGetPop()) < 80 )
return; // Don't start walls until we have pop room
int wallPlanID=aiPlanCreate("WallInBase", cPlanBuildWall);
if (wallPlanID != -1)
{
aiPlanSetVariableInt(wallPlanID, cBuildWallPlanWallType, 0, cBuildWallPlanWallTypeRing);
aiPlanAddUnitType(wallPlanID, gEconUnit, 0, 1, 2);
aiPlanSetVariableVector(wallPlanID, cBuildWallPlanWallRingCenterPoint, 0, kbBaseGetLocation(cMyID, kbBaseGetMainID(cMyID)));
aiPlanSetVariableFloat(wallPlanID, cBuildWallPlanWallRingRadius, 0.0, 89.0);
aiPlanSetVariableInt(wallPlanID, cBuildWallPlanNumberOfGates, 0, 20);
aiPlanSetBaseID(wallPlanID, kbBaseGetMainID(cMyID));
aiPlanSetEscrowID(wallPlanID, cEconomyEscrowID);
aiPlanSetDesiredPriority(wallPlanID, 80);
aiPlanSetActive(wallPlanID, true);
//Enable our wall gap rule, too.
xsEnableRule("fillInWallGapsAggressive");
aiEcho("Enabling Wall Plan for Base ID: "+kbBaseGetMainID(cMyID));
}
xsDisableSelf();
}
//==============================================================================
// RULE fillInWallGapsAggressive
//==============================================================================
rule fillInWallGapsAggressive
minInterval 31
inactive
{
//If we're not building walls, then start.
if (gBuildWalls == false)
{
xsEnableRule("turtleUp");
return;
}
//If we already have a build wall plan, don't make another one. (We try to build a second aggressive wall after our first preliminary one now)
if(aiPlanGetIDByTypeAndVariableType(cPlanBuildWall, cBuildWallPlanWallType, cBuildWallPlanWallTypeRing, true) >= 1)
return;
int wallPlanID=aiPlanCreate("FillInWallGapsAggressive", cPlanBuildWall);
if (wallPlanID != -1)
{
aiPlanSetVariableInt(wallPlanID, cBuildWallPlanWallType, 0, cBuildWallPlanWallTypeRing);
aiPlanAddUnitType(wallPlanID, gEconUnit, 1, 1, 2);
aiPlanSetVariableVector(wallPlanID, cBuildWallPlanWallRingCenterPoint, 0, kbBaseGetLocation(cMyID, kbBaseGetMainID(cMyID)));
aiPlanSetVariableFloat(wallPlanID, cBuildWallPlanWallRingRadius, 0.0, 89.0);
aiPlanSetVariableInt(wallPlanID, cBuildWallPlanNumberOfGates, 0, 20);
aiPlanSetBaseID(wallPlanID, kbBaseGetMainID(cMyID));
aiPlanSetEscrowID(wallPlanID, cEconomyEscrowID);
aiPlanSetDesiredPriority(wallPlanID,80);
aiPlanSetActive(wallPlanID, true);
}
}
Copy and paste this to the end of your AI file. By itself, it makes the AI build walls in Deathmatch games, and occasionally in supremacy. As a reference, I will explain what some things do, especially for the second one.
gEconunit, 1, 1, 2,); - the first "1", or "true", makes it "true" to build these walls, the 2nd is the amount, or layers of wall to be build, and the 3rd is the number of workers. If you want more layers, however, you have to add something like 1, 3i+3, 2,); so as to make the second wall 3 game meters out farther than the previous one. Wall plans set too close to each other will make the AI build them over each other.
BuildWallPlanWallRingRadius, 0.0, 89.0); - Sets the radius of the computer building walls around their base. The maximum base limit is 55 game meters around their base, so 59.0-62.0 meters is generally the ideal distance for the AI main defensive wall. 59.0 Allows them to build walls that don't interfere with their allies' walls, but may leave a small gap due to a plantation sticking out of the wall gap, thus allowing for easier raiding. 60.0-62.0 meters only works on larger maps for their build radius.
cBuildWallPlanNumberOfGates, 0, 20); - self explanitory, 20 gates for the whole radius, if possible (note that on ordinary maps only 12 gates will be built, because the wall is usually a semicircle; for 59.0 radius, you need 15 gates to make the AI to pass effectively through their walls).
if (wallPlanID != -1) - this makes this wall build plan infinite - thus the computer will use it quite often, and send people to rebuild their walls. Also, "0" here means a type of randomizer, and works infinitely. So its not always defined how the AI will build walls, but they build them back slightly randomized pattern - though close enough to their previous wall that it doesn't affect their building too much.
minInterval 31 - the minimum interval in game seconds the computer will choose to send villagers to build walls.
aiPlanSetDesiredPriority(wallPlanID,80); - priority, 99-100 being the highest, 50 being medium-low, anything <50 being very low or not at all.
Of course, if you build walls, you 1) need them upgraded, and 2) need them built always from a certain age onward. So, I have these solutions.
To make them always build walls from Industrial onwards, add this:
xsEnableRule("fillInWallGapsAggressive");
to this:
rule age4Monitor
inactive
minInterval 10
{
if (kbGetAge() >= cAge4)
{
aiEcho("*** We're in age 4.");
(Insert Enable rule HERE, then press "enter" to get a space)
// Bump up settler train plan
updateSettlerCounts();
Then, add this rule to the bottom of your AImain.xs file:
rule BastionUpgradeMonitor
inactive
minInterval 90
{
int upgradePlanID = -1;
// Disable rule for native or Asian civs
if ((civIsNative() == true) TT (civIsAsian() == true))
{
xsDisableSelf();
return;
}
if ((kbTechGetStatus(cTechBastion) == cTechStatusObtainable) && (kbUnitCount(cMyID, cUnitTypeAbstractWall, cUnitStateAlive) >= 20))
{
upgradePlanID = aiPlanGetIDByTypeAndVariableType(cPlanResearch, cResearchPlanTechID, cTechBastion);
if (upgradePlanID >= 0)
aiPlanDestroy(upgradePlanID);
createSimpleResearchPlan(cTechBastion, getUnit(cUnitTypeChurch), cMilitaryEscrowID, 50);
return;
}
}
And, again, then add it to be enabled from Industrial onwards:
rule age4Monitor
inactive
minInterval 10
{
if (kbGetAge() >= cAge4)
{
aiEcho("*** We're in age 4.");
xsEnableRule("fillInWallGapsAggressive");
xsEnableRule("BastionUpgradeMonitor");
// Bump up settler train plan
updateSettlerCounts();
If you want to build a second layer of walls, then copy and paste the rules I gave you, make them a different distance other than 89.0, and rename them something other than delayWallsAggressive, and fillInWallGapsAggressive. Then enable them from the Age4Monitor and enjoy .
regards,
murdilator