void CvDiplomacyAI::DoUpdatePeaceTreatyWillingness(bool bMyTurn)
{
CvCity* pCapital = GetPlayer()->getCapitalCity();
bool bLog = bMyTurn && GC.getLogging() && GC.getAILogging(); // Only log this once per turn to prevent log spam
int iLoop = 0;
if (GC.getGame().isOption(GAMEOPTION_ALWAYS_WAR) || GC.getGame().isOption(GAMEOPTION_NO_CHANGING_WAR_PEACE) || GetPlayer()->isHuman() || GetPlayer()->IsAITeammateOfHuman() || GetPlayer()->IsVassalOfSomeone())
{
for (int iPlayerLoop = 0; iPlayerLoop < MAX_MAJOR_CIVS; iPlayerLoop++)
{
PlayerTypes ePlayer = (PlayerTypes) iPlayerLoop;
SetTreatyWillingToOffer(ePlayer, NO_PEACE_TREATY_TYPE);
SetTreatyWillingToAccept(ePlayer, NO_PEACE_TREATY_TYPE);
}
if (bLog && !GetPlayer()->isHuman())
{
CvString strOutBuf;
CvString strBaseString;
CvString playerName;
CvString strLogName;
// Find the name of this civ and city
playerName = m_pPlayer->getCivilizationShortDescription();
// Open the log file
if (GC.getPlayerAndCityAILogSplit())
{
strLogName = "DiplomacyAI_Peace_Log" + playerName + ".csv";
}
else
{
strLogName = "DiplomacyAI_Peace_Log.csv";
}
FILogFile* pLog = NULL;
pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp);
// Get the leading info for this line
strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
strBaseString += playerName + " VS. Everyone";
strOutBuf.Format("Not allowed to change war/peace status with anyone!");
strBaseString += strOutBuf;
pLog->Msg(strBaseString);
}
return;
}
// STEP 1: See if we're in a critical state and check which players are valid
bool bCriticalState = GetPlayer()->IsEmpireSuperUnhappy() || !pCapital || pCapital->isInDangerOfFalling(true) || pCapital->getDamage() >= (pCapital->GetMaxHitPoints()/2);
bool bMakePeaceWithAllMinors = false;
bool bWorldConquest = IsGoingForWorldConquest() || IsCloseToWorldConquest();
bool bDiplomatic = IsGoingForDiploVictory() || IsDiplomat() || GetPlayer()->GetPlayerTraits()->IsDiplomat();
vector<PlayerTypes> vValidPlayers;
for (int iPlayerLoop = 0; iPlayerLoop < MAX_CIV_PLAYERS; iPlayerLoop++)
{
PlayerTypes eLoopPlayer = (PlayerTypes) iPlayerLoop;
if (GET_PLAYER(eLoopPlayer).isAlive() && IsAtWar(eLoopPlayer))
{
if (GET_PLAYER(eLoopPlayer).isMajorCiv())
{
if (IsPeaceBlocked(eLoopPlayer))
{
SetTreatyWillingToOffer(eLoopPlayer, NO_PEACE_TREATY_TYPE);
SetTreatyWillingToAccept(eLoopPlayer, NO_PEACE_TREATY_TYPE);
if (bLog)
{
CvString strOutBuf;
CvString strBaseString;
CvString playerName;
CvString otherPlayerName;
CvString strLogName;
CvString strPeaceBlockReason;
FmtPeaceBlockReasonLogStr(strPeaceBlockReason, GetID(), eLoopPlayer, GetPeaceBlockReason(eLoopPlayer));
// Find the name of this civ and city
playerName = m_pPlayer->getCivilizationShortDescription();
// Open the log file
if (GC.getPlayerAndCityAILogSplit())
{
strLogName = "DiplomacyAI_Peace_Log" + playerName + ".csv";
}
else
{
strLogName = "DiplomacyAI_Peace_Log.csv";
}
FILogFile* pLog = NULL;
pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp);
// Get the leading info for this line
strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
otherPlayerName = GET_PLAYER(eLoopPlayer).getCivilizationShortDescription();
strBaseString += playerName + " VS. " + otherPlayerName;
strOutBuf.Format("PEACE BLOCKED! ");
strOutBuf += strPeaceBlockReason;
strBaseString += strOutBuf;
pLog->Msg(strBaseString);
}
}
else
{
vValidPlayers.push_back(eLoopPlayer);
}
}
if (!bCriticalState)
{
WarStateTypes eWarState = GetWarState(eLoopPlayer);
if (eWarState == WAR_STATE_NEARLY_DEFEATED)
{
bCriticalState = true;
}
else if (eWarState <= WAR_STATE_TROUBLED)
{
if (GetPlayer()->IsNoNewWars() || !GET_PLAYER(eLoopPlayer).isMajorCiv() || !IsPhonyWar(eLoopPlayer) || GetWarScore(eLoopPlayer) <= WARSCORE_THRESHOLD_NEGATIVE)
bMakePeaceWithAllMinors = true;
}
}
}
else if (GET_PLAYER(eLoopPlayer).isMajorCiv())
{
SetTreatyWillingToOffer(eLoopPlayer, NO_PEACE_TREATY_TYPE);
SetTreatyWillingToAccept(eLoopPlayer, NO_PEACE_TREATY_TYPE);
}
}
if (bCriticalState)
bMakePeaceWithAllMinors = true;
// STEP 2: Make peace with any City-States here - this happens instantly!
if (bMyTurn)
{
for (int iPlayerLoop = MAX_MAJOR_CIVS; iPlayerLoop < MAX_CIV_PLAYERS; iPlayerLoop++)
{
PlayerTypes eMinor = (PlayerTypes) iPlayerLoop;
if (IsAtWar(eMinor))
{
if (IsPeaceBlocked(eMinor))
{
if (bLog)
{
CvString strOutBuf;
CvString strBaseString;
CvString playerName;
CvString otherPlayerName;
CvString strLogName;
CvString strPeaceBlockReason;
FmtPeaceBlockReasonLogStr(strPeaceBlockReason, GetID(), eMinor, GetPeaceBlockReason(eMinor));
// Find the name of this civ and city
playerName = m_pPlayer->getCivilizationShortDescription();
// Open the log file
if (GC.getPlayerAndCityAILogSplit())
{
strLogName = "DiplomacyAI_Peace_Log" + playerName + ".csv";
}
else
{
strLogName = "DiplomacyAI_Peace_Log.csv";
}
FILogFile* pLog = NULL;
pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp);
// Get the leading info for this line
strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
otherPlayerName = GET_PLAYER(eMinor).getCivilizationShortDescription();
strBaseString += playerName + " VS. " + otherPlayerName;
strOutBuf.Format("PEACE BLOCKED! ");
strOutBuf += strPeaceBlockReason;
strBaseString += strOutBuf;
pLog->Msg(strBaseString);
}
}
else
{
if (bMakePeaceWithAllMinors || GetCSWarTargetPlayer() != eMinor)
{
if (!bCriticalState)
{
// Exception if making peace with this City-State would prevent us from achieving Domination Victory
if (GC.getGame().WouldMakingPeacePreventDominationVictory(GetID(), eMinor))
{
if (IsGoingForWorldConquest() || IsCloseToWorldConquest())
continue;
}
// Exception under two circumstances: the minor's capital or a city they captured from us are in danger from us
for (CvCity* pLoopCity = GET_PLAYER(eMinor).firstCity(&iLoop); pLoopCity != NULL; pLoopCity = GET_PLAYER(eMinor).nextCity(&iLoop))
{
if (pLoopCity->isCapital() || GET_PLAYER(pLoopCity->getOriginalOwner()).getTeam() == GetTeam())
{
if (pLoopCity->IsInDanger(GetID()) && (pLoopCity->isUnderSiege() || pLoopCity->IsBlockadedWaterAndLand()))
{
continue;
}
}
}
}
GET_TEAM(GetTeam()).makePeace(GET_PLAYER(eMinor).getTeam(), true, false, GetID());
LogPeaceMade(eMinor);
if (bLog)
{
CvString strOutBuf;
CvString strBaseString;
CvString playerName;
CvString otherPlayerName;
CvString strLogName;
// Find the name of this civ and city
playerName = m_pPlayer->getCivilizationShortDescription();
// Open the log file
if (GC.getPlayerAndCityAILogSplit())
{
strLogName = "DiplomacyAI_Peace_Log" + playerName + ".csv";
}
else
{
strLogName = "DiplomacyAI_Peace_Log.csv";
}
FILogFile* pLog = NULL;
pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp);
// Get the leading info for this line
strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
otherPlayerName = GET_PLAYER(eMinor).getCivilizationShortDescription();
strBaseString += playerName + " VS. " + otherPlayerName;
if (bCriticalState)
strOutBuf.Format("Making peace with all possible City-States because we're in a critical state!");
else if (bMakePeaceWithAllMinors)
strOutBuf.Format("Making peace with all possible City-States because we're doing poorly in war!");
else
strOutBuf.Format("This City-State is no longer our CS war target!");
strBaseString += strOutBuf;
pLog->Msg(strBaseString);
}
}
}
}
}
}
// STEP 3: Determine whether we're willing to make peace with any majors
vector<PlayerTypes> vMakePeacePlayers;
bool bInTerribleShape = false;
bool bUABonusesFromCityConquest = false;
if (!bCriticalState)
{
bInTerribleShape = GetPlayer()->IsInTerribleShapeForWar();
CvPlayerTraits* pTraits = GetPlayer()->GetPlayerTraits();
if (!bInTerribleShape)
{
// Assyria, Japan, Indonesia, The Aztecs, Nuclear Gandhi, and anyone who keeps conquered buildings will prolong wars longer if they are winning and the enemy's cities are in danger from them.
bUABonusesFromCityConquest = pTraits->IsTechFromCityConquer();
bUABonusesFromCityConquest |= pTraits->GetCityConquestGWAM() > 0;
bUABonusesFromCityConquest |= pTraits->GetUniqueLuxuryQuantity() > 0;
bUABonusesFromCityConquest |= pTraits->GetGoldenAgeFromVictory() > 0;
bUABonusesFromCityConquest |= pTraits->IsKeepConqueredBuildings() || GetPlayer()->IsKeepConqueredBuildings();
bUABonusesFromCityConquest |= pTraits->GetCultureBonusModifierConquest() > 0;
bUABonusesFromCityConquest |= pTraits->GetProductionBonusModifierConquest() > 0;
bUABonusesFromCityConquest |= pTraits->IsFreeGreatWorkOnConquest();
bUABonusesFromCityConquest |= pTraits->IsConquestOfTheWorld();
bUABonusesFromCityConquest |= IsNuclearGandhi();
}
}
for (std::vector<PlayerTypes>::iterator it = vValidPlayers.begin(); it != vValidPlayers.end(); it++)
{
if (bCriticalState)
{
vMakePeacePlayers.push_back(*it);
if (bLog)
{
CvString strOutBuf;
CvString strBaseString;
CvString playerName;
CvString otherPlayerName;
CvString strLogName;
// Find the name of this civ and city
playerName = m_pPlayer->getCivilizationShortDescription();
// Open the log file
if (GC.getPlayerAndCityAILogSplit())
{
strLogName = "DiplomacyAI_Peace_Log" + playerName + ".csv";
}
else
{
strLogName = "DiplomacyAI_Peace_Log.csv";
}
FILogFile* pLog = NULL;
pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp);
// Get the leading info for this line
strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
otherPlayerName = GET_PLAYER(*it).getCivilizationShortDescription();
strBaseString += playerName + " VS. " + otherPlayerName;
strOutBuf.Format("Making peace with all possible civilizations because we're in a critical state!");
strBaseString += strOutBuf;
pLog->Msg(strBaseString);
}
continue;
}
// Let's see how much danger each of us are currently in ...
int iWarDuration = min(GetPlayer()->GetPlayerNumTurnsAtWar(*it), GetPlayer()->GetPlayerNumTurnsSinceCityCapture(*it));
int iWarScore = GetWarScore(*it);
int iOurDanger = 0;
int iTheirDanger = 0;
bool bSeriousDangerUs = false;
bool bSeriousDangerThem = false;
ReligionTypes eMyReligion = GetPlayer()->GetReligions()->GetOwnedReligion();
ReligionTypes eTheirReligion = GET_PLAYER(*it).GetReligions()->GetOwnedReligion();
vector<PlayerTypes> vOurWarAllies = GetOffensiveWarAllies(*it, /*bIncludeMinors*/ true, /*bReverseMode*/ false);
vector<PlayerTypes> vTheirWarAllies = GetOffensiveWarAllies(*it, /*bIncludeMinors*/ true, /*bReverseMode*/ true);
vOurWarAllies.push_back(GetID());
vTheirWarAllies.push_back(*it);
vector<PlayerTypes> vMyTeam = GET_TEAM(GetTeam()).getPlayers();
vector<int> vEnemyCitiesEndangered;
vector<int> vEnemyCitiesEndangeredByUs;
for (CvCity* pLoopCity = m_pPlayer->firstCity(&iLoop); pLoopCity != NULL; pLoopCity = m_pPlayer->nextCity(&iLoop))
{
if (pLoopCity->IsInDangerFromPlayers(vTheirWarAllies)) // Only care if we're in danger from them!
{
int iDangerMod = 1;
//look at the tactical map (is it up to date?)
CvTacticalDominanceZone* pLandZone = m_pPlayer->GetTacticalAI()->GetTacticalAnalysisMap()->GetZoneByCity(pLoopCity,false);
CvTacticalDominanceZone* pWaterZone = m_pPlayer->GetTacticalAI()->GetTacticalAnalysisMap()->GetZoneByCity(pLoopCity,true);
if (pLandZone && pLandZone->GetOverallDominanceFlag()==TACTICAL_DOMINANCE_ENEMY)
iDangerMod++;
if (pWaterZone && pWaterZone->GetOverallDominanceFlag()==TACTICAL_DOMINANCE_ENEMY)
iDangerMod++;
if (pLoopCity->isUnderSiege())
{
if (pLoopCity->isInDangerOfFalling(true))
iDangerMod += 3;
else
iDangerMod++;
if (pLoopCity->isInDangerOfFalling(true) || pLoopCity->getDamage() >= (pLoopCity->GetMaxHitPoints()/2))
{
if (pLoopCity->getOriginalOwner() == GetID())
{
bSeriousDangerUs = true;
}
else if (pLoopCity->isCapital() || pLoopCity->IsOriginalMajorCapital() || (eMyReligion != NO_RELIGION && pLoopCity->GetCityReligions()->IsHolyCityForReligion(eMyReligion)) || (eTheirReligion != NO_RELIGION && pLoopCity->GetCityReligions()->IsHolyCityForReligion(eTheirReligion))
|| pLoopCity->HasAnyWonder() || pLoopCity->getNumNationalWonders() > 0)
{
bSeriousDangerUs = true;
}
}
}
if (iDangerMod > 1 && pLoopCity->IsInDanger(*it) && GetPlayer()->GetMilitaryAI()->IsExposedToEnemy(pLoopCity, *it))
{
iDangerMod++;
}
if (pLoopCity->isCapital())
iDangerMod *= 3;
else if (pLoopCity->IsOriginalMajorCapital() || (eMyReligion != NO_RELIGION && pLoopCity->GetCityReligions()->IsHolyCityForReligion(eMyReligion)) || (eTheirReligion != NO_RELIGION && pLoopCity->GetCityReligions()->IsHolyCityForReligion(eTheirReligion)) || pLoopCity->HasAnyWonder())
iDangerMod *= 2;
else if (pLoopCity->GetCityReligions()->IsHolyCityAnyReligion() || pLoopCity->getNumNationalWonders() > 0)
iDangerMod++;
iOurDanger += iDangerMod;
}
}
for (CvCity* pLoopCity = GET_PLAYER(*it).firstCity(&iLoop); pLoopCity != NULL; pLoopCity = GET_PLAYER(*it).nextCity(&iLoop))
{
if (pLoopCity->IsInDangerFromPlayers(vOurWarAllies)) // Only care if they're in danger from us!
{
int iDangerMod = 1;
//look at the tactical map (is it up to date?)
CvTacticalDominanceZone* pLandZone = GET_PLAYER(*it).GetTacticalAI()->GetTacticalAnalysisMap()->GetZoneByCity(pLoopCity,false);
CvTacticalDominanceZone* pWaterZone = GET_PLAYER(*it).GetTacticalAI()->GetTacticalAnalysisMap()->GetZoneByCity(pLoopCity,true);
if (pLandZone && pLandZone->GetOverallDominanceFlag()==TACTICAL_DOMINANCE_ENEMY)
iDangerMod++;
if (pWaterZone && pWaterZone->GetOverallDominanceFlag()==TACTICAL_DOMINANCE_ENEMY)
iDangerMod++;
if (pLoopCity->isUnderSiege())
{
if (pLoopCity->isInDangerOfFalling(true))
iDangerMod += 3;
else
iDangerMod++;
if (pLoopCity->isInDangerOfFalling(true) || pLoopCity->getDamage() >= (pLoopCity->GetMaxHitPoints()/2))
{
bSeriousDangerThem = true;
}
}
if (iDangerMod > 1)
{
vEnemyCitiesEndangered.push_back(pLoopCity->GetID());
if (pLoopCity->IsInDangerFromPlayers(vMyTeam))
{
vEnemyCitiesEndangeredByUs.push_back(pLoopCity->GetID());
if (pLoopCity->IsInDanger(GetID()) && GetPlayer()->GetMilitaryAI()->IsPreferredAttackTarget(pLoopCity))
{
iDangerMod++;
}
}
}
if (pLoopCity->isCapital())
iDangerMod *= 3;
else if (pLoopCity->IsOriginalMajorCapital() || (eMyReligion != NO_RELIGION && pLoopCity->GetCityReligions()->IsHolyCityForReligion(eMyReligion)) || (eTheirReligion != NO_RELIGION && pLoopCity->GetCityReligions()->IsHolyCityForReligion(eTheirReligion)) || pLoopCity->HasAnyWonder())
iDangerMod *= 2;
else if (pLoopCity->GetCityReligions()->IsHolyCityAnyReligion())
iDangerMod++;
iTheirDanger += iDangerMod;
}
}
bool bCapturedKeyCity = IsCapitalCapturedBy(*it, true, true) || IsHolyCityCapturedBy(*it, true, true);
bool bPhonyWar = IsPhonyWar(*it);
bool bCapturedAnyCityFromUs = bCapturedKeyCity;
bool bCapturedAnyCityWeWantToLiberate = false;
bool bReadyForVassalage = iWarScore >= 75 && !bCapturedKeyCity && !IsEndgameAggressiveTo(*it) && GET_TEAM(GET_PLAYER(*it).getTeam()).canBecomeVassal(GetTeam()) && !IsUntrustworthy(*it);
if (!bInTerribleShape)
{
// Let's check if they have any of our cities. If they do, no vassalage!
for (CvCity* pLoopCity = GET_PLAYER(*it).firstCity(&iLoop); pLoopCity != NULL; pLoopCity = GET_PLAYER(*it).nextCity(&iLoop))
{
PlayerTypes eOriginalOwner = pLoopCity->getOriginalOwner();
if (GET_PLAYER(eOriginalOwner).getTeam() == GET_PLAYER(*it).getTeam())
continue;
CvPlot* pCityPlot = pLoopCity->plot();
if (!pCityPlot)
continue;
bool bEndangeredPeriod = std::find(vEnemyCitiesEndangered.begin(), vEnemyCitiesEndangered.end(), pLoopCity->GetID()) != vEnemyCitiesEndangered.end();
bool bEndangeredByOurTeam = bEndangeredPeriod && std::find(vEnemyCitiesEndangeredByUs.begin(), vEnemyCitiesEndangeredByUs.end(), pLoopCity->GetID()) != vEnemyCitiesEndangeredByUs.end();
// Ignore cities that are too far away from us (unless endangered).
if (GetPlayer()->GetCityDistanceInPlots(pCityPlot) > 12)
{
if (!bEndangeredByOurTeam && (!bEndangeredPeriod || GET_PLAYER(eOriginalOwner).getTeam() != GetTeam()))
continue;
}
if (GET_PLAYER(eOriginalOwner).getTeam() == GetTeam())
{
bReadyForVassalage = false;
bCapturedAnyCityFromUs = true;
}
// Is this a city that we want to liberate?
else if (IsTryingToLiberate(pLoopCity))
{
bReadyForVassalage = false;
bCapturedAnyCityWeWantToLiberate = true;
}
if (bCapturedAnyCityFromUs && bCapturedAnyCityWeWantToLiberate)
break;
// Is this a valuable city endangered by our team?
// Alternatively, if we're nasty/hateful or get bonuses from conquering cities, we're rarely willing to vassalize if ANY city is vulnerable.
if (bEndangeredByOurTeam && bReadyForVassalage)
{
bool bProceed = bUABonusesFromCityConquest || IsBackstabber() || GetMeanness() >= 8 || GetDiploBalance() <= 2 || GetCivOpinion(*it) == CIV_OPINION_UNFORGIVABLE;
bProceed |= pLoopCity->IsOriginalMajorCapital() || pLoopCity->GetCityReligions()->IsHolyCityAnyReligion() || pLoopCity->HasAnyWonder();
if (bProceed)
{
if (GetPlayer()->GetMilitaryAI()->IsPreferredAttackTarget(pLoopCity))
{
bReadyForVassalage = false;
}
else if (pLoopCity->isUnderSiege())
{
bReadyForVassalage = false;
}
else
{
//look at the tactical map (is it up to date?)
CvTacticalDominanceZone* pLandZone = GET_PLAYER(*it).GetTacticalAI()->GetTacticalAnalysisMap()->GetZoneByCity(pLoopCity,false);
CvTacticalDominanceZone* pWaterZone = GET_PLAYER(*it).GetTacticalAI()->GetTacticalAnalysisMap()->GetZoneByCity(pLoopCity,true);
if (pLandZone && pLandZone->GetOverallDominanceFlag()==TACTICAL_DOMINANCE_ENEMY)
{
bReadyForVassalage = false;
}
else if (pWaterZone && pWaterZone->GetOverallDominanceFlag()==TACTICAL_DOMINANCE_ENEMY)
{
bReadyForVassalage = false;
}
}
}
}
}
}
// No peace if they're in danger of losing a city and we're not.
if (bSeriousDangerThem && !bSeriousDangerUs)
{
if (iWarDuration < 40) // Failsafe in case of a problem somewhere - limit the amount of time peace is impossible for
{
SetTreatyWillingToOffer(*it, NO_PEACE_TREATY_TYPE);
SetTreatyWillingToAccept(*it, NO_PEACE_TREATY_TYPE);
if (bLog)
{
CvString strOutBuf;
CvString strBaseString;
CvString playerName;
CvString otherPlayerName;
CvString strLogName;
// Find the name of this civ and city
playerName = m_pPlayer->getCivilizationShortDescription();
// Open the log file
if (GC.getPlayerAndCityAILogSplit())
{
strLogName = "DiplomacyAI_Peace_Log" + playerName + ".csv";
}
else
{
strLogName = "DiplomacyAI_Peace_Log.csv";
}
FILogFile* pLog = NULL;
pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp);
// Get the leading info for this line
strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
otherPlayerName = GET_PLAYER(*it).getCivilizationShortDescription();
strBaseString += playerName + " VS. " + otherPlayerName;
strOutBuf.Format("No peace! They're in serious danger of losing a city and we're not!");
strBaseString += strOutBuf;
pLog->Msg(strBaseString);
}
continue;
}
}
// If we're in serious danger, let's offer peace.
else if ((iWarScore <= -90 && iOurDanger > 0) || (iWarScore <= -50 && (bInTerribleShape || bSeriousDangerUs)))
{
vMakePeacePlayers.push_back(*it);
if (bLog)
{
CvString strOutBuf;
CvString strBaseString;
CvString playerName;
CvString otherPlayerName;
CvString strLogName;
// Find the name of this civ and city
playerName = m_pPlayer->getCivilizationShortDescription();
// Open the log file
if (GC.getPlayerAndCityAILogSplit())
{
strLogName = "DiplomacyAI_Peace_Log" + playerName + ".csv";
}
else
{
strLogName = "DiplomacyAI_Peace_Log.csv";
}
FILogFile* pLog = NULL;
pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp);
// Get the leading info for this line
strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
otherPlayerName = GET_PLAYER(*it).getCivilizationShortDescription();
strBaseString += playerName + " VS. " + otherPlayerName;
strOutBuf.Format("Automatic peace offer: We're badly losing this war!");
strBaseString += strOutBuf;
pLog->Msg(strBaseString);
}
continue;
}
// Let's offer peace if we're in danger of losing a city we originally founded (or a really important city) and they're not at risk of losing a city
else if (bSeriousDangerUs && !bSeriousDangerThem)
{
vMakePeacePlayers.push_back(*it);
if (bLog)
{
CvString strOutBuf;
CvString strBaseString;
CvString playerName;
CvString otherPlayerName;
CvString strLogName;
// Find the name of this civ and city
playerName = m_pPlayer->getCivilizationShortDescription();
// Open the log file
if (GC.getPlayerAndCityAILogSplit())
{
strLogName = "DiplomacyAI_Peace_Log" + playerName + ".csv";
}
else
{
strLogName = "DiplomacyAI_Peace_Log.csv";
}
FILogFile* pLog = NULL;
pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp);
// Get the leading info for this line
strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
otherPlayerName = GET_PLAYER(*it).getCivilizationShortDescription();
strBaseString += playerName + " VS. " + otherPlayerName;
strOutBuf.Format("Automatic peace offer: We're in serious danger of losing an important city and they're not in serious danger!");
strBaseString += strOutBuf;
pLog->Msg(strBaseString);
}
continue;
}
// Do not make peace if it would block us from achieving a Domination Victory we're going for (possible with DiploAIOptions.sql)
if (!bReadyForVassalage && GC.getGame().WouldMakingPeacePreventDominationVictory(GetID(), *it))
{
if (IsGoingForWorldConquest() || IsCloseToWorldConquest())
{
SetTreatyWillingToOffer(*it, NO_PEACE_TREATY_TYPE);
SetTreatyWillingToAccept(*it, NO_PEACE_TREATY_TYPE);
if (bLog)
{
CvString strOutBuf;
CvString strBaseString;
CvString playerName;
CvString otherPlayerName;
CvString strLogName;
// Find the name of this civ and city
playerName = m_pPlayer->getCivilizationShortDescription();
// Open the log file
if (GC.getPlayerAndCityAILogSplit())
{
strLogName = "DiplomacyAI_Peace_Log" + playerName + ".csv";
}
else
{
strLogName = "DiplomacyAI_Peace_Log.csv";
}
FILogFile* pLog = NULL;
pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp);
// Get the leading info for this line
strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
otherPlayerName = GET_PLAYER(*it).getCivilizationShortDescription();
strBaseString += playerName + " VS. " + otherPlayerName;
strOutBuf.Format("No peace! We'll lose our shot at Domination Victory if we make peace!");
strBaseString += strOutBuf;
pLog->Msg(strBaseString);
}
continue;
}
}
// If this is a phony war and they're not in danger, let's offer peace.
if (bPhonyWar && iTheirDanger == 0)
{
vMakePeacePlayers.push_back(*it);
if (bLog)
{
CvString strOutBuf;
CvString strBaseString;
CvString playerName;
CvString otherPlayerName;
CvString strLogName;
// Find the name of this civ and city
playerName = m_pPlayer->getCivilizationShortDescription();
// Open the log file
if (GC.getPlayerAndCityAILogSplit())
{
strLogName = "DiplomacyAI_Peace_Log" + playerName + ".csv";
}
else
{
strLogName = "DiplomacyAI_Peace_Log.csv";
}
FILogFile* pLog = NULL;
pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp);
// Get the leading info for this line
strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
otherPlayerName = GET_PLAYER(*it).getCivilizationShortDescription();
strBaseString += playerName + " VS. " + otherPlayerName;
strOutBuf.Format("Automatic peace offer: This is a phony war and none of their cities are in danger!");
strBaseString += strOutBuf;
pLog->Msg(strBaseString);
}
continue;
}
// Test war progress score: if sufficiently negative, AI will agree to make white peace (at minimum)
// But ignore this if opponent's cities are endangered, unless the war has gone on for too long or we're in serious danger
if (vEnemyCitiesEndangered.size() == 0 || bSeriousDangerUs || bInTerribleShape || iWarDuration >= 40)
{
int iWarProgress = GetWarProgressScore(*it);
// Adjust for unhappiness/war weariness
if (MOD_BALANCE_VP)
{
iWarProgress -= GetPlayer()->GetUnhappinessFromWarWeariness();
int iHappiness = GetPlayer()->GetExcessHappiness();
if (iHappiness < 50)
{
iWarProgress += (50 - iHappiness) * /*-2*/ GD_INT_GET(WAR_PROGRESS_PER_UNHAPPY);
}
}
else if (GetPlayer()->GetExcessHappiness() < 0)
iWarProgress -= GetPlayer()->GetExcessHappiness() * /*-4*/ GD_INT_GET(WAR_PROGRESS_PER_UNHAPPY);
// Adjust for strategic resource shortages
int iStrategicDeficit = 0;
int iMaxStrategicDeficit = -50;
for (int iResourceLoop = 0; iResourceLoop < GC.getNumResourceInfos(); iResourceLoop++)
{
ResourceTypes eResource = (ResourceTypes) iResourceLoop;
if (eResource == NO_RESOURCE)
continue;
const CvResourceInfo* pkResourceInfo = GC.getResourceInfo(eResource);
if (pkResourceInfo == NULL)
continue;
if (pkResourceInfo->getResourceUsage() != RESOURCEUSAGE_STRATEGIC)
continue;
if (GetPlayer()->getResourceShortageValue(eResource) > 0)
iStrategicDeficit += GetPlayer()->getResourceShortageValue(eResource) * /*-5*/ GD_INT_GET(WAR_PROGRESS_PER_STRATEGIC_DEFICIT);
if (iStrategicDeficit <= iMaxStrategicDeficit)
break;
}
iWarProgress += max(iStrategicDeficit, iMaxStrategicDeficit);
if (iWarProgress <= 0)
{
vMakePeacePlayers.push_back(*it);
if (bLog)
{
CvString strOutBuf;
CvString strBaseString;
CvString playerName;
CvString otherPlayerName;
CvString strLogName;
// Find the name of this civ and city
playerName = m_pPlayer->getCivilizationShortDescription();
// Open the log file
if (GC.getPlayerAndCityAILogSplit())
{
strLogName = "DiplomacyAI_Peace_Log" + playerName + ".csv";
}
else
{
strLogName = "DiplomacyAI_Peace_Log.csv";
}
FILogFile* pLog = NULL;
pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp);
// Get the leading info for this line
strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
otherPlayerName = GET_PLAYER(*it).getCivilizationShortDescription();
strBaseString += playerName + " VS. " + otherPlayerName;
strOutBuf.Format("Automatic peace offer: We're making no progress in this war!");
strBaseString += strOutBuf;
pLog->Msg(strBaseString);
}
continue;
}
}
// If not ready for vassalage with a neighbor and the war is nearly won, let's persevere.
if (!bReadyForVassalage && GetWarState(*it) == WAR_STATE_NEARLY_WON && GetPlayer()->GetProximityToPlayer(*it) >= PLAYER_PROXIMITY_CLOSE && iWarDuration < 30 && !bInTerribleShape)
{
SetTreatyWillingToOffer(*it, NO_PEACE_TREATY_TYPE);
SetTreatyWillingToAccept(*it, NO_PEACE_TREATY_TYPE);
if (bLog)
{
CvString strOutBuf;
CvString strBaseString;
CvString playerName;
CvString otherPlayerName;
CvString strLogName;
CvString strNoVassalReason;
// Find the name of this civ and city
playerName = m_pPlayer->getCivilizationShortDescription();
// Open the log file
if (GC.getPlayerAndCityAILogSplit())
{
strLogName = "DiplomacyAI_Peace_Log" + playerName + ".csv";
}
else
{
strLogName = "DiplomacyAI_Peace_Log.csv";
}
FILogFile* pLog = NULL;
pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp);
// Get the leading info for this line
strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
otherPlayerName = GET_PLAYER(*it).getCivilizationShortDescription();
strBaseString += playerName + " VS. " + otherPlayerName;
strOutBuf.Format("No peace! We've almost won this war and ");
if (!GET_TEAM(GET_PLAYER(*it).getTeam()).canBecomeVassal(GetTeam()))
strNoVassalReason.Format("we're not able to make them a vassal!");
else if (bCapturedAnyCityFromUs)
strNoVassalReason.Format("they have a nearby city they captured from us!");
else if (IsEndgameAggressiveTo(*it))
strNoVassalReason.Format("they're in danger of winning the game!");
else if (bCapturedAnyCityWeWantToLiberate)
strNoVassalReason.Format("they have a nearby city we want to liberate!");
else if (iWarScore < 75)
strNoVassalReason.Format("war score is less than 75!");
else if (IsUntrustworthy(*it))
strNoVassalReason.Format("we don't trust them to be an obedient vassal!");
else
strNoVassalReason.Format("we still want to capture cities from them!");
strOutBuf += strNoVassalReason;
strBaseString += strOutBuf;
pLog->Msg(strBaseString);
}
continue;
}
bool bWarWeary = false;
if (MOD_BALANCE_VP)
{
int iPercentOfPop = GetPlayer()->GetUnhappinessFromWarWeariness() * 100 / max(1, GetPlayer()->getTotalPopulation());
if (iPercentOfPop >= 20)
bWarWeary = true;
}
// Okay, so no automatic peace. But should we consider peace at all?
bool bConsiderPeace = bReadyForVassalage || bPhonyWar || bSeriousDangerUs || bInTerribleShape || bWarWeary;
bConsiderPeace |= GetCivApproach(*it) > CIV_APPROACH_HOSTILE;
bConsiderPeace |= GetWarState(*it) <= WAR_STATE_TROUBLED;
bConsiderPeace |= iWarDuration >= 30;
// Not worth making peace with. Proceed.
if (!bConsiderPeace)
{
SetTreatyWillingToOffer(*it, NO_PEACE_TREATY_TYPE);
SetTreatyWillingToAccept(*it, NO_PEACE_TREATY_TYPE);
if (bLog)
{
CvString strOutBuf;
CvString strBaseString;
CvString playerName;
CvString otherPlayerName;
CvString strLogName;
// Find the name of this civ and city
playerName = m_pPlayer->getCivilizationShortDescription();
// Open the log file
if (GC.getPlayerAndCityAILogSplit())
{
strLogName = "DiplomacyAI_Peace_Log" + playerName + ".csv";
}
else
{
strLogName = "DiplomacyAI_Peace_Log.csv";
}
FILogFile* pLog = NULL;
pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp);
// Get the leading info for this line
strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
otherPlayerName = GET_PLAYER(*it).getCivilizationShortDescription();
strBaseString += playerName + " VS. " + otherPlayerName;
strOutBuf.Format("No peace! We don't have a good enough reason to consider peace yet!");
strBaseString += strOutBuf;
pLog->Msg(strBaseString);
}
continue;
}
// If we've gotten this far, we need to at least consider the merits of peace.
int iPeaceScore = 0;
// War score is of course a significant factor
// If we get a tourism bonus from high warscore or special conquest bonuses, let's not end early!
bool bProlong = GetPlayer()->GetPositiveWarScoreTourismMod() > 0 && GET_PLAYER(GetHighestWarscorePlayer()).getTeam() == GET_PLAYER(*it).getTeam();
if (iWarScore <= 0)
{
iPeaceScore += iWarScore / -2;
bProlong = false;
}
else if (bInTerribleShape || bSeriousDangerUs)
{
iPeaceScore += iWarScore / 3;
bProlong = false;
}
else if (vEnemyCitiesEndangeredByUs.size() > 0)
{
bProlong |= bUABonusesFromCityConquest;
if (!bProlong)
iPeaceScore += iWarScore / 5;
}
else if (!bProlong)
{
iPeaceScore += iWarScore / 5;
}
int iMinimumWarDuration = max(0, /*10*/ GD_INT_GET(WAR_MAJOR_MINIMUM_TURNS));
int iTooLongWarThreshold = max(15, iMinimumWarDuration);
if (bProlong)
{
iTooLongWarThreshold *= 2;
iMinimumWarDuration *= 2;
}
int iDurationPenalty = iWarDuration - iMinimumWarDuration;
// Lack of progress in war increases desire for peace (moreso if far away).
if (iWarDuration > iTooLongWarThreshold)
{
switch (GetPlayer()->GetProximityToPlayer(*it))
{
case PLAYER_PROXIMITY_NEIGHBORS:
iPeaceScore += iDurationPenalty;
break;
case PLAYER_PROXIMITY_CLOSE:
iPeaceScore += (iDurationPenalty * 150) / 100;
break;
case PLAYER_PROXIMITY_FAR:
iPeaceScore += iDurationPenalty * 2;
break;
case NO_PLAYER_PROXIMITY:
case PLAYER_PROXIMITY_DISTANT:
iPeaceScore += iDurationPenalty * 3;
break;
}
}
// War weariness
if (MOD_BALANCE_VP)
{
int iWarWeariness = GetPlayer()->GetUnhappinessFromWarWeariness();
iPeaceScore += iWarWeariness / 4;
if (iWarWeariness > 0 && (bWarWeary || GetPlayer()->IsEmpireUnhappy()))
{
if (GetPlayer()->IsEmpireVeryUnhappy() || (GetPlayer()->IsEmpireUnhappy() && bWarWeary))
iPeaceScore += iWarWeariness / 2;
else
iPeaceScore += iWarWeariness / 3;
}
}
// Danger considerations
int iOurMultiplier = 1;
int iTheirMultiplier = 1;
if (!bInTerribleShape || GetWarState(*it) == WAR_STATE_NEARLY_WON)
{
if (GetMilitaryStrengthComparedToUs(*it) < STRENGTH_AVERAGE)
{
iOurMultiplier++;
}
if (IsEasyTarget(*it))
{
iOurMultiplier++;
}
if (GetPlayer()->GetMilitaryAI()->HavePreferredAttackTarget(*it))
{
iOurMultiplier++;
}
if (GetWarState(*it) == WAR_STATE_NEARLY_WON || GET_PLAYER(*it).IsInTerribleShapeForWar())
{
iOurMultiplier++;
}
}
if (!GET_PLAYER(*it).IsInTerribleShapeForWar())
{
if (GetMilitaryStrengthComparedToUs(*it) > STRENGTH_AVERAGE)
{
iTheirMultiplier++;
}
if (bInTerribleShape)
{
iTheirMultiplier++;
}
if (GET_PLAYER(*it).GetDiplomacyAI()->IsEasyTarget(GetID()))
{
iTheirMultiplier++;
}
if (GetPlayer()->GetMilitaryAI()->IsExposedToEnemy(NULL, *it))
{
iTheirMultiplier++;
}
}
// They're in danger and we're not? Let's hold out longer!
if (iOurDanger == 0 && iTheirDanger > 0)
{
if (iWarDuration < 20 || iOurMultiplier > 2 || bSeriousDangerThem)
{
iPeaceScore -= (5 * iTheirDanger * iOurMultiplier);
}
else
{
iPeaceScore -= (2 * iTheirDanger * iOurMultiplier);
}
}
// We're in danger and they're not? Let's hold out less!
else if (iOurDanger > 0 && iTheirDanger == 0)
{
if (iWarScore <= GetWarscoreThresholdNegative()/2 || iTheirMultiplier > 2 || bSeriousDangerUs)
{
iPeaceScore += (5 * iOurDanger * iTheirMultiplier);
}
else
{
iPeaceScore += (2 * iOurDanger * iTheirMultiplier);
}
}
// We're both in danger - how much?
else
{
iPeaceScore -= (2 * iTheirDanger * iOurMultiplier);
iPeaceScore += (2 * iOurDanger * iTheirMultiplier);
}
// Also consider the overall war state
bool bLosingOverall = GetStateAllWars() == STATE_ALL_WARS_LOSING;
switch (GetWarState(*it))
{
case NO_WAR_STATE_TYPE:
UNREACHABLE(); // Being here would indicate we aren't at a war with this player.
case WAR_STATE_NEARLY_WON:
iPeaceScore -= bReadyForVassalage ? 0 : 10 * iOurMultiplier;
break;
case WAR_STATE_OFFENSIVE:
iPeaceScore -= 5 * iOurMultiplier;
break;
case WAR_STATE_CALM:
iPeaceScore -= bLosingOverall ? -5 * iTheirMultiplier : 2 * iOurMultiplier;
break;
case WAR_STATE_STALEMATE:
case WAR_STATE_TROUBLED:
iPeaceScore += bLosingOverall ? 5 * iTheirMultiplier : 2 * iTheirMultiplier;
break;
case WAR_STATE_DEFENSIVE:
case WAR_STATE_NEARLY_DEFEATED:
iPeaceScore += bLosingOverall ? 10 * iTheirMultiplier : 5 * iTheirMultiplier;
break;
}
// Hold out for longer if we have military support from nearby allies
int iAlliesMod = 0;
if (!bInTerribleShape)
{
for (std::vector<PlayerTypes>::iterator iter = vOurWarAllies.begin(); iter != vOurWarAllies.end(); iter++)
{
if (GET_PLAYER(*iter).GetID() == GetID())
continue;
if (!GET_PLAYER(*iter).isMajorCiv())
continue;
if (GET_PLAYER(*iter).IsInTerribleShapeForWar())
continue;
if (GET_PLAYER(*iter).GetProximityToPlayer(GetID()) < PLAYER_PROXIMITY_CLOSE)
continue;
if (GET_PLAYER(*iter).GetProximityToPlayer(*it) < PLAYER_PROXIMITY_CLOSE)
continue;
if (GET_PLAYER(*iter).GetDiplomacyAI()->GetWarState(*it) <= WAR_STATE_TROUBLED)
continue;
switch (GET_PLAYER(*iter).GetDiplomacyAI()->GetMilitaryStrengthComparedToUs(*it))
{
case NO_STRENGTH_VALUE:
UNREACHABLE(); // Strengths are supposed to have been evaluated by this point.
case STRENGTH_IMMENSE:
case STRENGTH_POWERFUL:
case STRENGTH_STRONG:
break;
case STRENGTH_AVERAGE:
case STRENGTH_POOR:
iAlliesMod -= 5;
break;
case STRENGTH_WEAK:
iAlliesMod -= 10;
break;
case STRENGTH_PATHETIC:
iAlliesMod -= 15;
break;
}
}
// Ongoing coop war? Minimum -10 modifier.
if (iAlliesMod > -10 && GetGlobalCoopWarAgainstState(*it) == COOP_WAR_STATE_ONGOING)
{
iAlliesMod = -10;
}
}
if (iWarScore <= GetWarscoreThresholdNegative() && GetWarState(*it) < WAR_STATE_OFFENSIVE)
{
iAlliesMod /= 2;
}
iPeaceScore += iAlliesMod;
// If we want to conquer them, let's hold out longer.
if (!bReadyForVassalage && IsWantsToConquer(*it))
{
iPeaceScore -= 10;
}
// If they captured one of our key cities, let's hold out for significantly longer.
if (bCapturedKeyCity)
{
iPeaceScore -= 15;
}
// If they're about to win the game, let's hold out for a lot longer.
if (IsEndgameAggressiveTo(*it))
{
iPeaceScore -= 20;
}
bool bAztecException = false;
if (iPeaceScore > 0)
{
// If we're going for world conquest, we want to fight our wars until we get their capital or can vassalize them
// We should also be more reluctant to make peace if they've captured cities from us, or cities that we want to liberate
// However, do not factor this in when losing
if (!bInTerribleShape)
{
if (iWarScore > 0 || (iWarScore > GetWarscoreThresholdNegative()/2 && GetRawTargetValue(*it) >= TARGET_VALUE_AVERAGE && GetWarState(*it) > WAR_STATE_TROUBLED))
{
if (iWarScore < WARSCORE_THRESHOLD_POSITIVE && GetPlayer()->GetPlayerTraits()->GetGoldenAgeFromVictory() > 0)
{
bAztecException = true;
iPeaceScore /= 2;
}
else if (bCapturedAnyCityFromUs)
{
if (iWarScore > (iWarDuration / 2))
iPeaceScore /= 2;
else
{
iPeaceScore *= 75;
iPeaceScore /= 100;
}
}
else if (bCapturedAnyCityWeWantToLiberate)
{
if ((bDiplomatic && iWarScore > 0) || iWarScore > iWarDuration)
{
if (bDiplomatic && iWarScore > iWarDuration)
{
iPeaceScore /= 2;
}
else
{
iPeaceScore *= 75;
iPeaceScore /= 100;
}
}
}
else if (bWorldConquest)
{
if (bReadyForVassalage || (GET_PLAYER(*it).GetCapitalConqueror() != NO_PLAYER && GET_PLAYER(*it).GetNumCapitalCities() <= 0))
{
// If they're economically weak or a bad target, boost peace willingness
if (GetEconomicStrengthComparedToUs(*it) <= STRENGTH_WEAK || GetRawTargetValue(*it) <= TARGET_VALUE_BAD)
iPeaceScore *= 2;
else if (GetTargetValue(*it) == TARGET_VALUE_DIFFICULT)
{
iPeaceScore *= 3;
iPeaceScore /= 2;
}
}
else if (GET_PLAYER(*it).GetCapitalConqueror() == NO_PLAYER || GET_PLAYER(*it).GetNumCapitalCities() > 0)
{
iPeaceScore *= 75;
iPeaceScore /= 100;
}
}
}
}
// Overall state is bad and we're doing great in this war, or at least haven't lost any cities? Let's peace out!
else if (!bCapturedAnyCityFromUs || bReadyForVassalage || GetWarState(*it) == WAR_STATE_NEARLY_WON)
{
iPeaceScore *= 2;
// Both? Even more likely to make peace!
if (!bCapturedAnyCityFromUs && (bReadyForVassalage || GetWarState(*it) == WAR_STATE_NEARLY_WON))
iPeaceScore *= 2;
}
// Modify based on leader flavors
// High Meanness leaders will fight to the bitter end when losing, high Diplo Balance leaders like to return to status quo when winning
if (iWarScore > 0)
{
iPeaceScore = AdjustConditionalModifier(iPeaceScore, GetDiploBalance());
}
else if (iWarScore < 0)
{
iPeaceScore = AdjustConditionalModifier(iPeaceScore, GetMeanness(), true);
}
}
// Must be high enough to return a true desire for peace
int iWarCount = GetPlayer()->CountNumDangerousMajorsAtWarWith(true, false) - 1;
if (iWarCount <= 0)
iWarCount = 0;
bool bWantedPeaceLastTime = IsWantsPeaceWithPlayer(*it) && !bAztecException; // if we were willing to make peace last update, add some leeway here to prevent flip-flopping
int iThreshold = bWantedPeaceLastTime ? /*17*/ GD_INT_GET(REQUEST_PEACE_LEEWAY_THRESHOLD) : /*20*/ GD_INT_GET(REQUEST_PEACE_TURN_THRESHOLD);
int iThresholdReductionPerOtherWar = bWantedPeaceLastTime ? /*3*/ GD_INT_GET(REQUEST_PEACE_LEEWAY_THRESHOLD_REDUCTION_PER_WAR) : /*2*/ GD_INT_GET(REQUEST_PEACE_THRESHOLD_REDUCTION_PER_WAR);
iThreshold = max(iThreshold - max(iThresholdReductionPerOtherWar * iWarCount, 0), 1);
if (iPeaceScore >= iThreshold)
vMakePeacePlayers.push_back(*it);
else
{
SetTreatyWillingToOffer(*it, NO_PEACE_TREATY_TYPE);
SetTreatyWillingToAccept(*it, NO_PEACE_TREATY_TYPE);
}
if (bLog)
{
CvString strOutBuf;
CvString strBaseString;
CvString playerName;
CvString otherPlayerName;
CvString strLogName;
// Find the name of this civ and city
playerName = m_pPlayer->getCivilizationShortDescription();
// Open the log file
if (GC.getPlayerAndCityAILogSplit())
{
strLogName = "DiplomacyAI_Peace_Log" + playerName + ".csv";
}
else
{
strLogName = "DiplomacyAI_Peace_Log.csv";
}
FILogFile* pLog = NULL;
pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp);
// Get the leading info for this line
strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
otherPlayerName = GET_PLAYER(*it).getCivilizationShortDescription();
strBaseString += playerName + " VS. " + otherPlayerName;
if (iPeaceScore >= iThreshold)
strOutBuf.Format("Willing to make peace, Score for Peace: %d, Required Score: %d", iPeaceScore, iThreshold);
else
strOutBuf.Format("Not willing to make peace, Score for Peace: %d, Required Score: %d", iPeaceScore, iThreshold);
strBaseString += strOutBuf;
pLog->Msg(strBaseString);
}
}
// STEP 4: Decide WHAT we're willing to accept/offer in exchange for peace.
for (std::vector<PlayerTypes>::iterator it = vMakePeacePlayers.begin(); it != vMakePeacePlayers.end(); it++)
{
PeaceTreatyTypes eTreatyWillingToOffer = PEACE_TREATY_WHITE_PEACE;
PeaceTreatyTypes eTreatyWillingToAccept = PEACE_TREATY_WHITE_PEACE;
int iWillingToOfferScore = 0;
int iWillingToAcceptScore = 0;
// What we're willing to offer/accept in a peace treaty.
int iWarScore = GetWarScore(*it);
// Negative Warscore? Offer more.
if (iWarScore < 0)
{
iWillingToOfferScore -= iWarScore;
}
// Positive Warscore? Accept more.
else
{
iWillingToAcceptScore += iWarScore;
}
// War Weary? We're more willing to make peace.
if (MOD_BALANCE_VP)
{
if (iWarScore <= 0)
{
iWillingToOfferScore += GetPlayer()->GetUnhappinessFromWarWeariness();
}
else
{
iWillingToAcceptScore -= GetPlayer()->GetUnhappinessFromWarWeariness();
}
}
// Do the final assessment
if (iWillingToOfferScore >= /*100*/ GD_INT_GET(PEACE_WILLINGNESS_OFFER_THRESHOLD_UN_SURRENDER))
eTreatyWillingToOffer = PEACE_TREATY_UNCONDITIONAL_SURRENDER;
else if (iWillingToOfferScore >= /*90*/ GD_INT_GET(PEACE_WILLINGNESS_OFFER_THRESHOLD_CAPITULATION))
eTreatyWillingToOffer = PEACE_TREATY_CAPITULATION;
else if (iWillingToOfferScore >= /*80*/ GD_INT_GET(PEACE_WILLINGNESS_OFFER_THRESHOLD_CESSION))
eTreatyWillingToOffer = PEACE_TREATY_CESSION;
else if (iWillingToOfferScore >= /*70*/ GD_INT_GET(PEACE_WILLINGNESS_OFFER_THRESHOLD_SURRENDER))
eTreatyWillingToOffer = PEACE_TREATY_SURRENDER;
else if (iWillingToOfferScore >= /*60*/ GD_INT_GET(PEACE_WILLINGNESS_OFFER_THRESHOLD_SUBMISSION))
eTreatyWillingToOffer = PEACE_TREATY_SUBMISSION;
else if (iWillingToOfferScore >= /*40*/ GD_INT_GET(PEACE_WILLINGNESS_OFFER_THRESHOLD_BACKDOWN))
eTreatyWillingToOffer = PEACE_TREATY_BACKDOWN;
else if (iWillingToOfferScore >= /*30*/ GD_INT_GET(PEACE_WILLINGNESS_OFFER_THRESHOLD_SETTLEMENT))
eTreatyWillingToOffer = PEACE_TREATY_SETTLEMENT;
else if (iWillingToOfferScore >= /*15*/ GD_INT_GET(PEACE_WILLINGNESS_OFFER_THRESHOLD_ARMISTICE))
eTreatyWillingToOffer = PEACE_TREATY_ARMISTICE;
// Do the final assessment
if (iWillingToAcceptScore >= /*100*/ GD_INT_GET(PEACE_WILLINGNESS_ACCEPT_THRESHOLD_UN_SURRENDER))
eTreatyWillingToAccept = PEACE_TREATY_UNCONDITIONAL_SURRENDER;
else if (iWillingToAcceptScore >= /*90*/ GD_INT_GET(PEACE_WILLINGNESS_ACCEPT_THRESHOLD_CAPITULATION))
eTreatyWillingToAccept = PEACE_TREATY_CAPITULATION;
else if (iWillingToAcceptScore >= /*80*/ GD_INT_GET(PEACE_WILLINGNESS_ACCEPT_THRESHOLD_CESSION))
eTreatyWillingToAccept = PEACE_TREATY_CESSION;
else if (iWillingToAcceptScore >= /*70*/ GD_INT_GET(PEACE_WILLINGNESS_ACCEPT_THRESHOLD_SURRENDER))
eTreatyWillingToAccept = PEACE_TREATY_SURRENDER;
else if (iWillingToAcceptScore >= /*60*/ GD_INT_GET(PEACE_WILLINGNESS_ACCEPT_THRESHOLD_SUBMISSION))
eTreatyWillingToAccept = PEACE_TREATY_SUBMISSION;
else if (iWillingToAcceptScore >= /*40*/ GD_INT_GET(PEACE_WILLINGNESS_ACCEPT_THRESHOLD_BACKDOWN))
eTreatyWillingToAccept = PEACE_TREATY_BACKDOWN;
else if (iWillingToAcceptScore >= /*30*/ GD_INT_GET(PEACE_WILLINGNESS_ACCEPT_THRESHOLD_SETTLEMENT))
eTreatyWillingToAccept = PEACE_TREATY_SETTLEMENT;
else if (iWillingToAcceptScore >= /*15*/ GD_INT_GET(PEACE_WILLINGNESS_ACCEPT_THRESHOLD_ARMISTICE))
eTreatyWillingToAccept = PEACE_TREATY_ARMISTICE;
// If we're in a critical state, always accept a white peace.
if (bCriticalState)
{
if (eTreatyWillingToOffer <= PEACE_TREATY_WHITE_PEACE)
eTreatyWillingToOffer = PEACE_TREATY_WHITE_PEACE;
eTreatyWillingToAccept = PEACE_TREATY_WHITE_PEACE;
}
SetTreatyWillingToOffer(*it, eTreatyWillingToOffer);
SetTreatyWillingToAccept(*it, eTreatyWillingToAccept);
}
}