#include "stdafx.h"

#include "module2.h"
/////////////////////////////////////////////////////////////////////////
struct MapCell **ppMap;	// массив карты лабиринта
int vMaxN;				// база с наибольшим номером в массиве
struct Base1 *pBase;	// массив баз
int vSizeArray;			// размер массива баз
int vWm;				// размер карты лабиринта
int vHm;				//
int vBaseN;				// кол-во баз на карте
/////////////////////////////////////////////////////////////////////////
// Инициализация карты лабиринта
void fMapInitialization (int _Wm, int _Hm)
{
	if (_Wm <= 0 || _Hm <= 0)
		return;

	if (ppMap)
	{
		for (int vvi=0;vvi<vWm;vvi++)
		{
			delete (void*)*((int*)&ppMap[vvi]);
		}
		delete ppMap;
		ppMap = NULL;
	}

	vWm = 0;
	vHm = 0;

	vWm = _Wm;
	vHm = _Hm;

	// создаем массив для карты лабиринта
	ppMap = new struct MapCell*[vWm];
	for (int vvi=0;vvi<vWm;vvi++)
	{
		ppMap[vvi] = new struct MapCell[vHm];
	}
	fNewMap(ppMap,vWm,vHm);		// создаем новую карту
}
// Создаем карту лабиринта
void fCreateMap ()
{
	// алгоритм

	if (!ppMap)
		return;

	fNewMap(ppMap,vWm,vHm);		// создаем новую карту

	fCreateBase2(ppMap,vWm,vHm);	// создаем базу вампа
	fCreateBase3(ppMap,vWm,vHm);	// создаем денс пул
	fCreateBase4(ppMap,vWm,vHm);	// создаем слаерку

	vBaseN = 0;			// обнуляем кол-во баз
	// запускаем цикл создания баз
	for (int vvi=0;vvi<vSizeArray;vvi++)
	{
		if (vvi > vMaxN)
			break;

		pBase[vvi].NumBase = -1;
		
		if (pBase[vvi].Id >= 0)
		if (fCreateBase1(ppMap,vWm,vHm,pBase[vvi],vBaseN) == 1)
		{
			pBase[vvi].NumBase = vBaseN;
			vBaseN++;
		}
	}

	fRetouchingMap(ppMap,vWm,vHm);	// очищаем карту от незанятых клеток
	fDelTails(ppMap,vWm,vHm);			// очищамем хвостики на карте длинной в 1 клетку
	fEditBases(ppMap,vWm,vHm);	// редактируем базы
	fCheckStubs(ppMap,vWm,vHm);			// проверяем уровень тупиков
	fCreateWaterOnMap(ppMap,vWm,vHm,2);	// создаем воду на карте
	fCreateTreesPerimeterMap(ppMap,vWm,vHm);// создать деревья по периметру карты
}
// Удалить базу
void fDelBase(int _Id)
{
	int vN;

	if (vSizeArray == 0)
		return;
	vN = 0;
	for (int vvi=0;vvi<=vMaxN;vvi++)
	{
		if (pBase[vvi].Id == _Id)
		{
			for (int vvj=0;vvj<sizeof(pBase[vvi]);vvj++)
				*((char*)&pBase[vvi]+vvj) = NULL;
			pBase[vvi].Id = -1;
			vN = vvi;
			break;
		}
	}
	if (vMaxN == vN && vMaxN != 0)
		vMaxN--;
}

// Взять базу
void fGetBase(Base1 &_Base, int _Id)
{
	if (vSizeArray == 0)
		return;
	for (int vvi=0;vvi<=vMaxN;vvi++)
	{
		if (pBase[vvi].Id == _Id)
		{
			_Base = pBase[vvi];
			break;
		}
	}
}
// Взять лист идентификаторов
void fGetListIdOfBases(int *&pListId, int &_N)
{
	if (!pListId)
		return;
	if (vSizeArray == 0)
		return;
	_N = 0;
	for (int vvi=0;vvi<=vMaxN;vvi++)
	{
		if (pBase[vvi].Id >= 0)
		{
			pListId[_N] = pBase[vvi].Id;
			_N++;
		}
	}
}

// Редактировать базу в массиве
void fEditBase (Base1 _Base)
{
	if (vSizeArray == 0)
		return;
	for (int vvi=0;vvi<=vMaxN;vvi++)
	{
		if (pBase[vvi].Id == _Base.Id)
		{
			pBase[vvi] = _Base;
			break;
		}
	}
}

// Добавить базу в массив
void fAddBase (Base1 &_Base)
{
	int vN;

	if (vSizeArray == vMaxN)
	{
		fIncreaseSizeArray(SIZE_ARRAY);
	}
	vN = 0;
	for (int vvi=0;vvi<=vMaxN+1;vvi++)
	{
		if (pBase[vvi].Id < 0)
		{
			_Base.Id = vvi;
			pBase[vvi] = _Base;
			vN = vvi;
			break;
		}
	}
	if (vN > vMaxN)
		vMaxN = vN;
}

// Заменить базу в массиве
void fReplaceBase (Base1 &_Base)
{
	if (vSizeArray == vMaxN)
	{
		fIncreaseSizeArray(SIZE_ARRAY);
	}
	pBase[_Base.Id] = _Base;
	if (_Base.Id > vMaxN)
		vMaxN = _Base.Id;
}

// Увеличить размер массива
void fIncreaseSizeArray(int _Size)
{
	int vPreviousSizeArray;
	struct Base1 *pTemp;
	if (vSizeArray < 0) vSizeArray = 0;
	if (vSizeArray > 0)
	{
		pTemp = new struct Base1[vSizeArray];
		for (int vvi=0;vvi<vSizeArray;vvi++)
		{
			pTemp[vvi] = pBase[vvi];
			delete &pBase[vvi];
		}
	}
	delete pBase;
	pBase = NULL;
	vPreviousSizeArray = vSizeArray;
	vSizeArray += _Size;
	pBase = new struct Base1[vSizeArray];
	if (vPreviousSizeArray > 0)
	{
		for (int vvi=0;vvi<vPreviousSizeArray;vvi++)
			pBase[vvi] = pTemp[vvi];
	}
	for (int vvi=0;vvi<vSizeArray;vvi++)
		pBase[vvi].Id = -1;
}

// Cоздаем лабиринт методом Прима
void fGeneratePrim(MapCell **Massive, int Wm, int Hm) 
{
int x;
int y;
int Count;
//int Size = 35;  // размер лабиринта
//int Cell = 15;   // размер ячейки
//int delay; // задержка для анимации
//MapCell **Map;  // массив карты лабиринта
//int MaxPeaks; // максимальное количество вершин

Count = 0;
for (int c=0;c<Wm;c++)
{
	for (int v=0;v<Hm;v++)
	{
		if(Massive[c][v].Attribute == OUTSIDE)
		{
			x = c;
			y = v;
			Count++;
		}
	}
}
if (Count == 0)
	return;
if (Count > 5)
if (Wm != NULL && Hm != NULL)
{
	//srand (time(NULL));	// полный рандом
	do
	{
		x = rand()%Wm;
		y = rand()%Hm;
	}
	while (!(Massive[x][y].Attribute == OUTSIDE));
}
else
	return;
Massive[x][y].Attribute = INSIDE;
if ((x-1)>=0 && Massive[x-1][y].Attribute == OUTSIDE) Massive[x-1][y].Attribute = BORDER;
if ((x+1)<Wm && Massive[x+1][y].Attribute == OUTSIDE) Massive[x+1][y].Attribute = BORDER;
if ((y-1)>=0 && Massive[x][y-1].Attribute == OUTSIDE) Massive[x][y-1].Attribute = BORDER;
if ((y+1)<Hm && Massive[x][y+1].Attribute == OUTSIDE) Massive[x][y+1].Attribute = BORDER;
// список ячеек с параметром Border
TPoint *mas;
mas = new TPoint[Wm*Hm];
int Bordcount; // курсор в массиве
do {   // повторяем пока есть хотя бы одна клетка Border
Bordcount = 0; // очистка счетчика
// просматриваем массив ищем все клетки с атрибутом Border
for (int c=0; c<Wm; c++)
 for (int v=0; v<Hm; v++)
  if (Massive[c][v].Attribute == BORDER)
    {mas[Bordcount].x = c;
     mas[Bordcount].y = v;
     Bordcount++;
    };
// список соседей с атрибутом Inside
TPoint Ins[4];
int count = 0; // счетчик
// Выберем случайную клетку, атрибут которой равен Border, и присвоим ей Inside
int buf;
if (Bordcount != NULL) buf = rand()%Bordcount;
else
	break;
x = mas[buf].x;
y = mas[buf].y;
Massive[x][y].Attribute = INSIDE;
// Изменим на Border атрибут всех соседних с текущей клеток, атрибут которых                        
// равен Outside
if ((x-1)>=0)
 if (Massive[x-1][y].Attribute == OUTSIDE)
	 Massive[x-1][y].Attribute = BORDER;
 else
 if (Massive[x-1][y].Attribute == INSIDE)
      {Ins[count].x = x-1;
       Ins[count].y = y;
       count++;
      };

if ((x+1)<Wm)
 if (Massive[x+1][y].Attribute == OUTSIDE) Massive[x+1][y].Attribute = BORDER; else
 if (Massive[x+1][y].Attribute == INSIDE)
      {Ins[count].x = x+1;
       Ins[count].y = y;
       count++;
      };

if ((y-1)>=0)
 if (Massive[x][y-1].Attribute == OUTSIDE) Massive[x][y-1].Attribute = BORDER; else
 if (Massive[x][y-1].Attribute == INSIDE)
      {Ins[count].x = x;
       Ins[count].y = y-1;
       count++;
      };

if ((y+1)<Hm)
 if (Massive[x][y+1].Attribute == OUTSIDE) Massive[x][y+1].Attribute = BORDER; else
 if (Massive[x][y+1].Attribute == INSIDE)
      {Ins[count].x = x;
       Ins[count].y = y+1;
       count++;
      };
// теперь из полученного массива выберем случайную и сломаем стену
// между текущей и ей
// X и Y до сих пор содержат текущие координаты
if (count != NULL) buf = rand()%count;
else buf = 0;

if ((Ins[buf].x > x) & (Ins[buf].y == y))
    { Massive[Ins[buf].x][Ins[buf].y].Left = true;
      Massive[x][y].Right = true;
    } else
if ((Ins[buf].x < x) && (Ins[buf].y == y))
    { Massive[Ins[buf].x][Ins[buf].y].Right = true;
      Massive[x][y].Left = true;
    }else
if ((Ins[buf].x == x) && (Ins[buf].y > y))
    { Massive[Ins[buf].x][Ins[buf].y].Up = true;
      Massive[x][y].Down = true;
    }else
if ((Ins[buf].x == x) && (Ins[buf].y < y))
    { Massive[Ins[buf].x][Ins[buf].y].Down = true;
      Massive[x][y].Up = true;
    };
} while (Bordcount > 0);
delete [] mas;
}
// Создаем воду на карте
void fCreateWaterOnMap(MapCell **Massive, int Wm, int Hm, int _N)
{
	int vShoalN;
	int _c;
	int _v;
	int _c2;
	int _v2;
	int vNumBase;
	int vFlag;
	int vFlag2;
	int vFlag3;
	int vCount;
	int vCount2;
	int vMinCellN;
	int vCellN;
	int vStep;
	int vNumPeak;

	vCount = 0;
	vShoalN = 0;
	do
	{
		vFlag = 0;
		vNumBase = -1;
		_c = rand()%Wm;
		_v = rand()%Hm;
		// SHOAL
		if((Massive[_c][_v].Attribute == OUTSIDE ||
			Massive[_c][_v].Attribute == INSIDE ||
			Massive[_c][_v].Attribute == BORDER ||
			Massive[_c][_v].Attribute == LANDSCAPE) &&
			fCheckBloodAroundCell(Massive,Wm,Hm,_c,_v) == 0 &&
			fCheckBaseLevelNearToShoal(Massive,Wm,Hm,_c,_v) == 1 &&
			fCheckWallAroundCell(Massive,Wm,Hm,_c,_v) == 0)
		{
			for (int vvi=-2;vvi<=2;vvi++)
			{
				for (int vvj=-2;vvj<=2;vvj++)
				{
					if (vvi != 0 && vvj != 0)
					{
						_c2 = _c + vvi;
						_v2 = _v + vvi;
						if (_c2 >= 0 && _v2 >= 0 && _c2 < Wm && _v2 < Hm)
						if (Massive[_c2][_v2].Attribute == BASEHUMAN)
						{
							if (vNumBase == -1)
							{
								vNumBase = Massive[_c2][_v2].NumBase;
							}
							else
							{
								if (vNumBase != Massive[_c2][_v2].NumBase)
								{
									vFlag = 1;
									break;
								}
							}
						}
					}
				}
			}
		}
		if (vFlag == 1)
		{
			for (int c=0; c<Wm; c++)
			{
				for (int v=0; v<Hm; v++)
				{
					Massive[c][v].Fill = 0;
				}
			}
			Massive[_c][_v].Fill = SHOAL_FILL;
			//Massive[_c][_v].LevelUpland = -1;
			vCellN = 1;
			vFlag3 = 0;
			vMinCellN = 3 + rand()%2;
			vCount2 = 0;
			do
			{
				_c2 = _c - 1 + rand()%3;
				_v2 = _v - 1 + rand()%3;
				if (_c2 >= 0 && _v2 >= 0 && _c2 < Wm && _v2 < Hm)
				if ((Massive[_c2][_v2].Attribute == OUTSIDE ||
					Massive[_c2][_v2].Attribute == INSIDE ||
					Massive[_c2][_v2].Attribute == BORDER ||
					Massive[_c2][_v2].Attribute == LANDSCAPE) &&
					Massive[_c2][_v2].Fill != SHOAL_FILL)
				{
					vFlag2 = 0;
					if (_c2 > 0)
					if (Massive[_c2][_v2].Left == true &&
						Massive[_c2-1][_v2].Fill == SHOAL_FILL && vFlag2 == 0)
						vFlag2 = 1;
					if (_v2 > 0)
					if (Massive[_c2][_v2].Up == true &&
						Massive[_c2][_v2-1].Fill == SHOAL_FILL && vFlag2 == 0)
						vFlag2 = 1;
					if (_c2 < Wm - 1)
					if (Massive[_c2][_v2].Right == true &&
						Massive[_c2+1][_v2].Fill == SHOAL_FILL && vFlag2 == 0)
						vFlag2 = 1;
					if (_v2 < Hm - 1)
					if (Massive[_c2][_v2].Down == true &&
						Massive[_c2][_v2+1].Fill == SHOAL_FILL && vFlag2 == 0)
						vFlag2 = 1;
					if (vFlag2 == 1)
					{
						if (fCheckBaseLevelNearToShoal(Massive,Wm,Hm,_c2,_v2) == 1)
						{
							if (fCheckWallAroundCell(Massive,Wm,Hm,_c2,_v2) == 0 &&
								fCheckBloodAroundCell(Massive,Wm,Hm,_c2,_v2) == 0)
							{
								Massive[_c2][_v2].Fill = SHOAL_FILL;
								vCellN++;
							}
						}
					}
					if (vCellN == vMinCellN)
					{
						// создаем клетки перехода в воде
						fCreateCellPassInWater(Massive,Wm,Hm,_c2,_v2);
						// проставляем бордюры вокруг воды
						fLetIsPutBordersRoundWater(Massive,Wm,Hm);
						// проверим карту на закрытые клетки
						if (fCheckMapOnTheClosedCells(Massive,Wm,Hm,Wm/2,Hm/2) == 0)
						{
							// очищаем карту от незанятых клеток
							fRetouchingMap(Massive,Wm,Hm);
							break;
						}
						vFlag3 = 1;
						vShoalN++;
					}
				}
				if (vCount2 == 1000) break;
				vCount2++;
			}
			while (vFlag3 != 1);
		}
		if (vFlag3 == 1)
		{
			for (int c=0; c<Wm; c++)
			{
				for (int v=0; v<Hm; v++)
				{
					if (Massive[c][v].Fill == SHOAL_FILL)
					{
						Massive[c][v].Attribute = SHOAL;
						Massive[c][v].LevelUpland = -1;
					}
				}
			}
		}
		if (vCount == 1000) break;
		vCount++;
	}
	while(vShoalN < _N);
}
// Проверим уровень баз рядом с мелководьем
int fCheckBaseLevelNearToShoal (MapCell **Massive, int Wm, int Hm, int _c1, int _v1)
{
	int _c2;
	int _v2;
	int vFlag;
	vFlag = 0;
	for (int vvi=-1;vvi<=1;vvi++)
	{
		for (int vvj=-1;vvj<=1;vvj++)
		{
			if (!(vvi == 0 && vvj == 0))
			{
				_c2 = _c1 + vvi;
				_v2 = _v1 + vvj;
				if (_c2 >= 0 && _v2 >= 0 && _c2 < Wm && _v2 < Hm)
				{
					if (Massive[_c2][_v2].Attribute == BASEHUMAN &&
						(Massive[_c2][_v2].LevelUpland > 2 ||
						Massive[_c2][_v2].LevelUpland < 0))
					{
						vFlag = 1;
						break;
					}
				}
			}
		}
		if (vFlag == 1) break;
	}
	if (vFlag == 1)
		return 0;
	return 1;
}
// Определяем тупики
void fDefinedStubs(MapCell **Massive, int Wm, int Hm)
{
	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			Massive[c][v].Deadlock = false;
			if(Massive[c][v].Attribute == INSIDE)
			{
				if(fNumberOutputsInTheCell(Massive,Wm,Hm,c,v) == 1)
				{
					Massive[c][v].Deadlock = true;
				}
			}


		}
	}
}

