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;
}
Пример #3
0
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;
}
Пример #4
0
// 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;
}