int CvSelectionGroupAI::AI_sumStrength(const CvPlot* pAttackedPlot, DomainTypes eDomainType, bool bCheckCanAttack, bool bCheckCanMove) const { CLLNode<IDInfo>* pUnitNode; CvUnit* pLoopUnit; int strSum = 0; pUnitNode = headUnitNode(); while (pUnitNode != NULL) { pLoopUnit = ::getUnit(pUnitNode->m_data); pUnitNode = nextUnitNode(pUnitNode); if (!pLoopUnit->isDead()) { bool bCanAttack = false; if (pLoopUnit->getDomainType() == DOMAIN_AIR) bCanAttack = pLoopUnit->canAirAttack(); else bCanAttack = pLoopUnit->canAttack(); if (!bCheckCanAttack || bCanAttack) { if (!bCheckCanMove || pLoopUnit->canMove()) if (!bCheckCanMove || pAttackedPlot == NULL || pLoopUnit->canMoveInto(pAttackedPlot, /*bAttack*/ true, /*bDeclareWar*/ true)) if (eDomainType == NO_DOMAIN || pLoopUnit->getDomainType() == eDomainType) strSum += pLoopUnit->currEffectiveStr(pAttackedPlot, pLoopUnit); } } } return strSum; }
// uses the same scale as CvPlayerAI::AI_getOurPlotStrength int CvSelectionGroupAI::AI_GroupPower(CvPlot* pPlot, bool bDefensiveBonuses) const { CLLNode<IDInfo>* pUnitNode; CvUnit* pLoopUnit; int iValue; iValue = 0; pUnitNode = headUnitNode(); while (pUnitNode != NULL) { pLoopUnit = ::getUnit(pUnitNode->m_data); pUnitNode = nextUnitNode(pUnitNode); if ((bDefensiveBonuses && pLoopUnit->canDefend()) || pLoopUnit->canAttack()) { if (!(pLoopUnit->isInvisible(getTeam(), false))) { if (pLoopUnit->atPlot(pPlot) || pLoopUnit->canMoveInto(pPlot) || pLoopUnit->canMoveInto(pPlot, /*bAttack*/ true)) { iValue += pLoopUnit->currEffectiveStr((bDefensiveBonuses ? pPlot : NULL), NULL); } } } } return iValue; }
CvUnit* CvSelectionGroupAI::AI_ejectBestDefender(CvPlot* pDefendPlot) { CLLNode<IDInfo>* pEntityNode; CvUnit* pLoopUnit; pEntityNode = headUnitNode(); CvUnit* pBestUnit = NULL; int iBestUnitValue = 0; while (pEntityNode != NULL) { pLoopUnit = ::getUnit(pEntityNode->m_data); pEntityNode = nextUnitNode(pEntityNode); //if (!pLoopUnit->noDefensiveBonus()) // commented out by K-Mod. The noDefBonus thing is already taken into account. { int iValue = pLoopUnit->currEffectiveStr(pDefendPlot, NULL) * 100; if (pDefendPlot->isCity(true, getTeam())) { iValue *= 100 + pLoopUnit->cityDefenseModifier(); iValue /= 100; } iValue *= 100; iValue /= (100 + pLoopUnit->cityAttackModifier() + pLoopUnit->getExtraCityAttackPercent()); iValue /= 2 + pLoopUnit->getLevel(); if (iValue > iBestUnitValue) { iBestUnitValue = iValue; pBestUnit = pLoopUnit; } } } if (NULL != pBestUnit && getNumUnits() > 1) { pBestUnit->joinGroup(NULL); } return pBestUnit; }
// K-Mod. I've removed bCheckMove, and changed bCheckCanAttack to include checks for moves, and for hasAlreadyAttacked / blitz int CvSelectionGroupAI::AI_sumStrength(const CvPlot* pAttackedPlot, DomainTypes eDomainType, bool bCheckCanAttack) const { CLLNode<IDInfo>* pUnitNode; CvUnit* pLoopUnit; int strSum = 0; bool bDefenders = pAttackedPlot ? pAttackedPlot->isVisibleEnemyUnit(getHeadOwner()) : false; // K-Mod bool bCountCollateral = pAttackedPlot && pAttackedPlot != plot(); // K-Mod pUnitNode = headUnitNode(); int iBaseCollateral = bCountCollateral ? iBaseCollateral = estimateCollateralWeight(pAttackedPlot, pAttackedPlot->getTeam() == getTeam() ? NO_TEAM : pAttackedPlot->getTeam()) : 0; while (pUnitNode != NULL) { pLoopUnit = ::getUnit(pUnitNode->m_data); pUnitNode = nextUnitNode(pUnitNode); if (!pLoopUnit->isDead()) { // K-Mod. (original checks deleted.) if (bCheckCanAttack) { if (pLoopUnit->getDomainType() == DOMAIN_AIR) { if (!pLoopUnit->canAirAttack() || !pLoopUnit->canMove() || (pAttackedPlot && bDefenders && !pLoopUnit->canMoveInto(pAttackedPlot, true, true))) continue; // can't attack. } else { if (!pLoopUnit->canAttack() || !pLoopUnit->canMove() || (pAttackedPlot && bDefenders && !pLoopUnit->canMoveInto(pAttackedPlot, true, true)) || (!pLoopUnit->isBlitz() && pLoopUnit->isMadeAttack())) continue; // can't attack. } } // K-Mod end if (eDomainType == NO_DOMAIN || pLoopUnit->getDomainType() == eDomainType) { strSum += pLoopUnit->currEffectiveStr(pAttackedPlot, pLoopUnit); // K-Mod estimate the attack power of collateral units. (cf with calculation in AI_localAttackStrength) if (bCountCollateral && pLoopUnit->collateralDamage() > 0) { int iPossibleTargets = pLoopUnit->collateralDamageMaxUnits(); // If !bCheckCanAttack, then lets not assume pAttackPlot won't get more units on it. if (bCheckCanAttack && pAttackedPlot->isVisible(getTeam(), false)) iPossibleTargets = std::min(iPossibleTargets, pAttackedPlot->getNumVisibleEnemyDefenders(pLoopUnit) - 1); if (iPossibleTargets > 0) { // collateral damage is not trivial to calculate. This estimate is pretty rough. // (Note: collateralDamage() and iBaseCollateral both include factors of 100.) strSum += pLoopUnit->baseCombatStr() * iBaseCollateral * pLoopUnit->collateralDamage() * iPossibleTargets / 10000; } } // K-Mod end } } } return strSum; }