// Создаем базу хумана
int fCreateBase1(MapCell **Massive, int Wm, int Hm, Base1 _Base, int _NumBase)
{
	int w1;
	int h1;
	int w2;
	int h2;
	bool Open;
	int Type;
	int SizeBase;
	int Allowance;
	int PosDistr;
	int OppositeSide;

	int _c;
	int _v;
	int _c1;
	int _v1;
	int _c2;
	int _v2;

	int vWidth;
	int vHeight;

	int vRw;
	int vRh;
	int vR;

	int vCount;
	int vSizeNewBase;
	int vFlag;
	int vFlag2;
	
	COLORREF vColor;
	int vColorN;

	if (_Base.Id < 0)
		return 0;

	if(_NumBase >= 0)
	{
		vColorN = rand()%7;
		if (vColorN == 0) vColor = 0x0000ff;	// красный
		if (vColorN == 1) vColor = 0x77ff77;	// салатовый
		if (vColorN == 2) vColor = 0xccccc5;	// серый
		if (vColorN == 3) vColor = 0x00ffff;	// желтый
		if (vColorN == 4) vColor = 0xffcc77;	// голубой
		if (vColorN == 5) vColor = 0xff00ff;	// розовый
		if (vColorN == 6) vColor = 0x00ff00;	// зеленый
		if (vColorN == 7) vColor = 0xff00ff;	// фиолетовый
		if (vColorN == 8) vColor = 0x7777ff;	// оранжевый
	}

	Open = _Base.Open;
	Type = _Base.Type;
	w1 = _Base.Location.left;
	h1 = _Base.Location.top;
	w2 = _Base.Location.right;
	h2 = _Base.Location.bottom;
	SizeBase = _Base.Size;
	Allowance = _Base.Allowance;
	PosDistr = _Base.PosDistr;
	_c2 = _Base._c2;
	_v2 = _Base._v2;

	if (Type != 1 && Type != 2)
		return 0;

	if (SizeBase < 0 || Allowance < 0)
		return 0;

	if (w1<0 || h1<0)
		return 0;

	if (w1 > w2 || h1 > h2)
		return 0;

	if (w2>=Wm) w2 = Wm-1;
	if (h2>=Hm) h2 = Hm-1;

	vWidth = w2 - w1;
	vHeight = h2 - h1;
	if (vWidth<0 || vHeight<0)
		return 0;

	vCount = 0;

m1:;
	vFlag = 0;
	vFlag2 = 0;
	if (Open == false)
	{
		if (PosDistr == POS_LEFT) OppositeSide = POS_RIGHT;
		if (PosDistr == POS_RIGHT) OppositeSide = POS_LEFT;
		if (PosDistr == POS_UP) OppositeSide = POS_DOWN;
		if (PosDistr == POS_DOWN) OppositeSide = POS_UP;
		if (PosDistr == POS_LEFTUP) OppositeSide = POS_RIGHTDOWN;
		if (PosDistr == POS_RIGHTDOWN) OppositeSide = POS_LEFTUP;
		if (PosDistr == POS_RIGHTUP) OppositeSide = POS_LEFTDOWN;
		if (PosDistr == POS_LEFTDOWN) OppositeSide = POS_RIGHTUP;
		if (PosDistr == POS_CENTER) OppositeSide = POS_CENTER;
		vFlag = 1;
	}
	else
		OppositeSide = -1;

m2:;
	if (PosDistr == POS_UP || PosDistr == POS_CENTER  || PosDistr == POS_DOWN)
		vRw = vWidth/2;
	if (PosDistr == POS_LEFT || PosDistr == POS_CENTER || PosDistr == POS_RIGHT)
		vRh = vHeight/2;
	if (PosDistr == POS_LEFTUP || PosDistr == POS_LEFT || PosDistr == POS_LEFTDOWN)
		vRw = 0;
	if (PosDistr == POS_LEFTUP || PosDistr == POS_UP || PosDistr == POS_RIGHTUP)
		vRh = 0;
	if (PosDistr == POS_RIGHTUP || PosDistr == POS_RIGHT || PosDistr == POS_RIGHTDOWN)
		vRw = vWidth;
	if (PosDistr == POS_LEFTDOWN || PosDistr == POS_DOWN || PosDistr == POS_RIGHTDOWN)
		vRh = vHeight;
	if (vWidth > vHeight)
		vR = vWidth;
	else
		vR = vHeight;
	if (Open == true && vFlag == 1) vR = 1;
m3:;
	fClearMap(Massive,Wm,Hm);
	if (Type == 1)
		// создаем лабиринт рекурсивным методом с возвратом
		fRecursiveBacktracking(Massive,Wm,Hm); 
	else
		fGeneratePrim(Massive,Wm,Hm); // создаем лабиринт методом Прима
	fDefinedStubs(Massive,Wm,Hm); // определяем все тупики
	fAddNotDatausaBorder(Massive,Wm,Hm); // проставим все недостающие границы
	// ищим тупики
	for (int r=0,rw=0,rh=0;r<vR;r++)
	{
		if (r <= vWidth) rw = r;
		if (r <= vHeight) rh = r;
		if (vFlag == 1)
		{
			if (PosDistr == POS_LEFTUP || PosDistr == POS_LEFT || PosDistr == POS_LEFTDOWN ||
				PosDistr == POS_RIGHTUP || PosDistr == POS_RIGHT || PosDistr == POS_RIGHTDOWN)
				rw = 0;
			if (PosDistr == POS_LEFTUP || PosDistr == POS_UP || PosDistr == POS_RIGHTUP ||
				PosDistr == POS_LEFTDOWN || PosDistr == POS_DOWN || PosDistr == POS_RIGHTDOWN)
				rh = 0;
		}
		for (int c=w1+vRw-rw;c<=w1+vRw+rw;c++)
		{
			for(int v=h1+vRh-rh;v<=h1+vRh+rh;v++)
			{
				if (c<=w1+vRw-rw || c>=w1+vRw+rw || v<=h1+vRh-rh || v>=h1+vRh+rh)
				{
					if (c >= 0 && c < Wm && v >= 0 && v < Hm)
					if (fFiendBase(Massive,Wm,Hm,c,v,SizeBase,Allowance,Open) == 1)
					{
						if(fCheckRegionBase(Massive,Wm,Hm,w1,h1,w2,h2) == 1 &&
							fCheckCorridors(Massive,Wm,Hm,w1,h1,w2,h2) == 1)
						{
							if (vFlag == 1 && fCreateTelportBase(Massive,Wm,Hm) == 1 ||
								vFlag == 0)
							{
								// определяем клетки базы
								fDefineCellsBase1(Massive,Wm,Hm,_c,_v,_NumBase,vColor);
								// очищаем карту от незанятых клеток
								fRetouchingMap(Massive,Wm,Hm);
								if (Open == true)
								{
									if (vFlag == 1)
										fDefineTeleports(Massive,Wm,Hm);
									vFlag2 = 1;
									break;
								}
								if (Open == false && OppositeSide >= 0)
								{
									SizeBase = 8;
									Allowance = 4;
									Open = true;
									break;
								}
							}
						}
					}
				}
			}
			if (Open == true && OppositeSide >= 0 || vFlag2 == 1) break;
		}
		if (Open == true && OppositeSide >= 0 || vFlag2 == 1) break;
	}
	//
	if (vFlag2 == 1)
	{
		if (fCheckMapOnTheClosedCells(Massive,Wm,Hm,Wm/2,Hm/2) == 1 &&
			_c>=0 && _v>=0 && _c<Wm && _v<Hm)
		{
			// создаем заглушку
			fCreateStub(Massive,Wm,Hm,_c,_v,_c1,_v1);
			if (_c1>=0 && _v1>=0 && _c1<Wm && _v1<Hm &&
				_c2>=0 && _v2>=0 && _c2<Wm && _v2<Hm)
			{
				// создаем тропинку
				fCreatePath(Massive,Wm,Hm,_c1,_v1,_c2,_v2);
			}
			return 1;
		}
		else
		{
			fDeleteBase1(Massive,Wm,Hm,_NumBase);
			goto m1;
		}
	}
	if (Open == true && OppositeSide >= 0)
	{
		PosDistr = OppositeSide;
		OppositeSide = -1;
		goto m2;
	}
	if (vCount < 3000)
	{
		vCount++;
		goto m3;
	}
	if (vFlag2 == 0 && vFlag == 1)
	{
		fDeleteBase1(Massive,Wm,Hm,_NumBase);
	}
	return 0;
}
//
int fDeleteBase1(MapCell **Massive, int Wm, int Hm, int _NumBase)
{
	int vFlag;
	int _c1;
	int _v1;

	if (_NumBase < 0)
		return 0;

	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			if(Massive[c][v].NumBase == _NumBase)
			{
				vFlag = 1;
				if(Massive[c][v].Wall == true)
				{
					if(fFindWayOutFromBase(Massive,Wm,Hm,_c1,_v1,_NumBase) == 1)
					{
						fUpdateCell(Massive,Wm,Hm,_c1,_v1,INSIDE);
					}
				}
				fUpdateCell(Massive,Wm,Hm,c,v,INSIDE);
			}
		}
	}
	if (vFlag == 1)
		return 1;
	return 0;
}
// Запустить жучка уничтожителя
/*int fStartBugExterminator(MapCell **Massive, int Wm, int Hm, int _c1, int _v1)
{
	int Step;

	if (_c1 < 0 || _v1 < 0 || _c1 >= Wm || _v1 >= Hm)
		return 0;

	//if (Massive[_c1][_v1].Attribute != TELEPORT)
		//return 0;

	fUpdateCell(Massive,Wm,Hm,_c1,_v1,LANDSCAPE);

	if (fPourBase(Massive,Wm,Hm,_c1,_v1,Step) == 0)
		return 0;

	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			if(Massive[c][v].Fill == BASE_FILL)
			{
				fUpdateCell(Massive,Wm,Hm,c,v,INSIDE);
			}
		}
	}
	fUpdateCell(Massive,Wm,Hm,_c1,_v1,INSIDE);

	return 1;
}*/
// Определяем телепорты
int fDefineTeleports(MapCell **Massive, int Wm, int Hm)
{
	int vFlag;
	int vPart;
	RECT DansePool;
	RECT Teleport[2];
	int _c;
	int _v;
	int vCount;
	MapCell vCell[4];
	int vFlag2;

	vFlag = 0;
	DansePool.left = -1;
	DansePool.top = -1;
	DansePool.right = -1;
	DansePool.bottom = -1;
	for (int c=0; c<Wm-1; c++)
	{
		for (int v=0; v<Hm-1; v++)
		{
			if (Massive[c][v].Attribute == DANCEPOOL &&
				Massive[c+1][v].Attribute == DANCEPOOL &&
				Massive[c][v+1].Attribute == DANCEPOOL &&
				Massive[c+1][v+1].Attribute == DANCEPOOL)
			{
				vFlag = 1;
				DansePool.left = c;
				DansePool.top = v;
				DansePool.right = c+1;
				DansePool.bottom = v+1;
				break;
			}
		}
		if (vFlag == 1) break;
	}
	
	vCount = 0;
	for (int c=0; c<Wm-1; c++)
	{
		for (int v=0; v<Hm-1; v++)
		{
			if (Massive[c][v].Attribute == TELEPORT && Massive[c][v].Tele == false &&
				Massive[c+1][v].Attribute == TELEPORT && Massive[c+1][v].Tele == false)
			{
				if (vCount < 2)
				{
					Teleport[vCount].left = c;
					Teleport[vCount].top = v;
					Teleport[vCount].right = c+1;
					Teleport[vCount].bottom = v;
				}
				vCount++;
			}
			if (Massive[c+1][v].Attribute == TELEPORT && Massive[c+1][v].Tele == false &&
				Massive[c+1][v+1].Attribute == TELEPORT && Massive[c+1][v+1].Tele == false)
			{
				if (vCount < 2)
				{
					Teleport[vCount].left = c+1;
					Teleport[vCount].top = v;
					Teleport[vCount].right = c+1;
					Teleport[vCount].bottom = v+1;
				}
				vCount++;
			}
			
		}
	}
	if (vCount != 2)
		return 0;
	for (int vvi=0;vvi<vCount;vvi++)
	{
		vFlag2 = 0;
		for (int vvj=0;vvj<2;vvj++)
		{
			vPart = 0;
			vFlag = 0;
			if (vvj == 0)
			{
				_c = Teleport[vvi].left;
				_v = Teleport[vvi].top;
			}
			if (vvj == 1)
			{
				_c = Teleport[vvi].right;
				_v = Teleport[vvi].bottom;
			}
			if (_c < Wm/2 && _v < Hm/2) vPart = 1;
			if (_c >= Wm/2 && _v < Hm/2) vPart = 2;
			if (_c >= Wm/2 && _v >= Hm/2) vPart = 3;
			if (_c < Wm/2 && _v >= Hm/2) vPart = 4;

			if (((((vPart == 1 || vPart == 3) && vvj == 0) ||
				((vPart == 2 || vPart == 4) && vvj == 1)) && vFlag2 == 0 || vFlag2 == 2) &&
				vFlag == 0)
			{
				vFlag = 1;
				Massive[_c][_v].Teleport = DansePool;
				Massive[_c][_v].NumTeleport = 1;
				vFlag2 = 1;
			}
			if (((((vPart == 2 || vPart == 4) && vvj == 0) ||
				((vPart == 1 || vPart == 3) && vvj == 1)) && vFlag2 == 0 || vFlag2 == 1) &&
				vFlag == 0)
			{
				vFlag = 1;
				if (vvi == 0) Massive[_c][_v].Teleport = Teleport[1];
				if (vvi == 1) Massive[_c][_v].Teleport = Teleport[0];
				Massive[_c][_v].NumTeleport = 2;
				vFlag2 = 2;
			}
			if (vFlag == 1)
				Massive[_c][_v].Tele = true;
		}
	}
	vCell[0] = Massive[Teleport[0].left][Teleport[0].top];
	vCell[1] = Massive[Teleport[0].right][Teleport[0].bottom];
	vCell[2] = Massive[Teleport[1].left][Teleport[1].top];
	vCell[3] = Massive[Teleport[1].right][Teleport[1].bottom];
	return 1;
}
// Создаем телепорт базы
int fCreateTelportBase (MapCell **Massive, int Wm, int Hm)
{
	int vFlag;
	vFlag = 0;
	for (int c=0; c<Wm-1; c++)
	{
		for (int v=0; v<Hm-1; v++)
		{	
			if(Massive[c][v].Fill == BASE_FILL &&
				Massive[c+1][v].Fill == BASE_FILL &&
				Massive[c][v+1].Fill == BASE_FILL &&
				Massive[c+1][v+1].Fill == BASE_FILL)
			{
				if (Massive[c][v].Up == false && Massive[c+1][v].Up == false &&
					(fCheckCellsAround(Massive,Wm,Hm,c,v,WALL_FILL) == 0) && 
					(fCheckCellsAround(Massive,Wm,Hm,c+1,v,WALL_FILL) == 0) && 
					vFlag == 0)
				{
					vFlag = 1;
					Massive[c][v].Fill = TELEPORT_FILL;
					Massive[c+1][v].Fill = TELEPORT_FILL;
				}
				if (Massive[c+1][v].Right == false && Massive[c+1][v+1].Right == false &&
					(fCheckCellsAround(Massive,Wm,Hm,c+1,v,WALL_FILL) == 0) && 
					(fCheckCellsAround(Massive,Wm,Hm,c+1,v+1,WALL_FILL) == 0) && 
					vFlag == 0)
				{
					vFlag = 1;
					Massive[c+1][v].Fill = TELEPORT_FILL;
					Massive[c+1][v+1].Fill = TELEPORT_FILL;
				}
				if (vFlag == 1)
				{
					Massive[c][v].Right = true;
					Massive[c][v].Down = true;
					Massive[c+1][v].Left = true;
					Massive[c+1][v].Down = true;
					Massive[c][v+1].Up = true;
					Massive[c][v+1].Right = true;
					Massive[c+1][v+1].Up = true;
					Massive[c+1][v+1].Left = true;
					return 1;
				}
			}
		}
		if (vFlag == 1) break;
	}
	return 0;
}
// Проверяем клетки с 4 сторон
int fCheckCellsAround (MapCell **Massive, int Wm, int Hm, int _c, int _v, int _Fill)
{
	if (_c > 0)
	if (Massive[_c][_v].Left == true &&
		Massive[_c-1][_v].Right == true &&
		Massive[_c-1][_v].Fill == _Fill)
		return 1;
	if (_v > 0)
	if (Massive[_c][_v].Up == true &&
		Massive[_c][_v-1].Down == true &&
		Massive[_c][_v-1].Fill == _Fill)
		return 1;
	if (_c < Wm - 1)
	if (Massive[_c][_v].Right == true &&
		Massive[_c+1][_v].Left == true &&
		Massive[_c+1][_v].Fill == _Fill)
		return 1;
	if (_v < Hm - 1)
	if (Massive[_c][_v].Down == true &&
		Massive[_c][_v+1].Up == true &&
		Massive[_c][_v+1].Fill == _Fill)
		return 1;
	return 0;
}
// Ищем базу
int fFiendBase(MapCell **Massive, int Wm, int Hm, int _cn, int _vn, int SizeBase, int Allowance,
			   bool Open)
{
	int vBord;
	
	int CountСells;
	int CountWay;
	int CountFreeCells;
	int Way;

	int _c = _cn;
	int _v = _vn;

	int _c1 = -1;
	int _v1 = -1;

	int _c2 = -1;
	int _v2 = -1;

	int _c3 = -1;
	int _v3 = -1;

	if (Massive[_c][_v].Deadlock != true || Massive[_c][_v].Attribute != INSIDE)
		return 0;

	CountСells = 0;

	for (int c=0;c<Wm;c++)
	{
		for (int v=0;v<Hm;v++)
		{
			Massive[c][v].Fill = 0;
		}
	}

	do
	{
		CountWay = 0;
		_c1 = _c;
		_v1 = _v;
		_c2 = _c;
		_v2 = _v;
		_c3 = _c;
		_v3 = _v;
		if (_c > 0 && _c < Wm && _v >= 0 && _v < Hm)
		if(Massive[_c][_v].Left == true && Massive[_c-1][_v].Fill == 0)
		{
			CountWay++;
			if (CountWay == 1) _c1 = _c - 1;
			if (CountWay == 2) _c2 = _c - 1;
			if (CountWay == 3) _c3 = _c - 1;
		}
		if (_c >= 0 && _c < Wm && _v > 0 && _v < Hm)
		if(Massive[_c][_v].Up == true && Massive[_c][_v-1].Fill == 0)
		{
			CountWay++;
			if (CountWay == 1) _v1 = _v - 1;
			if (CountWay == 2) _v2 = _v - 1;
			if (CountWay == 3) _v3 = _v - 1;
		}
		if (_c >= 0 && _c < Wm-1 && _v >= 0 && _v < Hm)
		if(Massive[_c][_v].Right == true && Massive[_c+1][_v].Fill == 0)
		{
			CountWay++;
			if (CountWay == 1) _c1 = _c + 1;
			if (CountWay == 2) _c2 = _c + 1;
			if (CountWay == 3) _c3 = _c + 1;
		}
		if (_c >= 0 && _c < Wm && _v >= 0 && _v < Hm-1)
		if(Massive[_c][_v].Down == true && Massive[_c][_v+1].Fill == 0)
		{
			CountWay++;
			if (CountWay == 1) _v1 = _v + 1;
			if (CountWay == 2) _v2 = _v + 1;
			if (CountWay == 3) _v3 = _v + 1;
		}
		if (CountWay == 1)
		{
			Massive[_c][_v].Fill = 1;
			fCountСells(Massive,Wm,Hm,1,CountСells);
			_c = _c1;
			_v = _v1;
		}
		if (CountWay >= 2)
		{
			Way = 0;
			// нужно выбрать наименьший путь до полного тупика
			Massive[_c1][_v1].Fill = 3;
			if (fCountFreeCells(Massive,Wm,Hm,_c1,_v1) == 0)
				Way = 3;
			Massive[_c2][_v2].Fill = 4;
			if (fCountFreeCells(Massive,Wm,Hm,_c2,_v2) == 0)
				Way = 4;
			if (CountWay >= 3)
			{
				Massive[_c3][_v3].Fill = 5;
				if (fCountFreeCells(Massive,Wm,Hm,_c3,_v3) == 0)
					Way = 5;
			}
			if (Way == 0 && CountWay == 2 || CountWay == 3) fFiendFullDeadlock(Massive,Wm,Hm,SizeBase-CountСells+Allowance,CountWay,Way);// беспредельное распростронение путей
			if (Way != 0)
			{
				fReplaceCells(Massive,Wm,Hm,Way,1);
				fCountСells(Massive,Wm,Hm,1,CountСells);
				for (int vvi=3;vvi<=5;vvi++)
				{
					fReplaceCells(Massive,Wm,Hm,vvi,0);
				}
			}
		}
		Massive[_c][_v].Fill = WALL_FILL;
		if (CountWay == 0)
		{
			if(CountСells < SizeBase - Allowance)
				return 0;
			else
				break;
		}
	}
	while(CountСells < SizeBase + Allowance);
	for (int vvi=3;vvi<=5;vvi++)
	{
		fReplaceCells(Massive,Wm,Hm,vvi,0);
	}
	CountFreeCells = fCountFreeCells(Massive,Wm,Hm,_c,_v);
	if(CountFreeCells > 1)
	{
		fUpdateWall(Massive,Wm,Hm,_c,_v);
	}
	if(Open == false)
	{
		if (fCloseBase(Massive,Wm,Hm,_c,_v) == 0)
			return 0;
	}
	if (CountСells > SizeBase - Allowance)
		return 1;
	return 0;
}
// Закрываем базу
int fCloseBase(MapCell **Massive, int Wm, int Hm, int &_c, int &_v)
{
	int vFlag;
	int vCount;
	int vCountFreeCells;
	vCount = 0;
	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			if (Massive[c][v].Fill == WALL_FILL)
			{
				_c = c;
				_v = v;
				vCount++;
			}
		}
	}
	if (vCount > 1)
		return 0;
	vCountFreeCells = fCountFreeCells(Massive,Wm,Hm,_c,_v);
	if (vCountFreeCells != 1)
		return 0;
	vFlag = 0;
	if (_c > 0)
	if (Massive[_c][_v].Left == true && Massive[_c-1][_v].Fill == 0 && vFlag == 0)
	{
		vFlag = 1;
		Massive[_c][_v].Left = false;
	}
	if (_v > 0)
	if (Massive[_c][_v].Up == true && Massive[_c][_v-1].Fill == 0 && vFlag == 0)
	{
		vFlag = 1;
		Massive[_c][_v].Up = false;
	}
	if (_c < Wm - 1)
	if (Massive[_c][_v].Right == true && Massive[_c+1][_v].Fill == 0 && vFlag == 0)
	{
		vFlag = 1;
		Massive[_c][_v].Right = false;
	}
	if (_v < Hm - 1)
	if (Massive[_c][_v].Down == true && Massive[_c][_v+1].Fill == 0 && vFlag == 0)
	{
		vFlag = 1;
		Massive[_c][_v].Down = false;
	}
	if (vFlag == 1)
	{
		Massive[_c][_v].Fill = BASE_FILL;
	}
	return 1;
}

