With my recent work on the AI in TAM I thought it would be a good idea to share some of my discoveries.
For the most part I'll be dealing with the following values in the CIV4LeaderHeadInfos.xml file:
<iBaseAttitude>0</iBaseAttitude>
<iBasePeaceWeight>0</iBasePeaceWeight>
<iPeaceWeightRand>0</iPeaceWeightRand>
<iWarmongerRespect>0</iWarmongerRespect>
Of these values only iBaseAttitude has any effect on the human players. Attitude is calculated every turn starting with the base attitude and then modifying it. So iBaseAttitude is much more important than the common belief that it only affects their attitude on initial contact.
From the SDK (CvPlayerAI.cpp):
So an iBaseAttitude of -2 will make a leader less friendly. Pretty simple
The peace weight values only affect AI to AI attitudes. The values in iPeaceWeightRand is a random modifier used to add between 0 and iPeaceWeightRand to iBasePeaceWeight. So if iPeaceWeightRand is 3 and iBasePeaceWeight is 0 the final PeaceWeight can be 0, 1, 2 or 3.
The calculation for the attitude modifier based on PeaceWeight is:
So what this does is take iBasePeaceWeight + (0 to iPeaceWeightRand) for each AI civ and calculates the difference (absolute value of the result) of them then subtracts that difference from 4 and uses the result as a modifier. So if Civ1 has a final peace weight of 4 and Civ2 has a final peace weight of 6 the result is a +2 attitude modifier. In the vanilla game Ghandi has a iBasePeaceWeight of 10 and Alexander has 0, without the random weight added in they would normally have a -6 attitude modifier with each other. Since it uses a difference of values any two leaders with the same values will receive a +4 attitude modifier.
At the same time iWarmongerRespect is added as a modifier. In this case the game uses the lowest iWarmongerRespect of the two leaders and applied that as a positive modifier. So if either leader has an iWarmongerRespect of 0 they receive no bonus between them (unless the other has a negative value, then they receive a penalty).
Here are some examples of using these values with each other. First, if you want all of the AI players to have relation based entirely on in-game actions (close borders, trade, etc) with no modifiers you could set them up like:
<iBaseAttitude>0</iBaseAttitude>
<iBasePeaceWeight>0</iBasePeaceWeight>
<iPeaceWeightRand>0</iPeaceWeightRand>
<iWarmongerRespect>-4</iWarmongerRespect>
If they are all set the same way the -4 iWarmongerRespect will cancel out the +4 peace weight modifier.
If you want the AI to AI attitudes to fluctuate a bit instead of simple improving you can set them up like:
<iBaseAttitude>0</iBaseAttitude>
<iBasePeaceWeight>0</iBasePeaceWeight>
<iPeaceWeightRand>4</iPeaceWeightRand>
<iWarmongerRespect>-2</iWarmongerRespect>
This will result in a final modifier between -2 and +2.
Now there is a lot more to the attitude ajustements than just these four values. However, the other values seem to work more like I expected them to while these didn't. One thing to keep in mind is that any "Rand" value (ie. iMaxWarRand) will be used to figure a 1 in "value" probability. A good example of this is the various WarRand values:
This, in a nutshell, means that the lower a "Rand" value is the better the odds of it occuring are.
The "Prob" values (ie. iRazeCityProb) are the opposite, so a higher value equals a higher chance.
So in this case a random number between 0-99 is generated and if that random number is less than the Declare War Prob (defined in HandicapInfos in this case) the result would be successful.
For the most part I'll be dealing with the following values in the CIV4LeaderHeadInfos.xml file:
<iBaseAttitude>0</iBaseAttitude>
<iBasePeaceWeight>0</iBasePeaceWeight>
<iPeaceWeightRand>0</iPeaceWeightRand>
<iWarmongerRespect>0</iWarmongerRespect>
Of these values only iBaseAttitude has any effect on the human players. Attitude is calculated every turn starting with the base attitude and then modifying it. So iBaseAttitude is much more important than the common belief that it only affects their attitude on initial contact.
From the SDK (CvPlayerAI.cpp):
Code:
iAttitude = GC.getLeaderHeadInfo(getPersonalityType()).getBaseAttitude();
So an iBaseAttitude of -2 will make a leader less friendly. Pretty simple
The peace weight values only affect AI to AI attitudes. The values in iPeaceWeightRand is a random modifier used to add between 0 and iPeaceWeightRand to iBasePeaceWeight. So if iPeaceWeightRand is 3 and iBasePeaceWeight is 0 the final PeaceWeight can be 0, 1, 2 or 3.
The calculation for the attitude modifier based on PeaceWeight is:
Code:
if (!(GET_PLAYER(ePlayer).isHuman()))
{
iAttitude += (4 - abs(AI_getPeaceWeight() - GET_PLAYER(ePlayer).AI_getPeaceWeight()));
iAttitude += min(GC.getLeaderHeadInfo(getPersonalityType()).getWarmongerRespect(), GC.getLeaderHeadInfo(GET_PLAYER(ePlayer).getPersonalityType()).getWarmongerRespect());
}
So what this does is take iBasePeaceWeight + (0 to iPeaceWeightRand) for each AI civ and calculates the difference (absolute value of the result) of them then subtracts that difference from 4 and uses the result as a modifier. So if Civ1 has a final peace weight of 4 and Civ2 has a final peace weight of 6 the result is a +2 attitude modifier. In the vanilla game Ghandi has a iBasePeaceWeight of 10 and Alexander has 0, without the random weight added in they would normally have a -6 attitude modifier with each other. Since it uses a difference of values any two leaders with the same values will receive a +4 attitude modifier.
At the same time iWarmongerRespect is added as a modifier. In this case the game uses the lowest iWarmongerRespect of the two leaders and applied that as a positive modifier. So if either leader has an iWarmongerRespect of 0 they receive no bonus between them (unless the other has a negative value, then they receive a penalty).
Here are some examples of using these values with each other. First, if you want all of the AI players to have relation based entirely on in-game actions (close borders, trade, etc) with no modifiers you could set them up like:
<iBaseAttitude>0</iBaseAttitude>
<iBasePeaceWeight>0</iBasePeaceWeight>
<iPeaceWeightRand>0</iPeaceWeightRand>
<iWarmongerRespect>-4</iWarmongerRespect>
If they are all set the same way the -4 iWarmongerRespect will cancel out the +4 peace weight modifier.
If you want the AI to AI attitudes to fluctuate a bit instead of simple improving you can set them up like:
<iBaseAttitude>0</iBaseAttitude>
<iBasePeaceWeight>0</iBasePeaceWeight>
<iPeaceWeightRand>4</iPeaceWeightRand>
<iWarmongerRespect>-2</iWarmongerRespect>
This will result in a final modifier between -2 and +2.
Now there is a lot more to the attitude ajustements than just these four values. However, the other values seem to work more like I expected them to while these didn't. One thing to keep in mind is that any "Rand" value (ie. iMaxWarRand) will be used to figure a 1 in "value" probability. A good example of this is the various WarRand values:
Code:
if (GC.getGameINLINE().getSorenRandNum(AI_maxWarRand(), "AI Maximum War") == 0)
This, in a nutshell, means that the lower a "Rand" value is the better the odds of it occuring are.
The "Prob" values (ie. iRazeCityProb) are the opposite, so a higher value equals a higher chance.
Code:
if ((GC.getGameINLINE().getSorenRandNum(100, "AI Declare War 1") < GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getAIDeclareWarProb())
So in this case a random number between 0-99 is generated and if that random number is less than the Declare War Prob (defined in HandicapInfos in this case) the result would be successful.