PHP-Code:
// rucivfan_upgrade_optimization ruo[
// old code[
//int CvUnit::upgradePrice(UnitTypes eUnit) const
//{
// int iPrice;
//
// CyArgsList argsList;
// argsList.add(getOwnerINLINE());
// argsList.add(getID());
// argsList.add((int) eUnit);
// long lResult=0;
// gDLL->getPythonIFace()->callFunction(PYGameModule, "getUpgradePriceOverride", argsList.makeFunctionArgs(), &lResult);
// if (lResult >= 0)
// {
// return lResult;
// }
//
// if (isBarbarian())
// {
// return 0;
// }
//
// //rucivfan_code_optimization rco[
// iPrice = GC.getBASE_UNIT_UPGRADE_COST();
//
// iPrice += (std::max(0, (GET_PLAYER(getOwnerINLINE()).getProductionNeeded(eUnit) - GET_PLAYER(getOwnerINLINE()).getProductionNeeded(getUnitType()))) * GC.getUNIT_UPGRADE_COST_PER_PRODUCTION());
// // ]rucivfan_code_optimization rco
//
// if (!isHuman() && !isBarbarian())
// {
// iPrice *= GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getAIUnitUpgradePercent();
// iPrice /= 100;
//
// iPrice *= std::max(0, ((GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getAIPerEraModifier() * GET_PLAYER(getOwnerINLINE()).getCurrentEra()) + 100));
// iPrice /= 100;
// }
//
// iPrice -= (iPrice * getUpgradeDiscount()) / 100;
//
// return iPrice;
//}
//
//
//bool CvUnit::upgradeAvailable(UnitTypes eFromUnit, UnitClassTypes eToUnitClass, int iCount) const
//{
// UnitTypes eLoopUnit;
// int iI;
// int numUnitClassInfos = GC.getNumUnitClassInfos();
//
// if (iCount > numUnitClassInfos)
// {
// return false;
// }
//
// CvUnitInfo &fromUnitInfo = GC.getUnitInfo(eFromUnit);
//
// if (fromUnitInfo.getUpgradeUnitClass(eToUnitClass))
// {
// return true;
// }
//
// for (iI = 0; iI < numUnitClassInfos; ++iI)
// {
// if (fromUnitInfo.getUpgradeUnitClass(iI))
// {
// eLoopUnit = ((UnitTypes)(GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(iI)));
//
// if (eLoopUnit != NO_UNIT)
// {
// if (upgradeAvailable(eLoopUnit, eToUnitClass, (iCount + 1)))
// {
// return true;
// }
// }
// }
// }
//
// return false;
//}
//
//
//bool CvUnit::canUpgrade(UnitTypes eUnit, bool bTestVisible) const
//{
// if (eUnit == NO_UNIT)
// {
// return false;
// }
//
// if(!isReadyForUpgrade())
// {
// return false;
// }
//
// if (!bTestVisible)
// {
// if (GET_PLAYER(getOwnerINLINE()).getGold() < upgradePrice(eUnit))
// {
// return false;
// }
// }
//
// if (hasUpgrade(eUnit))
// {
// return true;
// }
//
// return false;
//}
//
//bool CvUnit::isReadyForUpgrade() const
//{
// if (!canMove())
// {
// return false;
// }
//
// if (plot()->getTeam() != getTeam())
// {
// return false;
// }
//
// return true;
//}
//
//// has upgrade is used to determine if an upgrade is possible,
//// it specifically does not check whether the unit can move, whether the current plot is owned, enough gold
//// those are checked in canUpgrade()
//// does not search all cities, only checks the closest one
//bool CvUnit::hasUpgrade(bool bSearch) const
//{
// return (getUpgradeCity(bSearch) != NULL);
//}
//
//// has upgrade is used to determine if an upgrade is possible,
//// it specifically does not check whether the unit can move, whether the current plot is owned, enough gold
//// those are checked in canUpgrade()
//// does not search all cities, only checks the closest one
//bool CvUnit::hasUpgrade(UnitTypes eUnit, bool bSearch) const
//{
// return (getUpgradeCity(eUnit, bSearch) != NULL);
//}
//
//// finds the 'best' city which has a valid upgrade for the unit,
//// it specifically does not check whether the unit can move, or if the player has enough gold to upgrade
//// those are checked in canUpgrade()
//// if bSearch is true, it will check every city, if not, it will only check the closest valid city
//// NULL result means the upgrade is not possible
//CvCity* CvUnit::getUpgradeCity(bool bSearch) const
//{
// CvPlayerAI &kPlayer = GET_PLAYER(getOwnerINLINE());
// UnitAITypes eUnitAI = AI_getUnitAIType();
// CvArea *pArea = area();
//
// int iCurrentValue = kPlayer.AI_unitValue(getUnitType(), eUnitAI, pArea);
//
// int iBestSearchValue = MAX_INT;
// CvCity* pBestUpgradeCity = NULL;
//
// for (int iI = 0; iI < GC.getNumUnitInfos(); ++iI)
// {
// int iNewValue = kPlayer.AI_unitValue(((UnitTypes)iI), eUnitAI, pArea);
// if (iNewValue > iCurrentValue)
// {
// int iSearchValue;
// CvCity* pUpgradeCity = getUpgradeCity((UnitTypes)iI, bSearch, &iSearchValue);
// if (pUpgradeCity != NULL)
// {
// // if not searching or close enough, then this match will do
// if (!bSearch || iSearchValue < 16)
// {
// return pUpgradeCity;
// }
//
// if (iSearchValue < iBestSearchValue)
// {
// iBestSearchValue = iSearchValue;
// pBestUpgradeCity = pUpgradeCity;
// }
// }
// }
// }
//
// return pBestUpgradeCity;
//}
//
//// finds the 'best' city which has a valid upgrade for the unit, to eUnit type
//// it specifically does not check whether the unit can move, or if the player has enough gold to upgrade
//// those are checked in canUpgrade()
//// if bSearch is true, it will check every city, if not, it will only check the closest valid city
//// if iSearchValue non NULL, then on return it will be the city's proximity value, lower is better
//// NULL result means the upgrade is not possible
//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);
//
// if (GC.getCivilizationInfo(kPlayer.getCivilizationType()).getCivilizationUnits(kUnitInfo.getUnitClassType()) != eUnit)
// {
// return false;
// }
//
// 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?
// if (pLoopCity->canTrain(eUnit, false, false, true))
// {
// // 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)
// {
// // if we can train, then return this city (otherwise it will return NULL)
// if (pClosestCity->canTrain(eUnit, false, false, true))
// {
// // 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;
//}
//
//void CvUnit::upgrade(UnitTypes eUnit)
//{
// CvUnit* pUpgradeUnit;
//
// if (!canUpgrade(eUnit))
// {
// return;
// }
//
// GET_PLAYER(getOwnerINLINE()).changeGold(-(upgradePrice(eUnit)));
//
// pUpgradeUnit = GET_PLAYER(getOwnerINLINE()).initUnit(eUnit, getX_INLINE(), getY_INLINE(), AI_getUnitAIType());
//
// FAssertMsg(pUpgradeUnit != NULL, "UpgradeUnit is not assigned a valid value");
//
// pUpgradeUnit->joinGroup(getGroup());
//
// pUpgradeUnit->convert(this);
//
// pUpgradeUnit->finishMoves();
//
///************************************************************************************************/
///* BETTER_BTS_AI_MOD 02/24/10 jdog5000 */
///* */
///* AI Logging */
///************************************************************************************************/
// if( gUnitLogLevel > 2 )
// {
// CvWString szString;
// getUnitAIString(szString, AI_getUnitAIType());
// logBBAI(" %S spends %d to upgrade %S to %S, unit AI %S", GET_PLAYER(getOwnerINLINE()).getCivilizationDescription(0), upgradePrice(eUnit), getName(0).GetCString(), pUpgradeUnit->getName(0).GetCString(), szString.GetCString());
// }
///************************************************************************************************/
///* BETTER_BTS_AI_MOD END */
///************************************************************************************************/
//}
// ]old code
// new code[
int CvUnit::upgradePrice(UnitTypes eUnit) const
{
int iPrice;
if(GC.getUSE_ON_UNIT_UPGRADE_PRICE_CALLBACK())
{
CyArgsList argsList;
argsList.add(getOwnerINLINE());
argsList.add(getID());
argsList.add((int) eUnit);
long lResult=0;
gDLL->getPythonIFace()->callFunction(PYGameModule, "getUpgradePriceOverride", argsList.makeFunctionArgs(), &lResult);
if (lResult >= 0)
{
return lResult;
}
}
if (isBarbarian())
{
return 0;
}
CvUnitInfo &kUnitUpgrade = GC.getUnitInfo(eUnit);
CvPlayer &kPlayer = GET_PLAYER(getOwnerINLINE());
iPrice = GC.getUNIT_UPGRADE_BASE_COST();
iPrice += std::max(0, (kUnitUpgrade.getProductionCost() - getUnitInfo().getProductionCost())) * GC.getUNIT_UPGRADE_COST_PER_PRODUCTION();
if(getDomainType() == DOMAIN_AIR)
{
iPrice += std::max(0, kUnitUpgrade.getAirCombat() - getUnitInfo().getAirCombat()) * GC.getUNIT_UPGRADE_COST_PER_AIR_COMBAT();
}
else
{
iPrice += std::max(0, kUnitUpgrade.getCombat() - getUnitInfo().getCombat()) * GC.getUNIT_UPGRADE_COST_PER_COMBAT();
}
if(kUnitUpgrade.getUnitCombatType() != getUnitCombatType())
{
iPrice += GC.getUNIT_UPGRADE_COST_COMBAT_TYPE_CHANGE();
}
iPrice *= GC.getUNIT_UPGRADE_COST_PERCENT();
iPrice /= 100;
iPrice *= GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getTrainPercent();
iPrice /= 100;
iPrice *= GC.getEraInfo(GC.getGameINLINE().getStartEra()).getTrainPercent();
iPrice /= 100;
iPrice *= std::max(0, 100 - getUpgradeDiscount());
iPrice /= 100;
if(!kPlayer.isHuman())
{
CvHandicapInfo &kHandicapInfo = GC.getHandicapInfo(GC.getGameINLINE().getHandicapType());
iPrice *= kHandicapInfo.getAIUnitUpgradePercent();
iPrice /= 100;
iPrice *= std::max(0, (kHandicapInfo.getAIPerEraModifier() * kPlayer.getCurrentEra()) + 100);
iPrice /= 100;
}
return iPrice;
}
bool CvUnit::upgradeAvailable(UnitTypes eFromUnit, UnitClassTypes eToUnitClass, int iCount) const
{
UnitTypes eLoopUnit;
int iI;
if (iCount > GC.getNumUnitClassInfos())
{
return false;
}
CvUnitInfo &fromUnitInfo = GC.getUnitInfo(eFromUnit);
CvCivilizationInfo &kCivilization = GC.getCivilizationInfo(getCivilizationType());
for (iI = 0; iI < fromUnitInfo.getNumUpgradeUnitClass(); ++iI)
{
UnitClassTypes eLoopUnitClass = (UnitClassTypes)fromUnitInfo.getUpgradeUnitClass(iI);
if( eLoopUnitClass == eToUnitClass)
{
return true;
}
eLoopUnit = ((UnitTypes)(kCivilization.getCivilizationUnits(eLoopUnitClass)));
if (eLoopUnit != NO_UNIT)
{
if (upgradeAvailable(eLoopUnit, eToUnitClass, (iCount + 1)))
{
return true;
}
}
}
return false;
}
bool CvUnit::oneUpgradesAvailable(UnitTypes eUnit, int iCount) const
{
UnitTypes eLoopUnit;
int iI;
if (iCount > GC.getNumUnitClassInfos())
{
return false;
}
CvUnitInfo &kUnitInfo = GC.getUnitInfo(eUnit);
CvCivilizationInfo &kCivilization = GC.getCivilizationInfo(getCivilizationType());
if(iCount > 0)
{
if(hasUpgrade(eUnit, false))
{
return true;
}
}
for (iI = 0; iI < kUnitInfo.getNumUpgradeUnitClass(); ++iI)
{
eLoopUnit = ((UnitTypes)(kCivilization.getCivilizationUnits((UnitClassTypes)kUnitInfo.getUpgradeUnitClass(iI))));
if (eLoopUnit != NO_UNIT)
{
if (oneUpgradesAvailable(eLoopUnit, (iCount + 1)))
{
return true;
}
}
}
return false;
}
bool CvUnit::allUpgradesAvailable(UnitTypes eUnit, int iCount) const
{
UnitTypes eLoopUnit;
int iI;
CvUnitInfo &kUnitInfo = GC.getUnitInfo(eUnit);
CvCivilizationInfo &kCivilization = GC.getCivilizationInfo(getCivilizationType());
for (iI = 0; iI < kUnitInfo.getNumUpgradeUnitClass(); ++iI)
{
eLoopUnit = ((UnitTypes)(kCivilization.getCivilizationUnits((UnitClassTypes)kUnitInfo.getUpgradeUnitClass(iI))));
if (eLoopUnit != NO_UNIT)
{
if (!oneUpgradesAvailable(eLoopUnit, (iCount + 1)))
{
return false;
}
}
}
if(kUnitInfo.getNumUpgradeUnitClass() == 0)
{
return false;
}
return true;
}
bool CvUnit::getAvailableUpgrades(std::vector<UnitTypes> &vctiUnitUpgrades, UnitTypes eFromUnit, int iCount)
{
UnitTypes eLoopUnit;
int iI;
bool bOneUpgradeAvailable;
CvUnitInfo &kUnitInfo = GC.getUnitInfo(eFromUnit);
CvCivilizationInfo &kCivilization = GC.getCivilizationInfo(getCivilizationType());
bOneUpgradeAvailable = false;
for (iI = 0; iI < kUnitInfo.getNumUpgradeUnitClass(); ++iI)
{
eLoopUnit = ((UnitTypes)(kCivilization.getCivilizationUnits((UnitClassTypes)kUnitInfo.getUpgradeUnitClass(iI))));
if (eLoopUnit != NO_UNIT)
{
if(getAvailableUpgrades(vctiUnitUpgrades, eLoopUnit, (iCount + 1)))
{
bOneUpgradeAvailable = true;
}
else
{
if(hasUpgrade(eLoopUnit, false))
{
if(find(vctiUnitUpgrades.begin(), vctiUnitUpgrades.end(), eLoopUnit) == vctiUnitUpgrades.end())
{
vctiUnitUpgrades.push_back(eLoopUnit);
}
bOneUpgradeAvailable = true;
}
}
}
}
return bOneUpgradeAvailable;
}
bool CvUnit::canUpgrade(UnitTypes eUnit, bool bTestVisible) const
{
if (eUnit == NO_UNIT)
{
return false;
}
if(!isReadyForUpgrade())
{
return false;
}
if (!bTestVisible)
{
if (!hasUpgradeGold(eUnit))
{
return false;
}
}
if (hasUpgrade(eUnit, true))
{
return true;
}
return false;
}
bool CvUnit::isReadyForUpgrade() const
{
if (!canMove())
{
return false;
}
if (plot()->getTeam() != getTeam())
{
return false;
}
return true;
}
bool CvUnit::hasUpgrade(UnitTypes eUnit, bool bTestIsUpgrade) const
{
if (eUnit == NO_UNIT)
{
return false;
}
CvPlayerAI &kPlayer = GET_PLAYER(getOwnerINLINE());
CvUnitInfo &kUnitInfo = GC.getUnitInfo(eUnit);
if (GC.getCivilizationInfo(kPlayer.getCivilizationType()).getCivilizationUnits(kUnitInfo.getUnitClassType()) != eUnit)
{
return false;
}
if(bTestIsUpgrade)
{
if (!upgradeAvailable(getUnitType(), ((UnitClassTypes)(kUnitInfo.getUnitClassType()))))
{
return false;
}
if (oneUpgradesAvailable(eUnit))
{
return false;
}
}
if (!(kPlayer.canTrain(eUnit, false, false, true)))
{
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;
}
}
}
}
bool bValid = false;
if(!bValid)
{
if(plot()->getTeam() == getTeam())
{
if (plot()->canTrain(eUnit, false, false, false, true))
{
bValid = true;
}
}
}
if(!bValid)
{
//if(plot()->getTeam() != getTeam() || plot()->getWorkingCity() == NULL)
{
CvCity* pCapitalCity = kPlayer.getCapitalCity();
if(pCapitalCity != NULL)
{
if(pCapitalCity->plot()->canTrain(eUnit, false, false, false, true))
{
bValid = true;
}
}
}
}
if(!bValid)
{
return false;
}
return true;
}
bool CvUnit::hasUpgradeGold(UnitTypes eUnit) const
{
return upgradePrice(eUnit) <= GET_PLAYER(getOwnerINLINE()).getGold();
}
void CvUnit::upgrade(UnitTypes eUnit)
{
CvUnit* pUpgradeUnit;
if (!canUpgrade(eUnit))
{
return;
}
FAssertMsg(eUnit > NO_UNIT, "eUnit is not assigned a valid value");
GET_PLAYER(getOwnerINLINE()).changeGold(-(upgradePrice(eUnit)));
pUpgradeUnit = GET_PLAYER(getOwnerINLINE()).initUnit(eUnit, getX_INLINE(), getY_INLINE(), AI_getUnitAIType());
FAssertMsg(pUpgradeUnit != NULL, "UpgradeUnit is not assigned a valid value");
pUpgradeUnit->joinGroup(getGroup());
pUpgradeUnit->convert(this);
pUpgradeUnit->finishMoves();
if (pUpgradeUnit->getExperience() > GC.getUNIT_UPGRADE_MAX_EXPERIENCE_AFTER_UPGRADE())
{
pUpgradeUnit->setExperience(GC.getUNIT_UPGRADE_MAX_EXPERIENCE_AFTER_UPGRADE());
}
/************************************************************************************************/
/* BETTER_BTS_AI_MOD 02/24/10 jdog5000 */
/* */
/* AI Logging */
/************************************************************************************************/
if(GC.getLogging())
{
if( gUnitLogLevel > 2 )
{
CvWString szString;
getUnitAIString(szString, AI_getUnitAIType());
logBBAI(" %S spends %d to upgrade %S to %S, unit AI %S", GET_PLAYER(getOwnerINLINE()).getCivilizationDescription(0), upgradePrice(eUnit), getName(0).GetCString(), pUpgradeUnit->getName(0).GetCString(), szString.GetCString());
}
}
/************************************************************************************************/
/* BETTER_BTS_AI_MOD END */
/************************************************************************************************/
}
// ]new code
// ]rucivfan_upgrade_optimization ruo