// Подсчитываем кол-во клеток одинакового цвета
void fCountСells(MapCell **Massive, int Wm, int Hm, int Fill, int &CountСells)
{
	CountСells = 0;
	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			if(Massive[c][v].Fill == Fill) CountСells++;
		}
	}
}
// Находим все тупики
void fFiendFullDeadlock(MapCell **Massive, int Wm, int Hm, int SizeСellsWay, int CountWay, int &Way)
{
	int Count;
	int N;
	int Flag;
	int MassWay[3];
	int CountCellsWayN;
	int CountCellsFullWay;
	for (int vvi=0;vvi<3;vvi++)
	{
		MassWay[vvi] = 0;
	}
	Way = 0;
	CountCellsFullWay = 0;
	for (int vvi=0;vvi<CountWay;vvi++)
	{
		MassWay[vvi] = vvi + 3;
	}
	N = 0;
	do
	{
		for (int n=0;n<CountWay;n++)
		{
			CountCellsWayN = 0;
			if (MassWay[n] != -1)
			for (int c=0; c<Wm; c++)
			{
				for (int v=0; v<Hm; v++)
				{
					Flag = 0;
					for (int vvi=0;vvi<CountWay;vvi++)
					{
						if (Massive[c][v].Fill >= 3 && Massive[c][v].Fill != MassWay[vvi])
						{
							if (fCheckCellsAround(Massive,Wm,Hm,c,v,MassWay[vvi]) == 1)
							{
								Flag = 1;
								fReplaceCells(Massive,Wm,Hm,MassWay[vvi],Massive[c][v].Fill);
								MassWay[vvi] = -1;
							}
						}
					}
					if (Massive[c][v].Fill == MassWay[n] &&
						fCountFreeCells(Massive,Wm,Hm,c,v) > 0 && MassWay[n] != 0)
					{
						if (c > 0)
						if(Massive[c][v].Left == true && Massive[c-1][v].Fill == 0 &&
							Massive[c-1][v].Right == true)
						{
							Flag = 1;
							Massive[c-1][v].Fill = Massive[c][v].Fill;
						}
						if (v > 0)
						if(Massive[c][v].Up == true && Massive[c][v-1].Fill == 0 &&
							Massive[c][v-1].Down == true)
						{
							Flag = 1;
							Massive[c][v-1].Fill = Massive[c][v].Fill;
						}
						if (c < Wm-1)
						if(Massive[c][v].Right == true && Massive[c+1][v].Fill == 0 &&
							Massive[c+1][v].Left == true)
						{
							Flag = 1;
							Massive[c+1][v].Fill = Massive[c][v].Fill;
						}
						if (v < Hm-1)
						if(Massive[c][v].Down == true && Massive[c][v+1].Fill == 0 &&
							Massive[c][v+1].Up == true)
						{
							Flag = 1;
							Massive[c][v+1].Fill = Massive[c][v].Fill;
						}
						fCountСells(Massive,Wm,Hm,MassWay[n],CountCellsWayN);
						if (CountCellsWayN > SizeСellsWay - CountCellsFullWay)
						{
							Flag = 0;
							MassWay[n] = -1;
						}
						break;
					}
				}
				if(Flag == 1) break;
			}
			if (Flag == 0 && MassWay[n] != 0)
			{
				if (MassWay[n] > 0)
				{
					CountCellsFullWay += CountCellsWayN;
					MassWay[n] = 0;
				}
				N++;
				break;
			}
		}
	}
	while(!(Flag == 0 && N == CountWay - 1));
	Count = 0;
	for (int vvi=0;vvi<CountWay;vvi++)
	{
		if (MassWay[vvi] == 0) Count++;
	}
	if (Count == CountWay-1)
	{
		for (int vvi=0;vvi<CountWay;vvi++)
		{
			if (MassWay[vvi] == 0)
			{
				Way = 2;
				fReplaceCells(Massive,Wm,Hm,vvi+3,Way);
			}
		}
		
	}
}
// Заменяем клетки
void fReplaceCells(MapCell **Massive, int Wm, int Hm, int Way, int Fill)
{
	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			if (Massive[c][v].Fill == Way)
				Massive[c][v].Fill = Fill;
		}
	}
}

int fCountFreeCells(MapCell **Massive, int Wm, int Hm, int _c, int _v)
{
	int CountFreeCell;
	CountFreeCell = 0;
	if (_c > 0)
	if (Massive[_c][_v].Left == true &&
		Massive[_c-1][_v].Right == true &&
		Massive[_c-1][_v].Fill == 0)
		CountFreeCell++;
	if (_v > 0)
	if (Massive[_c][_v].Up == true &&
		Massive[_c][_v-1].Down == true &&
		Massive[_c][_v-1].Fill == 0)
		CountFreeCell++;
	if (_c < Wm - 1)
	if (Massive[_c][_v].Right == true &&
		Massive[_c+1][_v].Left == true &&
		Massive[_c+1][_v].Fill == 0)
		CountFreeCell++;
	if (_v < Hm - 1)
	if (Massive[_c][_v].Down == true &&
		Massive[_c][_v+1].Up == true &&
		Massive[_c][_v+1].Fill == 0)
		CountFreeCell++;
	return CountFreeCell;
}

// Определяем клетки базы хума
int fDefineCellsBase1(MapCell **Massive, int Wm, int Hm, int &_c, int &_v, int _NumBase, COLORREF _Color)
{
	int Flag;
	int CountFreeCells;
	int CountCells;
	
	Flag = 0;
	CountFreeCells = 0;
	CountCells = 0;
	_c = -1;
	_v = -1;
	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			if(Massive[c][v].Fill == BASE_FILL && Massive[c][v].Attribute == INSIDE)
			{
				Massive[c][v].Attribute = BASEHUMAN;
				Massive[c][v].NumBase = _NumBase;
				Massive[c][v].Color = _Color;
				CountCells++;
			}
			if(Massive[c][v].Fill == WALL_FILL && Massive[c][v].Attribute == INSIDE)
			{
				CountFreeCells = fCountFreeCells(Massive,Wm,Hm,c,v);
				if(CountFreeCells == 1)
				{
					Flag = 1;
					Massive[c][v].Wall = true;
					Massive[c][v].Attribute = BASEHUMAN;
					Massive[c][v].NumBase = _NumBase;
					Massive[c][v].Color = _Color;
					Massive[c][v].Fill = BASE_FILL;
					if (Massive[c][v].LevelUpland == 0)
						Massive[c][v].CellCountPass = 1;
					CountCells++;
					_c = c;
					_v = v;
				}
			}
			if(Massive[c][v].Fill == TELEPORT_FILL && Massive[c][v].Attribute == INSIDE)
			{
				Massive[c][v].Attribute = TELEPORT;
				Massive[c][v].NumBase = _NumBase;
				Massive[c][v].Color = _Color;
				Massive[c][v].Tele = false;
				CountCells++;
				if (Flag == 0)
				{
					_c = c;
					_v = v;
				}
			}
		}
	}
	return CountCells;
}

// Создать заглушку
void fCreateStub(MapCell **Massive, int Wm, int Hm, int _c, int _v, int &_c1, int &_v1)
{
	int Flag;
	Flag = 0;
	_c1 = -1;
	_v1 = -1;
	if (_c >= 0 && _v >= 0 && _c < Wm && _v < Hm)
	if(Massive[_c][_v].Wall == true)
	{
		if (_c > 0)
		if (Massive[_c][_v].Left == true && Massive[_c-1][_v].Fill == 0 && Flag == 0)
		{
			Flag = 1;
			_c1 = _c-1;
			_v1 = _v;
		}
		if (_v > 0)
		if (Massive[_c][_v].Up == true && Massive[_c][_v-1].Fill == 0 && Flag == 0)
		{
			Flag = 1;
			_c1 = _c;
			_v1 = _v-1;
		}
		if (_c < Wm - 1)
		if (Massive[_c][_v].Right == true && Massive[_c+1][_v].Fill == 0 && Flag == 0)
		{
			Flag = 1;
			_c1 = _c+1;
			_v1 = _v;
		}
		if (_v < Hm - 1)
		if (Massive[_c][_v].Down == true && Massive[_c][_v+1].Fill == 0 && Flag == 0)
		{
			Flag = 1;
			_c1 = _c;
			_v1 = _v+1;
		}
		if (Flag == 1)
			fUpdateCell(Massive,Wm,Hm,_c1,_v1,LANDSCAPE);
	}
}

// Создаем базу вампа
void fCreateBase2 (MapCell **Massive, int Wm, int Hm)
{
	double vDw1;
	double vDw2;
	double vDh1;
	double vDh2;
	vDw1 = (double)Wm/35*11;
	vDw2 = (double)Wm/35*11+8;
	vDh1 = (double)Hm/35*14;
	vDh2 = (double)Hm/35*14;
	for (int c=vDw1; c<=vDw2; c++)
	{
		for (int v=vDh1; v<=vDh2; v++)
		{
			fUpdateCell(Massive,Wm,Hm,c,v,LANDSCAPE);
		}
	}
	vDw1 = (double)Wm/35*11;
	vDw2 = (double)Wm/35*11+8;
	vDh1 = (double)Hm/35*15;
	vDh2 = (double)Hm/35*15+9;
	for (int c=vDw1; c<=vDw2; c++)
	{
		for (int v=vDh1; v<=vDh2; v++)
		{
			fUpdateCell(Massive,Wm,Hm,c,v,BASEVAMPIRE);
		}
	}
}

void fUpdateCell(MapCell **Massive, int Wm, int Hm, int _c, int _v, int Attribute)
{
	if (_c < 0 || _v < 0 || _c >= Wm || _v >= Hm)
		return;
	Massive[_c][_v].Attribute = Attribute;
	Massive[_c][_v].Left = true;
	Massive[_c][_v].Up = true;
	Massive[_c][_v].Right = true;
	Massive[_c][_v].Down = true;
	Massive[_c][_v].LevelUpland = 0;
	Massive[_c][_v].Wall = false;
	Massive[_c][_v].Deadlock = false;
	Massive[_c][_v].CellCountPass = 0;
	Massive[_c][_v].Fill = 0;
	Massive[_c][_v].NumBase = -1;
}

// Создаем денс пул
void fCreateBase3 (MapCell **Massive, int Wm, int Hm)
{
	double vDw1;
	double vDw2;
	double vDh1;
	double vDh2;
	int _c;
	int _v;
	_c = Wm/35*5;
	_v = Hm/35*5;
	if (Massive[_c][_v].Attribute != OUTSIDE)
		return;
	vDw1 = (double)Wm/35*7;
	vDw2 = (double)Wm/35*7+4;
	vDh1 = (double)Hm/35*3;
	vDh2 = (double)Hm/35*3+4;
	for (int c=vDw1; c<=vDw2; c++)
	{
		for (int v=vDh1; v<=vDh2; v++)
		{
			fUpdateCell(Massive,Wm,Hm,c,v,DANCEPOOL);
		}
	}
	fAddNotDatausaBorder(Massive,Wm,Hm);
}

// Создаем слаерку
void fCreateBase4 (MapCell **Massive, int Wm, int Hm)
{
	double vDw1;
	double vDw2;
	double vDh1;
	double vDh2;
	int Rw;
	int Rh;
	int x;
	int y;
	double Random;
	int t;
	int _c;
	int _v;
	t = (int)timeGetTime();
	Rw = (double)Wm/35*15;
	Rh = (double)Hm/35*15;
	//srand (t);
	//srand (time(NULL));	// полный рандом
m1:;
	Random = rand()%628/100;
	if (Random == 3.0) goto m1;
	Random += 3.14/5;
	x = (int)(cos(Random)*Rw);
	y = (int)(sin(Random)*Rh);
	_c = (double)Wm/35*16+x;
	_v = (double)Hm/35*16-y;
	if (_c < 0 || _v < 0 || _c >= Wm || _v >= Hm)
		return;
	if (Massive[_c][_v].Attribute != OUTSIDE)
		return;
	vDw1 = (double)Wm/35*16+x-2;
	vDw2 = (double)Wm/35*16+x+4;
	vDh1 = (double)Hm/35*16-y-2;
	vDh2 = (double)Hm/35*16-y+5;
	for (int c=vDw1; c<=vDw2; c++)
	{
		for (int v=vDh1; v<=vDh2; v++)
		{
			fUpdateCell(Massive,Wm,Hm,c,v,LANDSCAPE);
		}
	}
	vDw1 = (double)Wm/35*16+x-2;
	vDw2 = (double)Wm/35*16+x+3;
	vDh1 = (double)Hm/35*16-y-1;
	vDh2 = (double)Hm/35*16-y+4;
	for (int c=vDw1; c<=vDw2; c++)
	{
		for (int v=vDh1; v<=vDh2; v++)
		{
			fUpdateCell(Massive,Wm,Hm,c,v,SLAYERPLACE);
		}
	}
	fAddNotDatausaBorder(Massive,Wm,Hm);
}

void fAddNotDatausaBorder(MapCell **Massive, int Wm, int Hm)
{
	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			if (c > 0)
				if (Massive[c][v].Left == false) Massive[c-1][v].Right = false;
			if (v > 0)
				if (Massive[c][v].Up == false) Massive[c][v-1].Down = false;
			if (c < Wm-1)
				if (Massive[c][v].Right == false) Massive[c+1][v].Left = false;
			if (v < Hm-1)
				if (Massive[c][v].Down == false) Massive[c][v+1].Up = false;
			if (c == 0) Massive[c][v].Left = false;
			if (c == Wm-1) Massive[c][v].Right = false;
			if (v == 0) Massive[c][v].Up = false;
			if (v == Hm-1) Massive[c][v].Down = false;
		}
	}
}
// Отчищаем карту от незанятых клеток
void fRetouchingMap (MapCell **Massive, int Wm, int Hm)
{
	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			if (Massive[c][v].Attribute == LANDSCAPE)
			{
				fUpdateCell(Massive,Wm,Hm,c,v,LANDSCAPE);
			}
			if (Massive[c][v].Attribute == INSIDE || Massive[c][v].Attribute == OUTSIDE)
			{
				fUpdateCell(Massive,Wm,Hm,c,v,INSIDE);
			}
			if (Massive[c][v].Attribute == BASEVAMPIRE)
			{
				fUpdateCell(Massive,Wm,Hm,c,v,BASEVAMPIRE);
			}
			if (Massive[c][v].Attribute == DANCEPOOL)
			{
				fUpdateCell(Massive,Wm,Hm,c,v,DANCEPOOL);
			}
			if (Massive[c][v].Attribute == SLAYERPLACE)
			{
				fUpdateCell(Massive,Wm,Hm,c,v,SLAYERPLACE);
			}
		}
	}
	fAddNotDatausaBorder(Massive,Wm,Hm);
}

void fDelTails(MapCell **Massive, int Wm, int Hm)
{
	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			if (c < Wm-1 && v < Hm-1)
			{
				if((Massive[c][v].Attribute == BASEHUMAN ||
					Massive[c][v].Attribute == TELEPORT) &&
					(Massive[c+1][v].Attribute == BASEHUMAN ||
					Massive[c+1][v].Attribute == TELEPORT) &&
					(Massive[c][v+1].Attribute == BASEHUMAN ||
					Massive[c][v+1].Attribute == TELEPORT) &&
					(Massive[c+1][v+1].Attribute == BASEHUMAN ||
					Massive[c+1][v+1].Attribute == TELEPORT))
				{
					if(Massive[c][v].Left == false &&
						Massive[c][v+1].Left == false &&
						Massive[c][v].Down == false &&
						Massive[c][v+1].Up == false &&
						Massive[c+1][v].Down == true &&
						Massive[c+1][v+1].Up == true &&
						Massive[c][v].Right == true &&
						Massive[c+1][v].Left == true &&
						Massive[c][v+1].Right == true &&
						Massive[c+1][v+1].Left == true)
					{
						Massive[c][v].Down = true;
						Massive[c][v+1].Up = true;
					}

					if(Massive[c+1][v].Right == false &&
						Massive[c+1][v+1].Right == false &&
						Massive[c+1][v].Down == false &&
						Massive[c+1][v+1].Up == false &&
						Massive[c][v].Down == true &&
						Massive[c][v+1].Up == true &&
						Massive[c][v].Right == true &&
						Massive[c+1][v].Left == true &&
						Massive[c][v+1].Right == true &&
						Massive[c+1][v+1].Left == true)
					{
						Massive[c+1][v].Down = true;
						Massive[c+1][v+1].Up = true;
					}

					if(Massive[c][v].Up == false &&
						Massive[c+1][v].Up == false &&
						Massive[c][v].Right == false &&
						Massive[c+1][v].Left == false &&
						Massive[c][v+1].Right == true &&
						Massive[c+1][v+1].Left == true &&
						Massive[c][v].Down == true &&
						Massive[c][v+1].Up == true &&
						Massive[c+1][v].Down == true &&
						Massive[c+1][v+1].Up == true)
					{
						Massive[c][v].Right = true;
						Massive[c+1][v].Left = true;
					}

					if(Massive[c][v+1].Down == false &&
						Massive[c+1][v+1].Down == false &&
						Massive[c][v+1].Right == false &&
						Massive[c+1][v+1].Left == false &&
						Massive[c][v].Right == true &&
						Massive[c+1][v].Left == true &&
						Massive[c][v].Down == true &&
						Massive[c][v+1].Up == true &&
						Massive[c+1][v].Down == true &&
						Massive[c+1][v+1].Up == true)
					{
						Massive[c][v+1].Right = true;
						Massive[c+1][v+1].Left = true;
					}
				}
			}
			if (c < Wm-1 && v < Hm-2)
			{
				if((Massive[c][v].Attribute == BASEHUMAN ||
					Massive[c][v].Attribute == TELEPORT) &&
					(Massive[c+1][v].Attribute == BASEHUMAN ||
					Massive[c+1][v].Attribute == TELEPORT) &&
					(Massive[c][v+1].Attribute == BASEHUMAN ||
					Massive[c][v+1].Attribute == TELEPORT) &&
					(Massive[c+1][v+1].Attribute == BASEHUMAN ||
					Massive[c+1][v+1].Attribute == TELEPORT) &&
					(Massive[c][v+2].Attribute == BASEHUMAN ||
					Massive[c][v+2].Attribute == TELEPORT) &&
					(Massive[c+1][v+2].Attribute == BASEHUMAN ||
					Massive[c+1][v+2].Attribute == TELEPORT))
				{
					if(Massive[c][v].Right == true &&
						Massive[c][v+1].Right == false &&
						Massive[c][v+2].Right == true &&
						Massive[c+1][v].Left == true &&
						Massive[c+1][v+1].Left == false &&
						Massive[c+1][v+2].Left == true &&
						Massive[c][v].Down == true &&
						Massive[c][v+1].Up == true &&
						Massive[c][v+1].Down == true &&
						Massive[c][v+2].Up == true &&
						Massive[c+1][v].Down == true &&
						Massive[c+1][v+1].Up == true &&
						Massive[c+1][v+1].Down == true &&
						Massive[c+1][v+2].Up == true)
					{
						Massive[c][v+1].Right = true;
						Massive[c+1][v+1].Left = true;
					}
				}
			}
			if (c < Wm-2 && v < Hm-1)
			{
				if((Massive[c][v].Attribute == BASEHUMAN ||
					Massive[c][v].Attribute == TELEPORT) &&
					(Massive[c+1][v].Attribute == BASEHUMAN ||
					Massive[c+1][v].Attribute == TELEPORT) &&
					(Massive[c+2][v].Attribute == BASEHUMAN ||
					Massive[c+2][v].Attribute == TELEPORT) &&
					(Massive[c][v+1].Attribute == BASEHUMAN ||
					Massive[c][v+1].Attribute == TELEPORT) &&
					(Massive[c+1][v+1].Attribute == BASEHUMAN ||
					Massive[c+1][v+1].Attribute == TELEPORT) &&
					(Massive[c+2][v+1].Attribute == BASEHUMAN ||
					Massive[c+2][v+1].Attribute == TELEPORT))
				{
					if(Massive[c][v].Down == true &&
						Massive[c+1][v].Down == false &&
						Massive[c+2][v].Down == true &&
						Massive[c][v+1].Up == true &&
						Massive[c+1][v+1].Up == false &&
						Massive[c+2][v+1].Up == true &&
						Massive[c][v].Right == true &&
						Massive[c+1][v].Left == true &&
						Massive[c+1][v].Right == true &&
						Massive[c+2][v].Left == true &&
						Massive[c][v+1].Right == true &&
						Massive[c+1][v+1].Left == true &&
						Massive[c+1][v+1].Right == true &&
						Massive[c+2][v+1].Left == true)
					{
						Massive[c+1][v].Down = true;
						Massive[c+1][v+1].Up = true;
					}
				}
			}
		}
	}
}

