// This function has been significantly modified for K-Mod
bool CvUnitAI::AI_stackAttackCity(int iPowerThreshold)
{
PROFILE_FUNC();
CvPlot* pCityPlot = NULL;
int iSearchRange = 1;
FAssert(canMove());
for (int iDX = -(iSearchRange); iDX <= iSearchRange; iDX++)
{
for (int iDY = -(iSearchRange); iDY <= iSearchRange; iDY++)
{
CvPlot* pLoopPlot = plotXY(getX_INLINE(), getY_INLINE(), iDX, iDY);
if (pLoopPlot != NULL && AI_plotValid(pLoopPlot))
{
//if (pLoopPlot->isCity() || (pLoopPlot->isCity(true) && pLoopPlot->isVisibleEnemyUnit(this)))
if (pLoopPlot->isCity()) // K-Mod. We want to attack a city. We don't care about guarded forts!
{
if (AI_potentialEnemy(pLoopPlot->getTeam(), pLoopPlot))
{
//if (!atPlot(pLoopPlot) && ((bFollow) ? canMoveInto(pLoopPlot, /*bAttack*/ true, /*bDeclareWar*/ true) : (generatePath(pLoopPlot, 0, true, &iPathTurns) && (iPathTurns <= iRange))))
if (!atPlot(pLoopPlot) && getGroup()->canMoveOrAttackInto(pLoopPlot, true, true))
{
// K-Mod
if (iPowerThreshold < 0)
{
// basic threshold calculation.
CvCity* pCity = pLoopPlot->getPlotCity();
// This automatic threshold calculation is used by AI_follow; and so we can't assume this unit is the head of the group.
// ... But I think it's fair to assume that if our group has any bombard, it the head unit will have it.
if (getGroup()->getHeadUnit()->bombardRate() > 0)
{
// if we can bombard, then we should do a rough calculation to give us a 'skip bombard' threshold.
iPowerThreshold = ((GC.getMAX_CITY_DEFENSE_DAMAGE()-pCity->getDefenseDamage()) * GC.getBBAI_SKIP_BOMBARD_BASE_STACK_RATIO() + pCity->getDefenseDamage() * GC.getBBAI_SKIP_BOMBARD_MIN_STACK_RATIO()) / std::max(1, GC.getMAX_CITY_DEFENSE_DAMAGE());
}
else
[COLOR="Green"][B]{
// if we have no bombard ability - just use the minimum threshold
iPowerThreshold = GC.getBBAI_SKIP_BOMBARD_MIN_STACK_RATIO();
}[/B][/COLOR]
FAssert(iPowerThreshold >= GC.getBBAI_ATTACK_CITY_STACK_RATIO());
}
// K-Mod end
if (getGroup()->AI_compareStacks(pLoopPlot, true) >= iPowerThreshold)
{
pCityPlot = pLoopPlot;
}
}
}
break; // there can only be one.
}
}
}
}
if (pCityPlot != NULL)
{
if( gUnitLogLevel >= 1 && pCityPlot->getPlotCity() != NULL )
{
logBBAI(" Stack for player %d (%S) decides to attack city %S with stack ratio %d", getOwner(), GET_PLAYER(getOwnerINLINE()).getCivilizationDescription(0), pCityPlot->getPlotCity()->getName(0).GetCString(), getGroup()->AI_compareStacks(pCityPlot, true) );
logBBAI(" City %S has defense modifier %d, %d with ignore building", pCityPlot->getPlotCity()->getName(0).GetCString(), pCityPlot->getPlotCity()->getDefenseModifier(false), pCityPlot->getPlotCity()->getDefenseModifier(true) );
}
FAssert(!atPlot(pCityPlot));
AI_considerDOW(pCityPlot);
getGroup()->pushMission(MISSION_MOVE_TO, pCityPlot->getX_INLINE(), pCityPlot->getY_INLINE(), pCityPlot->isVisibleEnemyDefender(this) ? MOVE_DIRECT_ATTACK : 0);
return true;
}
return false;
}