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}