void fRecursiveBacktracking(MapCell **Massive, int Wm, int Hm)
{
	int x;
	int y;

	int Count;
	
	Count = 0;
	for (int c=0;c<Wm;c++)
	{
		for (int v=0;v<Hm;v++)
		{
			if(Massive[c][v].Attribute == OUTSIDE)
			{
				x = c;
				y = v;
				Count++;
			}
		}
	}
	if (Count == 0)
		return;
	if (Count > 5)
	if (Wm != NULL && Hm != NULL)
	{
		//srand (time(NULL));	// полный рандом
		do
		{
			x = rand()%Wm;
			y = rand()%Hm;
		}
		while (!(Massive[x][y].Attribute == OUTSIDE));
	}
	else
		return;
	Massive[x][y].Attribute = INSIDE;
	fCarvePassagesFrom(Massive,Wm,Hm,x,y);
	fAddNotDatausaBorder(Massive,Wm,Hm);
}
 
void fCarvePassagesFrom(MapCell **Massive, int Wm, int Hm, int _c, int _v)
{
	// 0 - E, 1 - W, 2 - N, 3 - S
	int vDx[4] = {1, -1, 0, 0};
	int vDy[4] = {0, 0, -1, 1};

	int nx;
	int ny;
	
	int vRand = rand()%4;
	int vTemp[4] = {2, 3, 0, 1};
	int vDirections[4];

	for (int vvi=0;vvi<4;vvi++)
		vDirections[vvi] = vTemp[(vvi+4-vRand)%4];
 
	for (int vvi=0;vvi<4;vvi++)
	{
		nx = _c + vDx[vDirections[vvi]];
		ny = _v + vDy[vDirections[vvi]];
		if (nx >= 0 && nx < Wm && ny >= 0 && ny < Hm &&
			Massive[nx][ny].Left == false &&
			Massive[nx][ny].Up == false &&
			Massive[nx][ny].Right == false &&
			Massive[nx][ny].Down == false &&
			Massive[nx][ny].Attribute == OUTSIDE)
		{
			if (vDirections[vvi] == 0) Massive[_c][_v].Right = true;
			if (vDirections[vvi] == 1) Massive[_c][_v].Left = true;
			if (vDirections[vvi] == 2) Massive[_c][_v].Up = true;
			if (vDirections[vvi] == 3) Massive[_c][_v].Down = true;

			if (vDirections[vvi] == 1) Massive[nx][ny].Right = true;
			if (vDirections[vvi] == 0) Massive[nx][ny].Left = true;
			if (vDirections[vvi] == 3) Massive[nx][ny].Up = true;
			if (vDirections[vvi] == 2) Massive[nx][ny].Down = true;

			Massive[nx][ny].Attribute = INSIDE;

			fCarvePassagesFrom(Massive,Wm,Hm,nx,ny);
		}
	}
}

int fCheckRegionBase(MapCell **Massive, int Wm, int Hm, int w1, int h1, int w2, int h2)
{
	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			if (c<w1 || c>w2 || v<h1 || v>h2)
			{
				if(Massive[c][v].Fill == BASE_FILL || Massive[c][v].Fill == WALL_FILL)
				{
					return 0;
				}
			}
		}
	}
	return 1;
}
// Очищаем карту
void fClearMap (MapCell **Massive, int Wm, int Hm)
{
	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			if (Massive[c][v].Attribute == INSIDE)
			{
				Massive[c][v].Attribute = OUTSIDE;
				Massive[c][v].Left = false;
				Massive[c][v].Up = false;
				Massive[c][v].Right = false;
				Massive[c][v].Down = false;
				Massive[c][v].Wall = false;
			}
		}
	}
}
// Создаем новую карту
void fNewMap (MapCell **Massive, int Wm, int Hm)
{
	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			Massive[c][v].Attribute = OUTSIDE;
			Massive[c][v].Left = false;
			Massive[c][v].Up = false;
			Massive[c][v].Right = false;
			Massive[c][v].Down = false;
			Massive[c][v].Wall = false;
			Massive[c][v].Tele = false;
			Massive[c][v].LevelUpland = 0;
			Massive[c][v].CellCountPass = 0;
			Massive[c][v].LeftT = 0;
			Massive[c][v].UpT = 0;
			Massive[c][v].RightT = 0;
			Massive[c][v].DownT = 0;
			Massive[c][v].Blood = false;
			Massive[c][v].NumBase = -1;
		}
	}
}

// Проверить коридоры
int fCheckCorridors (MapCell **Massive, int Wm, int Hm, int w1, int h1, int w2, int h2)
{
	MapCell vCells[6];
	int _w1;
	int _w2;
	int _h1;
	int _h2;
	_w1 = w1;
	_w2 = w2;
	_h1 = h1;
	_h2 = h2;
	if (w1 > 0)
		_w1 = w1-1;
	if (w2 < Wm-1)
		_w2 = w2+1;
	if (h1 > 0)
		_h1 = h1-1;
	if (h2 < Hm-1)
		_h2 = h2+1;
	for (int c=_w1; c<=_w2; c++)
	{
		for (int v=_h1; v<=_h2; v++)
		{
			if (c<=_w2-2 && v<=_h2-2)
			{
				vCells[0] = Massive[c][v];
				vCells[1] = Massive[c+1][v];
				vCells[2] = Massive[c+2][v];
				vCells[3] = Massive[c][v+1];
				vCells[4] = Massive[c+1][v+1];
				vCells[5] = Massive[c+2][v+1];
				if(vCells[0].Fill == 0 &&
					(vCells[1].Fill == BASE_FILL || vCells[1].Fill == WALL_FILL) &&
					vCells[2].Fill == 0 &&
					vCells[3].Fill == 0 &&
					(vCells[4].Fill == BASE_FILL || vCells[4].Fill == WALL_FILL) &&
					vCells[5].Fill == 0)
				{
					return 0;
				}
			}
			if (c<=_w2-2 && v<=_h2-2)
			{
				vCells[0] = Massive[c][v];
				vCells[1] = Massive[c][v+1];
				vCells[2] = Massive[c][v+2];
				vCells[3] = Massive[c+1][v];
				vCells[4] = Massive[c+1][v+1];
				vCells[5] = Massive[c+1][v+2];
				if(vCells[0].Fill == 0 &&
					(vCells[1].Fill == BASE_FILL || vCells[1].Fill == WALL_FILL) &&
					vCells[2].Fill == 0 &&
					vCells[3].Fill == 0 &&
					(vCells[4].Fill == BASE_FILL || vCells[4].Fill == WALL_FILL) &&
					vCells[5].Fill == 0)
				{
					return 0;
				}
			}
		}
	}
	return 1;
}

void fUpdateWall (MapCell **Massive, int Wm, int Hm, int _c, int _v)
{
	int Flag;
	Flag = 0;

	if(Massive[_c][_v].Attribute == INSIDE)
	{
		if(_c > 0)
		if(Massive[_c][_v].Left == true && Massive[_c-1][_v].Fill == BASE_FILL && Flag == 0)
		{
			Flag = 1;
			Massive[_c-1][_v].Fill = WALL_FILL;
		}
		if(_v > 0)
		if(Massive[_c][_v].Up == true && Massive[_c][_v-1].Fill == BASE_FILL && Flag == 0)
		{
			Flag = 1;
			Massive[_c][_v-1].Fill = WALL_FILL;
		}
		if(_c < Wm-1)
		if(Massive[_c][_v].Right == true && Massive[_c+1][_v].Fill == BASE_FILL && Flag == 0)
		{
			Flag = 1;
			Massive[_c+1][_v].Fill = WALL_FILL;
		}
		if(_v < Hm-1)
		if(Massive[_c][_v].Down == true && Massive[_c][_v+1].Fill == BASE_FILL && Flag == 0)
		{
			Flag = 1;
			Massive[_c][_v+1].Fill = WALL_FILL;
		}
		if (Flag == 1)
		{
			Massive[_c][_v].Fill = 0;
		}
	}
}

// Создать путь между двумя клетками
void fCreatePath (MapCell **Massive, int Wm, int Hm, int _c1, int _v1, int _c2, int _v2)
{
	int Flag;
	int Step;
	int _c;
	int _v;
	int vCord[4][2];	

	if (_c1 == _c2 && _v1 == _v2)
		return;
	if(ppMap[_c1][_v1].Attribute != LANDSCAPE)
		return;
	if(ppMap[_c2][_v2].Attribute != OUTSIDE &&
		ppMap[_c2][_v2].Attribute != INSIDE &&
		ppMap[_c2][_v2].Attribute != BORDER &&
		ppMap[_c2][_v2].Attribute != LANDSCAPE)
		return;
	ppMap[_c2][_v2].Attribute = LANDSCAPE;
	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			Massive[c][v].NumPeak = 0;
			Massive[c][v].PeakAttr = false;
		}
	}
	Step = 1;
	Massive[_c1][_v1].NumPeak = Step;
	Massive[_c1][_v1].PeakAttr = true;
	do
	{
		Flag = 0;
		for (int c=0; c<Wm; c++)
		{
			for (int v=0; v<Hm; v++)
			{
				if(Massive[c][v].PeakAttr == true && Massive[c][v].NumPeak == Step)
				{
					if(c > 0)
					if(Massive[c][v].Left == true && Massive[c-1][v].PeakAttr == false &&
						(Massive[c-1][v].Attribute == INSIDE ||
						Massive[c-1][v].Attribute == LANDSCAPE))
					{
						Flag = 1;
						Massive[c-1][v].NumPeak = Massive[c][v].NumPeak+1;
						Massive[c-1][v].PeakAttr = true;
					}
					if(v > 0)
					if(Massive[c][v].Up == true && Massive[c][v-1].PeakAttr == false &&
						(Massive[c][v-1].Attribute == INSIDE ||
						Massive[c][v-1].Attribute == LANDSCAPE))
					{
						Flag = 1;
						Massive[c][v-1].NumPeak = Massive[c][v].NumPeak+1;
						Massive[c][v-1].PeakAttr = true;
					}
					if(c < Wm-1)
					if(Massive[c][v].Right == true && Massive[c+1][v].PeakAttr == false &&
						(Massive[c+1][v].Attribute == INSIDE ||
						Massive[c+1][v].Attribute == LANDSCAPE))
					{
						Flag = 1;
						Massive[c+1][v].NumPeak = Massive[c][v].NumPeak+1;
						Massive[c+1][v].PeakAttr = true;
					}
					if(v < Hm-1)
					if(Massive[c][v].Down == true && Massive[c][v+1].PeakAttr == false &&
						(Massive[c][v+1].Attribute == INSIDE ||
						Massive[c][v+1].Attribute == LANDSCAPE))
					{
						Flag = 1;
						Massive[c][v+1].NumPeak = Massive[c][v].NumPeak+1;
						Massive[c][v+1].PeakAttr = true;
					}
				}
			}
		}
		Step++;
	}
	while(Flag == 1 && Massive[_c2][_v2].PeakAttr == false);
	if(Massive[_c2][_v2].PeakAttr == true)
	{
		_c = _c2;
		_v = _v2;
		Step = Massive[_c2][_v2].NumPeak;
		for (int vvi=0;vvi<Massive[_c2][_v2].NumPeak;vvi++)
		{
			Step--;
			Flag = 0;

			vCord[0][0] = -1;
			vCord[0][1] = -1;
			vCord[1][0] = -1;
			vCord[1][1] = -1;
			vCord[2][0] = -1;
			vCord[2][1] = -1;
			vCord[3][0] = -1;
			vCord[3][1] = -1;

			if(_c > 0)
			if(Massive[_c][_v].Left == true && Massive[_c-1][_v].PeakAttr == true &&
				Massive[_c-1][_v].NumPeak == Step &&
				(Massive[_c-1][_v].Attribute == INSIDE ||
				Massive[_c-1][_v].Attribute == LANDSCAPE))
			{
				Flag = 1;
				vCord[0][0] = _c-1;
				vCord[0][1] = _v;
			}
			if(_v > 0)
			if(Massive[_c][_v].Up == true && Massive[_c][_v-1].PeakAttr == true &&
				Massive[_c][_v-1].NumPeak == Step &&
				(Massive[_c][_v-1].Attribute == INSIDE ||
				Massive[_c][_v-1].Attribute == LANDSCAPE))
			{
				Flag = 1;
				vCord[1][0] = _c;
				vCord[1][1] = _v-1;
			}
			if(_c < Wm-1)
			if(Massive[_c][_v].Right == true && Massive[_c+1][_v].PeakAttr == true &&
				Massive[_c+1][_v].NumPeak == Step &&
				(Massive[_c+1][_v].Attribute == INSIDE ||
				Massive[_c+1][_v].Attribute == LANDSCAPE))
			{
				Flag = 1;
				vCord[2][0] = _c+1;
				vCord[2][1] = _v;
			}
			if(_v < Hm-1)
			if(Massive[_c][_v].Down == true && Massive[_c][_v+1].PeakAttr == true &&
				Massive[_c][_v+1].NumPeak == Step &&
				(Massive[_c][_v+1].Attribute == INSIDE ||
				Massive[_c][_v+1].Attribute == LANDSCAPE))
			{
				Flag = 1;
				vCord[3][0] = _c;
				vCord[3][1] = _v+1;
			}
			if (Flag == 1)
			{
				for (int vvj=0;vvj<4;vvj++)
				{
					if (vCord[vvj][0] >= 0 && vCord[vvj][1] >= 0)
					{
						_c = vCord[vvj][0];
						_v = vCord[vvj][1];
						break;
					}
				}
				fUpdateCell(Massive,Wm,Hm,_c,_v,LANDSCAPE);
			}
			else
				break;
		}
	}
}
// Заполнение уровней высот и количества клеток перехода
void fFillLevelsElevations (MapCell **Massive, int Wm, int Hm, int _c1, int _v1,
							double _LvlСhange, double _IncLvl, double _WidePass)
{
	int Flag;
	int Flag2;
	int Step;
	int vLevelUpland;
	int vCellCountPass;
	int vNumPeak;
	int vStep2;
	int vLevel;
	int vLvlСhange;
	int vNum;
	int vCountCells;

	int _c;
	int _v;
	int _c2;
	int _v2;

	RECT Teleport;

	int t;
	t = (int)timeGetTime();
	//srand (t);	// полный рандом

	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			Massive[c][v].NumPeak = 0;
			Massive[c][v].PeakAttr = false;
		}
	}
	Step = 1;
	Massive[_c1][_v1].NumPeak = Step;
	Massive[_c1][_v1].PeakAttr = true;
	vLevelUpland = 0;
	if (rand()%100 <= (int)(_LvlСhange*100))
	{
		if (rand()%100 <= (int)(_IncLvl*100))
		{
			if (vLevelUpland < 4) vLevelUpland++;
		}
		else
		{
			if (vLevelUpland > -2) vLevelUpland--;
		}
	}
	Massive[_c1][_v1].LevelUpland = vLevelUpland;

	do
	{
		Flag = 0;
		for (int c=0; c<Wm; c++)
		{
			for (int v=0; v<Hm; v++)
			{
				if(Massive[c][v].PeakAttr == true && Massive[c][v].NumPeak == Step)
				{
					if (Massive[c][v].Tele == true)
					{
						Flag = 1;
						vLevelUpland = rand()%2+1;
						Teleport = Massive[c][v].Teleport;
						for (int vvi=Teleport.left;vvi<=Teleport.right;vvi++)
						{
							for (int vvj=Teleport.top;vvj<=Teleport.bottom;vvj++)
							{
								_c = vvi;
								_v = vvj;
								if (_c >= 0 && _v >= 0 && _c < Wm && _v < Hm)
								{
									if (Massive[_c][_v].Attribute == TELEPORT &&
										Massive[_c][_v].PeakAttr == false &&
										Massive[_c][_v].NumPeak == 0)
									{
										Massive[_c][_v].NumPeak = Massive[c][v].NumPeak+1;
										Massive[_c][_v].PeakAttr = true;
										Massive[_c][_v].LevelUpland = vLevelUpland;
										fDetermineLevelUpland(Massive,Wm,Hm,_c,_v,_c,_v,
											_LvlСhange,_IncLvl,_WidePass);
									}
								}
							}
						}
					}
					if(c > 0)
					if(Massive[c][v].Left == true && Massive[c-1][v].PeakAttr == false &&
						(Massive[c-1][v].Attribute == BASEHUMAN ||
						Massive[c-1][v].Attribute == TELEPORT))
					{
						Flag = 1;
						fDetermineLevelUpland(Massive,Wm,Hm,c,v,c-1,v,
							_LvlСhange,_IncLvl,_WidePass);
					}
					if(v > 0)
					if(Massive[c][v].Up == true && Massive[c][v-1].PeakAttr == false &&
						(Massive[c][v-1].Attribute == BASEHUMAN ||
						Massive[c][v-1].Attribute == TELEPORT))
					{
						Flag = 1;
						fDetermineLevelUpland(Massive,Wm,Hm,c,v,c,v-1,
							_LvlСhange,_IncLvl,_WidePass);
					}
					if(c < Wm-1)
					if(Massive[c][v].Right == true && Massive[c+1][v].PeakAttr == false &&
						(Massive[c+1][v].Attribute == BASEHUMAN ||
						Massive[c+1][v].Attribute == TELEPORT))
					{
						Flag = 1;
						fDetermineLevelUpland(Massive,Wm,Hm,c,v,c+1,v,
							_LvlСhange,_IncLvl,_WidePass);
					}
					if(v < Hm-1)
					if(Massive[c][v].Down == true && Massive[c][v+1].PeakAttr == false &&
						(Massive[c][v+1].Attribute == BASEHUMAN ||
						Massive[c][v+1].Attribute == TELEPORT))
					{
						Flag = 1;
						fDetermineLevelUpland(Massive,Wm,Hm,c,v,c,v+1,
							_LvlСhange,_IncLvl,_WidePass);
					}
				}
			}
		}
		if (Flag == 1)
			vStep2 = 2;
		if (Flag == 0 && vStep2 > 0)
		{
			Flag = 1;
			vStep2--;
		}
		Step++;
	}
	while(Flag == 1);

	Massive[_c1][_v1].LevelUpland = 0;
	Massive[_c1][_v1].CellCountPass = 0;

	if (fPourBase(Massive,Wm,Hm,_c1,_v1,Step) == 0)
		return;

	vNum = 3;

	// ограничитель высот на 3 уровня
	while (fPourFollowingPlot(Massive,Wm,Hm,Step,Flag2,_c2,_v2) == 1)
	{
		Flag = 0;
		for (int c=0; c<Wm; c++)
		{
			for (int v=0; v<Hm; v++)
			{
				if (Massive[c][v].Fill == TEMPORARY_FILL)
				{					
					//
					for (int vvi=-1;vvi<=1;vvi++)
					{
						for (int vvj=-1;vvj<=1;vvj++)
						{
							if ((vvi == -1 && vvj == 0) ||
								(vvi == 0 && vvj == -1) ||
								(vvi == 1 && vvj == 0) ||
								(vvi == 0 && vvj == 1))
							{
								_c1 = c + vvi;
								_v1 = v + vvj;
								if (_c1 >= 0 && _v1 >= 0 && _c1 < Wm && _v1 < Hm)
								if (ppMap[_c1][_v1].Attribute == OUTSIDE ||
									ppMap[_c1][_v1].Attribute == INSIDE ||
									ppMap[_c1][_v1].Attribute == BORDER ||
									ppMap[_c1][_v1].Attribute == LANDSCAPE ||
									(ppMap[_c1][_v1].Attribute == BASEHUMAN &&
									ppMap[_c1][_v1].NumBase != ppMap[c][v].NumBase))
								{
									vLevel = Massive[c][v].LevelUpland - Massive[_c1][_v1].LevelUpland;
									if (vLevel < -vNum)
									{
										vLvlСhange = 1;
										Flag = 1;
										break;
									}
									if (vLevel > vNum)
									{
										vLvlСhange = -1;
										Flag = 1;
										break;
									}
								}
									
							}
						}
					}
					if (fCheckLevelAroundThisCell(Massive,Wm,Hm,c,v,vNum) == 0)
					{
						vLvlСhange = -1;
						Flag = 1;
						break;
					}
				}
			}
			if (Flag == 1) break;
		}
		if (Flag == 1)
		{
			for (int c=0; c<Wm; c++)
			{
				for (int v=0; v<Hm; v++)
				{
					if (Massive[c][v].Fill == TEMPORARY_FILL)
					{
						Massive[c][v].LevelUpland += vLvlСhange;
						Massive[c][v].CellCountPass = 0;
						// проверить переходы с 4 сторон
						// если у этих переходов уровни одинаковые, то их нужно убрать
						// если разные то, их нужно оставить
						Flag2 = 0;
						if (c > 0)
						if (Massive[c-1][v].LevelUpland != Massive[c][v].LevelUpland &&
							Massive[c-1][v].NumPeak < Massive[c][v].NumPeak)
						{
							Flag2 == 1;
						}
						if (v > 0)
						if (Massive[c][v-1].LevelUpland == Massive[c][v].LevelUpland &&
							Massive[c][v-1].NumPeak < Massive[c][v].NumPeak)
						{
							Flag2 == 1;
						}
						if (c < Wm - 1)
						if (Massive[c+1][v].LevelUpland == Massive[c][v].LevelUpland &&
							Massive[c+1][v].NumPeak < Massive[c][v].NumPeak)
						{
							Flag2 == 1;
						}
						if (v < Hm - 1)
						if (Massive[c][v+1].LevelUpland == Massive[c][v].LevelUpland &&
							Massive[c][v+1].NumPeak < Massive[c][v].NumPeak)
						{
							Flag2 == 1;
						}
						if (Flag2 == 1)
						{
							Massive[c][v].CellCountPass = 1;
						}
						if (Massive[c][v].LevelUpland == 0 && Massive[c][v].Wall == true)
							Massive[c][v].CellCountPass = 1;
					}
				}
			}
		}
		fReplaceCells(Massive,Wm,Hm,TEMPORARY_FILL,CHECK_FILL);
	}
	//
}

