void CvGame::normalizeAddExtras()
{
bool bIgnoreLatitude = pythonIsBonusIgnoreLatitudes();
int iTotalValue = 0;
int iPlayerCount = 0;
int iBestValue = 0;
int iWorstValue = MAX_INT;
int iI, iJ, iK;
for (iI = 0; iI < MAX_PC_PLAYERS; iI++)
{
if (GET_PLAYER((PlayerTypes)iI).isAlive())
{
CvPlot* pStartingPlot = GET_PLAYER((PlayerTypes)iI).getStartingPlot();
if (pStartingPlot != NULL)
{
int iValue = GET_PLAYER((PlayerTypes)iI).AI_foundValue(pStartingPlot->getX_INLINE(), pStartingPlot->getY_INLINE(), -1, true);
iTotalValue += iValue;
iPlayerCount++;
iBestValue = std::max(iValue, iBestValue);
iWorstValue = std::min(iValue, iWorstValue);
}
}
}
//iTargetValue = (iTotalValue + iBestValue) / (iPlayerCount + 1);
int iTargetValue = (iBestValue * 4) / 5;
for (iI = 0; iI < MAX_PC_PLAYERS; iI++)
{
if (GET_PLAYER((PlayerTypes)iI).isAlive())
{
gDLL->callUpdater(); // allow window to update during launch
CvPlot* pStartingPlot = GET_PLAYER((PlayerTypes)iI).getStartingPlot();
if (pStartingPlot != NULL)
{
int iCount = 0;
int iFeatureCount = 0;
int aiShuffle[NUM_CITY_PLOTS];
shuffleArray(aiShuffle, NUM_CITY_PLOTS, getMapRand());
for (iJ = 0; iJ < NUM_CITY_PLOTS; iJ++)
{
if (GET_PLAYER((PlayerTypes)iI).AI_foundValue(pStartingPlot->getX_INLINE(), pStartingPlot->getY_INLINE(), -1, true) >= iTargetValue)
{
break;
}
if (getSorenRandNum((iCount + 2), "Setting Feature Type") <= 1)
{
CvPlot* pLoopPlot = plotCity(pStartingPlot->getX_INLINE(), pStartingPlot->getY_INLINE(), aiShuffle[iJ]);
if (pLoopPlot != NULL)
{
if (pLoopPlot != pStartingPlot)
{
if (pLoopPlot->getBonusType() == NO_BONUS)
{
if (pLoopPlot->getFeatureType() == NO_FEATURE)
{
for (int iK = 0; iK < GC.getNumFeatureInfos(); iK++)
{
if ((GC.getFeatureInfo((FeatureTypes)iK).getYieldChange(YIELD_FOOD) + GC.getFeatureInfo((FeatureTypes)iK).getYieldChange(YIELD_PRODUCTION)) > 0)
{
if (pLoopPlot->canHaveFeature((FeatureTypes)iK))
{
pLoopPlot->setFeatureType((FeatureTypes)iK);
iCount++;
break;
}
}
}
}
iFeatureCount += (pLoopPlot->getFeatureType() != NO_FEATURE) ? 1 : 0;
}
}
}
}
}
int iCoastFoodCount = 0;
int iOceanFoodCount = 0;
int iOtherCount = 0;
int iWaterCount = 0;
for (iJ = 0; iJ < NUM_CITY_PLOTS; iJ++)
{
CvPlot* pLoopPlot = plotCity(pStartingPlot->getX_INLINE(), pStartingPlot->getY_INLINE(), iJ);
if (pLoopPlot != NULL)
{
if (pLoopPlot != pStartingPlot)
{
if (pLoopPlot->isWater())
{
iWaterCount++;
if (pLoopPlot->getBonusType() != NO_BONUS)
{
if (pLoopPlot->isAdjacentToLand())
{
iCoastFoodCount++;
}
else
{
iOceanFoodCount++;
}
}
}
else
{
if (pLoopPlot->getBonusType() != NO_BONUS)
{
iOtherCount++;
}
}
}
}
}
bool bLandBias = (iWaterCount > NUM_CITY_PLOTS / 2);
shuffleArray(aiShuffle, NUM_CITY_PLOTS, getMapRand());
for (iJ = 0; iJ < NUM_CITY_PLOTS; iJ++)
{
CvPlot* pLoopPlot = plotCity(pStartingPlot->getX_INLINE(), pStartingPlot->getY_INLINE(), aiShuffle[iJ]);
if ((pLoopPlot != NULL) && (pLoopPlot != pStartingPlot))
{
if (getSorenRandNum(((bLandBias && pLoopPlot->isWater()) ? 2 : 1), "Placing Bonuses") == 0)
{
if ((iOtherCount * 3 + iOceanFoodCount * 2 + iCoastFoodCount * 2) >= 12)
{
break;
}
if (GET_PLAYER((PlayerTypes)iI).AI_foundValue(pStartingPlot->getX_INLINE(), pStartingPlot->getY_INLINE(), -1, true) >= iTargetValue)
{
break;
}
bool bCoast = (pLoopPlot->isWater() && pLoopPlot->isAdjacentToLand());
bool bOcean = (pLoopPlot->isWater() && !bCoast);
if ((pLoopPlot != pStartingPlot)
&& !(bCoast && (iCoastFoodCount > 2))
&& !(bOcean && (iOceanFoodCount > 2)))
{
for (int iPass = 0; iPass < 2; iPass++)
{
if (pLoopPlot->getBonusType() == NO_BONUS)
{
for (iK = 0; iK < GC.getNumBonusInfos(); iK++)
{
if (GC.getBonusInfo((BonusTypes)iK).isNormalize())
{
//???no bonuses with negative yields?
if ((GC.getBonusInfo((BonusTypes)iK).getYieldChange(YIELD_FOOD) >= 0) &&
(GC.getBonusInfo((BonusTypes)iK).getYieldChange(YIELD_PRODUCTION) >= 0))
{
if ((GC.getBonusInfo((BonusTypes)iK).getTechCityTrade() == NO_TECH) || (GC.getTechInfo((TechTypes)(GC.getBonusInfo((BonusTypes)iK).getTechCityTrade())).getEra() <= getStartEra()))
{
if (GET_TEAM(GET_PLAYER((PlayerTypes)iI).getTeam()).isHasTech((TechTypes)(GC.getBonusInfo((BonusTypes)iK).getTechReveal())))
{
if ((iPass == 0) ? CvMapGenerator::GetInstance().canPlaceBonusAt(((BonusTypes)iK), pLoopPlot->getX(), pLoopPlot->getY(), bIgnoreLatitude) : pLoopPlot->canHaveBonus(((BonusTypes)iK), bIgnoreLatitude))
{
pLoopPlot->setBonusType((BonusTypes)iK);
iCoastFoodCount += bCoast ? 1 : 0;
iOceanFoodCount += bOcean ? 1 : 0;
iOtherCount += !(bCoast || bOcean) ? 1 : 0;
break;
}
}
}
}
}
}
if (bLandBias && !pLoopPlot->isWater() && pLoopPlot->getBonusType() == NO_BONUS)
{
if (((iFeatureCount > 4) && (pLoopPlot->getFeatureType() != NO_FEATURE))
&& ((iCoastFoodCount + iOceanFoodCount) > 2))
{
if (getSorenRandNum(2, "Clear feature to add bonus") == 0)
{
pLoopPlot->setFeatureType(NO_FEATURE);
for (iK = 0; iK < GC.getNumBonusInfos(); iK++)
{
if (GC.getBonusInfo((BonusTypes)iK).isNormalize())
{
//???no bonuses with negative yields?
if ((GC.getBonusInfo((BonusTypes)iK).getYieldChange(YIELD_FOOD) >= 0) &&
(GC.getBonusInfo((BonusTypes)iK).getYieldChange(YIELD_PRODUCTION) >= 0))
{
if ((GC.getBonusInfo((BonusTypes)iK).getTechCityTrade() == NO_TECH) || (GC.getTechInfo((TechTypes)(GC.getBonusInfo((BonusTypes)iK).getTechCityTrade())).getEra() <= getStartEra()))
{
if ((iPass == 0) ? CvMapGenerator::GetInstance().canPlaceBonusAt(((BonusTypes)iK), pLoopPlot->getX(), pLoopPlot->getY(), bIgnoreLatitude) : pLoopPlot->canHaveBonus(((BonusTypes)iK), bIgnoreLatitude))
{
pLoopPlot->setBonusType((BonusTypes)iK);
iOtherCount++;
break;
}
}
}
}
}
}
}
}
}
}
}
}
}
}
shuffleArray(aiShuffle, NUM_CITY_PLOTS, getMapRand());
for (iJ = 0; iJ < NUM_CITY_PLOTS; iJ++)
{
if (GET_PLAYER((PlayerTypes)iI).AI_foundValue(pStartingPlot->getX_INLINE(), pStartingPlot->getY_INLINE(), -1, true) >= iTargetValue)
{
break;
}
CvPlot* pLoopPlot = plotCity(pStartingPlot->getX_INLINE(), pStartingPlot->getY_INLINE(), aiShuffle[iJ]);
if (pLoopPlot != NULL)
{
if (pLoopPlot != pStartingPlot)
{
if (pLoopPlot->getBonusType() == NO_BONUS)
{
if (pLoopPlot->getFeatureType() == NO_FEATURE)
{
for (iK = 0; iK < GC.getNumFeatureInfos(); iK++)
{
if ((GC.getFeatureInfo((FeatureTypes)iK).getYieldChange(YIELD_FOOD) + GC.getFeatureInfo((FeatureTypes)iK).getYieldChange(YIELD_PRODUCTION)) > 0)
{
if (pLoopPlot->canHaveFeature((FeatureTypes)iK))
{
pLoopPlot->setFeatureType((FeatureTypes)iK);
break;
}
}
}
}
}
}
}
}
int iHillsCount = 0;
for (iJ = 0; iJ < NUM_CITY_PLOTS; iJ++)
{
CvPlot* pLoopPlot =plotCity(pStartingPlot->getX_INLINE(), pStartingPlot->getY_INLINE(), iJ);
if (pLoopPlot != NULL)
{
if (pLoopPlot->isHills())
{
iHillsCount++;
}
}
}
shuffleArray(aiShuffle, NUM_CITY_PLOTS, getMapRand());
for (iJ = 0; iJ < NUM_CITY_PLOTS; iJ++)
{
if (iHillsCount >= 3)
{
break;
}
CvPlot* pLoopPlot = plotCity(pStartingPlot->getX_INLINE(), pStartingPlot->getY_INLINE(), aiShuffle[iJ]);
if (pLoopPlot != NULL)
{
if (!pLoopPlot->isWater())
{
if (!pLoopPlot->isHills())
{
if ((pLoopPlot->getFeatureType() == NO_FEATURE) ||
!GC.getFeatureInfo(pLoopPlot->getFeatureType()).isRequiresFlatlands())
{
if ((pLoopPlot->getBonusType() == NO_BONUS) ||
GC.getBonusInfo(pLoopPlot->getBonusType()).isHills())
{
pLoopPlot->setPlotType(PLOT_HILLS, false, true);
iHillsCount++;
}
}
}
}
}
}
}
}
}
}