Bazaar developer reference

CvUnitEntry::DoUpdatePower()

Defined in
CvUnitClasses.cpp, line 1308
Class
CvUnitEntry
Hook name
CivHooks::CvUnitEntry_DoUpdatePower

Hooks

static bool BeforeCvUnitEntry_DoUpdatePower(CvUnitEntry* self);static void AfterCvUnitEntry_DoUpdatePower(CvUnitEntry* self);static void ReplaceCvUnitEntry_DoUpdatePower(void (*original)(CvUnitEntry*), CvUnitEntry* self);CivRegisterBefore<CivHooks::CvUnitEntry_DoUpdatePower>(host, &BeforeCvUnitEntry_DoUpdatePower);CivRegisterAfter<CivHooks::CvUnitEntry_DoUpdatePower>(host, &AfterCvUnitEntry_DoUpdatePower);CivRegisterReplace<CivHooks::CvUnitEntry_DoUpdatePower>(host, &ReplaceCvUnitEntry_DoUpdatePower);

Code

1307/// Update military Power1308void CvUnitEntry::DoUpdatePower()1309{1310	int iPower;13111312// ***************1313// Main Factors - Strength & Moves1314// ***************13151316	// We want a Unit that has twice the strength to be roughly worth 3x as much with regards to Power1317	iPower = int(pow((double) GetCombat(), 1.5));13181319	// Ranged Strength1320	int iRangedStrength = int(pow((double) GetRangedCombat(), 1.45));13211322	// Naval ranged attacks are less useful1323	if(GetDomainType() == DOMAIN_SEA)1324	{1325#if defined(MOD_BUGFIX_UNIT_POWER_CALC)1326		if (!MOD_BUGFIX_UNIT_POWER_CALC) {1327#if defined(MOD_BUGFIX_UNIT_POWER_NAVAL_CONSISTENCY)1328			if (!MOD_BUGFIX_UNIT_POWER_NAVAL_CONSISTENCY) {1329				// We can either ignore this or divide naval melee attacks by two, but if we leave this alone Destroyers are more than twice as powerful as Battleships!!!1330#endif1331#endif1332				iRangedStrength *= 3;1333				iRangedStrength /= 4;1334#if defined(MOD_BUGFIX_UNIT_POWER_CALC)1335#if defined(MOD_BUGFIX_UNIT_POWER_NAVAL_CONSISTENCY)1336			}1337#endif1338		}1339#endif1340	}13411342	if(iRangedStrength > iPower)1343	{1344		iPower = iRangedStrength;1345	}13461347	// We want Movement rate to be important, but not a dominating factor; a Unit with double the moves of a similarly-strengthed Unit should be ~1.5x as Powerful1348	iPower = int((float) iPower * pow(min(1.0,(double) GetMoves()), 0.3));1349#if defined(MOD_BUGFIX_UNIT_POWER_CALC)1350	if (IsImmobile()) {1351		// A unit that can't move should be worth half of one that can1352		iPower /= 2;1353	}1354#endif13551356// ***************1357// Other modifiers1358// ***************13591360	// Suicide Units are obviously less useful1361	if(IsSuicide())1362	{1363		iPower /= 2;1364	}13651366	// Nukes are cool1367	if(GetNukeDamageLevel() > 0)1368	{1369		iPower += 4000;1370	}13711372// ***************1373// Promotion modifiers1374// ***************13751376	int iTemp;1377	int iLoop;13781379#if defined(MOD_BUGFIX_UNIT_POWER_CALC)1380	if (MOD_BUGFIX_UNIT_POWER_CALC) {1381		int iBasePower = iPower;1382		int iBonusPower = 0;13831384	for(int iPromotionLoop = 0; iPromotionLoop < GC.getNumPromotionInfos(); iPromotionLoop++)1385	{1386		CvPromotionEntry* kPromotion = GC.getPromotionInfo((PromotionTypes)iPromotionLoop);1387		if(kPromotion == NULL)1388			continue;13891390		if(GetFreePromotions(iPromotionLoop))1391		{1392			// City Attack - add half of the bonus1393			if(kPromotion->GetCityAttackPercent() > 0)1394			{1395				iTemp = (iBasePower * kPromotion->GetCityAttackPercent() / 2);1396				iTemp /= 100;1397				iBonusPower += iTemp;1398			}13991400			// Attack - add half of the bonus1401			if(kPromotion->GetAttackMod() > 0)1402			{1403				iTemp = (iBasePower * kPromotion->GetAttackMod() / 2);1404				iTemp /= 100;1405				iBonusPower += iTemp;1406			}14071408			// Defense - add half of the bonus1409			if(kPromotion->GetDefenseMod() > 0)1410			{1411				iTemp = (iBasePower * kPromotion->GetDefenseMod() / 2);1412				iTemp /= 100;1413				iBonusPower += iTemp;1414			}14151416			// Paradrop - add 25%1417			if(kPromotion->GetDropRange() > 0)1418			{1419				iTemp = iBasePower;1420				iTemp /= 4;1421				iBonusPower += iTemp;1422			}14231424			// Blitz - add 20%1425			if(kPromotion->IsBlitz())1426			{1427				iTemp = iBasePower;1428				iTemp /= 5;1429				iBonusPower += iTemp;1430			}14311432			// Set Up For Ranged Attack - reduce by 20%1433			if(kPromotion->IsMustSetUpToRangedAttack())1434			{1435				iTemp = iBasePower;1436				iTemp /= 5;1437				iBonusPower -= iTemp;1438			}14391440			// Only Defensive - reduce  by 25%, but only if the Unit has no ranged capability1441			if(kPromotion->IsOnlyDefensive() && GetRangedCombat() == 0)1442			{1443				iTemp = iBasePower;1444				iTemp /= 4;1445				iBonusPower -= iTemp;1446			}14471448			for(iLoop = 0; iLoop < GC.getNumTerrainInfos(); iLoop++)1449			{1450				// Terrain Attack - add one quarter of the bonus1451				if(kPromotion->GetTerrainAttackPercent(iLoop) > 0)1452				{1453					iTemp = (iBasePower * kPromotion->GetTerrainAttackPercent(iLoop) / 4);1454					iTemp /= 100;1455					iBonusPower += iTemp;1456				}1457				// Terrain Defense - add one quarter of the bonus1458				if(kPromotion->GetTerrainDefensePercent(iLoop) > 0)1459				{1460					iTemp = (iBasePower * kPromotion->GetTerrainDefensePercent(iLoop) / 4);1461					iTemp /= 100;1462					iBonusPower += iTemp;1463				}1464			}14651466			for(iLoop = 0; iLoop < GC.getNumFeatureInfos(); iLoop++)1467			{1468				// Feature Attack - add one quarter of the bonus1469				if(kPromotion->GetFeatureAttackPercent(iLoop) > 0)1470				{1471					iTemp = (iBasePower * kPromotion->GetFeatureAttackPercent(iLoop) / 4);1472					iTemp /= 100;1473					iBonusPower += iTemp;1474				}1475				// Feature Defense - add one quarter of the bonus1476				if(kPromotion->GetFeatureDefensePercent(iLoop) > 0)1477				{1478					iTemp = (iBasePower * kPromotion->GetFeatureDefensePercent(iLoop) / 4);1479					iTemp /= 100;1480					iBonusPower += iTemp;1481				}1482			}14831484#if defined(MOD_BUGFIX_UNITCOMBAT_BONUS_VS_DOMAIN_ONLY)1485			if (MOD_BUGFIX_UNITCOMBAT_BONUS_VS_DOMAIN_ONLY) {1486				// Only add UNITCOMBAT bonuses against the same domain, so we need to know the domain of combat classes1487				//   DOMAIN_SEA is UNITCOMBAT_NAVALRANGED and UNITCOMBAT_NAVALMELEE1488				//   DOMAIN_AIR is UNITCOMBAT_HELICOPTER, UNITCOMBAT_FIGHTER and UNITCOMBAT_BOMBER1489				//   DOMAIN_LAND is everything else1490				int iMyDomain = GetDomainType();1491				for(iLoop = 0; iLoop < GC.getNumUnitCombatClassInfos(); iLoop++)1492				{1493					int iTheirDomain = NO_DOMAIN;1494					CvBaseInfo* pkUnitCombatInfo = GC.getUnitCombatClassInfo((UnitCombatTypes)iLoop);1495					if (pkUnitCombatInfo) {1496						int iTheirUnitCombat = pkUnitCombatInfo->GetID();1497					1498						if (iTheirUnitCombat == GC.getInfoTypeForString("UNITCOMBAT_NAVALRANGED", true) || iTheirUnitCombat == GC.getInfoTypeForString("UNITCOMBAT_NAVALMELEE", true)) {1499							iTheirDomain = DOMAIN_SEA;1500						} else if (iTheirUnitCombat == GC.getInfoTypeForString("UNITCOMBAT_HELICOPTER", true) || iTheirUnitCombat == GC.getInfoTypeForString("UNITCOMBAT_FIGHTER", true) || iTheirUnitCombat == GC.getInfoTypeForString("UNITCOMBAT_BOMBER", true)) {1501							iTheirDomain = DOMAIN_AIR;1502						} else {1503							iTheirDomain = DOMAIN_LAND;1504						}1505					}15061507					if (iMyDomain == iTheirDomain) {1508						// Unit Combat Class (e.g. Pikemen) - add one quarter of the bonus1509						if(kPromotion->GetUnitCombatModifierPercent(iLoop) > 0)1510						{1511							iTemp = (iBasePower * kPromotion->GetUnitCombatModifierPercent(iLoop) / 4);1512							iTemp /= 100;1513							iBonusPower += iTemp;1514						}1515					}1516				}1517			} else {1518#endif1519				for(iLoop = 0; iLoop < GC.getNumUnitCombatClassInfos(); iLoop++)1520				{1521					// Unit Combat Class (e.g. Pikemen) - add one quarter of the bonus1522					if(kPromotion->GetUnitCombatModifierPercent(iLoop) > 0)1523					{1524						iTemp = (iBasePower * kPromotion->GetUnitCombatModifierPercent(iLoop) / 4);1525						iTemp /= 100;1526						iBonusPower += iTemp;1527					}1528				}1529#if defined(MOD_BUGFIX_UNITCOMBAT_BONUS_VS_DOMAIN_ONLY)1530			}1531#endif15321533			for(iLoop = 0; iLoop < GC.getNumUnitClassInfos(); iLoop++)1534			{1535				// Unit Class (e.g. bonus ONLY against Galleys) - add one eighth of the bonus1536				// We're assuming here that the bonus against the other Unit is at least going to be somewhat useful - trust the XML! :o1537				if(kPromotion->GetUnitClassModifierPercent(iLoop) > 0)1538				{1539					iTemp = (iBasePower * kPromotion->GetUnitClassModifierPercent(iLoop) / 8);1540					iTemp /= 100;1541					iBonusPower += iTemp;1542				}1543				// Unit Class Attack - one tenth of the bonus1544				if(kPromotion->GetUnitClassAttackModifier(iLoop) > 0)1545				{1546					iTemp = (iBasePower * kPromotion->GetUnitClassAttackModifier(iLoop) / 10);1547					iTemp /= 100;1548					iBonusPower += iTemp;1549				}1550				// Unit Class Defense - one tenth of the bonus1551				if(kPromotion->GetUnitClassDefenseModifier(iLoop) > 0)1552				{1553					iTemp = (iBasePower * kPromotion->GetUnitClassDefenseModifier(iLoop) / 10);1554					iTemp /= 100;1555					iBonusPower += iTemp;1556				}1557			}15581559			for(iLoop = 0; iLoop < NUM_DOMAIN_TYPES; iLoop++)1560			{1561				// Domain - add one quarter of the bonus1562				if(kPromotion->GetDomainModifierPercent(iLoop) > 0)1563				{1564					iTemp = (iBasePower * kPromotion->GetDomainModifierPercent(iLoop) / 4);1565					iTemp /= 100;1566					iBonusPower += iTemp;1567				}1568			}1569		}1570	}15711572	iPower = iBasePower + iBonusPower;15731574	} else {1575#endif15761577	for(int iPromotionLoop = 0; iPromotionLoop < GC.getNumPromotionInfos(); iPromotionLoop++)1578	{1579		CvPromotionEntry* kPromotion = GC.getPromotionInfo((PromotionTypes)iPromotionLoop);1580		if(kPromotion == NULL)1581			continue;15821583		if(GetFreePromotions(iPromotionLoop))1584		{1585			// City Attack - add half of the bonus1586			if(kPromotion->GetCityAttackPercent() > 0)1587			{1588				iTemp = (iPower * kPromotion->GetCityAttackPercent() / 2);1589				iTemp /= 100;1590				iPower += iTemp;1591			}15921593			// Attack - add half of the bonus1594			if(kPromotion->GetAttackMod() > 0)1595			{1596				iTemp = (iPower * kPromotion->GetAttackMod() / 2);1597				iTemp /= 100;1598				iPower += iTemp;1599			}16001601			// Defense - add half of the bonus1602			if(kPromotion->GetDefenseMod() > 0)1603			{1604				iTemp = (iPower * kPromotion->GetDefenseMod() / 2);1605				iTemp /= 100;1606				iPower += iTemp;1607			}16081609			// Paradrop - add 25%1610			if(kPromotion->GetDropRange() > 0)1611			{1612				iTemp = iPower;1613				iTemp /= 4;1614				iPower += iTemp;1615			}16161617			// Blitz - add 20%1618			if(kPromotion->IsBlitz())1619			{1620				iTemp = iPower;1621				iTemp /= 5;1622				iPower += iTemp;1623			}16241625			// Set Up For Ranged Attack - reduce by 20%1626			if(kPromotion->IsMustSetUpToRangedAttack())1627			{1628				iTemp = iPower;1629				iTemp /= 5;1630				iPower -= iTemp;1631			}16321633			// Only Defensive - reduce  by 25%, but only if the Unit has no ranged capability1634			if(kPromotion->IsOnlyDefensive() && GetRangedCombat() == 0)1635			{1636				iTemp = iPower;1637				iTemp /= 4;1638				iPower -= iTemp;1639			}16401641			for(iLoop = 0; iLoop < GC.getNumTerrainInfos(); iLoop++)1642			{1643				// Terrain Attack - add one quarter of the bonus1644				if(kPromotion->GetTerrainAttackPercent(iLoop) > 0)1645				{1646					iTemp = (iPower * kPromotion->GetTerrainAttackPercent(iLoop) / 4);1647					iTemp /= 100;1648					iPower += iTemp;1649				}1650				// Terrain Defense - add one quarter of the bonus1651				if(kPromotion->GetTerrainDefensePercent(iLoop) > 0)1652				{1653					iTemp = (iPower * kPromotion->GetTerrainDefensePercent(iLoop) / 4);1654					iTemp /= 100;1655					iPower += iTemp;1656				}1657			}16581659			for(iLoop = 0; iLoop < GC.getNumFeatureInfos(); iLoop++)1660			{1661				// Feature Attack - add one quarter of the bonus1662				if(kPromotion->GetFeatureAttackPercent(iLoop) > 0)1663				{1664					iTemp = (iPower * kPromotion->GetFeatureAttackPercent(iLoop) / 4);1665					iTemp /= 100;1666					iPower += iTemp;1667				}1668				// Feature Defense - add one quarter of the bonus1669				if(kPromotion->GetFeatureDefensePercent(iLoop) > 0)1670				{1671					iTemp = (iPower * kPromotion->GetFeatureDefensePercent(iLoop) / 4);1672					iTemp /= 100;1673					iPower += iTemp;1674				}1675			}16761677			for(iLoop = 0; iLoop < GC.getNumUnitCombatClassInfos(); iLoop++)1678			{1679				// Unit Combat Class (e.g. Pikemen) - add one quarter of the bonus1680				if(kPromotion->GetUnitCombatModifierPercent(iLoop) > 0)1681				{1682					iTemp = (iPower * kPromotion->GetUnitCombatModifierPercent(iLoop) / 4);1683					iTemp /= 100;1684					iPower += iTemp;1685				}1686			}16871688			for(iLoop = 0; iLoop < GC.getNumUnitClassInfos(); iLoop++)1689			{1690				// Unit Class (e.g. bonus ONLY against Galleys) - add one eighth of the bonus1691				// We're assuming here that the bonus against the other Unit is at least going to be somewhat useful - trust the XML! :o1692				if(kPromotion->GetUnitClassModifierPercent(iLoop) > 0)1693				{1694					iTemp = (iPower * kPromotion->GetUnitClassModifierPercent(iLoop) / 8);1695					iTemp /= 100;1696					iPower += iTemp;1697				}1698				// Unit Class Attack - one tenth of the bonus1699				if(kPromotion->GetUnitClassAttackModifier(iLoop) > 0)1700				{1701					iTemp = (iPower * kPromotion->GetUnitClassAttackModifier(iLoop) / 10);1702					iTemp /= 100;1703					iPower += iTemp;1704				}1705				// Unit Class Defense - one tenth of the bonus1706				if(kPromotion->GetUnitClassDefenseModifier(iLoop) > 0)1707				{1708					iTemp = (iPower * kPromotion->GetUnitClassDefenseModifier(iLoop) / 10);1709					iTemp /= 100;1710					iPower += iTemp;1711				}1712			}17131714			for(iLoop = 0; iLoop < NUM_DOMAIN_TYPES; iLoop++)1715			{1716				// Domain - add one quarter of the bonus1717				if(kPromotion->GetDomainModifierPercent(iLoop) > 0)1718				{1719					iTemp = (iPower * kPromotion->GetDomainModifierPercent(iLoop) / 4);1720					iTemp /= 100;1721					iPower += iTemp;1722				}1723			}1724		}1725	}17261727#if defined(MOD_BUGFIX_UNIT_POWER_CALC)1728	}17291730	// CUSTOMLOG("UnitClass::Power\t%s\t%i", GetDescription(), iPower);1731#endif17321733	// Debug output1734	//char temp[256];1735	//sprintf(temp, "%s: %i\n", GetDescription(), iPower);1736	//OutputDebugString(temp);17371738	m_iCachedPower = iPower;1739}

Calls

Called by