Bazaar developer reference

CvHomelandAI::PlotUpgradeMoves()

Defined in
CvHomelandAI.cpp, line 1492
Class
CvHomelandAI
Hook name
CivHooks::CvHomelandAI_PlotUpgradeMoves

Hooks

static bool BeforeCvHomelandAI_PlotUpgradeMoves(CvHomelandAI* self);static void AfterCvHomelandAI_PlotUpgradeMoves(CvHomelandAI* self);static void ReplaceCvHomelandAI_PlotUpgradeMoves(void (*original)(CvHomelandAI*), CvHomelandAI* self);CivRegisterBefore<CivHooks::CvHomelandAI_PlotUpgradeMoves>(host, &BeforeCvHomelandAI_PlotUpgradeMoves);CivRegisterAfter<CivHooks::CvHomelandAI_PlotUpgradeMoves>(host, &AfterCvHomelandAI_PlotUpgradeMoves);CivRegisterReplace<CivHooks::CvHomelandAI_PlotUpgradeMoves>(host, &ReplaceCvHomelandAI_PlotUpgradeMoves);

Code

1491/// Find units that we can upgrade1492void CvHomelandAI::PlotUpgradeMoves()1493{1494	FStaticVector< CvHomelandUnit, 64, true, c_eCiv5GameplayDLL >::iterator moveUnitIt;1495	ResourceTypes eResource;1496	int iNumResource;1497	int iNumResourceInUnit;1498	bool bMissingResource;14991500	ClearCurrentMoveUnits();1501	for(list<int>::iterator it = m_CurrentTurnUnits.begin(); it != m_CurrentTurnUnits.end(); ++it)1502	{1503		// Don't try and upgrade a human player's unit or one already recruited for an operation1504		UnitHandle pUnit = m_pPlayer->getUnit(*it);1505#if defined(MOD_AI_SMART_V3)1506		if(pUnit && !pUnit->isHuman() && (MOD_AI_SMART_V3 || pUnit->getArmyID() == -1))1507#else1508		if(pUnit && !pUnit->isHuman() && pUnit->getArmyID() == -1)1509#endif1510		{1511#if defined(MOD_AI_SMART_V3)1512			if (MOD_AI_SMART_V3)1513			{1514				// Also eligible to upgrade if army is not moving/at destination1515				int iArmyId = pUnit->getArmyID();1516				if (iArmyId != -1)1517				{1518					CvArmyAI* pThisArmy = m_pPlayer->getArmyAI(iArmyId);15191520					if (pThisArmy)1521					{1522						if((pThisArmy->GetArmyAIState() == ARMYAISTATE_MOVING_TO_DESTINATION) || (pThisArmy->GetArmyAIState() == ARMYAISTATE_AT_DESTINATION))1523						{1524							continue;1525						}1526					}1527				}1528			}1529#endif15301531			// Can this unit be upgraded?1532			UnitTypes eUpgradeUnitType = pUnit->GetUpgradeUnitType();1533			if(eUpgradeUnitType != NO_UNIT)1534			{1535				// Tech requirement1536				TechTypes ePrereqTech = (TechTypes) GC.getUnitInfo(eUpgradeUnitType)->GetPrereqAndTech();1537				if(ePrereqTech == NO_TECH || GET_TEAM(m_pPlayer->getTeam()).GetTeamTechs()->HasTech(ePrereqTech))1538				{1539					// Resource requirement1540					bMissingResource = false;1541					for(int iResourceLoop = 0; iResourceLoop < GC.getNumResourceInfos() && !bMissingResource; iResourceLoop++)1542					{1543						eResource = (ResourceTypes) iResourceLoop;1544						iNumResource = GC.getUnitInfo(eUpgradeUnitType)->GetResourceQuantityRequirement(eResource);1545						if (iNumResource > 0)1546						{1547							iNumResourceInUnit = pUnit->getUnitInfo().GetResourceQuantityRequirement(eResource);1548							if (m_pPlayer->getNumResourceAvailable(eResource) + iNumResourceInUnit < iNumResource)1549							{1550								bMissingResource = true;1551							}1552						}1553					}15541555					if(!bMissingResource)1556					{1557						CvHomelandUnit unit;1558						unit.SetID(pUnit->GetID());15591560						// Initial priority: units with lowest power first1561						int iPriority = UPGRADE_THIS_TURN_PRIORITY_BOOST - GC.getUnitInfo(pUnit->getUnitType())->GetPower();15621563						// Priority is boosted if can upgrade immediately1564						if(pUnit->CanUpgradeRightNow(false))1565						{1566							iPriority += UPGRADE_THIS_TURN_PRIORITY_BOOST;1567						}15681569						// Alternatively, priority boosted a lesser amount if in friendly territory1570						else if(pUnit->getOwner() == pUnit->plot()->getOwner())1571						{1572							iPriority += UPGRADE_IN_TERRITORY_PRIORITY_BOOST;1573						}15741575						unit.SetAuxIntData(iPriority);1576						m_CurrentMoveUnits.push_back(unit);1577					}1578				}1579			}1580		}1581	}15821583	// No units found, cancel request for money if we have one in1584	if(m_CurrentMoveUnits.size() == 0)1585	{1586		if(!m_pPlayer->GetEconomicAI()->IsSavingForThisPurchase(PURCHASE_TYPE_UNIT_UPGRADE))1587		{1588			m_pPlayer->GetEconomicAI()->CancelSaveForPurchase(PURCHASE_TYPE_UNIT_UPGRADE);1589		}1590	}15911592	else1593	{1594		// Sort results so highest priority is first1595		std::stable_sort(m_CurrentMoveUnits.begin(), m_CurrentMoveUnits.end(), HomelandAIHelpers::CvHomelandUnitAuxIntReverseSort);15961597		int iFlavorMilitaryTraining = 0;1598		for(int iFlavorLoop = 0; iFlavorLoop < GC.getNumFlavorTypes() && iFlavorMilitaryTraining == 0; iFlavorLoop++)1599		{1600			if(GC.getFlavorTypes((FlavorTypes)iFlavorLoop) == "FLAVOR_MILITARY_TRAINING")1601			{1602				iFlavorMilitaryTraining = m_pPlayer->GetGrandStrategyAI()->GetPersonalityAndGrandStrategy((FlavorTypes)iFlavorLoop);1603			}1604		}16051606		iFlavorMilitaryTraining = max(1,iFlavorMilitaryTraining/3);1607		int iBonusUpgrades = max(0,GC.getGame().getHandicapInfo().GetID() - 5); // more at the higher difficulties (the AI should have more money to spend)1608#if defined(MOD_AI_SMART_V3)1609		iFlavorMilitaryTraining += (MOD_AI_SMART_V3 ? (m_CurrentMoveUnits.size() / 4) : 0);1610#endif1611		iFlavorMilitaryTraining += iBonusUpgrades;16121613		// Try to find a unit that can upgrade immediately1614		int iNumUpgraded = 0;1615		for(moveUnitIt = m_CurrentMoveUnits.begin(); moveUnitIt != m_CurrentMoveUnits.end(); ++moveUnitIt)1616		{1617			UnitHandle pUnit = m_pPlayer->getUnit(moveUnitIt->GetID());1618			if(pUnit->CanUpgradeRightNow(false))1619			{1620				CvUnit* pNewUnit = pUnit->DoUpgrade();1621				UnitProcessed(pUnit->GetID());1622				UnitProcessed(pNewUnit->GetID());16231624				if(GC.getLogging() && GC.getAILogging())1625				{1626					CvString strLogString;1627					CvString strTemp1, strTemp2;1628					strTemp1 = GC.getUnitInfo(pUnit->getUnitType())->GetDescription();1629					strTemp2 = GC.getUnitInfo(pNewUnit->getUnitType())->GetDescription();1630					strLogString.Format("Upgrading unit from type %s to type %s, X: %d, Y: %d", strTemp1.GetCString(), strTemp2.GetCString(), pNewUnit->getX(), pNewUnit->getY());1631					LogHomelandMessage(strLogString);1632				}16331634				iNumUpgraded++;1635				if(iNumUpgraded >= iFlavorMilitaryTraining)1636				{1637					return; // Only upgrade iFlavorMilitaryTraining units per turn1638				}1639			}1640		}16411642		if(iNumUpgraded > 0)1643		{1644			return;1645		}16461647		// Couldn't do all upgrades this turn, get ready for highest priority unit to upgrade1648		UnitHandle pUnit = m_pPlayer->getUnit(m_CurrentMoveUnits[0].GetID());16491650		int iAmountRequired = pUnit->upgradePrice(pUnit->GetUpgradeUnitType());1651		bool bRequiresGold = (iAmountRequired > 0);1652		int iGoldPriority = 0;16531654		if(bRequiresGold)1655		{1656			// Find priority of this financial request1657			int iCurrentFlavorMilitaryTraining = 0;1658			for(int iFlavorLoop = 0; iFlavorLoop < GC.getNumFlavorTypes() && iCurrentFlavorMilitaryTraining == 0; iFlavorLoop++)1659			{1660				if(GC.getFlavorTypes((FlavorTypes)iFlavorLoop) == "FLAVOR_MILITARY_TRAINING")1661				{1662					iCurrentFlavorMilitaryTraining = m_pPlayer->GetFlavorManager()->GetIndividualFlavor((FlavorTypes)iFlavorLoop);1663				}1664			}1665			iGoldPriority = GC.getAI_GOLD_PRIORITY_UPGRADE_BASE();1666			iGoldPriority += GC.getAI_GOLD_PRIORITY_UPGRADE_PER_FLAVOR_POINT() * iCurrentFlavorMilitaryTraining;1667		}16681669		// Start saving1670		if(bRequiresGold)1671		{1672			m_pPlayer->GetEconomicAI()->CancelSaveForPurchase(PURCHASE_TYPE_UNIT_UPGRADE);1673			m_pPlayer->GetEconomicAI()->StartSaveForPurchase(PURCHASE_TYPE_UNIT_UPGRADE, iAmountRequired, iGoldPriority);1674		}16751676		// Already in friendly territory1677		if(pUnit->plot()->getOwner() == pUnit->getOwner())1678		{1679			if(GC.getLogging() && GC.getAILogging())1680			{1681				CvString strLogString;1682				CvString strTemp;16831684				strTemp = pUnit->getUnitInfo().GetDescription();1685				strLogString.Format("Need gold for %s upgrade, GOLD: Available = %d, Needed = %d, Priority = %d",1686				                    strTemp.GetCString(), m_pPlayer->GetTreasury()->GetGold(), iAmountRequired, iGoldPriority);1687				LogHomelandMessage(strLogString);1688			}1689		}16901691		else1692		{1693			// Move top priority unit toward closest city1694			CvCity* pUpgradeCity = NULL;1695			int iBestDistance = MAX_INT;1696			for(unsigned int iI = 0; iI < m_TargetedCities.size(); iI++)1697			{1698				CvPlot* pTarget = GC.getMap().plot(m_TargetedCities[iI].GetTargetX(), m_TargetedCities[iI].GetTargetY());1699				CvCity* pCity = pTarget->getPlotCity();17001701				int iDistance = plotDistance(pCity->getX(), pCity->getY(), pUnit->getX(), pUnit->getY());17021703				if(iDistance < iBestDistance)1704				{1705					iBestDistance = iDistance;1706					pUpgradeCity = pCity;1707				}1708			}17091710			if(pUpgradeCity)1711			{1712				if(MoveToEmptySpaceNearTarget(pUnit.pointer(), pUpgradeCity->plot()))1713				{1714					pUnit->finishMoves();1715					UnitProcessed(pUnit->GetID());17161717					if(GC.getLogging() && GC.getAILogging())1718					{1719						CvString strLogString;1720						CvString strTemp;1721						strTemp = GC.getUnitInfo(pUnit->getUnitType())->GetDescription();1722						strLogString.Format("Moving %s for upgrade at %s, GOLD: Available = %d, Needed = %d, Priority = %d, Dist = %d",1723						                    strTemp.GetCString(), pUpgradeCity->getName().GetCString(),1724						                    m_pPlayer->GetTreasury()->GetGold(), iAmountRequired, iGoldPriority, iBestDistance);1725						LogHomelandMessage(strLogString);1726					}1727				}1728			}1729		}1730	}17311732	return;1733}

Calls

Called by