/// Calculate military presences in each owned dominance zone
void CvTacticalAnalysisMap::CalculateMilitaryStrengths()
{
	TeamTypes eTeam = GET_PLAYER(m_ePlayer).getTeam();

	// Loop through the dominance zones
	for(unsigned int iI = 0; iI < m_DominanceZones.size(); iI++)
	{
		CvTacticalDominanceZone* pZone = &m_DominanceZones[iI];
		CvCity *pClosestCity = pZone->GetZoneCity();
		if(pClosestCity)
		{
			// Start with strength of the city itself
			int iCityHitPoints = pClosestCity->GetMaxHitPoints() - pClosestCity->getDamage();
			int iStrength = pClosestCity->getStrengthValue() * iCityHitPoints / GC.getMAX_CITY_HIT_POINTS();

			if(pZone->GetTerritoryType() == TACTICAL_TERRITORY_FRIENDLY)
			{
				pZone->AddFriendlyMeleeStrength(iStrength);
				pZone->AddFriendlyRangedStrength(pClosestCity->getStrengthValue(true));
			}
			else if(pZone->GetTerritoryType() == TACTICAL_TERRITORY_ENEMY)
			{
				pZone->AddEnemyMeleeStrength(iStrength);
				pZone->AddEnemyRangedStrength(pClosestCity->getStrengthValue(true));
			}
			else
			{ 
				pZone->AddNeutralStrength(iStrength);
			}
		}

		// check all units in the world
		for(int iPlayerLoop = 0; iPlayerLoop < MAX_PLAYERS; iPlayerLoop++)
		{
			CvPlayer& kPlayer = GET_PLAYER((PlayerTypes) iPlayerLoop);
			bool bEnemy = GET_TEAM(eTeam).isAtWar(kPlayer.getTeam());
			bool bFriendly = (eTeam==kPlayer.getTeam());

			int iLoop;
			for(CvUnit* pLoopUnit = kPlayer.firstUnit(&iLoop); pLoopUnit != NULL; pLoopUnit = kPlayer.nextUnit(&iLoop))
			{
				if(!pLoopUnit->IsCombatUnit())
					continue;

				bool bUnitMayBeRelevant = (pLoopUnit->getDomainType() == DOMAIN_AIR ||
						pLoopUnit->isRanged() || //ranged power is cross-domain!
						(pLoopUnit->getDomainType() == DOMAIN_LAND && !pZone->IsWater()) ||
						((pLoopUnit->getDomainType() == DOMAIN_SEA || (pLoopUnit->isEmbarked() && pClosestCity) && pZone->IsWater())));
						//embarked melee still count in water zone if there's a city to attack/defend

				if (!bUnitMayBeRelevant)
					continue;

				CvPlot* pPlot = pLoopUnit->plot();
				if(!pPlot)
					continue;

				//a little cheating for AI - invisible units still count with reduced strength
				bool bVisible = pPlot->isVisible(eTeam) || pPlot->isAdjacentVisible(eTeam, false);
				bool bZoneTypeMismatch = (pLoopUnit->getDomainType() == DOMAIN_LAND && pZone->IsWater()) || (pLoopUnit->getDomainType() == DOMAIN_SEA && !pZone->IsWater());

				//embarked units and crossdomain count only partially
				bool bReducedStrength = pLoopUnit->isEmbarked() || bZoneTypeMismatch;

				//if there is a city, units in adjacent zones can also count
				int iDistance = 0;
				if (pClosestCity)
				{
					iDistance = plotDistance(pLoopUnit->getX(), pLoopUnit->getY(), pClosestCity->getX(), pClosestCity->getY());
					if (iDistance > m_iTacticalRange)
						continue;
					else if (iDistance > (m_iTacticalRange / 2))
					{
						if (bZoneTypeMismatch)
							continue;
						else
							bReducedStrength = true;
					}
					else
					{
						//if on another continent, they can't easily take part in the fight
						if (!pClosestCity->isMatchingArea(pLoopUnit->plot()))
							bReducedStrength = true;
					}
				}
				else
				{
					//if there is no city, the unit must be in the zone itself
					if ( GetCell(pLoopUnit->plot()->GetPlotIndex())->GetDominanceZone() != pZone->GetDominanceZoneID() )
						continue;
				}

				int iMultiplier = m_iTacticalRange + MIN(3 - iDistance, 0);  // 3 because action may still be spread out over the zone
				if(iMultiplier > 0)
				{
					int iUnitStrength = pLoopUnit->GetBaseCombatStrengthConsideringDamage();

					//unit might disembark ... so don't count it for water zone, but for adjacent land
					if(iUnitStrength == 0 && pLoopUnit->isEmbarked() && !pZone->IsWater())
						iUnitStrength = pLoopUnit->GetBaseCombatStrength();

					int iRangedStrength = pLoopUnit->GetMaxRangedCombatStrength(NULL, /*pCity*/ NULL, true, true) / 100;

					if(!bVisible || bReducedStrength)
					{
						iUnitStrength /= 2;
						iRangedStrength /= 2;
					}

					if (bEnemy)
					{
#if defined(MOD_BALANCE_CORE_MILITARY_LOGGING)
						//CvString msg;
						//msg.Format("Zone %d, Enemy %s %d with %d hp at %d,%d - distance %d, strength %d, ranged strength %d (total %d)",
						//	pZone->GetDominanceZoneID(), pLoopUnit->getName().c_str(), pLoopUnit->GetID(), pLoopUnit->GetCurrHitPoints(),
						//	pLoopUnit->getX(), pLoopUnit->getY(),	iDistance, iUnitStrength, iRangedStrength, pZone->GetOverallEnemyStrength());
						//GET_PLAYER(m_ePlayer).GetTacticalAI()->LogTacticalMessage(msg, true /*bSkipLogDominanceZone*/);
#endif

						if (pLoopUnit->getDomainType() == DOMAIN_SEA)
						{
							pZone->AddEnemyNavalStrength(iUnitStrength*iMultiplier*m_iUnitStrengthMultiplier);
							pZone->AddEnemyNavalRangedStrength(iRangedStrength*iMultiplier*m_iUnitStrengthMultiplier);
							pZone->AddEnemyNavalUnitCount(1);
						}
						else
						{
							pZone->AddEnemyMeleeStrength(iUnitStrength*iMultiplier*m_iUnitStrengthMultiplier);
							pZone->AddEnemyRangedStrength(iRangedStrength*iMultiplier*m_iUnitStrengthMultiplier);
							pZone->AddEnemyUnitCount(1);
						}

						//again only for enemies
						if(pZone->GetRangeClosestEnemyUnit()<0 || iDistance<pZone->GetRangeClosestEnemyUnit())
							pZone->SetRangeClosestEnemyUnit(iDistance);
					}
					else if (bFriendly)
					{

#if defined(MOD_BALANCE_CORE_MILITARY_LOGGING)
						//CvString msg;
						//msg.Format("Zone %d, Friendly %s %d with %d hp at %d,%d - distance %d, strength %d, ranged strength %d (total %d)",
						//	pZone->GetDominanceZoneID(), pLoopUnit->getName().c_str(), pLoopUnit->GetID(), pLoopUnit->GetCurrHitPoints(),
						//	pLoopUnit->getX(), pLoopUnit->getY(), iDistance, iUnitStrength, iRangedStrength, pZone->GetOverallFriendlyStrength());
						//GET_PLAYER(m_ePlayer).GetTacticalAI()->LogTacticalMessage(msg, true /*bSkipLogDominanceZone*/);
#endif

						if (pLoopUnit->getDomainType() == DOMAIN_SEA)
						{
							pZone->AddFriendlyNavalStrength(iUnitStrength*iMultiplier*m_iUnitStrengthMultiplier);
							pZone->AddFriendlyNavalRangedStrength(iRangedStrength*iMultiplier*m_iUnitStrengthMultiplier);
							pZone->AddFriendlyNavalUnitCount(1);
						}
						else
						{
							pZone->AddFriendlyMeleeStrength(iUnitStrength*iMultiplier*m_iUnitStrengthMultiplier);
							pZone->AddFriendlyRangedStrength(iRangedStrength*iMultiplier*m_iUnitStrengthMultiplier);
							pZone->AddFriendlyUnitCount(1);
						}
					}
					else
					{
						//neutral has only very few stats
						pZone->AddNeutralStrength(iUnitStrength*iMultiplier*m_iUnitStrengthMultiplier);
						pZone->AddNeutralUnitCount(1);
					}
				}
			}
		}
	}
}