bool CvReligionAI::DoFaithPurchases()
{
ReligionTypes eReligion = GetReligionToSpread();
CvGameReligions* pReligions = GC.getGame().GetGameReligions();
const CvReligion* pMyReligion = pReligions->GetReligion(eReligion, m_pPlayer->GetID());
#if !defined(MOD_BALANCE_CORE)
bool bTooManyMissionaries = m_pPlayer->GetNumUnitsWithUnitAI(UNITAI_MISSIONARY) > GC.getRELIGION_MAX_MISSIONARIES();
#endif
CvString strLogMsg;
if(GC.getLogging())
{
strLogMsg = m_pPlayer->getCivilizationShortDescription();
}
#if defined(MOD_BALANCE_CORE)
CvPlayer &kPlayer = GET_PLAYER(m_pPlayer->GetID());
if(kPlayer.GetID() == NO_PLAYER)
{
return false;
}
CvCity* pCapital = m_pPlayer->getCapitalCity();
CvCity *pHolyCity = NULL;
if(pMyReligion)
{
CvPlot* pHolyCityPlot = GC.getMap().plot(pMyReligion->m_iHolyCityX, pMyReligion->m_iHolyCityY);
if (pHolyCityPlot)
{
pHolyCity = pHolyCityPlot->getPlotCity();
if (pHolyCity && (pHolyCity->getOwner() == kPlayer.GetID()))
{
pCapital = pHolyCity;
}
}
}
if(pCapital == NULL)
{
return false;
}
UnitTypes eProphetType = kPlayer.GetSpecificUnitType("UNITCLASS_PROPHET", true);
UnitClassTypes eUnitClassMissionary = (UnitClassTypes)GC.getInfoTypeForString("UNITCLASS_MISSIONARY");
int iNumMissionaries = 0;
CvUnit* pLoopUnit;
int iLoop;
// Current Units
for (pLoopUnit = kPlayer.firstUnit(&iLoop); pLoopUnit != NULL; pLoopUnit = kPlayer.nextUnit(&iLoop))
{
if (pLoopUnit->GetReligionData() != NULL && pLoopUnit->GetReligionData()->GetSpreadsLeft() > 0 && pLoopUnit->GetReligionData()->GetReligion() == eReligion)
{
iNumMissionaries++;
}
}
int iMaxMissionaries = GC.getRELIGION_MAX_MISSIONARIES();
//Do we have any useful beliefs to consider?
CvBeliefXMLEntries* pkBeliefs = GC.GetGameBeliefs();
int iBonusValue = 0;
const int iNumBeliefs = pkBeliefs->GetNumBeliefs();
for(int iI = 0; iI < iNumBeliefs; iI++)
{
const BeliefTypes eBelief(static_cast<BeliefTypes>(iI));
CvBeliefEntry* pEntry = pkBeliefs->GetEntry(eBelief);
if(pEntry && m_pPlayer->HasBelief(eBelief))
{
for(int iI = 0; iI < NUM_YIELD_TYPES; iI++)
{
if(pEntry->GetYieldFromConversion((YieldTypes)iI) > 0)
{
iBonusValue++;
}
if(pEntry->GetYieldFromForeignSpread((YieldTypes)iI) > 0)
{
iBonusValue++;
}
if(pEntry->GetYieldFromSpread((YieldTypes)iI) > 0)
{
iBonusValue++;
}
if(pEntry->GetYieldPerFollowingCity((YieldTypes)iI) > 0)
{
iBonusValue++;
}
if (pEntry->GetYieldPerXFollowers((YieldTypes)iI) > 0)
{
iBonusValue++;
}
}
if(pEntry->GetMissionaryInfluenceCS() > 0)
{
iBonusValue++;
}
}
}
iMaxMissionaries += iBonusValue;
for (int i = MAX_MAJOR_CIVS; i < MAX_CIV_PLAYERS; i++)
{
PlayerTypes ePlayer = (PlayerTypes)i;
if (ePlayer == NO_PLAYER || !GET_PLAYER(ePlayer).isAlive())
continue;
if (!pReligions->HasAddedReformationBelief(ePlayer))
continue;
//we want fewer missionaries if reformations are poppping up (this is a good way to judge if we have a chance to spread or not)
//we want even fewer if we're reformed.
iMaxMissionaries -= m_pPlayer->GetID() == ePlayer ? 3 : 1;
}
//minimum 1 (prevents overflow issues if we're on a big map with tons of religions).
iMaxMissionaries = max(1, iMaxMissionaries);
if (MOD_BALANCE_CORE_QUEST_CHANGES)
{
for (int iMinorLoop = MAX_MAJOR_CIVS; iMinorLoop < MAX_CIV_PLAYERS; iMinorLoop++)
{
PlayerTypes eMinor = (PlayerTypes)iMinorLoop;
if (eMinor != NO_PLAYER)
{
CvPlayer* pMinor = &GET_PLAYER(eMinor);
if (pMinor)
{
CvMinorCivAI* pMinorCivAI = pMinor->GetMinorCivAI();
if (pMinorCivAI && pMinorCivAI->IsActiveQuestForPlayer(m_pPlayer->GetID(), MINOR_CIV_QUEST_CONTEST_FAITH))
{
iMaxMissionaries += 1;
}
}
}
}
}
bool bTooManyMissionaries = false;
if(eUnitClassMissionary != NO_UNITCLASS && m_pPlayer->GetPlayerTraits()->NoTrain(eUnitClassMissionary))
{
bTooManyMissionaries = true;
}
// If our civ benefits from sharing religion, even if we are not the founder, we will always be spreading if we can no longer found (Pius IX)
else if (kPlayer.GetPlayerTraits()->GetSharedReligionTourismModifier() > 0 && kPlayer.GetPlayerTraits()->GetExtraMissionaryStrength() > 0 && GC.getGame().GetGameReligions()->GetNumReligionsStillToFound() == 0)
{
bTooManyMissionaries = iNumMissionaries >= iMaxMissionaries;
}
//Let's not spread a non-founder religion outside of our owned cities. That makes us a pawn!
else if(eReligion != kPlayer.GetReligions()->GetReligionCreatedByPlayer())
{
iMaxMissionaries = 1;
if (AreAllOurCitiesConverted(eReligion, true /*bIncludePuppets*/))
{
iMaxMissionaries = 0;
bTooManyMissionaries = true;
}
}
else
{
bTooManyMissionaries = iNumMissionaries >= iMaxMissionaries;
}
//Let's see about our religious flavor...
CvFlavorManager* pFlavorManager = m_pPlayer->GetFlavorManager();
int iFlavorReligion = pFlavorManager->GetPersonalityIndividualFlavor((FlavorTypes)GC.getInfoTypeForString("FLAVOR_RELIGION"));
//Religion bonuses should artificially boost flavors.
iFlavorReligion += iBonusValue;
// UNITS - DOMESTIC
if(pCapital != NULL)
{
//FIRST PRIORITY
//Let's make sure our faith is enhanced.
if (pMyReligion != NULL && !pMyReligion->m_bEnhanced && IsProphetGainRateAcceptable())
{
if(eProphetType != NO_UNIT)
{
if (BuyGreatPerson(eProphetType, eReligion))
{
if(GC.getLogging())
{
strLogMsg += ", Bought a Prophet for religion enhancement.";
CvString strFaith;
strFaith.Format(", Faith: %d", m_pPlayer->GetFaith());
strLogMsg += strFaith;
GC.getGame().GetGameReligions()->LogReligionMessage(strLogMsg);
}
}
else
{
if(GC.getLogging())
{
strLogMsg += ", Saving up for a Prophet for religion enhancement.";
CvString strFaith;
strFaith.Format(", Faith: %d", m_pPlayer->GetFaith());
strLogMsg += strFaith;
GC.getGame().GetGameReligions()->LogReligionMessage(strLogMsg);
}
return true;
}
}
}
// SECOND PRIORITY
// If in Industrial, see if we want to save for buying a great person, but only if we've already got a Reformation belief and our cities are in good shape.
if (m_pPlayer->GetCurrentEra() >= GC.getGame().GetGameReligions()->GetFaithPurchaseGreatPeopleEra(m_pPlayer) && GetDesiredFaithGreatPerson() != NO_UNIT)
{
//reduce our max missionaries here if we're at this point, fyi.
iMaxMissionaries--;
bTooManyMissionaries = iNumMissionaries >= iMaxMissionaries;
if(pMyReligion != NULL)
{
if(m_pPlayer->IsReformation() || AreAllOurCitiesConverted(eReligion, false /*bIncludePuppets*/))
{
UnitTypes eGPType = GetDesiredFaithGreatPerson();
if(eGPType != NO_UNIT)
{
if (BuyGreatPerson(eGPType, (eGPType == eProphetType) ? eReligion : NO_RELIGION))
{
if(GC.getLogging())
{
strLogMsg += ", Bought a Great Person, as we're in the Industrial age, we've reformed, and all our cities are converted.";
strLogMsg += GC.getUnitInfo(eGPType)->GetDescription();
CvString strFaith;
strFaith.Format(", Faith: %d", m_pPlayer->GetFaith());
strLogMsg += strFaith;
GC.getGame().GetGameReligions()->LogReligionMessage(strLogMsg);
}
}
else
{
if(GC.getLogging())
{
strLogMsg += ", Saving up for a Great Person, as we're in the Industrial age, we've reformed, and all our cities are converted.";
strLogMsg += GC.getUnitInfo(eGPType)->GetDescription();
CvString strFaith;
strFaith.Format(", Faith: %d", m_pPlayer->GetFaith());
strLogMsg += strFaith;
GC.getGame().GetGameReligions()->LogReligionMessage(strLogMsg);
}
//If our faith is already really high, return false so we can make sure we're not overzealous in our purchase.
if (m_pPlayer->GetFaith() > 5000)
return false;
return false;
}
}
}
}
else
{
UnitTypes eGPType = GetDesiredFaithGreatPerson();
if(eGPType != NO_UNIT)
{
if (BuyGreatPerson(eGPType, (eGPType == eProphetType) ? eReligion : NO_RELIGION))
{
if(GC.getLogging())
{
strLogMsg += ", Bought a Great Person, as we don't have a faith and it is the Industrial age.";
strLogMsg += GC.getUnitInfo(eGPType)->GetDescription();
CvString strFaith;
strFaith.Format(", Faith: %d", m_pPlayer->GetFaith());
strLogMsg += strFaith;
GC.getGame().GetGameReligions()->LogReligionMessage(strLogMsg);
}
}
else
{
if(GC.getLogging())
{
strLogMsg += ", Saving up for a Great Person, as we don't have a faith and it is the Industrial age.";
strLogMsg += GC.getUnitInfo(eGPType)->GetDescription();
CvString strFaith;
strFaith.Format(", Faith: %d", m_pPlayer->GetFaith());
strLogMsg += strFaith;
GC.getGame().GetGameReligions()->LogReligionMessage(strLogMsg);
}
return false;
}
}
}
}
//THIRD PRIORITY
//Let's make sure all of our non-puppet cities are converted.
if((eReligion != NO_RELIGION) && !AreAllOurCitiesConverted(eReligion, false /*bIncludePuppets*/) && !bTooManyMissionaries)
{
if ((eProphetType != NO_UNIT) && ChooseProphetConversionCity(true/*bOnlyBetterThanEnhancingReligion*/) && (m_pPlayer->GetReligions()->GetNumProphetsSpawned(true) <= iFlavorReligion))
{
if (BuyGreatPerson(eProphetType, eReligion))
{
if(GC.getLogging())
{
strLogMsg += ", Bought a Prophet, badly need to Convert Non-Puppet Cities";
CvString strFaith;
strFaith.Format(", Faith: %d", m_pPlayer->GetFaith());
strLogMsg += strFaith;
GC.getGame().GetGameReligions()->LogReligionMessage(strLogMsg);
}
}
else if (!m_pPlayer->GetPlayerTraits()->IsPopulationBoostReligion())
{
if(GC.getLogging())
{
strLogMsg += ", Saving up for a Prophet, as we need to convert Non-Puppet Cities.";
CvString strFaith;
strFaith.Format(", Faith: %d", m_pPlayer->GetFaith());
strLogMsg += strFaith;
GC.getGame().GetGameReligions()->LogReligionMessage(strLogMsg);
}
return true;
}
}
else if (!m_pPlayer->GetPlayerTraits()->IsPopulationBoostReligion())
{
if(BuyMissionary(eReligion))
{
if(GC.getLogging())
{
strLogMsg += ", Bought a Missionary, need to Convert Non-Puppet Cities";
CvString strFaith;
strFaith.Format(", Faith: %d", m_pPlayer->GetFaith());
strLogMsg += strFaith;
GC.getGame().GetGameReligions()->LogReligionMessage(strLogMsg);
}
}
else
{
if(GC.getLogging())
{
strLogMsg += ", Saving up for a Prophet or Missionary, as we need to convert Non-Puppet Cities.";
CvString strFaith;
strFaith.Format(", Faith: %d", m_pPlayer->GetFaith());
strLogMsg += strFaith;
GC.getGame().GetGameReligions()->LogReligionMessage(strLogMsg);
}
return true;
}
}
}
//FOURTH PRIORITY
// Might as well convert puppet-cities to build our religious strength
if((eReligion != NO_RELIGION) && m_pPlayer->GetNumPuppetCities() > 0 && !AreAllOurCitiesConverted(eReligion, true /*bIncludePuppets*/) && !bTooManyMissionaries && !m_pPlayer->GetPlayerTraits()->IsPopulationBoostReligion())
{
if(BuyMissionary(eReligion))
{
if(GC.getLogging())
{
strLogMsg += ", Bought a Missionary, Need to Convert Puppet Cities";
CvString strFaith;
strFaith.Format(", Faith: %d", m_pPlayer->GetFaith());
strLogMsg += strFaith;
GC.getGame().GetGameReligions()->LogReligionMessage(strLogMsg);
}
}
else
{
if(GC.getLogging())
{
strLogMsg += ", Saving up for a Missionary, as we need to convert Puppet Cities.";
CvString strFaith;
strFaith.Format(", Faith: %d", m_pPlayer->GetFaith());
strLogMsg += strFaith;
GC.getGame().GetGameReligions()->LogReligionMessage(strLogMsg);
}
return true;
}
}
}
// FOREIGN UNITS
bool bStillTooManyMissionaries = (m_pPlayer->GetNumUnitsWithUnitAI(UNITAI_MISSIONARY) > iMaxMissionaries);
if((eReligion != NO_RELIGION) && (pMyReligion != NULL) && (pCapital != NULL) && !bStillTooManyMissionaries && AreAllOurCitiesConverted(eReligion, false /*bIncludePuppets*/) && !m_pPlayer->GetPlayerTraits()->IsPopulationBoostReligion())
{
if (m_pPlayer->GetPlayerTraits()->IsNoNaturalReligionSpread())
{
if(pMyReligion->m_Beliefs.GetUniqueCiv(m_pPlayer->GetID()) == m_pPlayer->getCivilizationType())
{
return false;
}
}
// FLAVOR DEPENDENCIES
// FIRST PRIORITY
//Let's start with the highest-flavor stuff and work our way down...
//Are we super religious? Target all cities, and always get Missionaries.
if (iFlavorReligion >= 10 && HaveNearbyConversionTarget(eReligion, true /*bCanIncludeReligionStarter*/))
{
if(BuyMissionary(eReligion))
{
if(GC.getLogging())
{
strLogMsg += ", Focusing on Missionaries, Need to Convert EVERYONE because religious zealotry";
CvString strFaith;
strFaith.Format(", Faith: %d", m_pPlayer->GetFaith());
strLogMsg += strFaith;
GC.getGame().GetGameReligions()->LogReligionMessage(strLogMsg);
}
}
else
{
if(GC.getLogging())
{
strLogMsg += ", Saving up for Missionaries, Need to Convert EVERYONE because religious zealotry";
CvString strFaith;
strFaith.Format(", Faith: %d", m_pPlayer->GetFaith());
strLogMsg += strFaith;
GC.getGame().GetGameReligions()->LogReligionMessage(strLogMsg);
}
return false;
}
}
//SECOND PRIORITY
// Have civs nearby to target who didn't start a religion?
if((iFlavorReligion >= 7) && HaveNearbyConversionTarget(eReligion, false /*bCanIncludeReligionStarter*/))
{
if(BuyMissionary(eReligion))
{
if(GC.getLogging())
{
strLogMsg += ", Focusing on Missionaries, Need to Convert Cities of Non-Religion Starters";
CvString strFaith;
strFaith.Format(", Faith: %d", m_pPlayer->GetFaith());
strLogMsg += strFaith;
GC.getGame().GetGameReligions()->LogReligionMessage(strLogMsg);
}
}
else
{
if(GC.getLogging())
{
strLogMsg += ", Saving up for Missionaries, Need to Convert Cities of Non-Religion Starters";
CvString strFaith;
strFaith.Format(", Faith: %d", m_pPlayer->GetFaith());
strLogMsg += strFaith;
GC.getGame().GetGameReligions()->LogReligionMessage(strLogMsg);
}
return false;
}
}
}
return false;
}