#include "stdafx.h"

#include "module3.h"
#include "War3TypesAndConstants.h"
#include "War3Map.h"
#include "W3ZMapEditDoc.h"
#include "module1.h"

/////////////////////////////////////////////////////////////////////////
extern MapCell **ppMap;		// массив карты лабиринта
extern int vWm;				// размер карты лабиринта
extern int vHm;				//
extern int vBaseN;			// кол-во баз на карте
int vkW;					//
int vkH;					//
WorldMap MapMain;			// карта основная
WorldMap MapSlayerPlace;	// карта слаерки
WorldMap MapDancePool;		// карта денс пула
WorldMap MapBaseVampire;	// карта базы вампа
WorldMap MapEditable;		// редактируемая карта
CW3ZMapEditDoc MapEditDoc;	// редактируемый документ карты
/////////////////////////////////////////////////////////////////////////
// Инициализируем карту
void fWorldMapInitialization (int _Width, int _Height, int _Rects, int _NumMap)
{
	WorldMap *pMap;

	pMap = NULL;
	if (fSelectMap(_NumMap,pMap) == 0)
		return;

	if (_Width <= 0 || _Height <= 0)
		return;

	//W3E
	pMap->SetMapSize(_Width,_Height);
	pMap->mapGroundTiles = "LdrtLdroLdrgLgrsLgrdOrokVstp";
	pMap->mapCliffTiles = "CLdiCLgr";

	pMap->mapMainTileset = 'L';
	pMap->mapCustomTilesets = 0;
	pMap->SetMapCenter((float)(_Width * 128 / -2), (float)(_Height * 128 / -2));

	//DOO
	pMap->mapUnknownDooInt = 07;

	pMap->MapInit(true);
	// чистим карту
	fClearMap(pMap);
}
// Загрузить стандартные карты
/*int fLoadDefaultMap ()
{
	RECT AllocationArea;

	if (!MapMain.CheckMapInit() )
		return 0;

	AllocationArea.left = MapMain.GetTilePointsTableWidth()/2 + 20;
	AllocationArea.top = MapMain.GetTilePointsTableHeight()/2 + 11;
	AllocationArea.right = MapMain.GetTilePointsTableWidth()/2 + 44;
	AllocationArea.bottom = MapMain.GetTilePointsTableHeight()/2 + 35;
	MapSlayerPlace = WorldMap(MapMain,AllocationArea);

	AllocationArea.left = MapMain.GetTilePointsTableWidth()/2 - 41;
	AllocationArea.top = MapMain.GetTilePointsTableHeight()/2 + 37;
	AllocationArea.right = MapMain.GetTilePointsTableWidth()/2 - 23;
	AllocationArea.bottom = MapMain.GetTilePointsTableHeight()/2 + 55;
	MapDancePool = WorldMap(MapMain,AllocationArea);

	AllocationArea.left = MapMain.GetTilePointsTableWidth()/2 - 21;
	AllocationArea.top = MapMain.GetTilePointsTableHeight()/2 - 27;
	AllocationArea.right = MapMain.GetTilePointsTableWidth()/2 + 13;
	AllocationArea.bottom = MapMain.GetTilePointsTableHeight()/2 + 11;
	MapBaseVampire = WorldMap(MapMain,AllocationArea);

}*/
// Очистить карту
void fClearMap (WorldMap *pMap)
{
	CDoodad nextdoodad;
	CTilePoint Tilepoint;
	RegionMap* pNextRegion;

	if (!pMap)
		return;
	if (!pMap->CheckMapInit())
		return;

	//GRASS
	fCreateNewTilePoint(GRASS,TILE_LAYER_LEVEL_ZERO,pMap,Tilepoint);
	for (int c=0; c<pMap->GetTilePointsTableWidth(); c++)
	{
		for (int v=0; v<pMap->GetTilePointsTableHeight(); v++)
		{
			pMap->SetTilePoint(c, v, Tilepoint);
		}
	}
	// удаляем объекты декораций
	pMap->GoFirstDoodad();
	do
	{
		nextdoodad = pMap->GetNextDoodad();
		if(nextdoodad.type == "")
			break;
		pMap->DelDoodad(nextdoodad);
	}
	while(nextdoodad.type != "");
	// удаляем все регионы
	pMap->DelAllRegions();
}
// Забрать индекс клетки земли
int fGetTileIndex(char *strTileID, const char *strTilelist)
{
	int vTileIndex;
	int vLen;

	if (!strTileID || !strTilelist)
		return 0;
	vTileIndex = -1;
	vLen = strlen(strTilelist);
	for (int vvi=0;vvi<vLen/4;vvi++)
	{
		if (memcmp(strTileID,strTilelist+vvi*4,WAR3STRID_MAXCHAR) == 0)
		{
			vTileIndex = vvi;
			break;
		}
	}
	return vTileIndex;
}
// Изменить ландшафт
int fChangeLandscape (CTilePoint &Tilepoint, int _Layer, int _Water)
{
	int vHeight;
	int vWaterLevel;

	if (_Layer < _Water || _Layer > TILE_MAX_LAYER ||
		_Water < 0 || _Water > 2)
		return 0;
	if (_Water == 0)
	{
		Tilepoint.height = TILE_HEIGHT_LEVEL_ZERO;
		Tilepoint.waterlevel = TILE_HEIGHT_LEVEL_ZERO;
		Tilepoint.flags &= ~TILE_FL_WATER;
	}
	else
	{
		// на сколько будет высоко вода в этой клетке
		vHeight = TILE_HEIGHT_LEVEL_ZERO + (float)(((_Layer + _Water) - TILE_LAYER_LEVEL_ZERO)*0x0200) / (float)4.0;
		Tilepoint.height = vHeight - (float)(_Water*0x0200) / (float)4.0;
		vWaterLevel = vHeight + (float)(TILE_HEIGHT_LEVEL_ZERO - TILE_WATER_OFFSET) / (float)4.0;;
		Tilepoint.waterlevel = vWaterLevel;
		Tilepoint.flags |= TILE_FL_WATER;
	}
	Tilepoint.layer = _Layer;

	return 1;
}
// Создать карту
void fCreateWorldMap(int _kW, int _kH)
{
	CTilePoint Tilepoint;	// клетка земли
	RegionMap NewRegion;	// новый регион карты
	RECT AllocationArea;	// выделенная область
	int vTerrainType;		// тип местности
	int vTerrainFlags;		// флаг местности
	int vW;					// размер карты земли
	int vH;					// 
	int Width;				// кол-во клеток для объектов декораций
	int Height;				// 
	int vCellCountPass;		// кол-во клеток в спуске
	int vDisplacement;		// смещение
	int vLayer1;			// слой 1
	int vLayer2;			// слой 2
	int vObject;			// объект
	int vGround;			// вероятность для типа местности
	int vCount;				// счетчик
	int vFlag;				// флаг
	int vType;				// тип
	int _c;					//
	int _v;					//
	CDoodad newdoodad;		//
	float _x;				//
	float _y;				//
	float _x1;				//
	float _y1;				//
	int vObjN;				// кол-во объектов
	int vFlagCellGround1;	// флаг клетки земли 1
	int vFlagCellGround2;	// флаг клетки земли 2
	int vBloodN;			// кол-во крови
	int vLevel;				// уровень
	int _c1;				//
	int _v1;				//

	if (_kW <= 0 && _kH <= 0)
		return;

	if (!MapSlayerPlace.CheckMapInit() ||
		!MapDancePool.CheckMapInit() ||
		!MapBaseVampire.CheckMapInit() ||
		!MapEditable.CheckMapInit() )
		return;

	vkW = _kW;
	vkH = _kH;

	vW = MapEditable.GetTilePointsTableWidth();
	vH = MapEditable.GetTilePointsTableHeight();

	fClearMap(&MapEditable);

	_c = -1;
	_v = -1;
	for (int c=0; c<vWm; c++)
	{
		for (int v=0; v<vHm; v++)
		{
			if (ppMap[c][v].Attribute == SLAYERPLACE)
			{
				if (_c < 0 && _v < 0)
				{
					AllocationArea.left = c*vkW;
					AllocationArea.top = v*vkH;
				}
				_c = c;
				_v = v;
			}
		}
	}
	AllocationArea.right = (_c+1)*vkW;
	AllocationArea.bottom = (_v+1)*vkH;
	MapEditable.CopyMap(MapSlayerPlace,AllocationArea);

	NewRegion.Type = SLAYERPLACE;
	NewRegion.Rect.left = AllocationArea.left + 9;
	NewRegion.Rect.top = AllocationArea.top + 6;
	NewRegion.Rect.right = AllocationArea.right - 10;
	NewRegion.Rect.bottom = AllocationArea.bottom - 14;
	MapEditable.AddRegion(NewRegion);
	// Исправить! ^

	_c = -1;
	_v = -1;
	for (int c=0; c<vWm; c++)
	{
		for (int v=0; v<vHm; v++)
		{
			if (ppMap[c][v].Attribute == DANCEPOOL)
			{
				if (_c < 0 && _v < 0)
				{
					AllocationArea.left = c*vkW;
					AllocationArea.top = v*vkH;
				}
				_c = c;
				_v = v;
			}
		}
	}
	AllocationArea.right = (_c+1)*vkW;
	AllocationArea.bottom = (_v+1)*vkH;
	MapEditable.CopyMap(MapDancePool,AllocationArea);

	NewRegion.Type = DANCEPOOL;
	NewRegion.Rect.left = AllocationArea.left + 3;
	NewRegion.Rect.top = AllocationArea.top + 6;
	NewRegion.Rect.right = AllocationArea.right - 13;
	NewRegion.Rect.bottom = AllocationArea.bottom - 11;
	MapEditable.AddRegion(NewRegion);
	// Исправить! ^

	AllocationArea.left = vW/2 - 21;
	AllocationArea.top = vH/2 - 11;
	AllocationArea.right = vW/2 + 13;
	AllocationArea.bottom = vH/2 + 27;
	MapEditable.CopyMap(MapBaseVampire,AllocationArea);

	NewRegion.Type = BASEVAMPIRE;
	NewRegion.Rect = AllocationArea;
	MapEditable.AddRegion(NewRegion);

	MapEditable.SetBaseN(vBaseN);

	Width = vWm*vkW;
	Height = vHm*vkH;

	for (int c=0; c<vWm; c++)
	{
		for (int v=0; v<vHm; v++)
		{
			//
			if (ppMap[c][v].Attribute == BASEHUMAN || ppMap[c][v].Attribute == TELEPORT)
			{
				vTerrainType = -1;
				for (int _c=0;_c<=4;_c++)
				{
					for (int _v=0;_v<=4;_v++)
					{
						vGround = rand()%100;
						if (vGround > 0 && vGround <= 60) vTerrainType = GRASS;
						if (vGround > 60 && vGround <= 65) vTerrainType = SOIL1;
						if (vGround > 65 && vGround <= 80) vTerrainType = COARSESOIL;
						if (vGround > 80 && vGround <= 85) vTerrainType = SOIL2;
						if (vGround > 85 && vGround < 100) vTerrainType = DARKGRASS;
						//Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
						vLayer1 = TILE_LAYER_LEVEL_ZERO + ppMap[c][v].LevelUpland;
						fCreateNewTilePoint(vTerrainType,vLayer1,&MapEditable,Tilepoint);
						MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
					}
				}
			}
		}
	}

	// +1 клетка к уклону больше 2 едениц
	for (int c=0; c<vWm; c++)
	{
		for (int v=0; v<vHm; v++)
		{
			vFlag = 0;
			if (c > 0)
			if (ppMap[c][v].LevelUpland == (ppMap[c-1][v].LevelUpland + 3))
			{
				Tilepoint = MapEditable.GetTilePoint(c*vkW+1, Height-(v*vkH)-1);
				vLayer1 = Tilepoint.layer - 2;
				for (int _c=-1;_c<=-1;_c++)
				{
					for (int _v=-1;_v<=4;_v++)
					{
						Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
						Tilepoint.layer = vLayer1;
						MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
					}
				}
			}
			if (v > 0)
			if (ppMap[c][v].LevelUpland == (ppMap[c][v-1].LevelUpland + 3))
			{
				Tilepoint = MapEditable.GetTilePoint(c*vkW+1, Height-(v*vkH)-1);
				vLayer1 = Tilepoint.layer - 2;
				for (int _c=-1;_c<=4;_c++)
				{
					for (int _v=-1;_v<=-1;_v++)
					{
						Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
						Tilepoint.layer = vLayer1;
						MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
					}
				}
			}
			if (c < vWm-1)
			if (ppMap[c][v].LevelUpland == (ppMap[c+1][v].LevelUpland + 3))
			{
				Tilepoint = MapEditable.GetTilePoint(c*vkW+1, Height-(v*vkH)-1);
				vLayer1 = Tilepoint.layer - 2;
				for (int _c=4;_c<=4;_c++)
				{
					for (int _v=-1;_v<=4;_v++)
					{
						Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
						Tilepoint.layer = vLayer1;
						MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
					}
				}
			}
			if (v < vHm-1)
			if (ppMap[c][v].LevelUpland == (ppMap[c][v+1].LevelUpland + 3))
			{
				Tilepoint = MapEditable.GetTilePoint(c*vkW+1, Height-(v*vkH)-1);
				vLayer1 = Tilepoint.layer - 2;
				for (int _c=-1;_c<=4;_c++)
				{
					for (int _v=4;_v<=4;_v++)
					{
						Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
						Tilepoint.layer = vLayer1;
						MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
					}
				}
			}
			if (c > 0 && v > 0)
			if (ppMap[c][v].Attribute == BASEHUMAN &&
				ppMap[c-1][v-1].Attribute == BASEHUMAN &&
				ppMap[c][v].LevelUpland > ppMap[c-1][v-1].LevelUpland &&
				ppMap[c][v].LevelUpland < (ppMap[c-1][v-1].LevelUpland + 3))
			{
				Tilepoint = MapEditable.GetTilePoint((c-1)*vkW+1, Height-((v-1)*vkH)-1);
				vLayer1 = Tilepoint.layer;
				for (int _c=-1;_c<=-1;_c++)
				{
					for (int _v=-1;_v<=-1;_v++)
					{
						Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
						Tilepoint.layer = vLayer1;
						MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
					}
				}
			}
			if (c < vWm-1 && v > 0)
			if (ppMap[c][v].Attribute == BASEHUMAN &&
				ppMap[c+1][v-1].Attribute == BASEHUMAN &&
				ppMap[c][v].LevelUpland > ppMap[c+1][v-1].LevelUpland &&
				ppMap[c][v].LevelUpland < (ppMap[c+1][v-1].LevelUpland + 3))
			{
				Tilepoint = MapEditable.GetTilePoint((c+1)*vkW+1, Height-((v-1)*vkH)-1);
				vLayer1 = Tilepoint.layer;
				for (int _c=4;_c<=4;_c++)
				{
					for (int _v=-1;_v<=-1;_v++)
					{
						Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
						Tilepoint.layer = vLayer1;
						MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
					}
				}
			}
			if (c < vWm-1 && v < vHm-1)
			if (ppMap[c][v].Attribute == BASEHUMAN &&
				ppMap[c+1][v+1].Attribute == BASEHUMAN &&
				ppMap[c][v].LevelUpland > ppMap[c+1][v+1].LevelUpland &&
				ppMap[c][v].LevelUpland < (ppMap[c+1][v+1].LevelUpland + 3))
			{
				Tilepoint = MapEditable.GetTilePoint((c+1)*vkW+1, Height-((v+1)*vkH)-1);
				vLayer1 = Tilepoint.layer;
				for (int _c=4;_c<=4;_c++)
				{
					for (int _v=4;_v<=4;_v++)
					{
						Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
						Tilepoint.layer = vLayer1;
						MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
					}
				}
			}
			if (c > 0 && v < vHm-1)
			if (ppMap[c][v].Attribute == BASEHUMAN &&
				ppMap[c-1][v+1].Attribute == BASEHUMAN &&
				ppMap[c][v].LevelUpland > ppMap[c-1][v+1].LevelUpland &&
				ppMap[c][v].LevelUpland < (ppMap[c-1][v+1].LevelUpland + 3))
			{
				Tilepoint = MapEditable.GetTilePoint((c-1)*vkW+1, Height-((v+1)*vkH)-1);
				vLayer1 = Tilepoint.layer;
				for (int _c=-1;_c<=-1;_c++)
				{
					for (int _v=4;_v<=4;_v++)
					{
						Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
						Tilepoint.layer = vLayer1;
						MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
					}
				}
			}
		}
	}

	// добавить воду на карту
	for (int c=0; c<vWm; c++)
	{
		for (int v=0; v<vHm; v++)
		{
			if (ppMap[c][v].Attribute == SHOAL)
			{
				for (int _c=0;_c<=vkW;_c++)
				{
					for (int _v=0;_v<=vkH;_v++)
					{
						Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
						//vLayer1 = TILE_LAYER_LEVEL_ZERO;
						if (!(Tilepoint.layer -  TILE_LAYER_LEVEL_ZERO > 1))
						{
							vLayer1 = Tilepoint.layer + ppMap[c][v].LevelUpland;
							fChangeLandscape (Tilepoint,vLayer1,WATER_SHALLOW);
							MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
						}
					}
				}
			}
		}
	}

	for (int vvi=0;vvi<2;vvi++)
	{
		for (int c=0; c<vWm; c++)
		{
			for (int v=0; v<vHm; v++)
			{
				// склоны
				vCellCountPass = ppMap[c][v].CellCountPass;
				if (vCellCountPass > 0 && vCellCountPass <= 3)// && ppMap[c][v].Attribute != SHOAL)
				{
					if ((ppMap[c][v].Attribute == BASEHUMAN && vvi == 0) ||
						(ppMap[c][v].Attribute == SHOAL && vvi == 1))
					{
						if (c > 0)
						if (ppMap[c][v].Left == true &&
							ppMap[c][v].LevelUpland != ppMap[c-1][v].LevelUpland)
						{
							vDisplacement = 0;
							if (ppMap[c][v].LevelUpland >= ppMap[c-1][v].LevelUpland)
								vDisplacement = 0;
							if (ppMap[c][v].LevelUpland <= ppMap[c-1][v].LevelUpland)
								vDisplacement = 1;
							vLayer1 = 0;
							vLayer2 = 0;
							Tilepoint = MapEditable.GetTilePoint(c*vkW+2, Height-(v*vkH)-2);
							vLayer1 = Tilepoint.layer;
							Tilepoint = MapEditable.GetTilePoint((c-1)*vkW+2, Height-(v*vkH)-2);
							vLayer2 = Tilepoint.layer;
							for (int _c=0;_c<4;_c++)
							{
								for (int _v=0;_v<5;_v++)
								{
									Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
									Tilepoint.layer = vLayer1;
									MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
									Tilepoint = MapEditable.GetTilePoint((c-1)*vkW+_c, Height-(v*vkH)-_v);
									Tilepoint.layer = vLayer2;
									MapEditable.SetTilePoint((c-1)*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
								}
							}
							for (int _c=-2+vDisplacement;_c<=0+vDisplacement;_c++)
							{
								for (int _v=1;_v<=1+vCellCountPass;_v++)
								{
									Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, (vHm-v-1)*vkH+_v);
									Tilepoint.flags |= TILE_FL_RAMP;
									MapEditable.SetTilePoint((c)*vkW+_c, (vHm-v-1)*vkH+_v, Tilepoint);
								}
							}
						}
						if (v > 0)
						if (ppMap[c][v].Up == true &&
							ppMap[c][v].LevelUpland != ppMap[c][v-1].LevelUpland)
						{
							vDisplacement = 0;
							if (ppMap[c][v].LevelUpland >= ppMap[c][v-1].LevelUpland)
								vDisplacement = 1;
							if (ppMap[c][v].LevelUpland <= ppMap[c][v-1].LevelUpland)
								vDisplacement = 0;
							vLayer1 = 0;
							vLayer2 = 0;
							Tilepoint = MapEditable.GetTilePoint(c*vkW+2, Height-(v*vkH)-2);
							vLayer1 = Tilepoint.layer;
							Tilepoint = MapEditable.GetTilePoint(c*vkW+2, Height-((v-1)*vkH)-2);
							vLayer2 = Tilepoint.layer;
							for (int _c=0;_c<5;_c++)
							{
								for (int _v=0;_v<4;_v++)
								{
									Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
									Tilepoint.layer = vLayer1;
									MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
									Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-((v-1)*vkH)-_v);
									Tilepoint.layer = vLayer2;
									MapEditable.SetTilePoint(c*vkW+_c, Height-((v-1)*vkH)-_v, Tilepoint);
								}
							}
							for (int _c=1;_c<=1+vCellCountPass;_c++)
							{
								for (int _v=3+vDisplacement;_v<=5+vDisplacement;_v++)
								{
									Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, (vHm-v-1)*vkH+_v);
									Tilepoint.flags |= TILE_FL_RAMP;
									MapEditable.SetTilePoint((c)*vkW+_c, (vHm-v-1)*vkH+_v, Tilepoint);
								}
							}
						}
						if (c < vWm-1)
						if (ppMap[c][v].Right == true &&
							ppMap[c][v].LevelUpland != ppMap[c+1][v].LevelUpland)
						{
							vDisplacement = 0;
							if (ppMap[c][v].LevelUpland >= ppMap[c+1][v].LevelUpland)
								vDisplacement = 1;
							if (ppMap[c][v].LevelUpland <= ppMap[c+1][v].LevelUpland)
								vDisplacement = 0;
							vLayer1 = 0;
							vLayer2 = 0;
							Tilepoint = MapEditable.GetTilePoint(c*vkW+2, Height-(v*vkH)-2);
							vLayer1 = Tilepoint.layer;
							Tilepoint = MapEditable.GetTilePoint((c+1)*vkW+2, Height-(v*vkH)-2);
							vLayer2 = Tilepoint.layer;
							for (int _c=0;_c<4;_c++)
							{
								for (int _v=0;_v<5;_v++)
								{
									Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
									Tilepoint.layer = vLayer1;
									MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
									Tilepoint = MapEditable.GetTilePoint((c+1)*vkW+_c, Height-(v*vkH)-_v);
									Tilepoint.layer = vLayer2;
									MapEditable.SetTilePoint((c+1)*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
								}
							}
							for (int _c=2+vDisplacement;_c<=4+vDisplacement;_c++)
							{
								for (int _v=1;_v<=1+vCellCountPass;_v++)
								{
									Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, (vHm-v-1)*vkH+_v);
									Tilepoint.flags |= TILE_FL_RAMP;
									MapEditable.SetTilePoint((c)*vkW+_c, (vHm-v-1)*vkH+_v, Tilepoint);
								}
							}
						}
						if (v < vHm-1)
						if (ppMap[c][v].Down == true &&
							ppMap[c][v].LevelUpland != ppMap[c][v+1].LevelUpland)
						{
							vDisplacement = 0;
							if (ppMap[c][v].LevelUpland >= ppMap[c][v+1].LevelUpland)
								vDisplacement = 0;
							if (ppMap[c][v].LevelUpland <= ppMap[c][v+1].LevelUpland)
								vDisplacement = 1;
							vLayer1 = 0;
							vLayer2 = 0;
							Tilepoint = MapEditable.GetTilePoint(c*vkW+2, Height-(v*vkH)-2);
							vLayer1 = Tilepoint.layer;
							Tilepoint = MapEditable.GetTilePoint(c*vkW+2, Height-((v+1)*vkH)-2);
							vLayer2 = Tilepoint.layer;
							for (int _c=0;_c<5;_c++)
							{
								for (int _v=0;_v<4;_v++)
								{
									Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
									Tilepoint.layer = vLayer1;
									MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
									Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-((v+1)*vkH)-_v);
									Tilepoint.layer = vLayer2;
									MapEditable.SetTilePoint(c*vkW+_c, Height-((v+1)*vkH)-_v, Tilepoint);
								}
							}
							for (int _c=1;_c<=1+vCellCountPass;_c++)
							{
								for (int _v=-1+vDisplacement;_v<=1+vDisplacement;_v++)
								{
									Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, (vHm-v-1)*vkH+_v);
									Tilepoint.flags |= TILE_FL_RAMP;
									MapEditable.SetTilePoint((c)*vkW+_c, (vHm-v-1)*vkH+_v, Tilepoint);
								}
							}
						}
					}
				}
			}
		}
		for (int c=0; c<vWm; c++)
		{
			for (int v=0; v<vHm; v++)
			{
				// местность около телепорта
				if (ppMap[c][v].Attribute == TELEPORT)
				{
					vTerrainType = STONE;
					if (c > 0)
					if (ppMap[c][v].Left == true && ppMap[c-1][v].Attribute == TELEPORT)
					{
						for (int _c=0;_c<=2;_c++)
						{
							for (int _v=2;_v<=2;_v++)
							{
								Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
								fCreateNewTilePoint(vTerrainType,Tilepoint.layer,&MapEditable,Tilepoint);
								MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
							}
						}
						for (int _c=2;_c<=4;_c++)
						{
							for (int _v=2;_v<=2;_v++)
							{
								Tilepoint = MapEditable.GetTilePoint((c-1)*vkW+_c, Height-(v*vkH)-_v);
								fCreateNewTilePoint(vTerrainType,Tilepoint.layer,&MapEditable,Tilepoint);
								MapEditable.SetTilePoint((c-1)*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
							}
						}
					}
					if (v > 0)
					if (ppMap[c][v].Up == true && ppMap[c][v-1].Attribute == TELEPORT)
					{
						for (int _c=2;_c<=2;_c++)
						{
							for (int _v=0;_v<=2;_v++)
							{
								Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
								fCreateNewTilePoint(vTerrainType,Tilepoint.layer,&MapEditable,Tilepoint);
								MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
							}
						}
						for (int _c=2;_c<=2;_c++)
						{
							for (int _v=2;_v<=4;_v++)
							{
								Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-((v-1)*vkH)-_v);
								fCreateNewTilePoint(vTerrainType,Tilepoint.layer,&MapEditable,Tilepoint);
								MapEditable.SetTilePoint(c*vkW+_c, Height-((v-1)*vkH)-_v, Tilepoint);
							}
						}
					}
					if (c < vWm-1)
					if (ppMap[c][v].Right == true && ppMap[c+1][v].Attribute == TELEPORT)
					{
						for (int _c=2;_c<=4;_c++)
						{
							for (int _v=2;_v<=2;_v++)
							{
								Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
								fCreateNewTilePoint(vTerrainType,Tilepoint.layer,&MapEditable,Tilepoint);
								MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
							}
						}
						for (int _c=0;_c<=2;_c++)
						{
							for (int _v=2;_v<=2;_v++)
							{
								Tilepoint = MapEditable.GetTilePoint((c+1)*vkW+_c, Height-(v*vkH)-_v);
								fCreateNewTilePoint(vTerrainType,Tilepoint.layer,&MapEditable,Tilepoint);
								MapEditable.SetTilePoint((c+1)*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
							}
						}
					}
					if (v > vHm-1)
					if (ppMap[c][v].Down == true && ppMap[c][v+1].Attribute == TELEPORT)
					{
						for (int _c=2;_c<=2;_c++)
						{
							for (int _v=2;_v<=4;_v++)
							{
								Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
								fCreateNewTilePoint(vTerrainType,Tilepoint.layer,&MapEditable,Tilepoint);
								MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
							}
						}
						for (int _c=2;_c<=2;_c++)
						{
							for (int _v=0;_v<=2;_v++)
							{
								Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-((v+1)*vkH)-_v);
								fCreateNewTilePoint(vTerrainType,Tilepoint.layer,&MapEditable,Tilepoint);
								MapEditable.SetTilePoint(c*vkW+_c, Height-((v+1)*vkH)-_v, Tilepoint);
							}
						}
					}
				}
			}
		}
	}
	// +2 клетки
	for (int c=0; c<vWm; c++)
	{
		for (int v=0; v<vHm; v++)
		{
			// склоны
			vCellCountPass = ppMap[c][v].CellCountPass;
			if (vCellCountPass > 0 && vCellCountPass <= 2)
			{
				if (c > 0)
				if (ppMap[c][v].Left == true &&
					ppMap[c][v].LevelUpland != ppMap[c-1][v].LevelUpland)
				{
					vDisplacement = 0;
					if (ppMap[c][v].LevelUpland >= ppMap[c-1][v].LevelUpland)
						vDisplacement = 0;
					if (ppMap[c][v].LevelUpland <= ppMap[c-1][v].LevelUpland)
						vDisplacement = 1;
					vLayer1 = 0;
					vLayer2 = 0;
					Tilepoint = MapEditable.GetTilePoint(c*vkW+2, Height-(v*vkH)-2);
					vLayer1 = Tilepoint.layer;
					Tilepoint = MapEditable.GetTilePoint((c-1)*vkW+2, Height-(v*vkH)-2);
					vLayer2 = Tilepoint.layer;
					if (vDisplacement == 0)
					{
						for (int _c=2;_c<4;_c++)
						{
							for (int _v=0;_v<5;_v++)
							{
								Tilepoint = MapEditable.GetTilePoint((c-1)*vkW+_c, Height-(v*vkH)-_v);
								Tilepoint.layer = vLayer2;
								MapEditable.SetTilePoint((c-1)*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
							}
						}
					}
					if (vDisplacement == 1)
					{
						for (int _c=0;_c<2;_c++)
						{
							for (int _v=0;_v<5;_v++)
							{	
								Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
								Tilepoint.layer = vLayer1;
								MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
							}
						}
					}
					if (vDisplacement == 0)
					{
						if (v > 0)
						{
							if (ppMap[c][v-1].CellCountPass == 0)
							{
								vLevel = ppMap[c][v-1].LevelUpland - ppMap[c][v].LevelUpland;
								if (vLevel >= 1)
								{
									for (int _c=0;_c<1;_c++)
									{
										for (int _v=-1;_v<0;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer1;
											MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
								if (vLevel < -1)
								{
									for (int _c=0;_c<1;_c++)
									{
										for (int _v=-1;_v<0;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer2;
											MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
							}
						}
						if (v < vHm-1)
						{
							if (ppMap[c][v+1].CellCountPass == 0)
							{
								vLevel = ppMap[c][v+1].LevelUpland - ppMap[c][v].LevelUpland;
								if (vLevel >= 1)
								{
									for (int _c=0;_c<1;_c++)
									{
										for (int _v=4;_v<5;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer1;
											MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
								if (vLevel < -1)
								{
									for (int _c=0;_c<1;_c++)
									{
										for (int _v=4;_v<5;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer2;
											MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
							}
						}
					}
					if (vDisplacement == 1)
					{
						if (c > 0 && v > 0)
						{
							if (ppMap[c-1][v-1].CellCountPass == 0)
							{
								vLevel = ppMap[c-1][v-1].LevelUpland - ppMap[c-1][v].LevelUpland;
								if (vLevel >= 1)
								{
									for (int _c=3;_c<4;_c++)
									{
										for (int _v=-1;_v<0;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint((c-1)*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer2;
											MapEditable.SetTilePoint((c-1)*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
								if (vLevel < -1)
								{
									for (int _c=3;_c<4;_c++)
									{
										for (int _v=-1;_v<0;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint((c-1)*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer1;
											MapEditable.SetTilePoint((c-1)*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
							}
						}
						if (c > 0 && v < vHm-1)
						{
							if (ppMap[c-1][v-1].CellCountPass == 0)
							{
								vLevel = ppMap[c-1][v+1].LevelUpland - ppMap[c-1][v].LevelUpland;
								if (vLevel >= 1)
								{
									for (int _c=3;_c<4;_c++)
									{
										for (int _v=4;_v<5;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint((c-1)*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer2;
											MapEditable.SetTilePoint((c-1)*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
								if (vLevel < -1)
								{
									for (int _c=3;_c<4;_c++)
									{
										for (int _v=4;_v<5;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint((c-1)*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer1;
											MapEditable.SetTilePoint((c-1)*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
							}
						}
					}
				}
				if (v > 0)
				if (ppMap[c][v].Up == true &&
					ppMap[c][v].LevelUpland != ppMap[c][v-1].LevelUpland)
				{
					vDisplacement = 0;
					if (ppMap[c][v].LevelUpland >= ppMap[c][v-1].LevelUpland)
						vDisplacement = 1;
					if (ppMap[c][v].LevelUpland <= ppMap[c][v-1].LevelUpland)
						vDisplacement = 0;
					vLayer1 = 0;
					vLayer2 = 0;
					Tilepoint = MapEditable.GetTilePoint(c*vkW+2, Height-(v*vkH)-2);
					vLayer1 = Tilepoint.layer;
					Tilepoint = MapEditable.GetTilePoint(c*vkW+2, Height-((v-1)*vkH)-2);
					vLayer2 = Tilepoint.layer;
					if (vDisplacement == 1)
					{
						for (int _c=0;_c<5;_c++)
						{
							for (int _v=2;_v<4;_v++)
							{
								Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-((v-1)*vkH)-_v);
								Tilepoint.layer = vLayer2;
								MapEditable.SetTilePoint(c*vkW+_c, Height-((v-1)*vkH)-_v, Tilepoint);
							}
						}
					}
					if (vDisplacement == 0)
					{
						for (int _c=0;_c<5;_c++)
						{
							for (int _v=0;_v<2;_v++)
							{
								Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
								Tilepoint.layer = vLayer1;
								MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
							}
						}
					}
					if (vDisplacement == 1)
					{
						if (c > 0)
						{
							if (ppMap[c-1][v].CellCountPass == 0)
							{
								vLevel = ppMap[c-1][v].LevelUpland - ppMap[c][v].LevelUpland;
								if (vLevel >= 1)
								{
									for (int _c=-1;_c<0;_c++)
									{
										for (int _v=0;_v<1;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer1;
											MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
								if (vLevel < -1)
								{
									for (int _c=-1;_c<0;_c++)
									{
										for (int _v=0;_v<1;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer2;
											MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
							}
						}
						if (c < vWm-1)
						{
							if (ppMap[c+1][v].CellCountPass == 0)
							{
								vLevel = ppMap[c+1][v].LevelUpland - ppMap[c][v].LevelUpland;
								if (vLevel >= 1)
								{
									for (int _c=4;_c<5;_c++)
									{
										for (int _v=0;_v<1;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer1;
											MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
								if (vLevel < -1)
								{
									for (int _c=4;_c<5;_c++)
									{
										for (int _v=0;_v<1;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer2;
											MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
							}
						}
					}
					if (vDisplacement == 0)
					{
						if (c > 0 && v > 0)
						{
							if (ppMap[c-1][v-1].CellCountPass == 0)
							{
								vLevel = ppMap[c-1][v-1].LevelUpland - ppMap[c][v-1].LevelUpland;
								if (vLevel >= 1)
								{
									for (int _c=-1;_c<0;_c++)
									{
										for (int _v=3;_v<4;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-((v-1)*vkH)-_v);
											Tilepoint.layer = vLayer2;
											MapEditable.SetTilePoint(c*vkW+_c, Height-((v-1)*vkH)-_v, Tilepoint);
										}
									}
								}
								if (vLevel < -1)
								{
									for (int _c=-1;_c<0;_c++)
									{
										for (int _v=3;_v<4;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-((v-1)*vkH)-_v);
											Tilepoint.layer = vLayer1;
											MapEditable.SetTilePoint(c*vkW+_c, Height-((v-1)*vkH)-_v, Tilepoint);
										}
									}
								}
							}
						}
						if (c < vWm-1 && v > 0)
						{
							if (ppMap[c+1][v-1].CellCountPass == 0)
							{
								vLevel = ppMap[c+1][v-1].LevelUpland - ppMap[c][v-1].LevelUpland;
								if (vLevel >= 1)
								{
									for (int _c=4;_c<5;_c++)
									{
										for (int _v=3;_v<4;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-((v-1)*vkH)-_v);
											Tilepoint.layer = vLayer2;
											MapEditable.SetTilePoint(c*vkW+_c, Height-((v-1)*vkH)-_v, Tilepoint);
										}
									}
								}
								if (vLevel < -1)
								{
									for (int _c=4;_c<5;_c++)
									{
										for (int _v=3;_v<4;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-((v-1)*vkH)-_v);
											Tilepoint.layer = vLayer1;
											MapEditable.SetTilePoint(c*vkW+_c, Height-((v-1)*vkH)-_v, Tilepoint);
										}
									}
								}
							}
						}
					}
				}
				if (c < vWm-1)
				if (ppMap[c][v].Right == true &&
					ppMap[c][v].LevelUpland != ppMap[c+1][v].LevelUpland)
				{
					vDisplacement = 0;
					if (ppMap[c][v].LevelUpland >= ppMap[c+1][v].LevelUpland)
						vDisplacement = 1;
					if (ppMap[c][v].LevelUpland <= ppMap[c+1][v].LevelUpland)
						vDisplacement = 0;
					vLayer1 = 0;
					vLayer2 = 0;
					Tilepoint = MapEditable.GetTilePoint(c*vkW+2, Height-(v*vkH)-2);
					vLayer1 = Tilepoint.layer;
					Tilepoint = MapEditable.GetTilePoint((c+1)*vkW+2, Height-(v*vkH)-2);
					vLayer2 = Tilepoint.layer;
					if (vDisplacement == 1)
					{
						for (int _c=0;_c<2;_c++)
						{
							for (int _v=0;_v<5;_v++)
							{
								Tilepoint = MapEditable.GetTilePoint((c+1)*vkW+_c, Height-(v*vkH)-_v);
								Tilepoint.layer = vLayer2;
								MapEditable.SetTilePoint((c+1)*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
							}
						}
					}
					if (vDisplacement == 0)
					{
						for (int _c=2;_c<4;_c++)
						{
							for (int _v=0;_v<5;_v++)
							{
								Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
								Tilepoint.layer = vLayer1;
								MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
							}
						}
					}
					if (vDisplacement == 1)
					{
						if (v > 0)
						{
							if (ppMap[c][v-1].CellCountPass == 0)
							{
								vLevel = ppMap[c][v-1].LevelUpland - ppMap[c][v].LevelUpland;
								if (vLevel >= 1)
								{
									for (int _c=3;_c<4;_c++)
									{
										for (int _v=-1;_v<0;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer1;
											MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
								if (vLevel < -1)
								{
									for (int _c=3;_c<4;_c++)
									{
										for (int _v=-1;_v<0;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer2;
											MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
							}
						}
						if (v < vHm-1)
						{
							if (ppMap[c][v+1].CellCountPass == 0)
							{
								vLevel = ppMap[c][v+1].LevelUpland - ppMap[c][v].LevelUpland;
								if (vLevel >= 1)
								{
									for (int _c=3;_c<4;_c++)
									{
										for (int _v=4;_v<5;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer1;
											MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
								if (vLevel < -1)
								{
									for (int _c=3;_c<4;_c++)
									{
										for (int _v=4;_v<5;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer2;
											MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
							}
						}
					}
					if (vDisplacement == 0)
					{
						if (c < vWm-1 && v > 0)
						{
							if (ppMap[c+1][v-1].CellCountPass == 0)
							{
								vLevel = ppMap[c+1][v-1].LevelUpland - ppMap[c+1][v].LevelUpland;
								if (vLevel >= 1)
								{
									for (int _c=0;_c<1;_c++)
									{
										for (int _v=-1;_v<0;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint((c+1)*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer2;
											MapEditable.SetTilePoint((c+1)*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
								if (vLevel < -1)
								{
									for (int _c=0;_c<1;_c++)
									{
										for (int _v=-1;_v<0;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint((c+1)*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer1;
											MapEditable.SetTilePoint((c+1)*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
							}
						}
						if (c < vWm-1 && v < vHm-1)
						{
							if (ppMap[c+1][v+1].CellCountPass == 0)
							{
								vLevel = ppMap[c+1][v+1].LevelUpland - ppMap[c+1][v].LevelUpland;
								if (vLevel >= 1)
								{
									for (int _c=0;_c<1;_c++)
									{
										for (int _v=4;_v<5;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint((c+1)*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer2;
											MapEditable.SetTilePoint((c+1)*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
								if (vLevel < -1)
								{
									for (int _c=0;_c<1;_c++)
									{
										for (int _v=4;_v<5;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint((c+1)*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer1;
											MapEditable.SetTilePoint((c+1)*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
							}
						}
					}
				}
				if (v < vHm-1)
				if (ppMap[c][v].Down == true &&
					ppMap[c][v].LevelUpland != ppMap[c][v+1].LevelUpland)
				{
					vDisplacement = 0;
					if (ppMap[c][v].LevelUpland >= ppMap[c][v+1].LevelUpland)
						vDisplacement = 0;
					if (ppMap[c][v].LevelUpland <= ppMap[c][v+1].LevelUpland)
						vDisplacement = 1;
					vLayer1 = 0;
					vLayer2 = 0;
					Tilepoint = MapEditable.GetTilePoint(c*vkW+2, Height-(v*vkH)-2);
					vLayer1 = Tilepoint.layer;
					Tilepoint = MapEditable.GetTilePoint(c*vkW+2, Height-((v+1)*vkH)-2);
					vLayer2 = Tilepoint.layer;
					if (vDisplacement == 0)
					{
						for (int _c=0;_c<5;_c++)
						{
							for (int _v=0;_v<2;_v++)
							{
								Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-((v+1)*vkH)-_v);
								Tilepoint.layer = vLayer2;
								MapEditable.SetTilePoint(c*vkW+_c, Height-((v+1)*vkH)-_v, Tilepoint);
							}
						}
					}
					if (vDisplacement == 1)
					{
						for (int _c=0;_c<5;_c++)
						{
							for (int _v=2;_v<4;_v++)
							{
								Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
								Tilepoint.layer = vLayer1;
								MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
							}
						}
					}
					if (vDisplacement == 0)
					{
						if (c > 0)
						{
							if (ppMap[c-1][v].CellCountPass == 0)
							{
								vLevel = ppMap[c-1][v].LevelUpland - ppMap[c][v].LevelUpland;
								if (vLevel >= 1)
								{
									for (int _c=-1;_c<0;_c++)
									{
										for (int _v=3;_v<4;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer1;
											MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
								if (vLevel < -1)
								{
									for (int _c=-1;_c<0;_c++)
									{
										for (int _v=3;_v<4;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer2;
											MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
							}
						}
						if (c < vWm-1)
						{
							if (ppMap[c+1][v].CellCountPass == 0)
							{
								vLevel = ppMap[c+1][v].LevelUpland - ppMap[c][v].LevelUpland;
								if (vLevel >= 1)
								{
									for (int _c=4;_c<5;_c++)
									{
										for (int _v=3;_v<4;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer1;
											MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
								if (vLevel < -1)
								{
									for (int _c=4;_c<5;_c++)
									{
										for (int _v=3;_v<4;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-(v*vkH)-_v);
											Tilepoint.layer = vLayer2;
											MapEditable.SetTilePoint(c*vkW+_c, Height-(v*vkH)-_v, Tilepoint);
										}
									}
								}
							}
						}
					}
					if (vDisplacement == 1)
					{
						if (c > 0 && v < vHm-1)
						{
							if (ppMap[c-1][v+1].CellCountPass == 0)
							{
								vLevel = ppMap[c-1][v+1].LevelUpland - ppMap[c][v+1].LevelUpland;
								if (vLevel >= 1)
								{
									for (int _c=-1;_c<0;_c++)
									{
										for (int _v=0;_v<1;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-((v+1)*vkH)-_v);
											Tilepoint.layer = vLayer2;
											MapEditable.SetTilePoint(c*vkW+_c, Height-((v+1)*vkH)-_v, Tilepoint);
										}
									}
								}
								if (vLevel < -1)
								{
									for (int _c=-1;_c<0;_c++)
									{
										for (int _v=0;_v<1;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-((v+1)*vkH)-_v);
											Tilepoint.layer = vLayer1;
											MapEditable.SetTilePoint(c*vkW+_c, Height-((v+1)*vkH)-_v, Tilepoint);
										}
									}
								}
							}
						}
						if (c < vWm-1 && v < vHm-1)
						{
							if (ppMap[c+1][v+1].CellCountPass == 0)
							{
								vLevel = ppMap[c+1][v+1].LevelUpland - ppMap[c][v+1].LevelUpland;
								if (vLevel >= 1)
								{
									for (int _c=4;_c<5;_c++)
									{
										for (int _v=0;_v<1;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-((v+1)*vkH)-_v);
											Tilepoint.layer = vLayer2;
											MapEditable.SetTilePoint(c*vkW+_c, Height-((v+1)*vkH)-_v, Tilepoint);
										}
									}
								}
								if (vLevel < -1)
								{
									for (int _c=4;_c<5;_c++)
									{
										for (int _v=0;_v<1;_v++)
										{
											Tilepoint = MapEditable.GetTilePoint(c*vkW+_c, Height-((v+1)*vkH)-_v);
											Tilepoint.layer = vLayer1;
											MapEditable.SetTilePoint(c*vkW+_c, Height-((v+1)*vkH)-_v, Tilepoint);
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
	// ограничитель высот на 3 уровня (клеточка)
	do
	{
		vFlag = 0;
		for (int _c=0; _c<vW; _c++)
		{
			for (int _v=0; _v<vH; _v++)
			{
				Tilepoint = MapEditable.GetTilePoint(_c, Height-_v);
				vLayer1 = Tilepoint.layer;
				for (int vvi=-1;vvi<=1;vvi++)
				{
					for (int vvj=-1;vvj<=1;vvj++)
					{
						if (!(vvi == 0 && vvj == 0))
						{
							_c1 = _c+vvi;
							_v1 = Height-_v+vvj;
							if (_c1 >= 0 && _v1 >= 0 && _c1 < vW && _v1 < vH)
							{
								Tilepoint = MapEditable.GetTilePoint(_c1, _v1);
								vLayer2 = Tilepoint.layer;
								if (vLayer1 - vLayer2 >= 3)
								{
									vFlag = 1;
									Tilepoint = MapEditable.GetTilePoint(_c, Height-_v);
									Tilepoint.layer--;
									vLayer1 = Tilepoint.layer;
									MapEditable.SetTilePoint(_c, Height-_v, Tilepoint);
								}
							}
						}
					}
				}
			}
		}
	}
	while (vFlag == 1);
	// раставим объекты декораций
	for (int c=0; c<vWm; c++)
	{
		for (int v=0; v<vHm; v++)
		{
			if (ppMap[c][v].Left == false && ppMap[c][v].LeftT > 0)
			{
				vObject = ppMap[c][v].LeftT;
				for (int _c=0;_c<=0;_c++)
				{
					for (int _v=0;_v<=3;_v++)
					{
						vCount = 0;
						for (int vvi=0;vvi<=2;vvi++)
						{
							if (fWhetherToCheckFreeCell(c*vkW+_c+vvi,Height-1-(v*vkH)-_v,&MapEditable))
								vCount++;
						}
						if (!fCheckRamp(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable) &&
							vCount == 3)
							fToPlaceDoodad(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable,vObject);
					}
				}
			}
			if (ppMap[c][v].Up == false && ppMap[c][v].UpT > 0)
			{
				vObject = ppMap[c][v].UpT;
				for (int _c=0;_c<=3;_c++)
				{
					for (int _v=0;_v<=0;_v++)
					{
						vCount = 0;
						for (int vvi=0;vvi<=2;vvi++)
						{
							if (fWhetherToCheckFreeCell(c*vkW+_c,Height-1-(v*vkH)-_v-vvi,&MapEditable))
								vCount++;
						}
						if (!fCheckRamp(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable) &&
							vCount == 3)
							fToPlaceDoodad(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable,vObject);
					}
				}
			}
			if (ppMap[c][v].Right == false && ppMap[c][v].RightT > 0)
			{
				vObject = ppMap[c][v].RightT;
				for (int _c=3;_c<=3;_c++)
				{
					for (int _v=0;_v<=3;_v++)
					{
						vCount = 0;
						for (int vvi=0;vvi<=2;vvi++)
						{
							if (fWhetherToCheckFreeCell(c*vkW+_c-vvi,Height-1-(v*vkH)-_v,&MapEditable))
								vCount++;
						}
						if (!fCheckRamp(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable) &&
							vCount == 3)
							fToPlaceDoodad(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable,vObject);
					}
				}
			}
			if (ppMap[c][v].Down == false && ppMap[c][v].DownT > 0)
			{
				vObject = ppMap[c][v].DownT;
				for (int _c=0;_c<=3;_c++)
				{
					for (int _v=3;_v<=3;_v++)
					{
						vCount = 0;
						for (int vvi=0;vvi<=2;vvi++)
						{
							if (fWhetherToCheckFreeCell(c*vkW+_c,Height-1-(v*vkH)-_v+vvi,&MapEditable))
								vCount++;
						}
						if (!fCheckRamp(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable) &&
							vCount == 3)
							fToPlaceDoodad(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable,vObject);
					}
				}
			}
			if (c > 0 && v > 0)
			if (ppMap[c][v].Left == false && ppMap[c-1][v].RightT > 0 &&
				ppMap[c][v].Up == false && ppMap[c][v-1].DownT > 0)
			{
				vObject = TREE;
				for (int _c=-1;_c<=-1;_c++)
				{
					for (int _v=-1;_v<=-1;_v++)
					{
						if (!fCheckRamp(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable))
							fToPlaceDoodad(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable,vObject);
					}
				}
			}
			if (c < vWm-1 && v > 0)
			if (ppMap[c][v].Up == false && ppMap[c][v-1].DownT > 0 &&
				ppMap[c][v].Right == false && ppMap[c+1][v].LeftT > 0)
			{
				vObject = TREE;
				for (int _c=4;_c<=4;_c++)
				{
					for (int _v=-1;_v<=-1;_v++)
					{
						if (!fCheckRamp(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable))
							fToPlaceDoodad(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable,vObject);
					}
				}
			}
			if (c < vWm-1 && v < vHm-1)
			if (ppMap[c][v].Right == false && ppMap[c+1][v].LeftT > 0 &&
				ppMap[c][v].Down == false && ppMap[c][v+1].UpT > 0)
			{
				vObject = TREE;
				for (int _c=4;_c<=4;_c++)
				{
					for (int _v=4;_v<=4;_v++)
					{
						if (!fCheckRamp(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable))
							fToPlaceDoodad(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable,vObject);
					}
				}
			}
			if (c > 0 && v < vHm-1)
			if (ppMap[c][v].Down == false && ppMap[c][v+1].UpT > 0 &&
				ppMap[c][v].Left == false && ppMap[c-1][v].RightT > 0)
			{
				vObject = TREE;
				for (int _c=-1;_c<=-1;_c++)
				{
					for (int _v=4;_v<=4;_v++)
					{
						if (!fCheckRamp(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable))
							fToPlaceDoodad(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable,vObject);
					}
				}
			}
		}
	}
	// сажаем, рандомно, цветочки на карте
	for (int c=0; c<vWm; c++)
	{
		for (int v=0; v<vHm; v++)
		{
			if (ppMap[c][v].Attribute == OUTSIDE ||
				ppMap[c][v].Attribute == INSIDE ||
				ppMap[c][v].Attribute == BORDER ||
				ppMap[c][v].Attribute == LANDSCAPE)
			{
				if (rand()%100 < 20)
				{
					vObject = HERB1;
					_c = rand()%vkW;
					_v = rand()%vkH;
					fToPlaceDoodad(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable,vObject);
				}
			}
		}
	}
	// сажаем, рандомно, деревья на карте
	for (int c=0; c<vWm; c++)
	{
		for (int v=0; v<vHm; v++)
		{
			if (ppMap[c][v].Attribute == OUTSIDE ||
				ppMap[c][v].Attribute == INSIDE ||
				ppMap[c][v].Attribute == BORDER ||
				ppMap[c][v].Attribute == LANDSCAPE)
			{
				vFlag = 0;
				for (int vvi=-1;vvi<=1;vvi++)
				{
					for (int vvj=-1;vvj<=1;vvj++)
					{
						if (!(vvi == 0 && vvj == 0))
						{
							_c = c + vvi;
							_v = v + vvj;
							if (_c >= 0 && _v >= 0 && _c < vWm && _v < vHm)
							if (ppMap[_c][_v].Wall == true)
							{
								vFlag = 1;
								break;
							}
						}
					}
					if (vFlag == 1) break;
				}
				if (vFlag == 0)
				{
					vCount = 0;
					vObjN = rand()%2;
					do
					{
						if (rand()%100 < 20)
						{
							vObject = TREE;
							_c = rand()%vkW;
							_v = rand()%vkH;
							fToPlaceDoodad(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable,vObject);
						}
						vCount++;
					}
					while(vCount < vObjN);
				}
			}
		}
	}
	// Большая клетка, где расположен вал, с нулевым уровнем, должна быть с проходом в 1 маленькую клетку
	for (int c=0; c<vWm; c++)
	{
		for (int v=0; v<vHm; v++)
		{
			if (ppMap[c][v].Wall == true && ppMap[c][v].LevelUpland == 0 &&
				ppMap[c][v].CellCountPass == 1)
			{
				if (c > 0)
				if (ppMap[c][v].Left == true &&
					(ppMap[c-1][v].Attribute == OUTSIDE ||
					ppMap[c-1][v].Attribute == INSIDE ||
					ppMap[c-1][v].Attribute == BORDER ||
					ppMap[c-1][v].Attribute == LANDSCAPE))
				{
					for (int _c=-1;_c<=-1;_c++)
					{
						for (int _v=-1;_v<=4;_v++)
						{
							if (_v != 1)
							{
								if (!fCheckRamp(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable))
									fToPlaceDoodad(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable,vObject);
							}
						}
					}
				}
				if (v > 0)
				if (ppMap[c][v].Up == true &&
					(ppMap[c][v-1].Attribute == OUTSIDE ||
					ppMap[c][v-1].Attribute == INSIDE ||
					ppMap[c][v-1].Attribute == BORDER ||
					ppMap[c][v-1].Attribute == LANDSCAPE))
				{
					for (int _c=-1;_c<=4;_c++)
					{
						for (int _v=-1;_v<=-1;_v++)
						{
							if (_c != 1)
							{
								if (!fCheckRamp(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable))
									fToPlaceDoodad(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable,vObject);
							}
						}
					}
				}
				if (c < vWm-1)
				if (ppMap[c][v].Right == true &&
					(ppMap[c+1][v].Attribute == OUTSIDE ||
					ppMap[c+1][v].Attribute == INSIDE ||
					ppMap[c+1][v].Attribute == BORDER ||
					ppMap[c+1][v].Attribute == LANDSCAPE))
				{
					for (int _c=3;_c<=3;_c++)
					{
						for (int _v=-1;_v<=4;_v++)
						{
							if (_v != 2)
							{
								if (!fCheckRamp(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable))
									fToPlaceDoodad(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable,vObject);
							}
						}
					}
				}
				if (v < vHm-1)
				if (ppMap[c][v].Down == true &&
					(ppMap[c][v+1].Attribute == OUTSIDE ||
					ppMap[c][v+1].Attribute == INSIDE ||
					ppMap[c][v+1].Attribute == BORDER ||
					ppMap[c][v+1].Attribute == LANDSCAPE))
				{
					for (int _c=-1;_c<=4;_c++)
					{
						for (int _v=3;_v<=3;_v++)
						{
							if (_c != 1)
							{
								if (!fCheckRamp(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable))
									fToPlaceDoodad(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable,vObject);
							}
						}
					}
				}
			}
		}
	}

	for (int c=0; c<vWm; c++)
	{
		for (int v=0; v<vHm; v++)
		{
			if (ppMap[c][v].Attribute == BASEHUMAN || ppMap[c][v].Attribute == TELEPORT)
			{
				if (ppMap[c][v].NumBase >= 0)
				{
					NewRegion.NumBase = ppMap[c][v].NumBase;
					NewRegion.Type = ppMap[c][v].Attribute;
					NewRegion.Rect.left = c*vkW;
					NewRegion.Rect.top = v*vkH;
					NewRegion.Rect.right = c*vkW+5;
					NewRegion.Rect.bottom = v*vkH+5;
					NewRegion.Color = ppMap[c][v].Color;
					MapEditable.AddRegion(NewRegion);
				}
				if (ppMap[c][v].Blood == true)
				{
					vObject = TREE;
					vDisplacement = 0;
					vBloodN = 1 + rand()%2;
					for (int vvi=0;vvi<vBloodN;vvi++)
					{
						vFlag = 0;
						NewRegion.NumBase = ppMap[c][v].NumBase;
						NewRegion.Type = BLOOD2;
						if (c > 0)
						if (ppMap[c][v].LeftT != 1 &&
							(ppMap[c-1][v].Attribute == OUTSIDE ||
							ppMap[c-1][v].Attribute == INSIDE ||
							ppMap[c-1][v].Attribute == BORDER ||
							ppMap[c-1][v].Attribute == LANDSCAPE ||
							((ppMap[c-1][v].Attribute == BASEHUMAN ||
							ppMap[c-1][v].Attribute == TELEPORT) &&
							ppMap[c-1][v].NumBase != ppMap[c][v].NumBase)) &&
							vFlag == 0)
						{
							_c = vkW/2;
							_v = 1 + vDisplacement;
							for (int vvi=0;vvi<vkW;vvi++)
							{
								if (fCheckForBias(c*vkW+_c-1,Height-1-(v*vkH)-_v,&MapEditable) &&
									fCheckDoodadThisCell(c*vkW+_c-1,Height-1-(v*vkH)-_v,&MapEditable,vObject) == 0)
									_c--;
								else
								{
									vFlag = 1;
									break;
								}
							}
						}
						if (v > 0)
						if (ppMap[c][v].UpT != 1 &&
							(ppMap[c][v-1].Attribute == OUTSIDE ||
							ppMap[c][v-1].Attribute == INSIDE ||
							ppMap[c][v-1].Attribute == BORDER ||
							ppMap[c][v-1].Attribute == LANDSCAPE ||
							((ppMap[c][v-1].Attribute == BASEHUMAN ||
							ppMap[c][v-1].Attribute == TELEPORT) &&
							ppMap[c][v-1].NumBase != ppMap[c][v].NumBase)) &&
							vFlag == 0)
						{
							_c = 1 + vDisplacement;
							_v = vkH/2;
							for (int vvi=0;vvi<vkW;vvi++)
							{
								if (fCheckForBias(c*vkW+_c,Height-1-(v*vkH)-_v+1,&MapEditable) &&
									fCheckDoodadThisCell(c*vkW+_c,Height-1-(v*vkH)-_v+1,&MapEditable,vObject) == 0)
									_v--;
								else
								{
									vFlag = 1;
									break;
								}
							}
						}
						if (c < vWm-1)
						if (ppMap[c][v].RightT != 1 &&
							(ppMap[c+1][v].Attribute == OUTSIDE ||
							ppMap[c+1][v].Attribute == INSIDE ||
							ppMap[c+1][v].Attribute == BORDER ||
							ppMap[c+1][v].Attribute == LANDSCAPE ||
							((ppMap[c+1][v].Attribute == BASEHUMAN ||
							ppMap[c+1][v].Attribute == TELEPORT) &&
							ppMap[c+1][v].NumBase != ppMap[c][v].NumBase)) &&
							vFlag == 0)
						{
							_c = vkW/2;
							_v = 1 + vDisplacement;
							for (int vvi=0;vvi<vkW;vvi++)
							{
								if (fCheckForBias(c*vkW+_c+1,Height-1-(v*vkH)-_v,&MapEditable) &&
									fCheckDoodadThisCell(c*vkW+_c+1,Height-1-(v*vkH)-_v,&MapEditable,vObject) == 0)
									_c++;
								else
								{
									vFlag = 1;
									break;
								}
							}
						}
						if (v < vHm-1)
						if (ppMap[c][v].DownT != 1 &&
							(ppMap[c][v+1].Attribute == OUTSIDE ||
							ppMap[c][v+1].Attribute == INSIDE ||
							ppMap[c][v+1].Attribute == BORDER ||
							ppMap[c][v+1].Attribute == LANDSCAPE ||
							((ppMap[c][v+1].Attribute == BASEHUMAN ||
							ppMap[c][v+1].Attribute == TELEPORT) &&
							ppMap[c][v+1].NumBase != ppMap[c][v].NumBase)) &&
							vFlag == 0)
						{
							_c = 1 + vDisplacement;
							_v = vkH/2;
							for (int vvi=0;vvi<vkW;vvi++)
							{
								if (fCheckForBias(c*vkW+_c,Height-1-(v*vkH)-_v-1,&MapEditable) &&
									fCheckDoodadThisCell(c*vkW+_c,Height-1-(v*vkH)-_v-1,&MapEditable,vObject) == 0)
									_v++;
								else
								{
									vFlag = 1;
									break;
								}
							}
						}
						if (vFlag == 1)
						{
							if (fWhetherToCheckFreeCell(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable) &&
								!fCheckRamp(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable))
							{
								NewRegion.Rect.left = c*vkW+_c+1;
								NewRegion.Rect.top = v*vkH+_v-1;
								NewRegion.Rect.right = c*vkW+_c+2;
								NewRegion.Rect.bottom = v*vkH+_v;
								MapEditable.AddRegion(NewRegion);
							}
						}
						vDisplacement++;
					}
				}
				if (ppMap[c][v].Wall == true)
				{
					vFlag = 0;
					_x1 = 64;
					_y1 = 64;
					NewRegion.NumBase = ppMap[c][v].NumBase;
					NewRegion.Type = RUNE2;
					if (c > 0)
					if (ppMap[c][v].LeftT != 1 && ppMap[c][v].Left == true &&
						(ppMap[c-1][v].Attribute == OUTSIDE ||
						ppMap[c-1][v].Attribute == INSIDE ||
						ppMap[c-1][v].Attribute == BORDER ||
						ppMap[c-1][v].Attribute == LANDSCAPE) &&
						vFlag == 0)
					{
						if (ppMap[c][v].LevelUpland > ppMap[c-1][v].LevelUpland)
							_c = -1;
						else
							_c = 0;
						_v = 1;
						if (ppMap[c][v].CellCountPass == 1)
						{
							if (ppMap[c][v].LevelUpland == 0)
							{
								_x1 = 32;
								_y1 = 64;
							}
							else
							{
								_x1 = 64;
								_y1 = 32;
							}
						}
						vFlag = 1;
					}
					if (v > 0)
					if (ppMap[c][v].UpT != 1 && ppMap[c][v].Up == true &&
						(ppMap[c][v-1].Attribute == OUTSIDE ||
						ppMap[c][v-1].Attribute == INSIDE ||
						ppMap[c][v-1].Attribute == BORDER ||
						ppMap[c][v-1].Attribute == LANDSCAPE) &&
						vFlag == 0)
					{
						_c = 2;
						if (ppMap[c][v].LevelUpland > ppMap[c][v-1].LevelUpland)
							_v = -2;
						else
							_v = -1;
						if (ppMap[c][v].CellCountPass == 1)
						{
							if (ppMap[c][v].LevelUpland == 0)
							{
								_x1 = 0;
								_y1 = 64;
							}
							else
							{
								_x1 = 32;
								_y1 = 64;
							}	
						}
							
						vFlag = 1;
					}
					if (c < vWm-1)
					if (ppMap[c][v].RightT != 1 && ppMap[c][v].Right == true &&
						(ppMap[c+1][v].Attribute == OUTSIDE ||
						ppMap[c+1][v].Attribute == INSIDE ||
						ppMap[c+1][v].Attribute == BORDER ||
						ppMap[c+1][v].Attribute == LANDSCAPE) &&
						vFlag == 0)
					{
						if (ppMap[c][v].LevelUpland > ppMap[c+1][v].LevelUpland)
							_c = 4;
						else
							_c = 3;
						_v = 1;
						if (ppMap[c][v].CellCountPass == 1)
						{
							if (ppMap[c][v].LevelUpland == 0)
							{
								_x1 = 64;
								_y1 = 0;
							}
							else
							{
								_x1 = 64;
								_y1 = 32;
							}
						}
						vFlag = 1;
					}
					if (v < vHm-1)
					if (ppMap[c][v].DownT != 1 && ppMap[c][v].Down == true &&
						(ppMap[c][v+1].Attribute == OUTSIDE ||
						ppMap[c][v+1].Attribute == INSIDE ||
						ppMap[c][v+1].Attribute == BORDER ||
						ppMap[c][v+1].Attribute == LANDSCAPE) &&
						vFlag == 0)
					{
						_c = 2;
						if (ppMap[c][v].LevelUpland > ppMap[c][v+1].LevelUpland)
							_v = 3;
						else
							_v = 2;
						if (ppMap[c][v].CellCountPass == 1)
						{
							if (ppMap[c][v].LevelUpland == 0)
							{
								_x1 = 0;
								_y1 = 64;
							}
							else
							{
								_x1 = 32;
								_y1 = 64;
							}	
						}
						vFlag = 1;
					}
					if (vFlag == 1)
					{
						vObject = RUNE;
						//fToPlaceDoodad(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable,vObject);
						_x = (float)((c*vkW+_c) * 128) + _x1;
						_y = (float)((Height-1-(v*vkH)-_v) * 128) + _y1;
						_x += (float)(vW * 128 / -2);
						_y += (float)(vH * 128 / -2);

						if (fCreateNewDoodad(newdoodad,_x,_y,&MapEditable,vObject))
							MapEditable.AddDoodad(newdoodad);	// добавить новый объект
					}
				}
			}
		}
	}
	
	for (int c=0; c<vWm; c++)
	{
		for (int v=0; v<vHm; v++)
		{
			//
			if (ppMap[c][v].Attribute == TELEPORT)
			{
				if (ppMap[c][v].NumBase >= 0)
				{
					vFlag = 0;
					NewRegion.NumBase = ppMap[c][v].NumBase;
					if (ppMap[c][v].NumTeleport == 1)
						NewRegion.Type = DANCEPOOLTELEPORT;
					if (ppMap[c][v].NumTeleport == 2)
						NewRegion.Type = DEFAULTTELEPORT;
					if (c > 0)
					if (ppMap[c][v].Left == true && ppMap[c-1][v].Attribute == TELEPORT &&
						vFlag == 0)
					{
						_c = 2;
						_v = 1;
						vFlag = 1;
					}
					if (v > 0)
					if (ppMap[c][v].Up == true && ppMap[c][v-1].Attribute == TELEPORT &&
						vFlag == 0)
					{
						_c = 2;
						_v = 1;
						vFlag = 1;
					}
					if (c < vWm-1)
					if (ppMap[c][v].Right == true && ppMap[c+1][v].Attribute == TELEPORT &&
						vFlag == 0)
					{
						_c = 2;
						_v = 1;
						vFlag = 1;
					}
					if (v < vHm-1)
					if (ppMap[c][v].Down == true && ppMap[c][v+1].Attribute == TELEPORT &&
						vFlag == 0)
					{
						_c = 2;
						_v = 1;
						vFlag = 1;
					}
					if (vFlag == 1)
					{
						if (ppMap[c][v].NumTeleport == 1)
						{
							vObject = RUNETELEPORT;
							//fToPlaceDoodad(c*vkW+_c,Height-1-(v*vkH)-_v,&MapEditable,vObject);
							_x = (float)((c*vkW+_c) * 128) + 64;
							_y = (float)((Height-1-(v*vkH)-_v) * 128) + 64;
							_x += (float)(vW * 128 / -2);
							_y += (float)(vH * 128 / -2);

							if (fCreateNewDoodad(newdoodad,_x,_y,&MapEditable,vObject))
								MapEditable.AddDoodad(newdoodad);	// добавить новый объект
								
						}
						NewRegion.Rect.left = c*vkW+_c;
						NewRegion.Rect.top = v*vkH+_v;
						NewRegion.Rect.right = c*vkW+_c+1;
						NewRegion.Rect.bottom = v*vkH+_v+1;
						MapEditable.AddRegion(NewRegion);
					}				
				}
			}
		}
	}
	MapEditable.ResetPathing();// обновить карту путей
}
// Создать новый объект декораций
int fCreateNewDoodad (CDoodad &newdoodad, float x, float y, WorldMap *pMap, int _Object)
{
	CDoodad doodad;
	CDoodad nextdoodad;
	float _R1;
	float _R2;
	float m_fMinDist;

	float distance, best;

	if (!pMap->CheckMapInit())
		return 0;

	best = -1;
	pMap->GoFirstDoodad();
	do
	{
		nextdoodad = pMap->GetNextDoodad();
		if(nextdoodad.type == "")
			break;
		distance = (nextdoodad.x - x)*(nextdoodad.x - x) + (nextdoodad.y - y)*(nextdoodad.y - y);
		fDefineObjectRadius(_R2,nextdoodad.type.GetStrID());
		if (((best < 0) || (distance < best)) && _R2 > 0)
		{
			best = distance;
			doodad = nextdoodad;		
		}
	}
	while(nextdoodad.type != "");

	fSelectDoodad(newdoodad,x,y,pMap,_Object);
	fDefineObjectRadius(_R1,newdoodad.type.GetStrID());
	fDefineObjectRadius(_R2,doodad.type.GetStrID());
	if (_R1 == 0)
		m_fMinDist = 0;
	else
		m_fMinDist = _R1/2 + _R2/2;

	if (pMap->GetDistance(x, y, doodad.x, doodad.y) < m_fMinDist &&
		doodad.ID >= 0)
		return 0;
	return 1;
}
// Удалить объект декораций
/*int fDeleteDoodad (int x, int y, WorldMap *pMap)
{
	CDoodad doodad;
	int vW;
	int vH;
	float _x;
	float _y;
	
	if (!ppMap)
		return 0;
	if (!pMap->CheckMapInit() )
		return 0;
	vW = pMap->GetMapWidth();
	vH = pMap->GetMapHeight();
	if (x < 0 || y < 0 || x >= vW || y >= vH)
		return 0;

	if(!fCheckForBias(x,y,pMap))	// проверить на уклон
		return 0;

	// определить координаты объекта
	_x = (float)(x * 128) + 64;
	_y = (float)(y * 128) + 64;
	_x += (float)(vW * 128 / -2);
	_y += (float)(vH * 128 / -2);

	doodad = pMap->GetClosestDoodad(_x, _y);
	if (pMap->GetDistance(_x,_y,doodad.x,doodad.y) <= TOOL_DOOD_DEFAULT_DIST)
		pMap->DelDoodad(doodad);
}*/
// Выбрать объект декораций
int fSelectDoodad(CDoodad &newdoodad, float x0, float y0, WorldMap *pMap, int _Object)
{
	char *pTypeDoodad;
	if (_Object < 0)
		return 0;
	pTypeDoodad = new char[4];
	switch (_Object)
	{
		case HERB1:
			sprintf(pTypeDoodad,"%s","ZPfw");
			break;
		case HERB2:
			sprintf(pTypeDoodad,"%s","LPlp");
			break;
		case HERB3:
			sprintf(pTypeDoodad,"%s","LPrs");
			break;
		case FLAGALLIANCE:
			sprintf(pTypeDoodad,"%s","LOh1");
			break;
		case EMPTY1:
			sprintf(pTypeDoodad,"%s","YTpb");
			break;
		case EMPTY2:
			sprintf(pTypeDoodad,"%s","YTlb");
			break;
		case EMPTY3:
			sprintf(pTypeDoodad,"%s","YOfs");
			break;
		case EMPTY4:
			sprintf(pTypeDoodad,"%s","YOr2");
			break;
		case EMPTY5:
			sprintf(pTypeDoodad,"%s","YOf2");
			break;
		case EMPTY6:
			sprintf(pTypeDoodad,"%s","LOsm");
			break;
		case TREE:
		case CUTTREE:
			sprintf(pTypeDoodad,"%s","LTlt");
			break;
		case BLOOD:
		case PORTAL1:
		case PORTAL2:
			sprintf(pTypeDoodad,"%s","KOdr");
			break;
		case RUNE:
			sprintf(pTypeDoodad,"%s","JOgr");
			break;
		case STONES:
			sprintf(pTypeDoodad,"%s","LRrk");
			break;
		case OBELISK1:
		case OBELISK2:
			sprintf(pTypeDoodad,"%s","YTpc");
			break;
		case STATUE1:
			sprintf(pTypeDoodad,"%s","YOks");
			break;
		case RUNETELEPORT:
			sprintf(pTypeDoodad,"%s","KOdr");
			break;
		default:
			*pTypeDoodad = NULL;
			break;
	}
	newdoodad.type = pTypeDoodad;
	switch (_Object)
	{
		case CUTTREE:
			newdoodad.life = (byte)0;
			break;
		default:
			newdoodad.life = (byte)100;
			break;
	}
	switch (_Object)
	{
		case HERB1:
			newdoodad.variation = 2;
			break;
		case HERB2:
			newdoodad.variation = 0;
			break;
		case HERB3:
			newdoodad.variation = 1;
			break;
		case TREE:
		case CUTTREE:
			newdoodad.variation = rand()%10;
			break;
		case BLOOD:
			//newdoodad.variation = 0;
			break;
		case PORTAL1:
			newdoodad.variation = 1;
			break;
		case PORTAL2:
			newdoodad.variation = 2;
			break;
		case RUNE:
			newdoodad.variation = rand()%9;
			break;
		case STONES:
			newdoodad.variation = rand()%10;
			break;
		case RUNETELEPORT:
			newdoodad.variation = rand()%2+1;
			break;
		default:
			newdoodad.variation = 0;
			break;
	}
	newdoodad.scaleX = 1;
	newdoodad.scaleY = 1;
	newdoodad.scaleZ = 1;
	switch (_Object)
	{
		case OBELISK1:
			newdoodad.angle = 270;
			break;
		case OBELISK2:
			newdoodad.angle = 180;
			break;
		case STATUE1:
			newdoodad.angle = 0;
			break;
		default:
			newdoodad.angle = 0;
			break;
	}
	newdoodad.flags = DOOD_FL_NORMAL;
	newdoodad.x = x0;
	newdoodad.y = y0;
	newdoodad.z = pMap->GetGroundLevel(x0, y0);
	newdoodad.selected = false;
	newdoodad.ID = -1; // no ID
	return 1;
}
// Определить радиус объекта
int fDefineObjectRadius(float &_R, char *pTypeDoodad)
{
	int vFlag;
	if (!pTypeDoodad)
		return 0;
	vFlag = 0;
	if (memcmp(pTypeDoodad,"KOdr",4) == 0 || // RUNETELEPORT
		memcmp(pTypeDoodad,"JOgr",4) == 0 || // RUNE
		memcmp(pTypeDoodad,"ZPfw",4) == 0 || // HERB1
		memcmp(pTypeDoodad,"LPlp",4) == 0 || // HERB2
		memcmp(pTypeDoodad,"LPrs",4) == 0 || // HERB3
		memcmp(pTypeDoodad,"YTpb",4) == 0 || // EMPTY1
		memcmp(pTypeDoodad,"YTlb",4) == 0 || // EMPTY2
		memcmp(pTypeDoodad,"YOfs",4) == 0 || // EMPTY3
		memcmp(pTypeDoodad,"YOr2",4) == 0 || // EMPTY4
		memcmp(pTypeDoodad,"YOf2",4) == 0 || // EMPTY5
		memcmp(pTypeDoodad,"LOsm",4) == 0) // EMPTY6
	{
		_R = 0;
		vFlag = 1;
	}
	if (memcmp(pTypeDoodad,"LOh1",4) == 0) // FLAGALLIANCE
	{
		_R = 64;
		vFlag = 1;
	}
	if (memcmp(pTypeDoodad,"LTlt",4) == 0 || // TREE
		memcmp(pTypeDoodad,"LRrk",4) == 0) // STONES
	{
		_R = 128;
		vFlag = 1;
	}
	if (memcmp(pTypeDoodad,"YTpc",4) == 0 || // OBELISK
		memcmp(pTypeDoodad,"YOks",4) == 0) // STATUE1
	{
		_R = 256;
		vFlag = 1;
	}
	if (vFlag == 0)
		return 0;
	return 1;
}
// Проверить свободная ли клетка
int fWhetherToCheckFreeCell(int x, int y, WorldMap *pMap)
{
	// можно ли разместить стандартный объект 128х128 в этой клетке
	CDoodad doodad;
	CDoodad nextdoodad;
	int vW;
	int vH;
	float _R1;
	float _R2;
	float m_fMinDist;

	float distance, best;

	if (!ppMap)
		return 0;
	if (!pMap->CheckMapInit() )
		return 0;
	vW = pMap->GetMapWidth();
	vH = pMap->GetMapHeight();
	if (x < 0 || y < 0 || x >= vW || y >= vH)
		return 0;

	if(!fCheckForBias(x,y,pMap))	// проверить на уклон
		return 0;

	best = -1;
	pMap->GoFirstDoodad();
	do
	{
		nextdoodad = pMap->GetNextDoodad();
		if(nextdoodad.type == "")
			break;
		distance = (nextdoodad.x - x)*(nextdoodad.x - x) + (nextdoodad.y - y)*(nextdoodad.y - y);
		fDefineObjectRadius(_R2,nextdoodad.type.GetStrID());
		if (((best < 0) || (distance < best)) && _R2 > 0)
		{
			best = distance;
			doodad = nextdoodad;		
		}
	}
	while(nextdoodad.type != "");

	_R1 = 128/2;
	fDefineObjectRadius(_R2,doodad.type.GetStrID());
	if (_R1 == 0)
		m_fMinDist = 0;
	else
		m_fMinDist = _R1/2 + _R2/2;

	if (pMap->GetDistance(x, y, doodad.x, doodad.y) < m_fMinDist)
		return 0;
	return 1;
}
// Проверить объект в этой клетке
int fCheckDoodadThisCell (int x, int y, WorldMap *pMap, int _Object)
{
	CDoodad doodad;
	CDoodad nextdoodad;
	int vW;
	int vH;
	float m_fMinDist;
	float _x;
	float _y;

	int vFlag;

	if (!ppMap)
		return 0;
	if (!pMap->CheckMapInit() )
		return 0;
	vW = pMap->GetMapWidth();
	vH = pMap->GetMapHeight();
	if (x < 0 || y < 0 || x >= vW || y >= vH)
		return 0;

	// определить координаты объекта
	_x = (float)(x * 128) + 64;
	_y = (float)(y * 128) + 64;
	_x += (float)(vW * 128 / -2);
	_y += (float)(vH * 128 / -2);

	fSelectDoodad(doodad,_x,_y,pMap,_Object);

	m_fMinDist = 128/2;

	vFlag = 0;
	pMap->GoFirstDoodad();
	do
	{
		nextdoodad = pMap->GetNextDoodad();
		if(nextdoodad.type == "")
			break;
		if (nextdoodad.type == doodad.type &&
			nextdoodad.life == doodad.life &&
			pMap->GetDistance(_x, _y, nextdoodad.x, nextdoodad.y) < m_fMinDist)
		{
			vFlag = 1;
			break;
		}
	}
	while(nextdoodad.type != "");

	if (vFlag == 1)
		return 1;
	return 0;
}
// Проверить спуск
int fCheckRamp(int x, int y, WorldMap *pMap)
{
	CTilePoint Tilepoint;
	int vW;
	int vH;
	int vCountRamp;
	
	if (!ppMap)
		return 0;
	if (!pMap->CheckMapInit() )
		return 0;
	vW = pMap->GetMapWidth();
	vH = pMap->GetMapHeight();
	if (x < 0 || y < 0 || x >= vW || y >= vH)
		return 0;

	vCountRamp = 0;
	// проверить на спуск
	for (int vvi=0;vvi<=1;vvi++)
	{
		for (int vvj=0;vvj<=1;vvj++)
		{
			Tilepoint = pMap->GetTilePoint(x+vvi, y+vvj);
			if (TILE_FL_RAMP & Tilepoint.flags)
				vCountRamp++;
		}
	}
	if (vCountRamp < 2)
		return 0;
	return 1;
}
// Разместить объект декораций
int fToPlaceDoodad(int x, int y, WorldMap *pMap, int _Object)
{
	CDoodad newdoodad;
	int vW;
	int vH;
	float _x;
	float _y;
	
	if (!ppMap)
		return 0;
	if (!pMap->CheckMapInit() )
		return 0;
	vW = pMap->GetMapWidth();
	vH = pMap->GetMapHeight();
	if (x < 0 || y < 0 || x >= vW || y >= vH)
		return 0;

	if(!fCheckForBias(x,y,pMap))	// проверить на уклон
		return 0;

	// определить координаты объекта
	_x = (float)(x * 128) + 64;
	_y = (float)(y * 128) + 64;
	_x += (float)(vW * 128 / -2);
	_y += (float)(vH * 128 / -2);

	// создать новый объект
	if (fCreateNewDoodad(newdoodad,_x,_y,pMap,_Object))
	{
		pMap->AddDoodad(newdoodad);	// добавить новый объект
	}
	return 1;
}
// Проверьте уклон
int fCheckForBias (int x, int y, WorldMap *pMap)
{
	CTilePoint Tilepoint;
	int vW;
	int vH;
	int vLayer1;
	int vLayer2;
	
	if (!ppMap)
		return 0;
	if (!pMap->CheckMapInit() )
		return 0;
	vW = pMap->GetMapWidth();
	vH = pMap->GetMapHeight();
	if (x < 0 || y < 0 || x >= vW || y >= vH)
		return 0;

	// проверить на уклон
	for (int vvi=0;vvi<=1;vvi++)
	{
		for (int vvj=0;vvj<=1;vvj++)
		{
			vLayer1 = 0;
			vLayer2 = 0;
			Tilepoint = pMap->GetTilePoint(x+vvi, y+vvi);
			vLayer1 = Tilepoint.layer;
			Tilepoint = pMap->GetTilePoint(x+vvj, y+1-vvj);
			vLayer2 = Tilepoint.layer;
			if(vLayer1 != vLayer2)
				return 0;
		}
	}
	return 1;
}
// Выбрать карту
int fSelectMap (int _NumMap, WorldMap *&pMap)
{
	if (pMap != NULL)
		return 0;
	switch (_NumMap)
	{
		case 0:
			pMap = &MapMain;
			break;
		case 1:
			pMap = &MapSlayerPlace;
			break;
		case 2:
			pMap = &MapDancePool;
			break;
		case 3:
			pMap = &MapBaseVampire;
			break;
		case 4:
			pMap = &MapEditable;
			break;
	}
	if (pMap == NULL)
		return 0;
	return 1;
}
// Загрузить архив
void fLoadFileArchive(char *pFileName, int _NumMap)
{
	WorldMap *pMap;

	pMap = NULL;
	if (fSelectMap(_NumMap,pMap) == 0)
		return;
	
	MapEditDoc.LoadFileArchive(pFileName,pMap);
}
// Сохранить архив
void fSaveFileArchive(char *pFileName)
{
	MapEditDoc.SaveFileArchive(pFileName,&MapMain);
}
// Изменить клетку земли
int fChangeGroundMapCell(int _c, int _v, int _TerrainType, int _LevelUpland, int _NumMap)
{
	WorldMap *pMap;
	CTilePoint Tilepoint;

	CDoodad nextdoodad;
	int Width;
	int Height;
	RECT AreaCoordsAlloc;
	float _x;
	float _y;
	int _W;
	int _H;

	if (_TerrainType < -1 || _LevelUpland < 0)
		return 0;

	pMap = NULL;
	if (fSelectMap(_NumMap,pMap) == 0)
		return 0;
	if (!pMap)
		return 0;
	if (!pMap->CheckMapInit())
		return 0;
	if (_c < 0 || _v < 0 ||
		_c > pMap->GetTilePointsTableWidth() || _v > pMap->GetTilePointsTableHeight())
		return 0;

	fCreateNewTilePoint(_TerrainType,_LevelUpland,pMap,Tilepoint);	// создать новую клетку земли
	if (Tilepoint.IsUnderWater())
		fChangeLandscape(Tilepoint,Tilepoint.layer-1,WATER_SHALLOW);
	
	// определяем координаты клетки земли
	_W = pMap->GetTilePointsTableWidth();
	_H = pMap->GetTilePointsTableHeight();
	_x = (float)(_c * 128);
	_y = (float)(_v * 128);
	_x += (float)(_W * 128 / -2);
	_y += (float)(_H * 128 / -2);
	AreaCoordsAlloc.left = _x;
	AreaCoordsAlloc.bottom = _y;
	_x = (float)(_c * 128);
	_y = (float)((_v+1) * 128);
	_x += (float)(_W * 128 / -2);
	_y += (float)(_H * 128 / -2);
	AreaCoordsAlloc.right = _x;
	AreaCoordsAlloc.top = _y;

	if (Tilepoint.groundtype == unsigned char(-1))
	{
		// удаляем объекты декораций
		pMap->GoFirstDoodad();
		do
		{
			nextdoodad = pMap->GetNextDoodad();
			if(nextdoodad.type == "")
				break;

			if (nextdoodad.x >= AreaCoordsAlloc.left &&
				nextdoodad.x <= AreaCoordsAlloc.right &&
				nextdoodad.y <= AreaCoordsAlloc.top &&
				nextdoodad.y >= AreaCoordsAlloc.bottom)
			{
				pMap->DelDoodad(nextdoodad);
			}
		}
		while(nextdoodad.type != "");
	}

	pMap->SetTilePoint(_c, _v, Tilepoint);
	return 1;
}
// Создать новую клетку земли
int fCreateNewTilePoint(int _TerrainType, int _LevelUpland, WorldMap *pMap, CTilePoint &Tilepoint)
{
	if (!pMap)
		return 0;
	if (!pMap->CheckMapInit())
		return 0;
	
	if (_TerrainType < 0 && _TerrainType > TERRAIN_TYPE_MAX)
		return 0;
	if (_LevelUpland < 0 && _LevelUpland > TERRAIN_LAYER_MAX)
		return 0;
	switch (_TerrainType)
	{
		case NONE:
			Tilepoint.groundtype = -1;
			break;
		case SOIL1:
		case SLOPESOIL1:
		case WATERSOIL1:
		case SLOPEWATERSOIL1:
		case CORRUPTIONSOIL1:
		case SLOPECORRUPTIONSOIL1:
			Tilepoint.groundtype = fGetTileIndex("Ldrt", pMap->mapGroundTiles.c_str());
			break;
		case COARSESOIL:
		case SLOPECOARSESOIL:
		case WATERCOARSESOIL:
		case SLOPEWATERCOARSESOIL:
		case CORRUPTIONCOARSESOIL:
		case SLOPECORRUPTIONCOARSESOIL:
			Tilepoint.groundtype = fGetTileIndex("Ldro", pMap->mapGroundTiles.c_str());
			break;
		case SOIL2:
		case SLOPESOIL2:
		case WATERSOIL2:
		case SLOPEWATERSOIL2:
		case CORRUPTIONSOIL2:
		case SLOPECORRUPTIONSOIL2:
			Tilepoint.groundtype = fGetTileIndex("Ldrg", pMap->mapGroundTiles.c_str());
			break;
		case GRASS:
		case SLOPEGRASS:
		case WATERGRASS:
		case SLOPEWATERGRASS:
		case CORRUPTIONGRASS:
		case SLOPECORRUPTIONGRASS:
			Tilepoint.groundtype = fGetTileIndex("Lgrs", pMap->mapGroundTiles.c_str());
			break;
		case DARKGRASS:
		case SLOPEDARKGRASS:
		case WATERDARKGRASS:
		case SLOPEWATERDARKGRASS:
		case CORRUPTIONDARKGRASS:
		case SLOPECORRUPTIONDARKGRASS:
			Tilepoint.groundtype = fGetTileIndex("Lgrd", pMap->mapGroundTiles.c_str());
			break;
		case STONE:
		case SLOPESTONE:
		case WATERSTONE:
		case SLOPEWATERSTONE:
		case CORRUPTIONSTONE:
		case SLOPECORRUPTIONSTONE:
			Tilepoint.groundtype = fGetTileIndex("Orok", pMap->mapGroundTiles.c_str());
			break;
		case ROCKYTRAIL:
		case SLOPEROCKYTRAIL:
		case WATERROCKYTRAIL:
		case SLOPEWATERROCKYTRAIL:
		case CORRUPTIONROCKYTRAIL:
		case SLOPECORRUPTIONROCKYTRAIL:
			Tilepoint.groundtype = fGetTileIndex("Vstp", pMap->mapGroundTiles.c_str());
			break;
	}
	if (Tilepoint.groundtype == -1)
		return 0;
	Tilepoint.clifftype = fGetTileIndex("CLgr", pMap->mapCliffTiles.c_str());
	switch (_TerrainType)
	{
		case SOIL1:
		case COARSESOIL:
		case SOIL2:
		case GRASS:
		case DARKGRASS:
		case STONE:
		case ROCKYTRAIL:
			Tilepoint.flags = TILE_FL_NULL;
			break;
		case SLOPESOIL1:
		case SLOPECOARSESOIL:
		case SLOPESOIL2:
		case SLOPEGRASS:
		case SLOPEDARKGRASS:
		case SLOPESTONE:
		case SLOPEROCKYTRAIL:
			Tilepoint.flags = TILE_FL_RAMP;
			break;
		case WATERSOIL1:
		case WATERCOARSESOIL:
		case WATERSOIL2:
		case WATERGRASS:
		case WATERDARKGRASS:
		case WATERSTONE:
		case WATERROCKYTRAIL:
			Tilepoint.flags = TILE_FL_WATER;
			break;
		case SLOPEWATERSOIL1:
		case SLOPEWATERCOARSESOIL:
		case SLOPEWATERSOIL2:
		case SLOPEWATERGRASS:
		case SLOPEWATERDARKGRASS:
		case SLOPEWATERSTONE:
		case SLOPEWATERROCKYTRAIL:
			Tilepoint.flags = TILE_FL_RAMP | TILE_FL_WATER;
			break;
		case CORRUPTIONSOIL1:
		case CORRUPTIONCOARSESOIL:
		case CORRUPTIONSOIL2:
		case CORRUPTIONGRASS:
		case CORRUPTIONDARKGRASS:
		case CORRUPTIONSTONE:
		case CORRUPTIONROCKYTRAIL:
			Tilepoint.flags = TILE_FL_BLIGHT;
			break;
		case SLOPECORRUPTIONSOIL1:
		case SLOPECORRUPTIONCOARSESOIL:
		case SLOPECORRUPTIONSOIL2:
		case SLOPECORRUPTIONGRASS:
		case SLOPECORRUPTIONDARKGRASS:
		case SLOPECORRUPTIONSTONE:
		case SLOPECORRUPTIONROCKYTRAIL:
			Tilepoint.flags = TILE_FL_RAMP | TILE_FL_BLIGHT;
			break;
		default:
			Tilepoint.flags = 0;
			break;
	}
	Tilepoint.height = TILE_HEIGHT_LEVEL_ZERO;
	Tilepoint.waterlevel = TILE_HEIGHT_LEVEL_ZERO;
	Tilepoint.details = 0;
	Tilepoint.layer = _LevelUpland;
	Tilepoint.selected = false;
	Tilepoint.viewcolor.rgbReserved = 0;
	Tilepoint.viewcolor.rgbRed = 0;
	Tilepoint.viewcolor.rgbGreen = 0;
	Tilepoint.viewcolor.rgbBlue = 0;
	return 1;
}
// Сохранить карту редактора
int fSaveMapEditor(int _NumMap, RECT rect)
{
	WorldMap *pMap;

	pMap = NULL;
	if (fSelectMap(_NumMap,pMap) == 0)
		return 0;
	if (!pMap)
		return 0;
	if (!MapEditable.CheckMapInit())
		return 0;
	*pMap = WorldMap(MapEditable,rect);
	(*pMap).ResetPathing();// обновить карту путей
	if (!pMap->CheckMapInit())
		return 0;
	return 1;
}
// Загрузить карту редактора
int fLoadMapEditor(int _NumMap, int &_Width, int &_Height)
{
	WorldMap *pMap;

	pMap = NULL;
	if (fSelectMap(_NumMap,pMap) == 0)
		return 0;
	if (!pMap)
		return 0;
	if (!pMap->CheckMapInit())
		return 0;
	MapEditable = *pMap;
	if (!MapEditable.CheckMapInit())
		return 0;
	_Width = pMap->GetMapWidth();
	_Height = pMap->GetMapHeight();
	return 1;
}
// Очистить карту редактора
void fClearMapEditable()
{
	fClearMap(&MapEditable);
}
////////////////////////////////////////////////////////////////////
// Конструктор
WorldMap::WorldMap()
{
	Regions = 0;
	pHeadRegion = NULL;
	pLastRegion = NULL;
	pСurrentRegion = NULL;
	bMapInit = false;
}
// Проверить инициализацию карты
bool WorldMap::CheckMapInit()
{
	return bMapInit;
};
// Инициализация карты
void WorldMap::MapInit(bool _MapInit)
{
	bMapInit = _MapInit;
};
// Конструктор копирования
WorldMap::WorldMap(WorldMap &M, RECT _AllocationArea)
{
	CTilePoint Tilepoint;
	CDoodad nextdoodad;
	RegionMap* pNextRegion;
	int Width;
	int Height;
	RECT AreaCoordsAlloc;
	float _x;
	float _y;
	int vW;
	int vH;

	Regions = 0;
	pHeadRegion = NULL;
	pLastRegion = NULL;
	pСurrentRegion = NULL;
	bMapInit = false;

	Width = _AllocationArea.right - _AllocationArea.left;
	Height = _AllocationArea.bottom - _AllocationArea.top;
	if(Width > 0 && Height > 0)
	{
		//W3E
		SetMapSize(Width,Height);
		mapGroundTiles = M.mapGroundTiles;
		mapCliffTiles = M.mapCliffTiles;

		mapMainTileset = M.mapMainTileset;
		mapCustomTilesets = M.mapCustomTilesets;
		SetMapCenter((float)(Width * 128 / -2), (float)(Height * 128 / -2));

		//DOO
		mapUnknownDooInt = M.mapUnknownDooInt;

		bMapInit = true;

		for (int c=_AllocationArea.left; c<=_AllocationArea.right; c++)
		{
			for (int v=_AllocationArea.top; v<=_AllocationArea.bottom; v++)
			{
				Tilepoint = M.GetTilePoint(c, v);
				SetTilePoint(c-_AllocationArea.left, v-_AllocationArea.top, Tilepoint);
			}
		}
		vW = M.GetMapWidth();
		vH = M.GetMapHeight();
		_x = (float)(_AllocationArea.left * 128) - 64;
		_y = (float)(_AllocationArea.bottom * 128) + 64;
		_x += (float)(vW * 128 / -2);
		_y += (float)(vH * 128 / -2);
		AreaCoordsAlloc.left = _x;
		AreaCoordsAlloc.top = _y;
		_x = (float)(_AllocationArea.right * 128) + 64;
		_y = (float)(_AllocationArea.top * 128) - 64;
		_x += (float)(vW * 128 / -2);
		_y += (float)(vH * 128 / -2);
		AreaCoordsAlloc.right = _x;
		AreaCoordsAlloc.bottom = _y;
		M.GoFirstDoodad();
		do
		{
			nextdoodad = M.GetNextDoodad();
			if(nextdoodad.type == "")
				break;
			
			if (nextdoodad.x > AreaCoordsAlloc.left &&
				nextdoodad.x < AreaCoordsAlloc.right &&
				nextdoodad.y < AreaCoordsAlloc.top &&
				nextdoodad.y > AreaCoordsAlloc.bottom)
			{
				if (Width != vW)
				{
					nextdoodad.x = (float)((nextdoodad.x + ((float)(vW)/2 - (_AllocationArea.left + (float)(Width)/2)) * 128));
				}
				if (Height != vH)
				{
					nextdoodad.y = (float)((nextdoodad.y - ((float)(vH)/2 - (vH-_AllocationArea.bottom + (float)(Height)/2)) * 128));
				}
				AddDoodad(nextdoodad);
			}
		}
		while(nextdoodad.type != "");
		
		M.GoFirstRegion();
		while(pNextRegion = M.GetNextRegion())
			AddRegion(*pNextRegion);
	}
}
// Скопировать карту
void WorldMap::CopyMap(WorldMap &M, RECT _AllocationArea)
{
	CTilePoint Tilepoint;
	CDoodad nextdoodad;
	int Width;
	int Height;
	RECT AreaCoordsAlloc;
	float _x;
	float _y;
	int vW;
	int vH;

	Width = M.GetMapWidth();
	Height = M.GetMapHeight();
	if(_AllocationArea.right - _AllocationArea.left > Width)
		_AllocationArea.right = _AllocationArea.left + Width;
	if(_AllocationArea.bottom - _AllocationArea.top > Height)
		_AllocationArea.bottom = _AllocationArea.top + Height;
	if(Width > 0 && Height > 0)
	{
		vW = GetMapWidth();
		vH = GetMapHeight();
		for (int c=_AllocationArea.left; c<=_AllocationArea.right; c++)
		{
			for (int v=vH-_AllocationArea.bottom; v<=vH-_AllocationArea.top; v++)
			{
				Tilepoint = M.GetTilePoint(c-_AllocationArea.left, v-(vH-_AllocationArea.bottom));
				if (Tilepoint.groundtype != unsigned char(-1))
					SetTilePoint(c, v, Tilepoint);
			}
		}
		_x = (float)(_AllocationArea.left * 128);
		_y = (float)((vH - _AllocationArea.top) * 128);
		_x += (float)(vW * 128 / -2);
		_y += (float)(vH * 128 / -2);
		AreaCoordsAlloc.left = _x;//-2048
		AreaCoordsAlloc.top = _y;//2048
		_x = (float)(_AllocationArea.right * 128);
		_y = (float)((vH - _AllocationArea.bottom) * 128);
		_x += (float)(vW * 128 / -2);
		_y += (float)(vH * 128 / -2);
		AreaCoordsAlloc.right = _x;//2048
		AreaCoordsAlloc.bottom = _y;//-2048
		M.GoFirstDoodad();
		do
		{
			nextdoodad = M.GetNextDoodad();
			if(nextdoodad.type == "")
				break;

			nextdoodad.x = (float)((nextdoodad.x - ((float)(vW)/2 - (_AllocationArea.left + (float)(Width)/2)) * 128));
			nextdoodad.y = (float)((nextdoodad.y + ((float)(vH)/2 - (_AllocationArea.top + (float)(Height)/2)) * 128));	
			if (nextdoodad.x >= AreaCoordsAlloc.left &&
				nextdoodad.x <= AreaCoordsAlloc.right &&
				nextdoodad.y <= AreaCoordsAlloc.top &&
				nextdoodad.y >= AreaCoordsAlloc.bottom)
			{AddDoodad(nextdoodad);}
		}
		while(nextdoodad.type != "");
	}
}
// Перегрузка оператора присваивания
const WorldMap &WorldMap::operator=(WorldMap &M)
{
	CTilePoint Tilepoint;
	CDoodad nextdoodad;
	RegionMap* pNextRegion;
	//W3E
	SetMapSize(M.GetMapWidth(),M.GetMapHeight());
	mapGroundTiles = M.mapGroundTiles;
	mapCliffTiles = M.mapCliffTiles;

	mapMainTileset = M.mapMainTileset;
	mapCustomTilesets = M.mapCustomTilesets;
	SetMapCenter((float)(M.GetMapWidth() * 128 / -2), (float)(M.GetMapHeight() * 128 / -2));

	//DOO
	mapUnknownDooInt = M.mapUnknownDooInt;

	bMapInit = true;

	for (int c=0; c<GetTilePointsTableWidth(); c++)
	{
		for (int v=0; v<GetTilePointsTableHeight(); v++)
		{
			Tilepoint = M.GetTilePoint(c, v);
			SetTilePoint(c, v, Tilepoint);
		}
	}
	M.GoFirstDoodad();
	do
	{
		nextdoodad = M.GetNextDoodad();
		if(nextdoodad.type == "")
			break;
		AddDoodad(nextdoodad);
	}
	while(nextdoodad.type != "");
	
	DelAllRegions();	// удалить все регионы

	M.GoFirstRegion();
	while(pNextRegion = M.GetNextRegion())
		AddRegion(*pNextRegion);

	return *this;
}
// Добавить регион карты в цепочку регионов
void WorldMap::AddRegion(RegionMap _Region)
{
	RegionMap* pNewRegion;

	pNewRegion = new RegionMap;
	_Region.Id = GetFreeId();
	_Region.pNext = NULL;
	*pNewRegion = _Region;

	if (pLastRegion)
	{
		pLastRegion->pNext = pNewRegion;
		pLastRegion = pNewRegion;
	}
	else
	{
		pLastRegion = pNewRegion;
		pHeadRegion = pNewRegion;
	}
	Regions++;
}
// Редактировать регион карты в цепочке регионов
void WorldMap::EditRegion(RegionMap _Region)
{
	RegionMap* pNextRegion;

	GoFirstRegion();
	while(pNextRegion = GetNextRegion())
	{
		if (pNextRegion->Id == _Region.Id)
		{
			pNextRegion->Type = _Region.Type;
			pNextRegion->Rect = _Region.Rect;
		}
	}
}
// Удалить все регионы карты из цепочки регионов
void WorldMap::DelAllRegions()
{
	RegionMap* pNextRegion;

	GoFirstRegion();
	while(pNextRegion = GetNextRegion())
	{
		if (pNextRegion)
		{
			delete pNextRegion;
			Regions--;
		}
	}
	pHeadRegion = NULL;
	pLastRegion = NULL;
	pСurrentRegion = NULL;
}
// Удалить регион карты из цепочки регионов по ID
void WorldMap::DelRegion(int _Id)
{
	RegionMap* pNextRegion;
	RegionMap* pRegion;

	pRegion = NULL;
	GoFirstRegion();
	while(pNextRegion = GetNextRegion())
	{
		if (pNextRegion)
		{
			if (pNextRegion->Id == _Id)
			{
				if (pRegion == NULL)
				{
					pHeadRegion = pNextRegion->pNext;
					if (pHeadRegion == NULL)
					{
						pLastRegion = NULL;
						pСurrentRegion = NULL;
					}
				}
				else
					pRegion->pNext = pNextRegion->pNext;
				delete pNextRegion;
				Regions--;
			}
		}
		pRegion = pNextRegion;
	}
}
// Удалить все регионы карты из цепочки регионов по типу региона
void WorldMap::DelRegions(int _Type)
{
	RegionMap* pNextRegion;
	RegionMap* pRegion;

	GoFirstRegion();
	while(pNextRegion = GetNextRegion())
	{
		if (pNextRegion->Id == _Type)
		{
			pRegion->pNext = pNextRegion->pNext;
			delete pNextRegion;
			Regions--;
		}
		pRegion = pNextRegion;
	}
}
// Забрать кол-во регионов карты
int WorldMap::GetRegions()
{
	return Regions;
}
// Перейти к первому региону карты в цепочке регионов
void WorldMap::GoFirstRegion()
{
	pСurrentRegion = pHeadRegion;
}
// Взять следующий регион карты из цепочки регионов
RegionMap* WorldMap::GetNextRegion()
{
	RegionMap *pRegion;
	if(pСurrentRegion)
	{
		pRegion = pСurrentRegion;
		pСurrentRegion = pСurrentRegion->pNext;
	}
	else
		pСurrentRegion = pHeadRegion;
	return pRegion;
}
// Взять регион карты из цепочки регионов по ID
void WorldMap::GetRegion(RegionMap &_Rect, int _Id)
{
	RegionMap* pNextRegion;

	GoFirstRegion();
	while(pNextRegion = GetNextRegion())
	{
		if (pNextRegion->Id == _Id)
			_Rect = *pNextRegion;
	}
}
// Взять свободный ID (идентификационный номер)
int WorldMap::GetFreeId()
{
	RegionMap* pNextRegion;
	int vId;
	int vFlag;

	vId = 0;
m1:;
	vFlag = 0;
	GoFirstRegion();
	while(pNextRegion = GetNextRegion())
	{
		if (pNextRegion->Id == vId)
		{
			vId++;
			vFlag = 1;
			break;
		}
	}
	if (vFlag == 1) goto m1;
	return vId;
}
// Взять лист ID регионов
void WorldMap::GetListId(int *&pListId, int &_N)
{
	RegionMap* pNextRegion;
	int i;

	_N = MapEditable.GetRegions();
	pListId = new int[_N];
	MapEditable.GoFirstRegion();
	i = 0;
	while(pNextRegion = GetNextRegion())
	{
		if (i < _N) pListId[i] = pNextRegion->Id;
		i++;
	}
}
// Установить кол-во баз на карте
void WorldMap::SetBaseN(int _BaseN)
{
	BaseN = _BaseN;
}
// Забрать кол-во баз на карте
int WorldMap::GetBaseN()
{
	return BaseN;
}
// Деструктор (пока безработный)
WorldMap::~WorldMap()
{
}
////////////////////////////////////////////////////////////////////