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}