// Остриё перехода
void fDetermineLevelUpland (MapCell **Massive, int Wm, int Hm, int _c1, int _v1, int _c2, int _v2,
							double _LvlСhange, double _IncLvl, double _WidePass)
{
	int vFlag;
	int vFlag2;
	int vLevelUpland;
	int vCellCountPass;
	
	int _c;
	int _v;

	int __c2;
	int __v2;

	int _LevelUpland;
	int _NumPeak;

	if (_c2 < 0 || _v2 < 0 || _c2 >= Wm || _v2 >= Hm)
		return;

	_NumPeak = Massive[_c1][_v1].NumPeak+1;
	_LevelUpland = Massive[_c1][_v1].LevelUpland;

	Massive[_c2][_v2].NumPeak = _NumPeak;
	Massive[_c2][_v2].LevelUpland = _LevelUpland;

	Massive[_c2][_v2].PeakAttr = true;

	if (_NumPeak == 2 && Massive[_c2][_v2].LevelUpland != 0)
	{
		vCellCountPass = 0;
		if (rand()%100 <= (int)(_WidePass*100))
			vCellCountPass = 2;
		else
			vCellCountPass = 1;
		Massive[_c2][_v2].CellCountPass = vCellCountPass;
		if (fCheckCellPass2(Massive,Wm,Hm,_c2,_v2) == 1 &&
			Massive[_c2][_v2].Attribute != TELEPORT)
		{
			Massive[_c2][_v2].LevelUpland = 0;
			Massive[_c2][_v2].CellCountPass = 1;
		}
		return;
	}

	do
	{
		vFlag = 0;
		__c2 = 0;
		__v2 = 0;
		vLevelUpland = 0;
		for (int vvi=-1;vvi<1;vvi++)
		{
			for (int vvj=-1;vvj<1;vvj++)
			{
				_c = _c2 + vvi;
				_v = _v2 + vvj;
				if (_c >= 0 && _v >= 0 && _c < Wm-1 && _v < Hm-1)
				{
					if (Massive[_c][_v].Right == false &&
						Massive[_c][_v+1].Right == true &&
						Massive[_c+1][_v].Left == false &&
						Massive[_c+1][_v+1].Left == true &&
						Massive[_c][_v].Down == true &&
						Massive[_c+1][_v].Down == true &&
						Massive[_c][_v+1].Up == true &&
						Massive[_c+1][_v+1].Up == true &&
						vFlag == 0)
					{
						if (Massive[_c][_v+1].Down == false)
						{
							if (vvi == -1 && vvj == -1 &&
								Massive[_c][_v].PeakAttr == false &&
								(Massive[_c][_v].Attribute == BASEHUMAN ||
								Massive[_c][_v].Attribute == TELEPORT) &&
								Massive[_c][_v+1].PeakAttr == false &&
								(Massive[_c][_v+1].Attribute == BASEHUMAN ||
								Massive[_c][_v+1].Attribute == TELEPORT) &&
								vFlag == 0)
							{
								vFlag = 1;
								__c2 = _c;
								__v2 = _v+1;
								break;
							}
							if (vvi == 0 && vvj == -1 &&
								Massive[_c+1][_v].PeakAttr == false &&
								(Massive[_c+1][_v].Attribute == BASEHUMAN ||
								Massive[_c+1][_v].Attribute == TELEPORT) &&
								Massive[_c+1][_v+1].PeakAttr == false &&
								(Massive[_c+1][_v+1].Attribute == BASEHUMAN ||
								Massive[_c+1][_v+1].Attribute == TELEPORT) &&
								vFlag == 0)
							{
								vFlag = 1;
								__c2 = _c+1;
								__v2 = _v+1;
								break;
							}
						}
						if (Massive[_c+1][_v+1].Down == false)
						{
							if (vvi == 0 && vvj == -1 &&
								Massive[_c+1][_v].PeakAttr == false &&
								(Massive[_c+1][_v].Attribute == BASEHUMAN ||
								Massive[_c+1][_v].Attribute == TELEPORT) &&
								Massive[_c+1][_v+1].PeakAttr == false &&
								(Massive[_c+1][_v+1].Attribute == BASEHUMAN ||
								Massive[_c+1][_v+1].Attribute == TELEPORT) &&
								vFlag == 0)
							{
								vFlag = 1;
								__c2 = _c+1;
								__v2 = _v+1;
								break;
							}
							if (vvi == -1 && vvj == -1 &&
								Massive[_c][_v].PeakAttr == false &&
								(Massive[_c][_v].Attribute == BASEHUMAN ||
								Massive[_c][_v].Attribute == TELEPORT) &&
								Massive[_c][_v+1].PeakAttr == false &&
								(Massive[_c][_v+1].Attribute == BASEHUMAN ||
								Massive[_c][_v+1].Attribute == TELEPORT) &&
								vFlag == 0)
							{
								vFlag = 1;
								__c2 = _c;
								__v2 = _v+1;
								break;
							}
						}
					}
					if (Massive[_c][_v].Right == true &&
						Massive[_c][_v+1].Right == false &&
						Massive[_c+1][_v].Left == true &&
						Massive[_c+1][_v+1].Left == false &&
						Massive[_c][_v].Down == true &&
						Massive[_c+1][_v].Down == true &&
						Massive[_c][_v+1].Up == true &&
						Massive[_c+1][_v+1].Up == true &&
						vFlag == 0)
					{
						if (Massive[_c][_v].Up == false)
						{
							if (vvi == -1 && vvj == 0 &&
								Massive[_c][_v].PeakAttr == false &&
								(Massive[_c][_v].Attribute == BASEHUMAN ||
								Massive[_c][_v].Attribute == TELEPORT) &&
								Massive[_c][_v+1].PeakAttr == false &&
								(Massive[_c][_v+1].Attribute == BASEHUMAN ||
								Massive[_c][_v+1].Attribute == TELEPORT) &&
								vFlag == 0)
							{
								vFlag = 1;
								__c2 = _c;
								__v2 = _v;
								break;
							}
							if (vvi == 0 && vvj == 0 &&
								Massive[_c+1][_v].PeakAttr == false &&
								(Massive[_c+1][_v].Attribute == BASEHUMAN ||
								Massive[_c+1][_v].Attribute == TELEPORT) &&
								Massive[_c+1][_v+1].PeakAttr == false &&
								(Massive[_c+1][_v+1].Attribute == BASEHUMAN ||
								Massive[_c+1][_v+1].Attribute == TELEPORT) &&
								vFlag == 0)
							{
								vFlag = 1;
								__c2 = _c+1;
								__v2 = _v;
								break;
							}
						}
						if (Massive[_c+1][_v].Up == false)
						{
							if (vvi == 0 && vvj == 0 &&
								Massive[_c+1][_v].PeakAttr == false &&
								(Massive[_c+1][_v].Attribute == BASEHUMAN ||
								Massive[_c+1][_v].Attribute == TELEPORT) &&
								Massive[_c+1][_v+1].PeakAttr == false &&
								(Massive[_c+1][_v+1].Attribute == BASEHUMAN ||
								Massive[_c+1][_v+1].Attribute == TELEPORT) &&
								vFlag == 0)
							{
								vFlag = 1;
								__c2 = _c+1;
								__v2 = _v;
								break;
							}
							if (vvi == -1 && vvj == 0 &&
								Massive[_c][_v].PeakAttr == false &&
								(Massive[_c][_v].Attribute == BASEHUMAN ||
								Massive[_c][_v].Attribute == TELEPORT) &&
								Massive[_c][_v+1].PeakAttr == false &&
								(Massive[_c][_v+1].Attribute == BASEHUMAN ||
								Massive[_c][_v+1].Attribute == TELEPORT) &&
								vFlag == 0)
							{
								vFlag = 1;
								__c2 = _c;
								__v2 = _v;
								break;
							}
						}
					}
					if (Massive[_c][_v].Right == true &&
						Massive[_c][_v+1].Right == true &&
						Massive[_c+1][_v].Left == true &&
						Massive[_c+1][_v+1].Left == true &&
						Massive[_c][_v].Down == false &&
						Massive[_c+1][_v].Down == true &&
						Massive[_c][_v+1].Up == false &&
						Massive[_c+1][_v+1].Up == true &&
						vFlag == 0)
					{
						if (Massive[_c+1][_v].Right == false)
						{
							if (vvi == -1 && vvj == -1 &&
								Massive[_c][_v].PeakAttr == false &&
								(Massive[_c][_v].Attribute == BASEHUMAN ||
								Massive[_c][_v].Attribute == TELEPORT) &&
								Massive[_c+1][_v].PeakAttr == false &&
								(Massive[_c+1][_v].Attribute == BASEHUMAN ||
								Massive[_c+1][_v].Attribute == TELEPORT) &&
								vFlag == 0)
							{
								vFlag = 1;
								__c2 = _c+1;
								__v2 = _v;
								break;
							}
							if (vvi == -1 && vvj == 0 &&
								Massive[_c][_v+1].PeakAttr == false &&
								(Massive[_c][_v+1].Attribute == BASEHUMAN ||
								Massive[_c][_v+1].Attribute == TELEPORT) &&
								Massive[_c+1][_v+1].PeakAttr == false &&
								(Massive[_c+1][_v+1].Attribute == BASEHUMAN ||
								Massive[_c+1][_v+1].Attribute == TELEPORT) &&
								vFlag == 0)
							{
								vFlag = 1;
								__c2 = _c+1;
								__v2 = _v+1;
								break;
							}
						}
						if (Massive[_c+1][_v+1].Right == false)
						{
							if (vvi == -1 && vvj == 0 &&
								Massive[_c][_v+1].PeakAttr == false &&
								(Massive[_c][_v+1].Attribute == BASEHUMAN ||
								Massive[_c][_v+1].Attribute == TELEPORT) &&
								Massive[_c+1][_v+1].PeakAttr == false &&
								(Massive[_c+1][_v+1].Attribute == BASEHUMAN ||
								Massive[_c+1][_v+1].Attribute == TELEPORT) &&
								vFlag == 0)
							{
								vFlag = 1;
								__c2 = _c+1;
								__v2 = _v+1;
								break;
							}
							if (vvi == -1 && vvj == -1 &&
								Massive[_c][_v].PeakAttr == false &&
								(Massive[_c][_v].Attribute == BASEHUMAN ||
								Massive[_c][_v].Attribute == TELEPORT) &&
								Massive[_c+1][_v].PeakAttr == false &&
								(Massive[_c+1][_v].Attribute == BASEHUMAN ||
								Massive[_c+1][_v].Attribute == TELEPORT) &&
								vFlag == 0)
							{
								vFlag = 1;
								__c2 = _c+1;
								__v2 = _v;
								break;
							}
						}
					}
					if (Massive[_c][_v].Right == true &&
						Massive[_c][_v+1].Right == true &&
						Massive[_c+1][_v].Left == true &&
						Massive[_c+1][_v+1].Left == true &&
						Massive[_c][_v].Down == true &&
						Massive[_c+1][_v].Down == false &&
						Massive[_c][_v+1].Up == true &&
						Massive[_c+1][_v+1].Up == false &&
						vFlag == 0)
					{
						if (Massive[_c][_v].Left == false)
						{
							if (vvi == 0 && vvj == -1 &&
								Massive[_c][_v].PeakAttr == false &&
								(Massive[_c][_v].Attribute == BASEHUMAN ||
								Massive[_c][_v].Attribute == TELEPORT) &&
								Massive[_c+1][_v].PeakAttr == false &&
								(Massive[_c+1][_v].Attribute == BASEHUMAN ||
								Massive[_c+1][_v].Attribute == TELEPORT) &&
								vFlag == 0)
							{
								vFlag = 1;
								__c2 = _c;
								__v2 = _v;
								break;
							}
							if (vvi == 0 && vvj == 0 &&
								Massive[_c][_v+1].PeakAttr == false &&
								(Massive[_c][_v+1].Attribute == BASEHUMAN ||
								Massive[_c][_v+1].Attribute == TELEPORT) &&
								Massive[_c+1][_v+1].PeakAttr == false &&
								(Massive[_c+1][_v+1].Attribute == BASEHUMAN ||
								Massive[_c+1][_v+1].Attribute == TELEPORT) &&
								vFlag == 0)
							{
								vFlag = 1;
								__c2 = _c;
								__v2 = _v+1;
								break;
							}
						}
						if (Massive[_c][_v+1].Left == false)
						{
							if (vvi == 0 && vvj == 0 &&
								Massive[_c][_v+1].PeakAttr == false &&
								(Massive[_c][_v+1].Attribute == BASEHUMAN ||
								Massive[_c][_v+1].Attribute == TELEPORT) &&
								Massive[_c+1][_v+1].PeakAttr == false &&
								(Massive[_c+1][_v+1].Attribute == BASEHUMAN ||
								Massive[_c+1][_v+1].Attribute == TELEPORT) &&
								vFlag == 0)
							{
								vFlag = 1;
								__c2 = _c;
								__v2 = _v+1;
								break;
							}
							if (vvi == 0 && vvj == -1 &&
								Massive[_c][_v].PeakAttr == false &&
								(Massive[_c][_v].Attribute == BASEHUMAN ||
								Massive[_c][_v].Attribute == TELEPORT) &&
								Massive[_c+1][_v].PeakAttr == false &&
								(Massive[_c+1][_v].Attribute == BASEHUMAN ||
								Massive[_c+1][_v].Attribute == TELEPORT) &&
								vFlag == 0)
							{
								vFlag = 1;
								__c2 = _c;
								__v2 = _v;
								break;
							}
						}
					}
				}
				if (_c >= 1 && _v >= 0 && _c < Wm-2 && _v < Hm-1)
				{
					if (Massive[_c-1][_v].Down == false &&
						Massive[_c][_v].Down == true &&
						Massive[_c+1][_v].Down == false &&
						Massive[_c-1][_v+1].Up == false &&
						Massive[_c][_v+1].Up == true &&
						Massive[_c+1][_v+1].Up == false &&
						vFlag == 0)
					{
						if (vvi == 0 && vvj == -1 &&
							Massive[_c-1][_v].Right == true &&
							Massive[_c][_v].Left == true &&
							Massive[_c][_v].Right == true &&
							Massive[_c+1][_v].Left == true &&
							Massive[_c-1][_v].PeakAttr == false &&
							(Massive[_c-1][_v].Attribute == BASEHUMAN ||
							Massive[_c-1][_v].Attribute == TELEPORT) &&
							Massive[_c][_v].PeakAttr == false &&
							(Massive[_c][_v].Attribute == BASEHUMAN ||
							Massive[_c][_v].Attribute == TELEPORT) &&
							Massive[_c+1][_v].PeakAttr == false &&
							(Massive[_c+1][_v].Attribute == BASEHUMAN ||
							Massive[_c+1][_v].Attribute == TELEPORT) &&
							Massive[_c-1][_v].Right == true &&
							vFlag == 0)
						{
							vFlag = 1;
							__c2 = _c;
							__v2 = _v;
							break;
						}
						if (vvi == 0 && vvj == 0 &&
							Massive[_c-1][_v+1].Right == true &&
							Massive[_c][_v+1].Left == true &&
							Massive[_c][_v+1].Right == true &&
							Massive[_c+1][_v+1].Left == true &&
							Massive[_c-1][_v+1].PeakAttr == false &&
							(Massive[_c-1][_v+1].Attribute == BASEHUMAN ||
							Massive[_c-1][_v+1].Attribute == TELEPORT) &&
							Massive[_c][_v+1].PeakAttr == false &&
							(Massive[_c][_v+1].Attribute == BASEHUMAN ||
							Massive[_c][_v+1].Attribute == TELEPORT) &&
							Massive[_c+1][_v+1].PeakAttr == false &&
							(Massive[_c+1][_v+1].Attribute == BASEHUMAN ||
							Massive[_c+1][_v+1].Attribute == TELEPORT) &&
							vFlag == 0)
						{
							vFlag = 1;
							__c2 = _c;
							__v2 = _v+1;
							break;
						}
					}
				}
				if (_c >= 0 && _v >= 1 && _c < Wm-1 && _v < Hm-2)
				{
					if (Massive[_c][_v-1].Right == false &&
						Massive[_c][_v].Right == true &&
						Massive[_c][_v+1].Right == false &&
						Massive[_c+1][_v-1].Left == false &&
						Massive[_c+1][_v].Left == true &&
						Massive[_c+1][_v+1].Left == false &&
						vFlag == 0)
					{
						if (vvi == -1 && vvj == 0 &&
							Massive[_c][_v-1].Down == true &&
							Massive[_c][_v].Up == true &&
							Massive[_c][_v].Down == true &&
							Massive[_c][_v+1].Up == true &&
							Massive[_c][_v-1].PeakAttr == false &&
							(Massive[_c][_v-1].Attribute == BASEHUMAN ||
							Massive[_c][_v-1].Attribute == TELEPORT) &&
							Massive[_c][_v].PeakAttr == false &&
							(Massive[_c][_v].Attribute == BASEHUMAN ||
							Massive[_c][_v].Attribute == TELEPORT) &&
							Massive[_c][_v+1].PeakAttr == false &&
							(Massive[_c][_v+1].Attribute == BASEHUMAN ||
							Massive[_c][_v+1].Attribute == TELEPORT))
						{
							vFlag = 1;
							__c2 = _c;
							__v2 = _v;
							break;
						}
						if (vvi == 0 && vvj == 0 &&
							Massive[_c+1][_v-1].Down == true &&
							Massive[_c+1][_v].Up == true &&
							Massive[_c+1][_v].Down == true &&
							Massive[_c+1][_v+1].Up == true &&
							Massive[_c+1][_v-1].PeakAttr == false &&
							(Massive[_c+1][_v-1].Attribute == BASEHUMAN ||
							Massive[_c+1][_v-1].Attribute == TELEPORT) &&
							Massive[_c+1][_v].PeakAttr == false &&
							(Massive[_c+1][_v].Attribute == BASEHUMAN ||
							Massive[_c+1][_v].Attribute == TELEPORT) &&
							Massive[_c+1][_v+1].PeakAttr == false &&
							(Massive[_c+1][_v+1].Attribute == BASEHUMAN ||
							Massive[_c+1][_v+1].Attribute == TELEPORT))
						{
							vFlag = 1;
							__c2 = _c+1;
							__v2 = _v;
							break;
						}
					}
				}
			}
			if (vFlag == 1) break;
		}
		//
		if (vFlag == 1)
		{
			vFlag2 = 0;
			if(__c2 > 0)
			if(Massive[__c2-1][__v2].Attribute == TELEPORT && vFlag2 == 0)
			{
				vFlag2 = 1;
			}
			if(__v2 > 0)
			if(Massive[__c2][__v2-1].Attribute == TELEPORT && vFlag2 == 0)
			{
				vFlag2 = 1;
			}
			if(__c2 < Wm-1)
			if(Massive[__c2+1][__v2].Attribute == TELEPORT && vFlag2 == 0)
			{
				vFlag2 = 1;
			}
			if(__v2 < Hm-1)
			if(Massive[__c2][__v2+1].Attribute == TELEPORT && vFlag2 == 0)
			{
				vFlag2 = 1;
			}
			if (vFlag2 == 0 && fCheckCellPass(Massive,Wm,Hm,__c2,__v2) == 0 &&
				fCheckCellPass2(Massive,Wm,Hm,__c2,__v2) == 0 &&
				Massive[__c2][__v2].Attribute != TELEPORT)
			{
				vLevelUpland = _LevelUpland;
				vCellCountPass = 0;
				if (rand()%100 <= (int)(_LvlСhange*100))
				{
					if (rand()%100 < (int)(_IncLvl*100))
					{
						if (vLevelUpland < 4) vLevelUpland++;
					}
					else
					{
						if (vLevelUpland > -2) vLevelUpland--;
					}
					if (vLevelUpland != _LevelUpland)
					{
						if (rand()%100 <= (int)(_WidePass*100))
							vCellCountPass = 2;
						else
							vCellCountPass = 1;
					}
				}
				Massive[__c2][__v2].LevelUpland = vLevelUpland;
				Massive[__c2][__v2].CellCountPass = vCellCountPass;
			}
			else
				Massive[__c2][__v2].LevelUpland = _LevelUpland;
			Massive[__c2][__v2].NumPeak = _NumPeak+1;
			Massive[__c2][__v2].PeakAttr = true;
		}
	}
	while(vFlag == 1);
	//
}

