A couple of things that I spotted are:
AI_getSharedEnemyAttitude
-------------------------------------
You don't check whether ePlayer is alive, this is a potential CTD.
You have:
PHP:
GET_PLAYER(ePlayer).getID()
This will actually just return you ePlayer so it is very inefficient
The function will only ever return a 1 or a 0 so there is no real need for the iAttitude variable. Maybe this would be better returning a bool rather than an int to make it clearer to understand.
As AI_SharedEnemy returns a boolean you can use that directly to determine the return value.
PHP:
int CvPlayerAI::AI_getSharedEnemyAttitude(PlayerTypes ePlayer) const
{
if (GET_PLAYER(ePlayer).isAlive && !atWar(getTeam(), GET_PLAYER(ePlayer).getTeam()))
{
return AI_sharedEnemy(ePlayer) ? 1 : 0;
}
}
AI_SharedEnemy
---------------------
I would rename this as AI_sharedEnemy as the convention is to use a lowercase as the first character after the underscore (remember to make the change in CvPlayerAI.h as well).
You have quite a few checks inside the for loop that do not use the loop variables so will be called multiple times when they only need to be called once. These should be pulled out of the loop and tested first.
You have the following test twice:
PHP:
if (GET_TEAM(getTeam()).isHasMet((GET_PLAYER((PlayerTypes)iI).getTeam())))
For readability it can be easier to reverse the logic of code so that you do not have deeply nested if statements. This is just a matter of style, but can make code easier to follow at times.
Tholal is also correct in that using some more variables can improve readability.
I have just rearranged what you had written taking the above into account which gives the following:
PHP:
bool CvPlayerAI::AI_sharedEnemy(PlayerTypes ePlayer) const
{
if (getID() == ePlayer)
return false;
CvPlayer& kPlayer = GET_PLAYER(ePlayer);
if (!kPlayer.isAlive())
return false;
if (kPlayer.isMinorCiv())
return false;
if (!GET_TEAM(getTeam()).isHasMet(kPlayer.getTeam()))
return false;
for (int iI = 0; iI < MAX_CIV_PLAYERS; iI++)
{
if ((iI == ePlayer) || (iI == getID()))
continue;
CvPlayer &kLoopPLayer = GET_PLAYER((PlayerTypes)iI);
if (!kLoopPLayer.isAlive())
continue;
if (kLoopPLayer.isMinorCiv())
continue;
if (!GET_TEAM(getTeam()).isHasMet(kLoopPLayer.getTeam()))
continue;
if (!GET_TEAM(kPlayer.getTeam()).isHasMet(kLoopPLayer.getTeam()))
continue;
if (kPlayer.AI_getAttitude((PlayerTypes)iI) < ATTITUDE_CAUTIOUS)
{
if (AI_getAttitude((PlayerTypes)iI) < ATTITUDE_CAUTIOUS)
{
return true;
}
}
}
return false;
}
All of my comments above may be very nice, but they don't explain how the line you highlighted would cause a CTD, however it may be easier to spot what is causing the issue when you step through the code.