/// Remove a unit from the army
bool CvArmyAI::RemoveUnit(int iUnitToRemoveID)
{
	for(int iI = 0; iI < (int)m_FormationEntries.size(); iI++)
	{
		CvArmyFormationSlot slot = m_FormationEntries[iI];
		if(slot.GetUnitID() == iUnitToRemoveID)
		{
			UnitHandle pThisUnit = GET_PLAYER(GetOwner()).getUnit(iUnitToRemoveID);
			if(pThisUnit)
			{
				// Clears unit's army ID and erase from formation entries
				pThisUnit->setArmyID(-1);
				pThisUnit->AI_setUnitAIType(pThisUnit->getUnitInfo().GetDefaultUnitAIType());
				m_FormationEntries[iI].SetUnitID(ARMYSLOT_NO_UNIT);

				// Tell the associate operation that a unit was lost
				CvAIOperation* pThisOperation = GET_PLAYER(GetOwner()).getAIOperation(m_iOperationID);
				if(pThisOperation)
				{
					pThisOperation->UnitWasRemoved(GetID(), iI);
				}

				return true;
			}
		}
	}

	return false;
}
/// Delete the army
void CvArmyAI::Kill()
{
	CvAssert(GetOwner() != NO_PLAYER);
	CvAssertMsg(GetID() != -1, "GetID() is not expected to be equal with -1");

	int iUnitID;
	iUnitID = GetFirstUnitID();

	while(iUnitID != ARMYSLOT_NO_UNIT)
	{
		UnitHandle pThisUnit = GET_PLAYER(GetOwner()).getUnit(iUnitID);
		if(pThisUnit)
		{
			pThisUnit->setArmyID(-1);
#if defined(MOD_BALANCE_CORE)
			pThisUnit->AI_setUnitAIType(pThisUnit->getUnitInfo().GetDefaultUnitAIType());
#endif
		}
		iUnitID = GetNextUnitID();
	}

	m_FormationEntries.clear();

	CvAIOperation* pOperation = GET_PLAYER(GetOwner()).getAIOperation(m_iOperationID);
	if (pOperation)
		pOperation->DeleteArmyAI(m_iID);

	GET_PLAYER(GetOwner()).deleteArmyAI(m_iID);
}
/// Add a unit to our army (and we know which slot)
void CvArmyAI::AddUnit(int iUnitID, int iSlotNum)
{
	CvAssertMsg(iUnitID != ARMYSLOT_NO_UNIT,"Expect unit to be non-NULL");

	CvPlayer& thisPlayer = GET_PLAYER(m_eOwner);
	UnitHandle pThisUnit = thisPlayer.getUnit(iUnitID);

	// remove this unit from an army if it is already in one
	thisPlayer.removeFromArmy(pThisUnit->getArmyID(), GetID());

	m_FormationEntries[iSlotNum].SetUnitID(iUnitID);
	pThisUnit->setArmyID(GetID());

#if defined(MOD_BALANCE_CORE)
	//just for avoiding confusion
	pThisUnit->setTacticalMove(NO_TACTICAL_MOVE);
#endif

	// Finally, compute when we think this unit will arrive at the next checkpoint
	CvPlot* pMusterPlot = GC.getMap().plot(GetX(), GetY());
	if(pMusterPlot)
	{
		int iFlags = CvUnit::MOVEFLAG_APPROXIMATE_TARGET | CvUnit::MOVEFLAG_IGNORE_STACKING | CvUnit::MOVEFLAG_IGNORE_ZOC;
		int iTurnsToReachCheckpoint = pThisUnit->TurnsToReachTarget(pMusterPlot, iFlags, GC.getAI_OPERATIONAL_MAX_RECRUIT_TURNS_ENEMY_TERRITORY());
		if(iTurnsToReachCheckpoint < MAX_INT)
		{
			SetEstimatedTurn(iSlotNum, iTurnsToReachCheckpoint);
		}
	}
}
/// Remove a unit from the army
bool CvArmyAI::RemoveUnit(int iUnitToRemoveID)
{
	bool bWasOneOrMoreRemoved = false;
	CvArmyFormationSlot slot;

	for(int iI = 0; iI < (int)m_FormationEntries.size(); iI++)
	{
		slot = m_FormationEntries[iI];
		if(slot.GetUnitID() == iUnitToRemoveID)
		{
			UnitHandle pThisUnit = GET_PLAYER(GetOwner()).getUnit(iUnitToRemoveID);
			if(pThisUnit)
			{
				// Clears unit's army ID and erase from formation entries
				pThisUnit->setArmyID(FFreeList::INVALID_INDEX);
				m_FormationEntries[iI].SetUnitID(ARMY_NO_UNIT);
				bWasOneOrMoreRemoved = true;

				// Tell the associate operation that a unit was lost
				CvAIOperation* pThisOperation = GET_PLAYER(GetOwner()).getAIOperation(m_iOperationID);
				if(pThisOperation)
				{
					pThisOperation->UnitWasRemoved(GetID(), iI);
				}
			}
		}
	}

	return bWasOneOrMoreRemoved;
}
/// Remove a unit from the army
bool CvArmyAI::RemoveUnit(int iUnitToRemoveID)
{
	bool bWasOneOrMoreRemoved = false;
	CvArmyFormationSlot slot;

	for(int iI = 0; iI < (int)m_FormationEntries.size(); iI++)
	{
		slot = m_FormationEntries[iI];
		if(slot.GetUnitID() == iUnitToRemoveID)
		{
			UnitHandle pThisUnit = GET_PLAYER(GetOwner()).getUnit(iUnitToRemoveID);
			if(pThisUnit)
			{
				// Clears unit's army ID and erase from formation entries
				pThisUnit->setArmyID(-1);
#if defined(MOD_BALANCE_CORE)
				pThisUnit->AI_setUnitAIType(pThisUnit->getUnitInfo().GetDefaultUnitAIType());
#endif
				m_FormationEntries[iI].SetUnitID(ARMY_NO_UNIT);
				bWasOneOrMoreRemoved = true;

				// Tell the associate operation that a unit was lost
				CvAIOperation* pThisOperation = GET_PLAYER(GetOwner()).getAIOperation(m_iOperationID);
				if(pThisOperation)
				{
					pThisOperation->UnitWasRemoved(GetID(), iI);
				}
			}
		}
	}

	return bWasOneOrMoreRemoved;
}
/// Delete the army
void CvArmyAI::Kill()
{
	CvAssert(GetOwner() != NO_PLAYER);
	CvAssertMsg(GetID() != FFreeList::INVALID_INDEX, "GetID() is not expected to be equal with FFreeList::INVALID_INDEX");

	int iUnitID;
	iUnitID = GetFirstUnitID();

	while(iUnitID != ARMY_NO_UNIT)
	{
		UnitHandle pThisUnit = GET_PLAYER(GetOwner()).getUnit(iUnitID);
		if(pThisUnit)
		{
			pThisUnit->setArmyID(FFreeList::INVALID_INDEX);
		}
		iUnitID = GetNextUnitID();
	}

	m_FormationEntries.clear();
}
/// Add a unit to our army (and we know which slot)
void CvArmyAI::AddUnit(int iUnitID, int iSlotNum)
{
	CvAssertMsg(iUnitID != ARMY_NO_UNIT,"Expect unit to be non-NULL");

	CvPlayer& thisPlayer = GET_PLAYER(m_eOwner);
	UnitHandle pThisUnit = thisPlayer.getUnit(iUnitID);

	// remove this unit from an army if it is already in one
	thisPlayer.removeFromArmy(pThisUnit->getArmyID(), GetID());

	m_FormationEntries[iSlotNum].SetUnitID(iUnitID);
	pThisUnit->setArmyID(GetID());

	// Finally, compute when we think this unit will arrive at the next checkpoint
	CvPlot* pMusterPlot = GC.getMap().plot(GetX(), GetY());
	if(pMusterPlot)
	{
		int iTurnsToReachCheckpoint = TurnsToReachTarget(pThisUnit, pMusterPlot, true /*bReusePaths*/, true, true);
		if(iTurnsToReachCheckpoint < MAX_INT)
		{
			SetEstimatedTurn(iSlotNum, iTurnsToReachCheckpoint);
		}
	}
}