void fCheckStubs (MapCell **Massive, int Wm, int Hm)
{
	// если меняется уровень возвышенности в клетке с тупиком в одну клетку, то возвращаем
	// параметры из предыдущей клетки
	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			if (Massive[c][v].Attribute == BASEHUMAN ||
				Massive[c][v].Attribute == TELEPORT)
			{
				if(fNumberOutputsInTheCell(Massive,Wm,Hm,c,v) == 1)
				{
					if(c > 0)
					if(Massive[c][v].Left == true &&
						(Massive[c-1][v].Attribute == BASEHUMAN ||
						Massive[c-1][v].Attribute == TELEPORT) &&
						Massive[c-1][v].LevelUpland != Massive[c][v].LevelUpland)
					{
						Massive[c][v].LevelUpland = Massive[c-1][v].LevelUpland;
						Massive[c][v].CellCountPass = Massive[c-1][v].CellCountPass;
					}
					if(v > 0)
					if(Massive[c][v].Up == true &&
						(Massive[c][v-1].Attribute == BASEHUMAN ||
						Massive[c][v-1].Attribute == TELEPORT) &&
						Massive[c][v-1].LevelUpland != Massive[c][v].LevelUpland)
					{
						Massive[c][v].LevelUpland = Massive[c][v-1].LevelUpland;
						Massive[c][v].CellCountPass = Massive[c][v-1].CellCountPass;
					}
					if(c < Wm-1)
					if(Massive[c][v].Right == true &&
						(Massive[c+1][v].Attribute == BASEHUMAN ||
						Massive[c+1][v].Attribute == TELEPORT) &&
						Massive[c+1][v].LevelUpland != Massive[c][v].LevelUpland)
					{
						Massive[c][v].LevelUpland = Massive[c+1][v].LevelUpland;
						Massive[c][v].CellCountPass = Massive[c+1][v].CellCountPass;
					}
					if(v < Hm-1)
					if(Massive[c][v].Down == true &&
						(Massive[c][v+1].Attribute == BASEHUMAN ||
						Massive[c][v+1].Attribute == TELEPORT) &&
						Massive[c][v+1].LevelUpland != Massive[c][v].LevelUpland)
					{
						Massive[c][v].LevelUpland = Massive[c][v+1].LevelUpland;
						Massive[c][v].CellCountPass = Massive[c][v+1].CellCountPass;
					}
				}
			}
		}
	}
}

int fNumberOutputsInTheCell (MapCell **Massive, int Wm, int Hm, int _c, int _v)
{
	int vOutputs;
	if (_c < 0 || _v < 0 || _v >= Wm || _v >= Hm)
		return 0;
	vOutputs = 0;
	if(Massive[_c][_v].Left == true) vOutputs++;
	if(Massive[_c][_v].Up == true) vOutputs++;
	if(Massive[_c][_v].Right == true) vOutputs++;
	if(Massive[_c][_v].Down == true) vOutputs++;
	return vOutputs;
}

// Создаем деревья
void fCreateTrees(MapCell **Massive, int Wm, int Hm, int _c1, int _v1,
				  double _Tree, double _FelledTrees)
{
	int Flag;
	int Step;

	int t;
	t = (int)timeGetTime();
	//srand (t);	// полный рандом

	if (fPourBase(Massive,Wm,Hm,_c1,_v1,Step) == 0)
		return;

	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			if(Massive[c][v].Fill == BASE_FILL)
			{
				if(c > 0)
				if(Massive[c-1][v].Fill == 0 && (Massive[c-1][v].Attribute != BASEHUMAN ||
					(Massive[c-1][v].Attribute == BASEHUMAN &&
					Massive[c-1][v].LevelUpland == Massive[c][v].LevelUpland)))
				{
					Massive[c-1][v].RightT = 1;
				}
				if(v > 0)
				if(Massive[c][v-1].Fill == 0 && (Massive[c][v-1].Attribute != BASEHUMAN ||
					(Massive[c][v-1].Attribute == BASEHUMAN &&
					Massive[c][v-1].LevelUpland == Massive[c][v].LevelUpland)))
				{
					Massive[c][v-1].DownT = 1;
				}
				if(c < Wm-1)
				if(Massive[c+1][v].Fill == 0 && (Massive[c+1][v].Attribute != BASEHUMAN ||
					(Massive[c+1][v].Attribute == BASEHUMAN &&
					Massive[c+1][v].LevelUpland == Massive[c][v].LevelUpland)))
				{
					Massive[c+1][v].LeftT = 1;
				}
				if(v < Hm-1)
				if(Massive[c][v+1].Fill == 0 && (Massive[c][v+1].Attribute != BASEHUMAN ||
					(Massive[c][v+1].Attribute == BASEHUMAN &&
					Massive[c][v+1].LevelUpland == Massive[c][v].LevelUpland)))
				{
					Massive[c][v+1].UpT = 1;
				}
			}
		}
	}

	do
	{
		Flag = 0;
		for (int c=0; c<Wm; c++)
		{
			for (int v=0; v<Hm; v++)
			{
				if(Massive[c][v].Fill == BASE_FILL)
				{
					if (fNumberOutputsInTheCell(Massive,Wm,Hm,c,v) == 1)
					{
						Flag = 1;
						Massive[c][v].Fill = DEADLOCK_FILL;
					}
					else
					{
						if (fToLookForMegaDeadlocks(Massive,Wm,Hm,c,v) == 1)
						{
							Flag = 1;
							fReplaceCells(Massive,Wm,Hm,TEMPORARY_FILL,DEADLOCK_FILL);
						}
						else
							fReplaceCells(Massive,Wm,Hm,TEMPORARY_FILL,BASE_FILL);
					}
				}
			}
		}
	}
	while(Flag == 1);

	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			if(Massive[c][v].Fill == DEADLOCK_FILL)
			{
				if(Massive[c][v].Left == 0)
					Massive[c][v].LeftT = 1;
				if(Massive[c][v].Up == 0)
					Massive[c][v].UpT = 1;
				if(Massive[c][v].Right == 0)
					Massive[c][v].RightT = 1;
				if(Massive[c][v].Down == 0)
					Massive[c][v].DownT = 1;
			}
		}
	}
	//fReplaceCells(Massive,Wm,Hm,DEADLOCK_FILL,BASE_FILL);

	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			if(Massive[c][v].Fill == BASE_FILL)
			{
				Flag = 0;
				if(c > 0)
				if(Massive[c-1][v].Fill == 0 && Massive[c-1][v].Blood == false)
				{
					Flag = 1;
					if (rand()%100 <= (int)(_Tree*100))
					{
						if (rand()%100 <= (int)(_FelledTrees*100))
						{
							if (Massive[c][v].Wall != true)
								Massive[c][v].LeftT = 2;
						}
						else
							Massive[c][v].LeftT = 1;
					}
					else
					{
						Massive[c][v].LeftT = 0;
					}
				}
				if(v > 0)
				if(Massive[c][v-1].Fill == 0 && Massive[c][v-1].Blood == false)
				{
					Flag = 1;
					if (rand()%100 <= (int)(_Tree*100))
					{
						if (rand()%100 <= (int)(_FelledTrees*100))
						{
							if (Massive[c][v].Wall != true)
								Massive[c][v].UpT = 2;
						}
						else
							Massive[c][v].UpT = 1;
					}
					else
					{
						Massive[c][v].UpT = 0;
					}
				}
				if(c < Wm-1)
				if(Massive[c+1][v].Fill == 0 && Massive[c+1][v].Blood == false)
				{
					Flag = 1;
					if (rand()%100 <= (int)(_Tree*100))
					{
						if (rand()%100 <= (int)(_FelledTrees*100))
						{
							if (Massive[c][v].Wall != true)
								Massive[c][v].RightT = 2;
						}
						else
							Massive[c][v].RightT = 1;
					}
					else
					{
						Massive[c][v].RightT = 0;
					}
				}
				if(v < Hm-1)
				if(Massive[c][v+1].Fill == 0 && Massive[c][v+1].Blood == false)
				{
					Flag = 1;
					if (rand()%100 <= (int)(_Tree*100))
					{
						if (rand()%100 <= (int)(_FelledTrees*100))
						{
							if (Massive[c][v].Wall != true)
								Massive[c][v].DownT = 2;
						}
						else
							Massive[c][v].DownT = 1;
					}
					else
					{
						Massive[c][v].DownT = 0;
					}
				}
				if (Flag == 1)
				{
					Massive[c][v].Fill = PERIMETER_FILL;
				}
			}
		}
	}

	if(_c1 > 0)
	if(Massive[_c1][_v1].Left == true &&
		(Massive[_c1-1][_v1].Attribute == BASEHUMAN ||
		Massive[_c1-1][_v1].Attribute == TELEPORT))
	{
		Massive[_c1][_v1].LeftT = 0;
		Massive[_c1-1][_v1].RightT = 0;
	}
	if(_v1 > 0)
	if(Massive[_c1][_v1].Up == true &&
		(Massive[_c1][_v1-1].Attribute == BASEHUMAN ||
		Massive[_c1][_v1-1].Attribute == TELEPORT))
	{
		Massive[_c1][_v1].UpT = 0;
		Massive[_c1][_v1-1].DownT = 0;
	}
	if(_c1 < Wm-1)
	if(Massive[_c1][_v1].Right == true &&
		(Massive[_c1+1][_v1].Attribute == BASEHUMAN ||
		Massive[_c1+1][_v1].Attribute == TELEPORT))
	{
		Massive[_c1][_v1].RightT = 0;
		Massive[_c1+1][_v1].LeftT = 0;
	}
	if(_v1 < Hm-1)
	if(Massive[_c1][_v1].Down == true &&
		(Massive[_c1][_v1+1].Attribute == BASEHUMAN ||
		Massive[_c1][_v1+1].Attribute == TELEPORT))
	{
		Massive[_c1][_v1].DownT = 0;
		Massive[_c1][_v1+1].UpT = 0;
	}
}

// Искать мега тупики
int fToLookForMegaDeadlocks(MapCell **Massive, int Wm, int Hm, int _c, int _v)
{
	int Count;
	if (Massive[_c][_v].Fill != BASE_FILL || Massive[_c][_v].CellCountPass > 0)
		return 0;
	Count = 0;
	Massive[_c][_v].Fill = TEMPORARY_FILL;
	if (fCheckOutputs(Massive,Wm,Hm) == 1)
		return 1;
	Count++;
	do
	{
		for (int c=0; c<Wm; c++)
		{
			for (int v=0; v<Hm; v++)
			{
				if (Massive[c][v].Fill == TEMPORARY_FILL)
				{
					if(c > 0)
					if(Massive[c][v].Left == true && Massive[c-1][v].Fill == BASE_FILL &&
						Massive[c][v].CellCountPass <= 0)
					{
						Massive[c-1][v].Fill == TEMPORARY_FILL;
						if (fCheckOutputs(Massive,Wm,Hm) == 1)
							return 1;
						Count++;
					}
					if(v > 0)
					if(Massive[c][v].Up == true && Massive[c][v-1].Fill == BASE_FILL &&
						Massive[c][v].CellCountPass <= 0)
					{
						Massive[c][v-1].Fill == TEMPORARY_FILL;
						if (fCheckOutputs(Massive,Wm,Hm) == 1)
							return 1;
						Count++;
					}
					if(c < Wm-1)
					if(Massive[c][v].Right == true && Massive[c+1][v].Fill == BASE_FILL &&
						Massive[c][v].CellCountPass <= 0)
					{
						Massive[c+1][v].Fill == TEMPORARY_FILL;
						if (fCheckOutputs(Massive,Wm,Hm) == 1)
							return 1;
						Count++;
					}
					if(v < Hm-1)
					if(Massive[c][v].Down == true && Massive[c][v+1].Fill == BASE_FILL &&
						Massive[c][v].CellCountPass <= 0)
					{
						Massive[c][v+1].Fill == TEMPORARY_FILL;
						if (fCheckOutputs(Massive,Wm,Hm) == 1)
							return 1;
						Count++;
					}
					if (Count >= 4) break;
				}
			}
			if (Count >= 4) break;
		}
	}
	while(Count < 4);
	return 0;
}

// Проверить выходы в временной заливке
int fCheckOutputs(MapCell **Massive, int Wm, int Hm)
{
	int Outputs;
	Outputs = 0;
	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			if (Massive[c][v].Fill == TEMPORARY_FILL)
			{
				if(c > 0)
				if(Massive[c][v].Left == true &&
					Massive[c-1][v].Fill != TEMPORARY_FILL &&
					Massive[c-1][v].Fill != DEADLOCK_FILL)
				{
					Outputs++;
				}
				if(v > 0)
				if(Massive[c][v].Up == true &&
					Massive[c][v-1].Fill != TEMPORARY_FILL &&
					Massive[c][v-1].Fill != DEADLOCK_FILL)
				{
					Outputs++;
				}
				if(c < Wm-1)
				if(Massive[c][v].Right == true &&
					Massive[c+1][v].Fill != TEMPORARY_FILL &&
					Massive[c+1][v].Fill != DEADLOCK_FILL)
				{
					Outputs++;
				}
				if(v < Hm-1)
				if(Massive[c][v].Down == true &&
					Massive[c][v+1].Fill != TEMPORARY_FILL &&
					Massive[c][v+1].Fill != DEADLOCK_FILL)
				{
					Outputs++;
				}
			}
		}
	}
	if (Outputs == 1)
		return 1;
	return 0;
}

// Создать деревья по периметру карты
void fCreateTreesPerimeterMap (MapCell **Massive, int Wm, int Hm)
{
	for (int c=0; c<Wm; c++)
	{
		Massive[c][0].UpT = 1;
		Massive[c][Hm-1].DownT = 1;
	}
	for (int v=0; v<Hm; v++)
	{
		Massive[0][v].LeftT = 1;
		Massive[Wm-1][v].RightT = 1;
	}
}

// Проверить уровень вокруг клетки
int fCheckLevelAroundThisCell(MapCell **Massive, int Wm, int Hm, int _c1, int _v1, int Num)
{
	int _Level;
	int _NumPeak;
	int vLevel;
	int vNumPeak;
	int _NumBase;
	int vNumBase;

	int _c;
	int _v;
	if (_c1 < 0 || _v1 < 0 || _c1 >= Wm || _v1 >= Hm)
		return 0;
	_Level = Massive[_c1][_v1].LevelUpland;
	_NumPeak = Massive[_c1][_v1].NumPeak;
	_NumBase = Massive[_c1][_v1].NumBase;
	//
	for (int c=-1;c<=1;c++)
	{
		for (int v=-1;v<=1;v++)
		{
			if ((c == -1 && v == 0 && Massive[_c1][_v1].LeftT == 0) ||
				(c == 0 && v == -1 && Massive[_c1][_v1].UpT == 0) ||
				(c == 1 && v == 0 && Massive[_c1][_v1].RightT == 0) ||
				(c == 0 && v == 1 && Massive[_c1][_v1].DownT == 0))
			{
				_c = _c1 + c;
				_v = _v1 + v;
				if (_c >= 0 && _v >= 0 && _c < Wm && _v < Hm)
				{
					vLevel = Massive[_c][_v].LevelUpland - _Level;
					vNumPeak = Massive[_c][_v].NumPeak;
					vNumBase = Massive[_c][_v].NumBase;
					if (_NumPeak > vNumPeak && _NumBase == vNumBase &&
						abs(vLevel) > Num && abs(vLevel) <= Num + 1 )
						return 0;
				}
			}
		}
	}
	return 1;
}

