int CvPlayerAI::AI_foundValue(int iX, int iY, int iMinRivalRange, bool bStartingLoc)
{
PROFILE("CvPlayerAI::AI_foundValue()");
CvCity* pNearestCity;
CvArea* pArea;
CvPlot* pPlot;
CvPlot* pLoopPlot;
FeatureTypes eFeature;
BonusTypes eBonus;
bool bHasGoodBonus;
int iOwnedTiles;
int iBadTile;
int iTakenTiles;
int iTeammateTakenTiles;
int iDifferentAreaTile;
int iTeamAreaCities;
int iHealth;
int iValue;
int iTempValue;
int iRange;
int iDX, iDY;
int iI;
/*FfH: Added by Chalid Sprawling 06/11/2006*/
int iNumCityPlots = 21;
int iSprawling = 0;
//FfH: End Add
if (!canFound(iX, iY))
{
return 0;
}
/*FfH: Added by Chalid Sprawling 06/11/2006*/
if (this->isSprawling())
{
iNumCityPlots = 37;
iSprawling = 1;
}
//FfH: End Add
pPlot = GC.getMapINLINE().plotINLINE(iX, iY);
pArea = pPlot->area();
if (iMinRivalRange != -1)
{
for (iDX = -(iMinRivalRange); iDX <= iMinRivalRange; iDX++)
{
for (iDY = -(iMinRivalRange); iDY <= iMinRivalRange; iDY++)
{
pLoopPlot = plotXY(iX, iY, iDX, iDY);
if (pLoopPlot != NULL)
{
if (pLoopPlot->plotCheck(PUF_isOtherTeam, getID()) != NULL)
{
return 0;
}
}
}
}
}
if (bStartingLoc)
{
if (pPlot->isGoody())
{
return 0;
}
/*FfH: Modified by Chalid Sprawling 06/11/2006*/
// for (iI = 0; iI < NUM_CITY_PLOTS; iI++)
// {
// pLoopPlot = plotCity(iX, iY, iI);
for (iI = 0; iI < iNumCityPlots; iI++)
{
pLoopPlot = plotCity(iX, iY, iI, iSprawling);
//FfH: End Modify
if (pLoopPlot == NULL)
{
return 0;
}
}
}
iOwnedTiles = 0;
/*FfH: Modified by Chalid Sprawling 06/11/2006*/
// for (iI = 0; iI < NUM_CITY_PLOTS; iI++)
// {
// pLoopPlot = plotCity(iX, iY, iI);
for (iI = 0; iI < iNumCityPlots; iI++)
{
pLoopPlot = plotCity(iX, iY, iI, iSprawling);
//FfH: End Modify
if (pLoopPlot == NULL)
{
iOwnedTiles++;
}
else
{
if (pLoopPlot->isOwned())
{
if (pLoopPlot->getTeam() != getTeam())
{
iOwnedTiles++;
}
}
}
}
/*FfH: Modified by Chalid Sprawling 06/11/2006*/
// if (iOwnedTiles > (NUM_CITY_PLOTS / 3))
if (iOwnedTiles > (iNumCityPlots / 3))
//FfH: End Modify
{
return 0;
}
iBadTile = 0;
/*FfH: Modified by Chalid Sprawling 06/11/2006*/
// for (iI = 0; iI < NUM_CITY_PLOTS; iI++)
// {
// PROFILE("CvPlayerAI::AI_foundValue() 1");
// pLoopPlot = plotCity(iX, iY, iI);
for (iI = 0; iI < iNumCityPlots; iI++)
{
PROFILE("CvPlayerAI::AI_foundValue() 1");
pLoopPlot = plotCity(iX, iY, iI, iSprawling);
//FfH: End Modify
if ((pLoopPlot == NULL) || pLoopPlot->isImpassable())
{
iBadTile += 2;
}
else if (!(pLoopPlot->isFreshWater()) && !(pLoopPlot->isHills()))
{
if ((pLoopPlot->calculateBestNatureYield(YIELD_FOOD, getTeam()) == 0) || (pLoopPlot->calculateTotalBestNatureYield(getTeam()) <= 1))
{
iBadTile += 2;
}
//FfH: Modified by Blake 09/28/2006
// else if (pLoopPlot->isWater() && (pLoopPlot->calculateBestNatureYield(YIELD_FOOD, getTeam()) <= 1))
else if (pLoopPlot->isWater() && !(pPlot->isCoastalLand()) && (pLoopPlot->calculateBestNatureYield(YIELD_FOOD, getTeam()) <= 1) )
//FfH: End Modify
{
iBadTile++;
}
}
}
iBadTile /= 2;
if (!bStartingLoc)
{
/*FfH: Modified by Chalid Sprawling 06/11/2006*/
// if (iBadTile > (NUM_CITY_PLOTS / 3))
if (iBadTile > (iNumCityPlots / 3))
//FfH: End Modify
{
bHasGoodBonus = false;
/*FfH: Modified by Chalid Sprawling 06/11/2006*/
// for (iI = 0; iI < NUM_CITY_PLOTS; iI++)
for (iI = 0; iI < iNumCityPlots; iI++)
{
// pLoopPlot = plotCity(iX, iY, iI);
pLoopPlot = plotCity(iX, iY, iI, iSprawling);
//FfH: End Modify
if (pLoopPlot != NULL)
{
if (!(pLoopPlot->isOwned()))
{
if (pLoopPlot->isWater() || (pLoopPlot->area() == pArea))
{
eBonus = pLoopPlot->getBonusType(getTeam());
if (eBonus != NO_BONUS)
{
if ((getNumTradeableBonuses(eBonus) == 0) || (AI_bonusVal(eBonus) > 10))
{
bHasGoodBonus = true;
break;
}
}
}
}
}
}
if (!bHasGoodBonus)
{
return 0;
}
}
}
iTakenTiles = 0;
iTeammateTakenTiles = 0;
iHealth = 0;
iValue = 1000;
/*FfH: Modified by Chalid Sprawling 06/11/2006*/
// for (iI = 0; iI < NUM_CITY_PLOTS; iI++)
// {
// PROFILE("CvPlayerAI::AI_foundValue() 2");
// pLoopPlot = plotCity(iX, iY, iI);
//For Settlements only consider the inner circle.
//This is true independed of the fact if we actually use reduced city circles
//As we want to settle really close to Boni.
int iTempCityPlots = iNumCityPlots;
//Modified du to flexible Sprawling.
// if (this->isSprawling() && this->getNumCities()>GC.getDefineINT("SPRAWLING_NUMBER_OF_CITIES"))
// {
// iTempCityPlots = 9;
// }
if (this->isSprawling())
{
int iSprCities=GC.getDefineINT("SPRAWLING_NUMBER_OF_CITIES");
switch (GC.getMapINLINE().getWorldSize())
{
case WORLDSIZE_DUEL:
iSprCities--;
break;
case WORLDSIZE_LARGE:
iSprCities++;
break;
case WORLDSIZE_HUGE:
iSprCities +=2;
break;
default:
break;
}
if (this->getNumCities()>iSprCities)
{
iTempCityPlots = 9;
}
}
//End Modify flexible Sprawling
for (iI = 0; iI < iTempCityPlots; iI++)
{
PROFILE("CvPlayerAI::AI_foundValue() 2");
pLoopPlot = plotCity(iX, iY, iI, iSprawling);
//FfH: End Modify
if (pLoopPlot == NULL)
{
iTakenTiles++;
}
else if (pLoopPlot->isCityRadius())
{
iTakenTiles++;
if (pLoopPlot->isWithinTeamCityRadius(getTeam(), getID()))
{
iTeammateTakenTiles++;
}
}
else
{
PROFILE("CvPlayerAI::AI_foundValue() 3");
iTempValue = 0;
if (pLoopPlot->getYield(YIELD_FOOD) >= GC.getFOOD_CONSUMPTION_PER_POPULATION())
{
iTempValue += (pLoopPlot->getYield(YIELD_FOOD) * 20);
iTempValue += (pLoopPlot->getYield(YIELD_PRODUCTION) * 80);
iTempValue += (pLoopPlot->getYield(YIELD_COMMERCE) * 40);
if (bStartingLoc)
{
iTempValue *= 2;
}
}
else if (pLoopPlot->getYield(YIELD_FOOD) == (GC.getFOOD_CONSUMPTION_PER_POPULATION() - 1))
{
iTempValue += (pLoopPlot->getYield(YIELD_FOOD) * 10);
iTempValue += (pLoopPlot->getYield(YIELD_PRODUCTION) * 40);
iTempValue += (pLoopPlot->getYield(YIELD_COMMERCE) * 20);
}
else
{
iTempValue += (pLoopPlot->getYield(YIELD_FOOD) * 10);
iTempValue += (pLoopPlot->getYield(YIELD_PRODUCTION) * 20);
iTempValue += (pLoopPlot->getYield(YIELD_COMMERCE) * 10);
}
if (pLoopPlot->isRiver())
{
iTempValue += 10;
}
if (iI == CITY_HOME_PLOT)
{
iTempValue *= 2;
}
else if (stepDistance(iX, iY, pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE()) == 1)
{
iTempValue *= 3;
iTempValue /= 2;
}
iValue += iTempValue;
eFeature = pLoopPlot->getFeatureType();
if (eFeature != NO_FEATURE)
{
iHealth += GC.getFeatureInfo(eFeature).getHealthPercent();
}
eBonus = pLoopPlot->getBonusType((bStartingLoc) ? NO_TEAM : getTeam());
if (eBonus != NO_BONUS)
{
PROFILE("CvPlayerAI::AI_foundValue() 4");
iValue += (AI_bonusVal(eBonus) * (((getNumTradeableBonuses(eBonus) == 0) && !bStartingLoc) ? 80 : 20));
iValue += 10;
//FfH: Added by Blake 09/28/2006
if (pLoopPlot->isWater())
{
iValue += 300;
}
//FfH: End Add
}
}
}
/*FfH: Modified by Chalid Sprawling 06/11/2006*/
// if (iTakenTiles > (NUM_CITY_PLOTS / 3))
if (iTakenTiles > (iNumCityPlots / 3))
//FfH: End Modify
{
return 0;
}
if (iTeammateTakenTiles > 1)
{
return 0;
}
iValue += (iHealth / 10);
if (pPlot->isCoastalLand())
{
iValue += 600;
if (!bStartingLoc)
{
if (pArea->getCitiesPerPlayer(getID()) == 0)
{
iValue += 400;
}
iValue += 200;
}
}
if (pPlot->isHills())
{
iValue += 200;
}
if (pPlot->isRiver())
{
iValue += 60;
}
if (pPlot->isFreshWater())
{
iValue += 40;
iValue += (GC.getDefineINT("FRESH_WATER_HEALTH_CHANGE") * 20);
}
if (bStartingLoc)
{
PROFILE("CvPlayerAI::AI_foundValue() 5");
iRange = GREATER_FOUND_RANGE;
for (iDX = -(iRange); iDX <= iRange; iDX++)
{
for (iDY = -(iRange); iDY <= iRange; iDY++)
{
pLoopPlot = plotXY(iX, iY, iDX, iDY);
if (pLoopPlot != NULL)
{
if (pLoopPlot->isWater() || (pLoopPlot->area() == pArea))
{
if (plotDistance(iX, iY, pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE()) <= iRange)
{
iValue += (pLoopPlot->getYield(YIELD_FOOD) * 10);
iValue += (pLoopPlot->getYield(YIELD_PRODUCTION) * 10);
iValue += (pLoopPlot->getYield(YIELD_COMMERCE) * 5);
}
}
}
}
}
}
if (bStartingLoc)
{
if (pPlot->getMinOriginalStartDist() == -1)
{
iValue += (GC.getMapINLINE().maxStepDistance() * 100);
}
else
{
iValue += (pPlot->getMinOriginalStartDist() * 100);
}
}
pNearestCity = GC.getMapINLINE().findCity(iX, iY, ((isBarbarian()) ? NO_PLAYER : getID()));
if (pNearestCity != NULL)
{
if (isBarbarian())
{
iValue -= (max(0, (8 - plotDistance(iX, iY, pNearestCity->getX_INLINE(), pNearestCity->getY_INLINE()))) * 200);
}
else
{
/*FfH: Modified by Chalid Sprawling 06/11/2006*/
// iValue -= (abs(plotDistance(iX, iY, pNearestCity->getX_INLINE(), pNearestCity->getY_INLINE()) - 5) * 500);
if (this->isSprawling())
{
iValue -= (abs(plotDistance(iX, iY, pNearestCity->getX_INLINE(), pNearestCity->getY_INLINE()) - 8) * 500);
}
else
{
iValue -= (abs(plotDistance(iX, iY, pNearestCity->getX_INLINE(), pNearestCity->getY_INLINE()) - 5) * 500);
}
//FfH: End Modify
}
}
if (pArea->getNumCities() == 0)
{
iValue *= 2;
}
else
{
iTeamAreaCities = GET_TEAM(getTeam()).countNumCitiesByArea(pArea);
if (pArea->getNumCities() == iTeamAreaCities)
{
iValue *= 3;
iValue /= 2;
}
else if (pArea->getNumCities() == (iTeamAreaCities + GET_TEAM(BARBARIAN_TEAM).countNumCitiesByArea(pArea)))
{
iValue *= 4;
iValue /= 3;
}
else if (iTeamAreaCities > 0)
{
iValue *= 5;
iValue /= 4;
}
}
/*FfH: Modified by Chalid Sprawling 06/11/2006*/
// iValue /= (max(0, (iBadTile - (NUM_CITY_PLOTS / 4))) + 3);
iValue /= (max(0, (iBadTile - (iNumCityPlots / 4))) + 3);
//FfH: End Modify
if (pPlot->getBonusType() != NO_BONUS)
{
//FfH: Modified by Blake 09/28/2006
// iValue /= 4;
iValue -= 300;
//FfH: End Modify
}
if (bStartingLoc)
{
iDifferentAreaTile = 0;
/*FfH: Modified by Chalid Sprawling 06/11/2006*/
// for (iI = 0; iI < NUM_CITY_PLOTS; iI++)
for (iI = 0; iI < iNumCityPlots; iI++)
//FfH: End Modify
{
//FfH: Modified by Kael 03/07/2007
// pLoopPlot = plotCity(iX, iY, iI);
pLoopPlot = plotCity(iX, iY, iI, 0);
//FfH: End Modify
if ((pLoopPlot == NULL) || (pLoopPlot->area() != pArea))
{
iDifferentAreaTile++;
}
}
/*FfH: Modified by Chalid Sprawling 06/11/2006*/
// iValue /= (max(0, (iDifferentAreaTile - ((NUM_CITY_PLOTS * 2) / 3))) + 2);
iValue /= (max(0, (iDifferentAreaTile - ((iNumCityPlots * 2) / 3))) + 2);
//FfH: End Modify
}
return max(1, iValue);
}