diff --git a/CvGameCoreDLL_Expansion2/CvCity.cpp b/CvGameCoreDLL_Expansion2/CvCity.cpp index 020ac93228..067207442e 100644 --- a/CvGameCoreDLL_Expansion2/CvCity.cpp +++ b/CvGameCoreDLL_Expansion2/CvCity.cpp @@ -32539,10 +32539,17 @@ bool CvCity::IsInDanger(PlayerTypes eEnemy) const if (GET_PLAYER(getOwner()).GetPlotDanger(this) == 0) return false; - int iFriendlyPower = GetPower(); - int iEnemyPower = 0; + int iFriendlyLandPower = GetPower(); + int iFriendlySeaPower = 0; + int iFriendlyOtherPower = 0; + int iEnemyLandPower = 0; + int iEnemySeaPower = 0; + int iEnemyOtherPower = 0; bool bFriendlyGeneralInTheVicinity = false; + bool bFriendlyAdmiralInTheVicinity = false; bool bEnemyGeneralInTheVicinity = false; + bool bEnemyAdmiralInTheVicinity = false; + for (int i = RING0_PLOTS; i < RING4_PLOTS; i++) { CvPlot* pPlot = iterateRingPlots(plot(), i); @@ -32555,33 +32562,79 @@ bool CvCity::IsInDanger(PlayerTypes eEnemy) const if (pUnit->IsCombatUnit()) { if (pUnit->getTeam() == getTeam()) - iFriendlyPower += pUnit->GetPower(); - if (pUnit->getOwner() == eEnemy) - iEnemyPower += pUnit->GetPower(); + { + DomainTypes eDomainType = pUnit->getDomainType(); + switch (eDomainType) + { + case DOMAIN_LAND: + iFriendlyLandPower += pUnit->GetPower(); + break; + case DOMAIN_SEA: + iFriendlySeaPower += pUnit->GetPower(); + break; + default: + iFriendlyOtherPower += pUnit->GetPower(); + } + } + else if (pUnit->getOwner() == eEnemy) + { + DomainTypes eDomainType = pUnit->getDomainType(); + switch (eDomainType) + { + case DOMAIN_LAND: + iEnemyLandPower += pUnit->GetPower(); + break; + case DOMAIN_SEA: + iEnemySeaPower += pUnit->GetPower(); + break; + default: + iEnemyOtherPower += pUnit->GetPower(); + } + } } - else if (pUnit->IsGreatGeneral()) + if (pUnit->GetGreatGeneralCount() > 0) { if (pUnit->getTeam() == getTeam()) bFriendlyGeneralInTheVicinity = true; if (pUnit->getOwner() == eEnemy) bEnemyGeneralInTheVicinity = true; } + if (pUnit->GetGreatAdmiralCount() > 0) + { + if (pUnit->getTeam() == getTeam()) + bFriendlyAdmiralInTheVicinity = true; + if (pUnit->getOwner() == eEnemy) + bEnemyAdmiralInTheVicinity = true; + } } } if (bFriendlyGeneralInTheVicinity) { - iFriendlyPower *= 11; - iFriendlyPower /= 10; + iFriendlyLandPower *= 115; + iFriendlyLandPower /= 100; + } + if (bFriendlyAdmiralInTheVicinity) + { + iFriendlySeaPower *= 115; + iFriendlySeaPower /= 100; } if (bEnemyGeneralInTheVicinity) { - iEnemyPower *= 11; - iEnemyPower /= 10; + iEnemyLandPower *= 115; + iEnemyLandPower /= 100; + } + if (bEnemyAdmiralInTheVicinity) + { + iEnemySeaPower *= 115; + iEnemySeaPower /= 100; } - return (iEnemyPower > iFriendlyPower); + // Final tally and assessment + int iEnemyPower = iEnemyLandPower + iEnemySeaPower + iEnemyOtherPower; + int iFriendlyPower = iFriendlyLandPower + iFriendlySeaPower + iFriendlyOtherPower; + return iEnemyPower > iFriendlyPower; } bool CvCity::IsInDangerFromPlayers(vector& vWarAllies) const @@ -32589,13 +32642,151 @@ bool CvCity::IsInDangerFromPlayers(vector& vWarAllies) const if (vWarAllies.empty()) return false; + //unit strength doesn't matter if the city is low on hitpoints + if (isInDangerOfFalling()) + return true; + + //cannot use the tactical zone here, because it's not specific to a certain enemy + //but we can use the danger plots to exclude some cities + if (GET_PLAYER(getOwner()).GetPlotDanger(this) == 0) + return false; + + int iFriendlyLandPower = GetPower(); + int iFriendlySeaPower = 0; + int iFriendlyOtherPower = 0; + bool bFriendlyGeneralInTheVicinity = false; + bool bFriendlyAdmiralInTheVicinity = false; + + // Store each enemy's power by domain in weighted vectors to facilitate the Great General/Admiral buffs applying to those players only + vector vOtherGGNearby; + vector vOtherGANearby; + CvWeightedVector veEnemyLandPowers; + CvWeightedVector veEnemySeaPowers; + CvWeightedVector veEnemyOtherPowers; + std::map vectorIndices; + int iIndex = 0; for (std::vector::iterator it = vWarAllies.begin(); it != vWarAllies.end(); it++) { - if (GET_PLAYER(*it).isAlive() && IsInDanger(*it)) - return true; + veEnemyLandPowers.push_back(*it, 0); + veEnemySeaPowers.push_back(*it, 0); + veEnemyOtherPowers.push_back(*it, 0); + vectorIndices.insert(std::make_pair(*it, iIndex)); + iIndex++; } - return false; + for (int i = RING0_PLOTS; i < RING4_PLOTS; i++) + { + CvPlot* pPlot = iterateRingPlots(plot(), i); + if (!pPlot) + continue; + + for (int j = 0; j < pPlot->getNumUnits(); j++) + { + CvUnit* pUnit = pPlot->getUnitByIndex(j); + if (pUnit->IsCombatUnit()) + { + if (pUnit->getTeam() == getTeam()) + { + DomainTypes eDomainType = pUnit->getDomainType(); + switch (eDomainType) + { + case DOMAIN_LAND: + iFriendlyLandPower += pUnit->GetPower(); + break; + case DOMAIN_SEA: + iFriendlySeaPower += pUnit->GetPower(); + break; + default: + iFriendlyOtherPower += pUnit->GetPower(); + } + } + else + { + std::map::iterator vectorIndexFinder = vectorIndices.find(pUnit->getOwner()); + if (vectorIndexFinder != vectorIndices.end()) + { + iIndex = vectorIndexFinder->second; + DomainTypes eDomainType = pUnit->getDomainType(); + switch (eDomainType) + { + case DOMAIN_LAND: + veEnemyLandPowers.IncreaseWeight(iIndex, pUnit->GetPower()); + break; + case DOMAIN_SEA: + veEnemySeaPowers.IncreaseWeight(iIndex, pUnit->GetPower()); + break; + default: + veEnemyOtherPowers.IncreaseWeight(iIndex, pUnit->GetPower()); + } + } + } + } + if (pUnit->GetGreatGeneralCount() > 0) + { + if (pUnit->getTeam() == getTeam()) + bFriendlyGeneralInTheVicinity = true; + else + vOtherGGNearby.push_back(pUnit->getOwner()); + } + if (pUnit->GetGreatAdmiralCount() > 0) + { + if (pUnit->getTeam() == getTeam()) + bFriendlyAdmiralInTheVicinity = true; + else + vOtherGANearby.push_back(pUnit->getOwner()); + } + } + } + + // Tally up friendly power + if (bFriendlyGeneralInTheVicinity) + { + iFriendlyLandPower *= 11; + iFriendlyLandPower /= 10; + } + if (bFriendlyAdmiralInTheVicinity) + { + iFriendlySeaPower *= 11; + iFriendlySeaPower /= 10; + } + int iFriendlyPower = iFriendlyLandPower + iFriendlySeaPower + iFriendlyOtherPower; + + + // Tally up enemy power + int iEnemyPower = 0; + for (int i = 0; i < veEnemyLandPowers.size(); i++) + { + PlayerTypes eIndex = veEnemyLandPowers.GetElement(i); + int iEnemyLandPower = veEnemyLandPowers.GetWeight(i); + + if (std::find(vOtherGGNearby.begin(), vOtherGGNearby.end(), eIndex) != vOtherGGNearby.end()) + { + iEnemyLandPower *= 11; + iEnemyLandPower /= 10; + } + + iEnemyPower += iEnemyLandPower; + } + for (int i = 0; i < veEnemySeaPowers.size(); i++) + { + PlayerTypes eIndex = veEnemySeaPowers.GetElement(i); + int iEnemySeaPower = veEnemySeaPowers.GetWeight(i); + + if (std::find(vOtherGANearby.begin(), vOtherGANearby.end(), eIndex) != vOtherGANearby.end()) + { + iEnemySeaPower *= 11; + iEnemySeaPower /= 10; + } + + iEnemyPower += iEnemySeaPower; + } + for (int i = 0; i < veEnemyOtherPowers.size(); i++) + { + iEnemyPower += veEnemyOtherPowers.GetWeight(i); + } + + // Final assessment + return iEnemyPower > iFriendlyPower; } // -------------------------------------------------------------------------------- diff --git a/CvGameCoreDLL_Expansion2/CvGlobals.cpp b/CvGameCoreDLL_Expansion2/CvGlobals.cpp index 97ac45189b..c47cd22066 100644 --- a/CvGameCoreDLL_Expansion2/CvGlobals.cpp +++ b/CvGameCoreDLL_Expansion2/CvGlobals.cpp @@ -2897,6 +2897,16 @@ const CvString CvGlobals::getDiploMinorLogFileName(const CvPlayer* pPlayer) cons return CvString("DiplomacyAI_MinorCiv_Log.csv"); } +const CvString CvGlobals::getDiploPeaceLogFileName(const CvPlayer* pPlayer) const +{ + // Open the log file + if (GC.getPlayerAndCityAILogSplit()) + return CvString("DiplomacyAI_Peace_Log_") + pPlayer->getCivilizationShortDescription() + ".csv"; + + //default + return CvString("DiplomacyAI_Peace_Log.csv"); +} + bool CvGlobals::GetTutorialLogging() const { return m_bTutorialLogging; diff --git a/CvGameCoreDLL_Expansion2/CvGlobals.h b/CvGameCoreDLL_Expansion2/CvGlobals.h index 7e9ffa0069..70a848f5d6 100644 --- a/CvGameCoreDLL_Expansion2/CvGlobals.h +++ b/CvGameCoreDLL_Expansion2/CvGlobals.h @@ -253,6 +253,7 @@ class CvGlobals bool getPlayerAndCityAILogSplit() const; void setPlayerAndCityAILogSplit(bool bEnable); const CvString getDiploMinorLogFileName(const CvPlayer* pPlayer) const; + const CvString getDiploPeaceLogFileName(const CvPlayer* pPlayer) const; bool GetTutorialLogging() const; void SetTutorialLogging(bool bEnable); diff --git a/CvGameCoreDLL_Expansion2/CvUnit.cpp b/CvGameCoreDLL_Expansion2/CvUnit.cpp index e9a85e0567..5d02e483b1 100644 --- a/CvGameCoreDLL_Expansion2/CvUnit.cpp +++ b/CvGameCoreDLL_Expansion2/CvUnit.cpp @@ -13538,8 +13538,6 @@ bool CvUnit::build(BuildTypes eBuild) } } - UnitTypes eBestUnit = NO_UNIT; - int iStrengthBestCombat = 0; if (pkBuildInfo->IsFreeBestDomainUnit() && kPlayer.GetNumUnitsToSupply() > kPlayer.GetNumUnitsSupplied()) { bool bWater = pkBuildInfo->IsWater();