// Залить базу
int fPourBase (MapCell **Massive, int Wm, int Hm, int _c1, int _v1, int &_Step)
{
	int Flag;
	int Step;

	int _c;
	int _v;

	RECT Teleport;

	if (_c1 < 0 || _v1 < 0 || _c1 >= Wm || _v1 >= Hm)
		return 0;

	if ( Massive[_c1][_v1].Attribute != LANDSCAPE)
		return 0;

	for (int c=0;c<Wm;c++)
	{
		for (int v=0;v<Hm;v++)
		{
			Massive[c][v].Fill = 0;
			Massive[c][v].NumPeak = 0;
			Massive[c][v].PeakAttr = false;
		}
	}

	Step = 1;
	Massive[_c1][_v1].NumPeak = Step;
	Massive[_c1][_v1].PeakAttr = true;

	do
	{
		Flag = 0;
		for (int c=0; c<Wm; c++)
		{
			for (int v=0; v<Hm; v++)
			{
				if(Massive[c][v].PeakAttr == true && Massive[c][v].NumPeak == Step)
				{
					if (Massive[c][v].Tele == true)
					{
						Flag = 1;
						Teleport = Massive[c][v].Teleport;
						for (int vvi=Teleport.left;vvi<=Teleport.right;vvi++)
						{
							for (int vvj=Teleport.top;vvj<=Teleport.bottom;vvj++)
							{
								_c = vvi;
								_v = vvj;
								if (_c >= 0 && _v >= 0 && _c < Wm && _v < Hm)
								{
									if (Massive[_c][_v].Attribute == TELEPORT &&
										Massive[_c][_v].PeakAttr == false &&
										Massive[_c][_v].NumPeak == 0)
									{
										Massive[_c][_v].NumPeak = Massive[c][v].NumPeak+1;
										Massive[_c][_v].PeakAttr = true;
										Massive[_c][_v].Fill = BASE_FILL;
									}
								}
							}
						}
					}
					if(c > 0)
					if(Massive[c][v].Left == true && Massive[c-1][v].PeakAttr == false &&
						Massive[c-1][v].Fill == 0 &&
						(Massive[c-1][v].Attribute == BASEHUMAN ||
						Massive[c-1][v].Attribute == TELEPORT))
					{
						Flag = 1;
						Massive[c-1][v].NumPeak = Massive[c][v].NumPeak+1;
						Massive[c-1][v].PeakAttr = true;
						Massive[c-1][v].Fill = BASE_FILL;
					}
					if(v > 0)
					if(Massive[c][v].Up == true && Massive[c][v-1].PeakAttr == false &&
						Massive[c][v-1].Fill == 0 &&
						(Massive[c][v-1].Attribute == BASEHUMAN ||
						Massive[c][v-1].Attribute == TELEPORT))
					{
						Flag = 1;
						Massive[c][v-1].NumPeak = Massive[c][v].NumPeak+1;
						Massive[c][v-1].PeakAttr = true;
						Massive[c][v-1].Fill = BASE_FILL;
					}
					if(c < Wm-1)
					if(Massive[c][v].Right == true && Massive[c+1][v].PeakAttr == false &&
						Massive[c+1][v].Fill == 0 &&
						(Massive[c+1][v].Attribute == BASEHUMAN ||
						Massive[c+1][v].Attribute == TELEPORT))
					{
						Flag = 1;
						Massive[c+1][v].NumPeak = Massive[c][v].NumPeak+1;
						Massive[c+1][v].PeakAttr = true;
						Massive[c+1][v].Fill = BASE_FILL;
					}
					if(v < Hm-1)
					if(Massive[c][v].Down == true && Massive[c][v+1].PeakAttr == false &&
						Massive[c][v+1].Fill == 0 &&
						(Massive[c][v+1].Attribute == BASEHUMAN ||
						Massive[c][v+1].Attribute == TELEPORT))
					{
						Flag = 1;
						Massive[c][v+1].NumPeak = Massive[c][v].NumPeak+1;
						Massive[c][v+1].PeakAttr = true;
						Massive[c][v+1].Fill = BASE_FILL;
					}
				}
			}
		}
		Step++;
	}
	while(Flag == 1);
	Massive[_c1][_v1].NumPeak = 0;
	Massive[_c1][_v1].PeakAttr = false;
	_Step = Step;
	return 1;
}

