CvCity* CvUnit::getUpgradeCity(UnitTypes eUnit, bool bSearch, int* iSearchValue) const
{
if (eUnit == NO_UNIT)
{
return false;
}
CvPlayerAI& kPlayer = GET_PLAYER(getOwnerINLINE());
CvUnitInfo& kUnitInfo = GC.getUnitInfo(eUnit);
//FfH: Modified by Kael 05/09/2008
// if (GC.getCivilizationInfo(kPlayer.getCivilizationType()).getCivilizationUnits(kUnitInfo.getUnitClassType()) != eUnit)
// {
// return false;
// }
if (m_pUnitInfo->getUpgradeCiv() == NO_CIVILIZATION)
{
/*************************************************************************************************/
/** Xienwolf Tweak 08/20/08 Xienwolf **/
/** **/
/** Enables upgrades to Unique Units in Assimilated Cities **/
/*************************************************************************************************/
/** ---- Start Original Code ---- **
if (GC.getCivilizationInfo(kPlayer.getCivilizationType()).getCivilizationUnits(kUnitInfo.getUnitClassType()) != eUnit)
{
return false;
}
/** ---- End Original Code ---- **/
if (!kPlayer.isAssimilation())
if (GC.getCivilizationInfo(kPlayer.getCivilizationType()).getCivilizationUnits(kUnitInfo.getUnitClassType()) != eUnit)
return false;
/*************************************************************************************************/
/** Xienwolf Tweak END **/
/*************************************************************************************************/
}
else
{
if (GC.getCivilizationInfo((CivilizationTypes)m_pUnitInfo->getUpgradeCiv()).getCivilizationUnits(kUnitInfo.getUnitClassType()) != eUnit)
{
return false;
}
}
//FfH: End Modify
if (!upgradeAvailable(getUnitType(), ((UnitClassTypes)(kUnitInfo.getUnitClassType()))))
{
return false;
}
if (kUnitInfo.getCargoSpace() < getCargo())
{
return false;
}
CLLNode<IDInfo>* pUnitNode = plot()->headUnitNode();
while (pUnitNode != NULL)
{
CvUnit* pLoopUnit = ::getUnit(pUnitNode->m_data);
pUnitNode = plot()->nextUnitNode(pUnitNode);
if (pLoopUnit->getTransportUnit() == this)
{
if (kUnitInfo.getSpecialCargo() != NO_SPECIALUNIT)
{
if (kUnitInfo.getSpecialCargo() != pLoopUnit->getSpecialUnitType())
{
return false;
}
}
if (kUnitInfo.getDomainCargo() != NO_DOMAIN)
{
if (kUnitInfo.getDomainCargo() != pLoopUnit->getDomainType())
{
return false;
}
}
}
}
// sea units must be built on the coast
bool bCoastalOnly = (getDomainType() == DOMAIN_SEA);
// results
int iBestValue = MAX_INT;
CvCity* pBestCity = NULL;
// if search is true, check every city for our team
if (bSearch)
{
// air units can travel any distance
bool bIgnoreDistance = (getDomainType() == DOMAIN_AIR);
TeamTypes eTeam = getTeam();
int iArea = getArea();
int iX = getX_INLINE(), iY = getY_INLINE();
// check every player on our team's cities
for (int iI = 0; iI < MAX_PLAYERS; iI++)
{
// is this player on our team?
CvPlayerAI& kLoopPlayer = GET_PLAYER((PlayerTypes)iI);
if (kLoopPlayer.isAlive() && kLoopPlayer.getTeam() == eTeam)
{
int iLoop;
for (CvCity* pLoopCity = kLoopPlayer.firstCity(&iLoop); pLoopCity != NULL; pLoopCity = kLoopPlayer.nextCity(&iLoop))
{
// if coastal only, then make sure we are coast
CvArea* pWaterArea = NULL;
if (!bCoastalOnly || ((pWaterArea = pLoopCity->waterArea()) != NULL && !pWaterArea->isLake()))
{
// can this city tran this unit?
//FfH Units: Modified by Kael 05/24/2008
// if (pLoopCity->canTrain(eUnit, false, false, true))
if (pLoopCity->canUpgrade(eUnit, false, false, true))
//FfH: End Modify
{
// if we do not care about distance, then the first match will do
if (bIgnoreDistance)
{
// if we do not care about distance, then return 1 for value
if (iSearchValue != NULL)
{
*iSearchValue = 1;
}
return pLoopCity;
}
int iValue = plotDistance(iX, iY, pLoopCity->getX_INLINE(), pLoopCity->getY_INLINE());
// if not same area, not as good (lower numbers are better)
if (iArea != pLoopCity->getArea() && (!bCoastalOnly || iArea != pWaterArea->getID()))
{
iValue *= 16;
}
// if we cannot path there, not as good (lower numbers are better)
if (!generatePath(pLoopCity->plot(), 0, true))
{
iValue *= 16;
}
if (iValue < iBestValue)
{
iBestValue = iValue;
pBestCity = pLoopCity;
}
}
}
}
}
}
}
else
{
// find the closest city
CvCity* pClosestCity = GC.getMapINLINE().findCity(getX_INLINE(), getY_INLINE(), NO_PLAYER, getTeam(), true, bCoastalOnly);
if (pClosestCity != NULL)
{
/*************************************************************************************************/
/** Xienwolf Tweak 08/20/08 Xienwolf **/
/** **/
/** Enables upgrades to Unique Units in Assimilated Cities **/
/*************************************************************************************************/
if (kPlayer.isAssimilation() && (m_pUnitInfo->getUpgradeCiv() == NO_CIVILIZATION))
if (GC.getCivilizationInfo(pClosestCity->getCivilizationType()).getCivilizationUnits(kUnitInfo.getUnitClassType()) != eUnit && GC.getCivilizationInfo(kPlayer.getCivilizationType()).getCivilizationUnits(kUnitInfo.getUnitClassType()) != eUnit)
return false;
/*************************************************************************************************/
/** Xienwolf Tweak END **/
/*************************************************************************************************/
// if we can train, then return this city (otherwise it will return NULL)
//FfH Units: Modified by Kael 08/07/2007
// if (pClosestCity->canTrain(eUnit, false, false, true))
if (pClosestCity->canUpgrade(eUnit, false, false, true))
//FfH: End Add
{
// did not search, always return 1 for search value
iBestValue = 1;
pBestCity = pClosestCity;
}
}
}
// return the best value, if non-NULL
if (iSearchValue != NULL)
{
*iSearchValue = iBestValue;
}
return pBestCity;
}