Hooks
static bool BeforeCvTacticalAI_ComputeTotalExpectedDamage(CvTacticalAI* self, CvTacticalTarget* pTarget, CvPlot* pTargetPlot, int& result);static void AfterCvTacticalAI_ComputeTotalExpectedDamage(CvTacticalAI* self, CvTacticalTarget* pTarget, CvPlot* pTargetPlot, int& result);static int ReplaceCvTacticalAI_ComputeTotalExpectedDamage(int (*original)(CvTacticalAI*, CvTacticalTarget*, CvPlot*), CvTacticalAI* self, CvTacticalTarget* pTarget, CvPlot* pTargetPlot);CivRegisterBefore<CivHooks::CvTacticalAI_ComputeTotalExpectedDamage>(host, &BeforeCvTacticalAI_ComputeTotalExpectedDamage);CivRegisterAfter<CivHooks::CvTacticalAI_ComputeTotalExpectedDamage>(host, &AfterCvTacticalAI_ComputeTotalExpectedDamage);CivRegisterReplace<CivHooks::CvTacticalAI_ComputeTotalExpectedDamage>(host, &ReplaceCvTacticalAI_ComputeTotalExpectedDamage);
Code
9582/// Estimates the damage we can apply to a target9583int CvTacticalAI::ComputeTotalExpectedDamage(CvTacticalTarget* pTarget, CvPlot* pTargetPlot)9584{9585 int rtnValue = 0;9586 int iExpectedDamage;9587 int iExpectedSelfDamage;95889589 // Loop through all units who can reach the target9590 for(unsigned int iI = 0; iI < m_CurrentMoveUnits.size(); iI++)9591 {9592 UnitHandle pAttacker = m_pPlayer->getUnit(m_CurrentMoveUnits[iI].GetID());9593#if defined(MOD_AI_SMART_V3)9594 // If the unit is out of initial range, may not reach successfully to target (we still not know), so value is halved.9595 int farAwayUnitDivisor = MOD_AI_SMART_V3 ? ((plotDistance(pAttacker->getX(), pAttacker->getY(), pTargetPlot->getX(), pTargetPlot->getY()) > pAttacker-> GetRange()) ? 2 : 1) : 1;9596#endif95979598 // Is target a unit?9599 switch(pTarget->GetTargetType())9600 {9601 case AI_TACTICAL_TARGET_HIGH_PRIORITY_UNIT:9602 case AI_TACTICAL_TARGET_MEDIUM_PRIORITY_UNIT:9603 case AI_TACTICAL_TARGET_LOW_PRIORITY_UNIT:9604 {9605 UnitHandle pDefender = pTargetPlot->getVisibleEnemyDefender(m_pPlayer->GetID());9606 if(pDefender)9607 {9608 if(pAttacker->IsCanAttackRanged())9609 {9610#if defined(MOD_AI_SMART_V3)9611 iExpectedDamage = pAttacker->GetRangeCombatDamage(pDefender.pointer(), NULL, false) / farAwayUnitDivisor;9612#else9613 iExpectedDamage = pAttacker->GetRangeCombatDamage(pDefender.pointer(), NULL, false);9614#endif9615 iExpectedSelfDamage = 0;9616 }9617 else9618 {9619 int iAttackerStrength = pAttacker->GetMaxAttackStrength(NULL, pTargetPlot, NULL);9620 int iDefenderStrength = pDefender->GetMaxDefenseStrength(pTargetPlot, pAttacker.pointer());9621 UnitHandle pFireSupportUnit = CvUnitCombat::GetFireSupportUnit(pDefender->getOwner(), pTargetPlot->getX(), pTargetPlot->getY(), pAttacker->getX(), pAttacker->getY());9622 int iDefenderFireSupportCombatDamage = 0;9623 if(pFireSupportUnit)9624 {9625 iDefenderFireSupportCombatDamage = pFireSupportUnit->GetRangeCombatDamage(pAttacker.pointer(), NULL, false);9626 }9627 iExpectedDamage = pAttacker->getCombatDamage(iAttackerStrength, iDefenderStrength, pAttacker->getDamage() + iDefenderFireSupportCombatDamage, /*bIncludeRand*/ false, /*bAttackerIsCity*/ false, /*bDefenderIsCity*/ false);9628 iExpectedSelfDamage = pDefender->getCombatDamage(iDefenderStrength, iAttackerStrength, pDefender->getDamage(), /*bIncludeRand*/ false, /*bAttackerIsCity*/ false, /*bDefenderIsCity*/ false);9629 }9630 m_CurrentMoveUnits[iI].SetExpectedTargetDamage(iExpectedDamage);9631 m_CurrentMoveUnits[iI].SetExpectedSelfDamage(iExpectedSelfDamage);9632 rtnValue += iExpectedDamage;9633 }9634 }9635 break;96369637 case AI_TACTICAL_TARGET_CITY:9638 {9639 CvCity* pCity = pTargetPlot->getPlotCity();9640 if(pCity != NULL)9641 {9642 if(pAttacker->IsCanAttackRanged() && pAttacker->GetMaxRangedCombatStrength(NULL, /*pCity*/ NULL, true, true) > pAttacker->GetMaxAttackStrength(NULL, pTargetPlot, NULL))9643 {9644#if defined(MOD_AI_SMART_V3)9645 iExpectedDamage = pAttacker->GetRangeCombatDamage(NULL, pCity, false) / farAwayUnitDivisor;9646#else9647 iExpectedDamage = pAttacker->GetRangeCombatDamage(NULL, pCity, false);9648#endif9649 iExpectedSelfDamage = 0;9650 }9651 else9652 {9653 int iAttackerStrength = pAttacker->GetMaxAttackStrength(NULL, pTargetPlot, NULL);9654 int iDefenderStrength = pCity->getStrengthValue();9655 CvUnit* pFireSupportUnit = CvUnitCombat::GetFireSupportUnit(pCity->getOwner(), pTargetPlot->getX(), pTargetPlot->getY(), pAttacker->getX(), pAttacker->getY());9656 int iDefenderFireSupportCombatDamage = 0;9657 if(pFireSupportUnit != NULL)9658 {9659 iDefenderFireSupportCombatDamage = pFireSupportUnit->GetRangeCombatDamage(pAttacker.pointer(), NULL, false);9660 }9661 iExpectedDamage = pAttacker->getCombatDamage(iAttackerStrength, iDefenderStrength, pAttacker->getDamage() + iDefenderFireSupportCombatDamage, /*bIncludeRand*/ false, /*bAttackerIsCity*/ false, /*bDefenderIsCity*/ true);9662 iExpectedSelfDamage = pAttacker->getCombatDamage(iDefenderStrength, iAttackerStrength, pCity->getDamage(), /*bIncludeRand*/ false, /*bAttackerIsCity*/ true, /*bDefenderIsCity*/ false);9663 }9664 m_CurrentMoveUnits[iI].SetExpectedTargetDamage(iExpectedDamage);9665 m_CurrentMoveUnits[iI].SetExpectedSelfDamage(iExpectedSelfDamage);9666 rtnValue += iExpectedDamage;9667 }9668 }9669 break;9670 }9671 }96729673 return rtnValue;9674}