int fPourFollowingPlot (MapCell **Massive, int Wm, int Hm, int _Step,
						 int &_Flag2, int &_c2, int &_v2)
{
	int Flag;
	int Flag2;
	int Step;
	int vLevel;

	int _c;
	int _v;

	RECT Teleport;

	if (_Step < 0)
		return 0;

	Step = _Step;
	vLevel = 0;

	Flag2 = 0;
	Flag = 0;
	for (int vvi=0;vvi<Step;vvi++)
	{
		for (int c=0; c<Wm; c++)
		{
			for (int v=0; v<Hm; v++)
			{
				if (Massive[c][v].Fill == BASE_FILL && Massive[c][v].NumPeak == vvi)
				{
					Flag = 1;
					Massive[c][v].Fill = TEMPORARY_FILL;
					vLevel = Massive[c][v].LevelUpland;
					break;
				}
			}
			if (Flag == 1) break;
		}
		if (Flag == 1) break;
	}
	if (Flag == 0)
		return 0;		
	do	// проверить уровни возвышенности
	{
		Flag = 0;
		for (int c=0; c<Wm; c++)
		{
			for (int v=0; v<Hm; v++)
			{
				if (Massive[c][v].Fill == TEMPORARY_FILL)
				{
					if (Massive[c][v].Tele == true)
					{
						Teleport = Massive[c][v].Teleport;
						for (int vvi=Teleport.left;vvi<=Teleport.right;vvi++)
						{
							for (int vvj=Teleport.top;vvj<=Teleport.bottom;vvj++)
							{
								_c = vvi;
								_v = vvj;
								if (_c >= 0 && _v >= 0 && _c < Wm && _v < Hm)
								if (Massive[_c][_v].Attribute == TELEPORT)
								{
									Flag2 = 1;
									_c2 = _c-1;
									_v2 = _v;
								}
							}
						}
					}
					if(c > 0)
					if(Massive[c][v].Left == true && Massive[c-1][v].Fill == BASE_FILL)
					{
						if (Massive[c-1][v].LevelUpland == vLevel)
						{
							Flag = 1;
							Massive[c-1][v].Fill = TEMPORARY_FILL;
						}
						else
						{
							Flag2 = 1;
							_c2 = c-1;
							_v2 = v;
						}
					}
					if(v > 0)
					if(Massive[c][v].Up == true && Massive[c][v-1].Fill == BASE_FILL)
					{
						if (Massive[c][v-1].LevelUpland == vLevel)
						{
							Flag = 1;
							Massive[c][v-1].Fill = TEMPORARY_FILL;
						}
						else
						{
							Flag2 = 1;
							_c2 = c;
							_v2 = v-1;
						}
					}
					if(c < Wm-1)
					if(Massive[c][v].Right == true && Massive[c+1][v].Fill == BASE_FILL)
					{
						if (Massive[c+1][v].LevelUpland == vLevel)
						{
							Flag = 1;
							Massive[c+1][v].Fill = TEMPORARY_FILL;
						}
						else
						{
							Flag2 = 1;
							_c2 = c+1;
							_v2 = v;
						}
					}
					if(v < Hm-1)
					if(Massive[c][v].Down == true && Massive[c][v+1].Fill == BASE_FILL)
					{
						if (Massive[c][v+1].LevelUpland == vLevel)
						{
							Flag = 1;
							Massive[c][v+1].Fill = TEMPORARY_FILL;
						}
						else
						{
							Flag2 = 1;
							_c2 = c;
							_v2 = v+1;
						}
					}
				}
			}
		}
	}
	while (Flag == 1);
	_Flag2 = Flag2;
	return 1;
}
// Проверить кровь вокруг клетки
int fCheckBloodAroundCell (MapCell **Massive, int Wm, int Hm, int _c, int _v)
{
	int _c1;
	int _v1;
	int vFlag;

	if (_c < 0 || _v < 0 || _c >= Wm || _v >= Hm)
		return 0;

	vFlag = 0;
	for (int vvi=-1;vvi<=1;vvi++)
	{
		for (int vvj=-1;vvj<=1;vvj++)
		{
			if (!(vvi == 0 && vvj == 0))
			{
				_c1 = _c + vvi;
				_v1 = _v + vvj;
				if (_c1 >= 0 && _v1 >= 0 && _c1 < Wm && _v1 < Hm)
				if (Massive[_c1][_v1].Blood == true)
				{
					vFlag = 1;
					break;
				}
			}
		}
		if (vFlag == 1) break;
	}
	if (vFlag == 1)
		return 1;
	return 0;
}
// Проверить вал вокруг клетки
int fCheckWallAroundCell (MapCell **Massive, int Wm, int Hm, int _c, int _v)
{
	int _c1;
	int _v1;
	int vFlag;

	if (_c < 0 || _v < 0 || _c >= Wm || _v >= Hm)
		return 0;

	vFlag = 0;
	for (int vvi=-1;vvi<=1;vvi++)
	{
		for (int vvj=-1;vvj<=1;vvj++)
		{
			if (!(vvi == 0 && vvj == 0))
			{
				_c1 = _c + vvi;
				_v1 = _v + vvj;
				if (_c1 >= 0 && _v1 >= 0 && _c1 < Wm && _v1 < Hm)
				if (Massive[_c1][_v1].Wall == true)
				{
					vFlag = 1;
					break;
				}
			}
		}
		if (vFlag == 1) break;
	}
	if (vFlag == 1)
		return 1;
	return 0;
}
// Кол-во свободных клеток вокруг этой клетки
int fCountFreeCellsAroundThisCell(MapCell **Massive, int Wm, int Hm, int _c, int _v)
{
	int CountFreeCell;

	if (_c < 0 || _v < 0 || _c >= Wm || _v >= Hm)
		return 0;

	CountFreeCell = 0;
	if (_c > 0)
	if ((Massive[_c-1][_v].Attribute == OUTSIDE ||
		Massive[_c-1][_v].Attribute == INSIDE ||
		Massive[_c-1][_v].Attribute == BORDER ||
		Massive[_c-1][_v].Attribute == LANDSCAPE) &&
		Massive[_c-1][_v].Fill == 0)
		CountFreeCell++;
	if (_v > 0)
	if ((Massive[_c][_v-1].Attribute == OUTSIDE ||
		Massive[_c][_v-1].Attribute == INSIDE ||
		Massive[_c][_v-1].Attribute == BORDER ||
		Massive[_c][_v-1].Attribute == LANDSCAPE) &&
		Massive[_c][_v-1].Fill == 0)
		CountFreeCell++;
	if (_c < Wm - 1)
	if ((Massive[_c+1][_v].Attribute == OUTSIDE ||
		Massive[_c+1][_v].Attribute == INSIDE ||
		Massive[_c+1][_v].Attribute == BORDER ||
		Massive[_c+1][_v].Attribute == LANDSCAPE) &&
		Massive[_c+1][_v].Fill == 0)
		CountFreeCell++;
	if (_v < Hm - 1)
	if ((Massive[_c][_v+1].Attribute == OUTSIDE ||
		Massive[_c][_v+1].Attribute == INSIDE ||
		Massive[_c][_v+1].Attribute == BORDER ||
		Massive[_c][_v+1].Attribute == LANDSCAPE) &&
		Massive[_c][_v+1].Fill == 0)
		CountFreeCell++;
	return CountFreeCell;
}
// Проверить клетки перехода
int fCheckCellPass (MapCell **Massive, int Wm, int Hm, int _c, int _v)
{
	int vFlag;
	int _c1;
	int _v1;

	if (_c < 0 || _v < 0 || _c >= Wm || _v >= Hm)
		return 0;
	// проверить клетки перехода вокруг
	vFlag = 0;
	for (int vvi=-1;vvi<=1;vvi++)
	{
		for (int vvj=-1;vvj<=1;vvj++)
		{
			if (!(vvi == 0 && vvj == 0))
			{
				_c1 = _c+vvi;
				_v1 = _v+vvj;
				if (_c1 >= 0 && _v1 >= 0 && _c1 < Wm && _v1 < Hm)
				{
					if (Massive[_c1][_v1].CellCountPass > 0)
					{
						vFlag = 1;
						break;
					}
				}
			}
		}
		if (vFlag == 1) break;
	}
	if (vFlag == 1)
		return 1;
	return 0;
}
// Проверить клетки перехода 2
int fCheckCellPass2 (MapCell **Massive, int Wm, int Hm, int _c, int _v)
{
	if (_c < 0 || _v < 0 || _c >= Wm || _v >= Hm)
		return 0;
	// проверить переходы, которые располагаются с 4 сторон, через одну клетку  
	if (_c > 1)
	if (Massive[_c-2][_v].CellCountPass > 0 &&
		Massive[_c-2][_v].LevelUpland > Massive[_c-1][_v].LevelUpland)
		return 1;
	if (_v > 1)
	if (Massive[_c][_v-2].CellCountPass > 0 &&
		Massive[_c][_v-2].LevelUpland > Massive[_c][_v-1].LevelUpland)
		return 1;
	if (_c < Wm - 2)
	if (Massive[_c+2][_v].CellCountPass > 0 &&
		Massive[_c+2][_v].LevelUpland > Massive[_c+1][_v].LevelUpland)
		return 1;
	if (_v < Hm - 2)
	if (Massive[_c][_v+2].CellCountPass > 0 &&
		Massive[_c][_v+2].LevelUpland > Massive[_c][_v+1].LevelUpland)
		return 1;
	return 0;
}
// Проверить клетки перехода 3
int fCheckCellPass3 (MapCell **Massive, int Wm, int Hm, int _c, int _v)
{
	int vFlag;
	int _c1;
	int _v1;

	if (_c < 0 || _v < 0 || _c >= Wm || _v >= Hm)
		return 0;

	if (Massive[_c][_v].Attribute != BASEHUMAN)
		return 0;

	// проверить обе клетки перехода
	vFlag = 0;
	for (int vvi=-1;vvi<=1;vvi++)
	{
		for (int vvj=-1;vvj<=1;vvj++)
		{
			if ((vvi == -1 && vvj == 0) ||
				(vvi == 0 && vvj == -1) ||
				(vvi == 1 && vvj == 0) ||
				(vvi == 0 && vvj == 1))
			{
				_c1 = _c+vvi;
				_v1 = _v+vvj;
				if (_c1 >= 0 && _v1 >= 0 && _c1 < Wm && _v1 < Hm)
				{
					if (Massive[_c1][_v1].Attribute == OUTSIDE ||
						Massive[_c1][_v1].Attribute == INSIDE ||
						Massive[_c1][_v1].Attribute == BORDER ||
						Massive[_c1][_v1].Attribute == LANDSCAPE)
					{
						if (Massive[_c1][_v1].CellCountPass > 0)
						{
							vFlag = 1;
							break;
						}
						else
						{
							if (_c1 > 0)
							if (Massive[_c1-1][_v1].LevelUpland != Massive[_c1][_v1].LevelUpland &&
								Massive[_c1-1][_v1].NumPeak > Massive[_c1][_v1].NumPeak)
							{
								vFlag = 1;
								break;
							}
							if (_v1 > 0)
							if (Massive[_c1][_v1-1].LevelUpland != Massive[_c1][_v1].LevelUpland &&
								Massive[_c1][_v1-1].NumPeak > Massive[_c1][_v1].NumPeak)
							{
								vFlag = 1;
								break;
							}
							if (_c1 < Wm - 1)
							if (Massive[_c1+1][_v1].LevelUpland != Massive[_c1][_v1].LevelUpland &&
								Massive[_c1+1][_v1].NumPeak > Massive[_c1][_v1].NumPeak)
							{
								vFlag = 1;
								break;
							}
							if (_v1 < Hm - 1)
							if (Massive[_c1][_v1+1].LevelUpland != Massive[_c1][_v1].LevelUpland &&
								Massive[_c1][_v1+1].NumPeak > Massive[_c1][_v1].NumPeak)
							{
								vFlag = 1;
								break;
							}			
						}
					}
				}
			}
		}
		if (vFlag == 1) break;
	}
	if (vFlag == 1)
		return 1;
	return 0;
}
// Проверить уровень вокруг клетки 2
int fCheckLevelAroundThisCell2(MapCell **Massive, int Wm, int Hm, int _c1, int _v1, int Num)
{
	int _Level;
	int vLevel;
	int _c;
	int _v;
	int vCountCells;
	if (_c1 < 0 || _v1 < 0 || _c1 >= Wm || _v1 >= Hm)
		return 0;
	_Level = Massive[_c1][_v1].LevelUpland;
	vCountCells = 0;
	//
	for (int c=-1;c<=1;c++)
	{
		for (int v=-1;v<=1;v++)
		{
			if ((c == -1 && v == 0) ||
				(c == 0 && v == -1) ||
				(c == 1 && v == 0) ||
				(c == 0 && v == 1))
			{
				_c = _c1 + c;
				_v = _v1 + v;
				if (_c >= 0 && _v >= 0 && _c < Wm && _v < Hm)
				if (ppMap[_c][_v].Attribute == OUTSIDE ||
					ppMap[_c][_v].Attribute == INSIDE ||
					ppMap[_c][_v].Attribute == BORDER ||
					ppMap[_c][_v].Attribute == LANDSCAPE ||
					(ppMap[_c][_v].Attribute == BASEHUMAN &&
					ppMap[_c][_v].NumBase != ppMap[_c1][_v1].NumBase))
				{
					vLevel = Massive[_c][_v].LevelUpland - _Level;
					if (abs(vLevel) <= Num)
						vCountCells++;
				}
					
			}
		}
	}
	if (vCountCells == 0)
		return 0;
	return 1;
}
// Редактировать базы
int fEditBases(MapCell **Massive, int Wm, int Hm)
{
	int vFlag;
	int vFlag2;
	int vNumBase;

	int _c1;
	int _v1;

	double vTree;
	double vFelledTrees;
	double vLvlСhange;
	double vIncLvl;
	double vWidePass;

	double vBlood;

	vNumBase = 0;
	//
	do
	{
		vFlag = 0;
		for (int vvi=0;vvi<vSizeArray;vvi++)
		{
			if (vvi > vMaxN)
				break;
			
			if (pBase[vvi].Id >= 0)
			if (pBase[vvi].NumBase == vNumBase && vFlag == 0)
			{
				vFlag = 1;
				if (fFindWayOutFromBase(Massive,Wm,Hm,_c1,_v1,vNumBase) == 1)
				{
					vTree = pBase[vvi].Tree;
					vFelledTrees = pBase[vvi].FelledTrees;
					vLvlСhange = pBase[vvi].LvlСhange;
					vIncLvl = pBase[vvi].IncLvl;
					vWidePass = pBase[vvi].WidePass;

					if (!(vTree < 0 || vTree > 1 ||
						vFelledTrees < 0 || vFelledTrees > 1 ||
						vLvlСhange < 0 || vLvlСhange > 1 ||
						vIncLvl < 0 || vIncLvl > 1 ||
						vWidePass < 0 || vWidePass > 1))
					{
						// заполнить уровни высот
						fFillLevelsElevations(Massive,Wm,Hm,_c1,_v1,
							vLvlСhange,vIncLvl,vWidePass);
						// создаем деревья
						fCreateTrees(Massive,Wm,Hm,_c1,_v1,
							vTree,vFelledTrees);
					}
				}
				break;
			}
		}
		vNumBase++;
	}
	while (vFlag == 1);

	vNumBase = 0;
	//
	do
	{
		vFlag = 0;
		for (int vvi=0;vvi<vSizeArray;vvi++)
		{
			if (vvi > vMaxN - 1)
				break;
			
			if (pBase[vvi].Id >= 0)
			if (pBase[vvi].NumBase == vNumBase && vFlag == 0)
			{
				vFlag = 1;
				if (fFindWayOutFromBase(Massive,Wm,Hm,_c1,_v1,vNumBase) == 1)
				{
					vBlood = pBase[vvi].Blood;

					if (!(vBlood < 0 || vBlood > 1))
					{
						if (rand()%100 <= (int)(vBlood*100))
						{
							fCreateBloodBase(Massive,Wm,Hm,_c1,_v1);
						}
					}
				}
				break;
			}
		}
		vNumBase++;
	}
	while (vFlag == 1);
	return 1;
}
// Найти выход с базы
int fFindWayOutFromBase (MapCell **Massive, int Wm, int Hm, int &_c1, int &_v1, int _NumBase)
{
	int vFlag;
	
	if (_NumBase < 0)
		return 0;

	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			if (Massive[c][v].Wall == true && Massive[c][v].NumBase == _NumBase)
			{
				vFlag = 0;
				if (c > 0)
				if (Massive[c][v].Left == true &&
					(Massive[c-1][v].Attribute == OUTSIDE ||
					Massive[c-1][v].Attribute == INSIDE ||
					Massive[c-1][v].Attribute == BORDER ||
					Massive[c-1][v].Attribute == LANDSCAPE))
				{
					vFlag = 1;
					_c1 = c-1;
					_v1 = v;
					break;
				}
				if (v > 0)
				if (Massive[c][v].Up == true &&
					(Massive[c][v-1].Attribute == OUTSIDE ||
					Massive[c][v-1].Attribute == INSIDE ||
					Massive[c][v-1].Attribute == BORDER ||
					Massive[c][v-1].Attribute == LANDSCAPE))
				{
					vFlag = 1;
					_c1 = c;
					_v1 = v-1;
					break;
				}
				if (c < Wm - 1)
				if (Massive[c][v].Right == true &&
					(Massive[c+1][v].Attribute == OUTSIDE ||
					Massive[c+1][v].Attribute == INSIDE ||
					Massive[c+1][v].Attribute == BORDER ||
					Massive[c+1][v].Attribute == LANDSCAPE))
				{
					vFlag = 1;
					_c1 = c+1;
					_v1 = v;
					break;
				}
				if (v < Hm - 1)
				if (Massive[c][v].Down == true &&
					(Massive[c][v+1].Attribute == OUTSIDE ||
					Massive[c][v+1].Attribute == INSIDE ||
					Massive[c][v+1].Attribute == BORDER ||
					Massive[c][v+1].Attribute == LANDSCAPE))
				{
					vFlag = 1;
					_c1 = c;
					_v1 = v+1;
					break;
				}
			}
		}
		if (vFlag == 1) break;
	}
	if (vFlag == 1)
		return 1;
	return 0;
}
// Создать кровь базы
void fCreateBloodBase(MapCell **Massive, int Wm, int Hm, int _c1, int _v1)
{
	int Flag;
	int Flag2;
	int Step;
	int vLevel;
	int vNum;
	int vFill;

	int _c;
	int _v;
	int _c2;
	int _v2;

	RECT Teleport;

	int t;
	t = (int)timeGetTime();
	//srand (t);	// полный рандом

	if (_c1 < 0 || _v1 < 0 || _c1 >= Wm || _v1 >= Hm)
		return;

	Massive[_c1][_v1].LevelUpland = 0;
	Massive[_c1][_v1].CellCountPass = 0;

	if (fPourBase(Massive,Wm,Hm,_c1,_v1,Step) == 0)
		return;

	vNum = 1;

	// определить двойную возвышенность на предпоследней и последней локе
	while(fPourFollowingPlot(Massive,Wm,Hm,Step,Flag2,_c2,_v2) == 1)
	{
		if (Flag2 == 0)
		{
			// делаем заливку базы
			// план 1 - последняя лока (локация)
			// план 2 - предпоследняя локация
			// план 1 = план 2
			// темп = план 1
			// база = план 1
			fReplaceCells(Massive,Wm,Hm,PLANE_FILL,PLANE2_FILL);
			fReplaceCells(Massive,Wm,Hm,TEMPORARY_FILL,PLANE_FILL);
			fReplaceCells(Massive,Wm,Hm,BASE_FILL,PLANE_FILL);
			// определяем двойную возвышенность
			for (int c=0; c<Wm; c++)
			{
				for (int v=0; v<Hm; v++)
				{
					if ((Massive[c][v].Fill == PLANE_FILL ||
						Massive[c][v].Fill == PLANE2_FILL) &&
						Massive[c][v].Tele == false && Massive[c][v].Wall == false)
					{
						if (fCheckLevelAroundThisCell(Massive,Wm,Hm,c,v,vNum) == 0)
						{
							Massive[c][v].Fill = DOUBLEHILL_FILL;
						}
					}
				}
			}
			break;
		}
		// план 1 = чек
		// темп = план 1
		fReplaceCells(Massive,Wm,Hm,PLANE_FILL,CHECK_FILL);
		fReplaceCells(Massive,Wm,Hm,TEMPORARY_FILL,PLANE_FILL);
	}
	// чек = база
	fReplaceCells(Massive,Wm,Hm,CHECK_FILL,BASE_FILL);
	// поставить кровь на двойной возвышености в последней и предпоследней локе
	// совпадающей с периметром базы
	// расставляем периметры базы:
	// последней локи, предпоследей локи, и оставщийся периметр базы
	Flag2 = 0;
	_c = -1;
	_v = -1;
	for (int vvi=0;vvi<Step;vvi++)
	{
		for (int c=0; c<Wm; c++)
		{
			for (int v=0; v<Hm; v++)
			{
				if(Massive[c][v].Fill != 0)
				{
					Flag = 0;
					if(c > 0)
					if((Massive[c][v].LeftT == 0 ||
						Massive[c][v].LeftT == 2) &&
						Massive[c-1][v].Fill == 0 &&
						(Massive[c-1][v].Attribute != BASEHUMAN ||
						(Massive[c-1][v].Attribute == BASEHUMAN &&
						Massive[c-1][v].NumBase != Massive[c][v].NumBase &&
						((Massive[c-1][v].LevelUpland == Massive[c][v].LevelUpland &&
						Massive[c-1][v].RightT == 1) ||
						(Massive[c-1][v].LevelUpland != Massive[c][v].LevelUpland &&
						Massive[c-1][v].RightT != 1)))))
					{
						Flag = 1;
					}
					if(v > 0)
					if((Massive[c][v].UpT == 0 ||
						Massive[c][v].UpT == 2) &&
						Massive[c][v-1].Fill == 0 &&
						(Massive[c][v-1].Attribute != BASEHUMAN ||
						(Massive[c][v-1].Attribute == BASEHUMAN &&
						Massive[c][v-1].NumBase != Massive[c][v].NumBase &&
						((Massive[c][v-1].LevelUpland == Massive[c][v].LevelUpland &&
						Massive[c][v-1].DownT == 1) ||
						(Massive[c][v-1].LevelUpland != Massive[c][v].LevelUpland &&
						Massive[c][v-1].DownT != 1)))))
					{
						Flag = 1;
					}
					if(c < Wm-1)
					if((Massive[c][v].RightT == 0 ||
						Massive[c][v].RightT == 2) &&
						Massive[c+1][v].Fill == 0 &&
						(Massive[c+1][v].Attribute != BASEHUMAN ||
						(Massive[c+1][v].Attribute == BASEHUMAN &&
						Massive[c+1][v].NumBase != Massive[c][v].NumBase &&
						((Massive[c+1][v].LevelUpland == Massive[c][v].LevelUpland &&
						Massive[c+1][v].LeftT == 1) ||
						(Massive[c+1][v].LevelUpland != Massive[c][v].LevelUpland &&
						Massive[c+1][v].LeftT != 1)))))
					{
						Flag = 1;
					}
					if(v < Hm-1)
					if((Massive[c][v].DownT == 0 ||
						Massive[c][v].DownT == 2) &&
						Massive[c][v+1].Fill == 0 &&
						(Massive[c][v+1].Attribute != BASEHUMAN ||
						(Massive[c][v+1].Attribute == BASEHUMAN &&
						Massive[c][v+1].NumBase != Massive[c][v].NumBase &&
						((Massive[c][v+1].LevelUpland == Massive[c][v].LevelUpland &&
						Massive[c][v+1].UpT == 1) ||
						(Massive[c][v+1].LevelUpland != Massive[c][v].LevelUpland &&
						Massive[c][v+1].UpT != 1)))))
					{
						Flag = 1;
					}
					if (Flag == 1)
					{
						if (Massive[c][v].Tele == false && Massive[c][v].Wall == false &&
							fCheckBloodAroundCell(Massive,Wm,Hm,c,v) == 0 &&
							//fCheckCellPass3(Massive,Wm,Hm,c,v) == 0)// &&
							fCheckWallAroundCell(Massive,Wm,Hm,c,v) == 0)
						{
							if (Massive[c][v].Fill == DOUBLEHILL_FILL)
							{
								if (_c == -1 && _v == -1)
								{
									Flag2 = 1;
									_c = c;
									_v = v;
								}
								if (_c >= 0 && _v >= 0 && _c < Wm && _v < Hm)
								if (Massive[c][v].NumPeak > Massive[_c][_v].NumPeak)
								{
									Flag2 = 1;
									_c = c;
									_v = v;
								}
							}
							if (Massive[c][v].Fill == PLANE_FILL)
								Massive[c][v].Fill = PERIMETER3_FILL;
							if (Massive[c][v].Fill == PLANE2_FILL)
								Massive[c][v].Fill = PERIMETER2_FILL;
							if (Massive[c][v].Fill == BASE_FILL)
								Massive[c][v].Fill = PERIMETER_FILL;
						}
					}
				}
			}
		}
	}
	if (Flag2 == 1)
	{
		Massive[_c][_v].Blood = true;
		return;
	}
	fReplaceCells(Massive,Wm,Hm,PLANE_FILL,BASE_FILL);
	fReplaceCells(Massive,Wm,Hm,PLANE2_FILL,BASE_FILL);
	vNum = 2;
	// расставляем кровь на периметре базы, по приоритету
	for (int vvi=0;vvi<3;vvi++)
	{
		if (vvi == 0) vFill = PERIMETER2_FILL;	// поставить кровь на периметре предпоследней локи
		if (vvi == 1) vFill = PERIMETER3_FILL;	// поставить кровь на периметре последней локи
		if (vvi == 2) vFill = PERIMETER_FILL;	// поставить кровь на периметре
		Flag2 = 0;
		_c = -1;
		_v = -1;
		for (int c=0; c<Wm; c++)
		{
			for (int v=0; v<Hm; v++)
			{
				if(Massive[c][v].Fill == vFill &&
					Massive[c][v].Tele == false && Massive[c][v].Wall == false &&
					fCheckBloodAroundCell(Massive,Wm,Hm,c,v) == 0 &&
					fCheckWallAroundCell(Massive,Wm,Hm,c,v) == 0 &&
					//fCheckCellPass3(Massive,Wm,Hm,c,v) == 0 &&
					Massive[c][v].LevelUpland <= 2 &&
					Massive[c][v].LevelUpland >= -2 &&
					fCheckCellPass2(Massive,Wm,Hm,c,v) == 0 &&
					fCheckLevelAroundThisCell2(Massive,Wm,Hm,c,v,vNum) == 1)
				{
					Flag2 = 1;
					_c = c;
					_v = v;
					break;
				}
			}
			if (Flag2 == 1) break;
		}
		if (Flag2 == 1)
		{
			Massive[_c][_v].Blood = true;
			break;
		}
	}
}
// Проверить карту на закрытые клетки
int fCheckMapOnTheClosedCells (MapCell **Massive, int Wm, int Hm, int _c1, int _v1)
{
	int vFlag;
	int vStep;
	int _c;
	int _v;

	RECT Teleport;

	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			Massive[c][v].NumPeak = 0;
			Massive[c][v].PeakAttr = false;
		}
	}
	vStep = 1;
	Massive[_c1][_v1].NumPeak = vStep;
	Massive[_c1][_v1].PeakAttr = true;
	do
	{
		vFlag = 0;
		for (int c=0; c<Wm; c++)
		{
			for (int v=0; v<Hm; v++)
			{
				if(Massive[c][v].PeakAttr == true && Massive[c][v].NumPeak == vStep)
				{
					if (Massive[c][v].Tele == true)
					{
						vFlag = 1;
						Teleport = Massive[c][v].Teleport;
						for (int vvi=Teleport.left;vvi<=Teleport.right;vvi++)
						{
							for (int vvj=Teleport.top;vvj<=Teleport.bottom;vvj++)
							{
								_c = vvi;
								_v = vvj;
								if (_c >= 0 && _v >= 0 && _c < Wm && _v < Hm)
								{
									if (Massive[_c][_v].Attribute == TELEPORT &&
										Massive[_c][_v].PeakAttr == false &&
										Massive[_c][_v].NumPeak == 0)
									{
										Massive[_c][_v].NumPeak = Massive[c][v].NumPeak+1;
										Massive[_c][_v].PeakAttr = true;
									}
								}
							}
						}
					}
					if(c > 0)
					if(Massive[c][v].Left == true && Massive[c-1][v].PeakAttr == false)
					{
						vFlag = 1;
						Massive[c-1][v].NumPeak = Massive[c][v].NumPeak+1;
						Massive[c-1][v].PeakAttr = true;
					}
					if(v > 0)
					if(Massive[c][v].Up == true && Massive[c][v-1].PeakAttr == false)
					{
						vFlag = 1;
						Massive[c][v-1].NumPeak = Massive[c][v].NumPeak+1;
						Massive[c][v-1].PeakAttr = true;
					}
					if(c < Wm-1)
					if(Massive[c][v].Right == true && Massive[c+1][v].PeakAttr == false)
					{
						vFlag = 1;
						Massive[c+1][v].NumPeak = Massive[c][v].NumPeak+1;
						Massive[c+1][v].PeakAttr = true;
					}
					if(v < Hm-1)
					if(Massive[c][v].Down == true && Massive[c][v+1].PeakAttr == false)
					{
						vFlag = 1;
						Massive[c][v+1].NumPeak = Massive[c][v].NumPeak+1;
						Massive[c][v+1].PeakAttr = true;
					}
				}
			}
		}
		vStep++;
	}
	while(vFlag == 1);
	//
	vFlag = 0;
	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			if(Massive[c][v].PeakAttr == false)
			{
				vFlag = 1;
				break;
			}
		}
		if (vFlag == 1) break;
	}
	if (vFlag == 1)
		return 0;
	return 1;
}
// Поставим бордюрчики вокруг воды (учитывая клетки перехода)
int fLetIsPutBordersRoundWater(MapCell **Massive, int Wm, int Hm)
{
	int vBorderN;
	int vPassN;
	int vFlag;

	for (int c=0; c<Wm; c++)
	{
		for (int v=0; v<Hm; v++)
		{
			if(Massive[c][v].Fill == SHOAL_FILL)
			{
				vBorderN = 0;
				vPassN = 0;
				if (Massive[c][v].CellCountPass == 2)
					vPassN = 1;
				if (Massive[c][v].CellCountPass == 1)
					vPassN = 1 + rand()%2;
				//
				if (c > 0)
				if (Massive[c-1][v].Fill != SHOAL_FILL)
				{
					Massive[c][v].Left = false;
					if ((Massive[c-1][v].Attribute == OUTSIDE ||
						Massive[c-1][v].Attribute == INSIDE ||
						Massive[c-1][v].Attribute == BORDER ||
						Massive[c-1][v].Attribute == LANDSCAPE) &&
						vBorderN < vPassN)
					{
						vFlag = 0;
						if (c > 0 && v > 0)
						if (Massive[c-1][v-1].Fill == SHOAL_FILL)
							vFlag = 1;
						if (c > 0 && v < Hm-1)
						if (Massive[c-1][v+1].Fill == SHOAL_FILL)
							vFlag = 1;
						if (vFlag == 0)
						{
							Massive[c][v].Left = true;
							vBorderN++;
						}
					}
				}
				if (v > 0)
				if (Massive[c][v-1].Fill != SHOAL_FILL)
				{
					Massive[c][v].Up = false;
					if ((ppMap[c][v-1].Attribute == OUTSIDE ||
						ppMap[c][v-1].Attribute == INSIDE ||
						ppMap[c][v-1].Attribute == BORDER ||
						ppMap[c][v-1].Attribute == LANDSCAPE) &&
						vBorderN < vPassN)
					{
						vFlag = 0;
						if (c > 0 && v > 0)
						if (Massive[c-1][v-1].Fill == SHOAL_FILL)
							vFlag = 1;
						if (c < Wm-1 && v > 0)
						if (Massive[c+1][v-1].Fill == SHOAL_FILL)
							vFlag = 1;
						if (vFlag == 0)
						{
							Massive[c][v].Up = true;
							vBorderN++;
						}
					}
				}
				if (c < Wm-1)
				if (Massive[c+1][v].Fill != SHOAL_FILL)
				{
					Massive[c][v].Right = false;
					if ((ppMap[c+1][v].Attribute == OUTSIDE ||
						ppMap[c+1][v].Attribute == INSIDE ||
						ppMap[c+1][v].Attribute == BORDER ||
						ppMap[c+1][v].Attribute == LANDSCAPE) &&
						vBorderN < vPassN)
					{
						vFlag = 0;
						if (c < Wm-1 && v > 0)
						if (Massive[c+1][v-1].Fill == SHOAL_FILL)
							vFlag = 1;
						if (c < Wm-1 && v < Hm-1)
						if (Massive[c+1][v+1].Fill == SHOAL_FILL)
							vFlag = 1;
						if (vFlag == 0)
						{
							Massive[c][v].Right = true;
							vBorderN++;
						}
					}
				}
				if (v < Hm-1)
				if (Massive[c][v+1].Fill != SHOAL_FILL)
				{
					Massive[c][v].Down = false;
					if ((ppMap[c][v+1].Attribute == OUTSIDE ||
						ppMap[c][v+1].Attribute == INSIDE ||
						ppMap[c][v+1].Attribute == BORDER ||
						ppMap[c][v+1].Attribute == LANDSCAPE) &&
						vBorderN < 1 && vPassN > 0)
						//vBorderN < vPassN// && ((Massive[c][v].Left == false &&
						//Massive[c-1][v].Fill != SHOAL_FILL) ||
						//Massive[c-1][v].Fill == SHOAL_FILL))
					{
						vFlag = 0;
						if (c > 0 && v < Hm-1)
						if (Massive[c-1][v+1].Fill == SHOAL_FILL)
							vFlag = 1;
						if (c < Wm-1 && v < Hm-1)
						if (Massive[c+1][v+1].Fill == SHOAL_FILL)
							vFlag = 1;
						if (vFlag == 0)
						{
							Massive[c][v].Down = true;
							vBorderN++;
						}
					}
				}
			}
		}
	}
	fAddNotDatausaBorder(Massive,Wm,Hm);
	return 1;
}
// Создаем клетки перехода в воде
void fCreateCellPassInWater(MapCell **Massive, int Wm, int Hm, int _c1, int _v1)
{
	int _c2;
	int _v2;
	int vNumBase;
	int vFlag;
	int vCellN;
	int vStep;
	int vNumPeak;

	_c2 = _c1;
	_v2 = _v1;

	for (int vvi=0;vvi<2;vvi++)
	{
		vFlag = 0;
		vStep = 0;

		for (int c=0; c<Wm; c++)
		{
			for (int v=0; v<Hm; v++)
			{
				Massive[c][v].NumPeak = 0;
				Massive[c][v].PeakAttr = false;
			}
		}

		vStep = 1;
		Massive[_c2][_v2].NumPeak = vStep;
		Massive[_c2][_v2].PeakAttr = true;

		do
		{
			vFlag = 0;
			for (int c=0; c<Wm; c++)
			{
				for (int v=0; v<Hm; v++)
				{
					if(Massive[c][v].PeakAttr == true && Massive[c][v].NumPeak == vStep)
					{
						if(c > 0)
						if(Massive[c][v].Left == true && Massive[c-1][v].PeakAttr == false &&
							Massive[c-1][v].Fill == SHOAL_FILL)
						{
							vFlag = 1;
							Massive[c-1][v].NumPeak = Massive[c][v].NumPeak+1;
							Massive[c-1][v].PeakAttr = true;
						}
						if(v > 0)
						if(Massive[c][v].Up == true && Massive[c][v-1].PeakAttr == false &&
							Massive[c][v-1].Fill == SHOAL_FILL)
						{
							vFlag = 1;
							Massive[c][v-1].NumPeak = Massive[c][v].NumPeak+1;
							Massive[c][v-1].PeakAttr = true;
						}
						if(c < Wm-1)
						if(Massive[c][v].Right == true && Massive[c+1][v].PeakAttr == false &&
							Massive[c+1][v].Fill == SHOAL_FILL)
						{
							vFlag = 1;
							Massive[c+1][v].NumPeak = Massive[c][v].NumPeak+1;
							Massive[c+1][v].PeakAttr = true;
						}
						if(v < Hm-1)
						if(Massive[c][v].Down == true && Massive[c][v+1].PeakAttr == false &&
							Massive[c][v+1].Fill == SHOAL_FILL)
						{
							vFlag = 1;
							Massive[c][v+1].NumPeak = Massive[c][v].NumPeak+1;
							Massive[c][v+1].PeakAttr = true;
						}
					}
				}
			}
			vStep++;
		}
		while(vFlag == 1);

		for (int c=0; c<Wm; c++)
		{
			for (int v=0; v<Hm; v++)
			{
				if (Massive[c][v].Fill == SHOAL_FILL)
				{
					vNumPeak = Massive[c][v].NumPeak;
					if (Massive[c][v].NumPeak == vStep-1)
					{
						vFlag = 1;
						_c2 = c;
						_v2 = v;
						break;
					}
				}
			}
			if (vFlag == 1) break;
		}
		if (vFlag == 1)
		{
			vCellN = fCountFreeCellsAroundThisCell(Massive,Wm,Hm,_c2,_v2);
			if (vCellN > 0)
			{
				if (vCellN > 1 && vvi == 0)
					Massive[_c2][_v2].CellCountPass = 2;
				else
					Massive[_c2][_v2].CellCountPass = 1;
				Massive[_c2][_v2].Wall = true;
			}
		}
	}
}