瀏覽代碼

* moved map reading to the map.cpp
* merged changes from trunk (since r461)

Michał W. Urbańczyk 17 年之前
父節點
當前提交
c351496a47
共有 15 個文件被更改,包括 2345 次插入2274 次删除
  1. 1 0
      CAdvmapInterface.cpp
  2. 48 18
      CBattleInterface.cpp
  3. 1 1
      CBattleInterface.h
  4. 3 2
      CCallback.cpp
  5. 112 97
      CConsoleHandler.cpp
  6. 52 8
      CGameState.cpp
  7. 6 4
      CGameState.h
  8. 4 1
      CHeroWindow.cpp
  9. 4 7
      CMT.cpp
  10. 16 20
      CPathfinder.cpp
  11. 2 0
      CPlayerInterface.cpp
  12. 43 2095
      hch/CAmbarCendamo.cpp
  13. 3 16
      hch/CAmbarCendamo.h
  14. 2044 4
      map.cpp
  15. 6 1
      map.h

+ 1 - 0
CAdvmapInterface.cpp

@@ -316,6 +316,7 @@ void CTerrainRect::clickLeft(tribool down)
 		//Convert to old format.
 		currentPath = LOCPLINT->adventureInt->heroList.items[LOCPLINT->adventureInt->heroList.selected].second = CGI->pathf->ConvertToOldFormat(p);
 
+		delete p;
 		//currentPath = LOCPLINT->adventureInt->heroList.items[LOCPLINT->adventureInt->heroList.selected].second = CGI->pathf->getPath(bufpos,mp,currentHero,1);
 	}
 }

+ 48 - 18
CBattleInterface.cpp

@@ -213,7 +213,7 @@ void CBattleInterface::show(SDL_Surface * to)
 		}
 	}
 	//showing selected unit's range
-	if(creAnims[activeStack]->getType() != 0) //don't show if unit is moving
+	if(activeStack != -1 && creAnims[activeStack]->getType() != 0) //don't show if unit is moving
 	{
 		showRange(to, activeStack);
 	}
@@ -240,37 +240,68 @@ void CBattleInterface::show(SDL_Surface * to)
 		defendingHero->show(to);
 
 	//showing units //a lot of work...
-	int stackByHex[187];
-	for(int b=0; b<187; ++b)
-		stackByHex[b] = -1;
+	std::vector<int> stackAliveByHex[187];
+	//double loop because dead stacks should be printed first
 	for(std::map<int, CStack>::iterator j=stacks.begin(); j!=stacks.end(); ++j)
 	{
-		stackByHex[j->second.position] = j->second.ID;
+		if(j->second.alive)
+			stackAliveByHex[j->second.position].push_back(j->second.ID);
+	}
+	std::vector<int> stackDeadByHex[187];
+	for(std::map<int, CStack>::iterator j=stacks.begin(); j!=stacks.end(); ++j)
+	{
+		if(!j->second.alive)
+			stackDeadByHex[j->second.position].push_back(j->second.ID);
 	}
 
 	attackingShowHelper(); // handle attack animation
 
-	for(int b=0; b<187; ++b)
+	for(int b=0; b<187; ++b) //showing dead stacks
+	{
+		for(int v=0; v<stackDeadByHex[b].size(); ++v)
+		{
+			creAnims[stackDeadByHex[b][v]]->nextFrame(to, creAnims[stackDeadByHex[b][v]]->pos.x, creAnims[stackDeadByHex[b][v]]->pos.y, creDir[stackDeadByHex[b][v]], (animCount%2==0 || creAnims[stackDeadByHex[b][v]]->getType()!=2) && stacks[stackDeadByHex[b][v]].alive, stackDeadByHex[b][v]==activeStack); //increment always when moving, never if stack died
+			//printing amount
+			if(stacks[stackDeadByHex[b][v]].amount > 0) //don't print if stack is not alive
+			{
+				if(stacks[stackDeadByHex[b][v]].attackerOwned)
+				{
+					CSDL_Ext::blit8bppAlphaTo24bpp(amountNormal, NULL, to, &genRect(amountNormal->h, amountNormal->w, creAnims[stackDeadByHex[b][v]]->pos.x + 220, creAnims[stackDeadByHex[b][v]]->pos.y + 260));
+					std::stringstream ss;
+					ss<<stacks[stackDeadByHex[b][v]].amount;
+					CSDL_Ext::printAtMiddleWB(ss.str(), creAnims[stackDeadByHex[b][v]]->pos.x + 220 + 14, creAnims[stackDeadByHex[b][v]]->pos.y + 260 + 4, GEOR13, 20, zwykly, to);
+				}
+				else
+				{
+					CSDL_Ext::blit8bppAlphaTo24bpp(amountNormal, NULL, to, &genRect(amountNormal->h, amountNormal->w, creAnims[stackDeadByHex[b][v]]->pos.x + 202, creAnims[stackDeadByHex[b][v]]->pos.y + 260));
+					std::stringstream ss;
+					ss<<stacks[stackDeadByHex[b][v]].amount;
+					CSDL_Ext::printAtMiddleWB(ss.str(), creAnims[stackDeadByHex[b][v]]->pos.x + 202 + 14, creAnims[stackDeadByHex[b][v]]->pos.y + 260 + 4, GEOR13, 20, zwykly, to);
+				}
+			}
+		}
+	}
+	for(int b=0; b<187; ++b) //showing alive stacks
 	{
-		if(stackByHex[b]!=-1)
+		for(int v=0; v<stackAliveByHex[b].size(); ++v)
 		{
-			creAnims[stackByHex[b]]->nextFrame(to, creAnims[stackByHex[b]]->pos.x, creAnims[stackByHex[b]]->pos.y, creDir[stackByHex[b]], (animCount%2==0 || creAnims[stackByHex[b]]->getType()!=2) && stacks[stackByHex[b]].alive, stackByHex[b]==activeStack); //increment always when moving, never if stack died
+			creAnims[stackAliveByHex[b][v]]->nextFrame(to, creAnims[stackAliveByHex[b][v]]->pos.x, creAnims[stackAliveByHex[b][v]]->pos.y, creDir[stackAliveByHex[b][v]], (animCount%2==0 || creAnims[stackAliveByHex[b][v]]->getType()!=2) && stacks[stackAliveByHex[b][v]].alive, stackAliveByHex[b][v]==activeStack); //increment always when moving, never if stack died
 			//printing amount
-			if(stacks[stackByHex[b]].amount > 0) //don't print if stack is not alive
+			if(stacks[stackAliveByHex[b][v]].amount > 0) //don't print if stack is not alive
 			{
-				if(stacks[stackByHex[b]].attackerOwned)
+				if(stacks[stackAliveByHex[b][v]].attackerOwned)
 				{
-					CSDL_Ext::blit8bppAlphaTo24bpp(amountNormal, NULL, to, &genRect(amountNormal->h, amountNormal->w, creAnims[stackByHex[b]]->pos.x + 220, creAnims[stackByHex[b]]->pos.y + 260));
+					CSDL_Ext::blit8bppAlphaTo24bpp(amountNormal, NULL, to, &genRect(amountNormal->h, amountNormal->w, creAnims[stackAliveByHex[b][v]]->pos.x + 220, creAnims[stackAliveByHex[b][v]]->pos.y + 260));
 					std::stringstream ss;
-					ss<<stacks[stackByHex[b]].amount;
-					CSDL_Ext::printAtMiddleWB(ss.str(), creAnims[stackByHex[b]]->pos.x + 220 + 14, creAnims[stackByHex[b]]->pos.y + 260 + 4, GEOR13, 20, zwykly, to);
+					ss<<stacks[stackAliveByHex[b][v]].amount;
+					CSDL_Ext::printAtMiddleWB(ss.str(), creAnims[stackAliveByHex[b][v]]->pos.x + 220 + 14, creAnims[stackAliveByHex[b][v]]->pos.y + 260 + 4, GEOR13, 20, zwykly, to);
 				}
 				else
 				{
-					CSDL_Ext::blit8bppAlphaTo24bpp(amountNormal, NULL, to, &genRect(amountNormal->h, amountNormal->w, creAnims[stackByHex[b]]->pos.x + 202, creAnims[stackByHex[b]]->pos.y + 260));
+					CSDL_Ext::blit8bppAlphaTo24bpp(amountNormal, NULL, to, &genRect(amountNormal->h, amountNormal->w, creAnims[stackAliveByHex[b][v]]->pos.x + 202, creAnims[stackAliveByHex[b][v]]->pos.y + 260));
 					std::stringstream ss;
-					ss<<stacks[stackByHex[b]].amount;
-					CSDL_Ext::printAtMiddleWB(ss.str(), creAnims[stackByHex[b]]->pos.x + 202 + 14, creAnims[stackByHex[b]]->pos.y + 260 + 4, GEOR13, 20, zwykly, to);
+					ss<<stacks[stackAliveByHex[b][v]].amount;
+					CSDL_Ext::printAtMiddleWB(ss.str(), creAnims[stackAliveByHex[b][v]]->pos.x + 202 + 14, creAnims[stackAliveByHex[b][v]]->pos.y + 260 + 4, GEOR13, 20, zwykly, to);
 				}
 			}
 		}
@@ -1113,12 +1144,11 @@ bool CBattleConsole::addText(std::string text)
 		{
 			texts.push_back( text.substr(firstInToken, i-firstInToken) );
 			firstInToken = i+1;
-			lastShown++;
 		}
 	}
 
 	texts.push_back( text.substr(firstInToken, text.size()) );
-	lastShown++;
+	lastShown = texts.size()-1;
 	return true;
 }
 

+ 1 - 1
CBattleInterface.h

@@ -35,7 +35,7 @@ public:
 	bool hovered, strictHovered;
 	CBattleInterface * myInterface; //interface that owns me
 	static std::pair<int, int> getXYUnitAnim(int hexNum, bool attacker, CCreature * creature); //returns (x, y) of left top corner of animation
-	static signed char mutualPosition(int hex1, int hex2); //returns info about mutual position of given hexes (-1 - they distant, 0 - left top, 1 - right top, 2 - right, 3 - right bottom, 4 - left bottom, 5 - left)
+	static signed char mutualPosition(int hex1, int hex2); //returns info about mutual position of given hexes (-1 - they're distant, 0 - left top, 1 - right top, 2 - right, 3 - right bottom, 4 - left bottom, 5 - left)
 	//for user interactions
 	void hover (bool on);
 	void activate();

+ 3 - 2
CCallback.cpp

@@ -132,9 +132,10 @@ bool CCallback::moveHero(int ID, CPath * path, int idtype, int pathType)
 		{
 			hero->pos = endpos;
 		}*/
-		if((hero->movement>=CGI->mh->getCost(int3(stpos.x-1, stpos.y, stpos.z), int3(endpos.x-1, endpos.y, endpos.z), hero))  || player==-1)
+		if(hero->movement >= (ourPath->nodes.size()>=2 ?  (*(ourPath->nodes.end()-2)).dist : 0) - ourPath->nodes[i].dist  || player==-1)
 		{ //performing move
-			hero->movement-=CGI->mh->getCost(int3(stpos.x-1, stpos.y, stpos.z), int3(endpos.x-1, endpos.y, endpos.z), hero);
+			hero->movement -= (ourPath->nodes.size()>=2 ?  (*(ourPath->nodes.end()-2)).dist : 0) - ourPath->nodes[i].dist;
+			ourPath->nodes.pop_back();
 			
 			std::vector< CGObjectInstance * > vis = CGI->mh->getVisitableObjs(CGHeroInstance::convertPosition(curd.dst,false));
 			bool blockvis = false;

+ 112 - 97
CConsoleHandler.cpp

@@ -16,6 +16,13 @@
 #include "hch/CLodHandler.h"
 #include "boost/filesystem/operations.hpp"
 #include <boost/algorithm/string.hpp>
+#ifdef WIN32
+#include <conio.h>
+#else
+#endif
+
+bool continueReadingConsole = true;
+
 int internalFunc(void * callback)
 {
 	CCallback * cb = (CCallback*)callback;
@@ -23,119 +30,127 @@ int internalFunc(void * callback)
 	std::string readed;
 	while(true)
 	{
-		std::cin.getline(usersMessage, 500);
-		std::istringstream readed;
-		std::string pom(usersMessage);
-		readed.str(pom);
-		std::string cn; //command name
-		readed >> cn;
-		int3 src, dst;
+#ifdef WIN32
+		if(continueReadingConsole && kbhit())
+#else
+#endif
+		{
+			std::cin.getline(usersMessage, 500);
+			std::istringstream readed;
+			std::string pom(usersMessage);
+			readed.str(pom);
+			std::string cn; //command name
+			readed >> cn;
+			int3 src, dst;
 
-		int heronum;
-		int3 dest;
+			int heronum;
+			int3 dest;
 
-		if(pom==std::string("die, fool"))
-			exit(0);
-		else if(pom==std::string("get txt"))
-		{
-			boost::filesystem::create_directory("Extracted_txts");
-			std::cout<<"Command accepted. Opening .lod file...\t";
-			CLodHandler * txth = new CLodHandler;
-			txth->init(std::string("Data\\H3bitmap.lod"),"Data");
-			std::cout<<"done.\nScanning .lod file\n";
-			int curp=0;
-			std::string pattern = ".TXT";
-			for(int i=0;i<txth->entries.size(); i++)
+			if(pom==std::string("die, fool"))
+				exit(0);
+			else if(pom==std::string("get txt"))
 			{
-				std::string pom = txth->entries[i].nameStr;
-				if(boost::algorithm::find_last(pom,pattern))
-				{
-					txth->extractFile(std::string("Extracted_txts\\")+pom,pom);
-				}
-				int p2 = ((float)i/(float)txth->entries.size())*(float)100;
-				if(p2!=curp)
+				boost::filesystem::create_directory("Extracted_txts");
+				std::cout<<"Command accepted. Opening .lod file...\t";
+				CLodHandler * txth = new CLodHandler;
+				txth->init(std::string("Data\\H3bitmap.lod"),"data");
+				std::cout<<"done.\nScanning .lod file\n";
+				int curp=0;
+				std::string pattern = ".TXT";
+				for(int i=0;i<txth->entries.size(); i++)
 				{
-					curp = p2;
-					std::cout<<"\r"<<curp<<"%";
+					std::string pom = txth->entries[i].nameStr;
+					if(boost::algorithm::find_last(pom,pattern))
+					{
+						txth->extractFile(std::string("Extracted_txts\\")+pom,pom);
+					}
+					int p2 = ((float)i/(float)txth->entries.size())*(float)100;
+					if(p2!=curp)
+					{
+						curp = p2;
+						std::cout<<"\r"<<curp<<"%";
+					}
 				}
+				std::cout<<"\rExtracting done :)\n";
 			}
-			std::cout<<"\rExtracting done :)\n";
-		}
-		vector<Coordinate>* p;
-		switch (*cn.c_str())
-		{
-		//case 'P':
-		//	std::cout<<"Policzyc sciezke."<<std::endl;		
-		//	readed>>src>>dst;
-		//	
-		//	p = CGI->pathf->GetPath(Coordinate(src),Coordinate(dst),CGI->heroh->heroInstances[0]);
-		//	LOCPLINT->adventureInt->terrain.currentPath = CGI->pathf->ConvertToOldFormat(p);
-			//LOCPLINT->adventureInt->terrain.currentPath = CGI->pathf->getPath(src,dst,CGI->heroh->heroInstances[0]);
-			//break;
-		case 'm': //number of heroes
-			std::cout<<"Number of heroes: "<<CGI->mh->map->heroes.size()<<std::endl;
-			break;
-		case 'H': //position of hero
-			readed>>heronum;
-			std::cout<<"Position of hero "<<heronum<<": "<<CGI->mh->map->heroes[heronum]->getPosition(false)<<std::endl;
-			break;
-		case 'M': //move heroa
-			{
-				readed>>heronum>>dest;
-				const CGHeroInstance * hero = cb->getHeroInfo(0,heronum,0);
-				p = CGI->pathf->GetPath(Coordinate(hero->getPosition(false)),Coordinate(dest),hero);
-				cb->moveHero(heronum, CGI->pathf->ConvertToOldFormat(p), 0, 0);
-				//LOCPLINT->adventureInt->terrain.currentPath = CGI->pathf->getPath(src,dst,CGI->heroh->heroInstances[0]);
-				break;
-			}
-		case 'D': //pos description
-			readed>>src;
-			CGI->mh->getObjDescriptions(src);
-			break;
-		case 'I': 
+			vector<Coordinate>* p;
+			switch (*cn.c_str())
 			{
-				SDL_Surface * temp = LOCPLINT->infoWin(NULL);
-				blitAtWR(temp,605,389);
-				SDL_FreeSurface(temp);
+			//case 'P':
+			//	std::cout<<"Policzyc sciezke."<<std::endl;		
+			//	readed>>src>>dst;
+			//	
+			//	p = CGI->pathf->GetPath(Coordinate(src),Coordinate(dst),CGI->heroh->heroInstances[0]);
+			//	LOCPLINT->adventureInt->terrain.currentPath = CGI->pathf->ConvertToOldFormat(p);
+			//	//LOCPLINT->adventureInt->terrain.currentPath = CGI->pathf->getPath(src,dst,CGI->heroh->heroInstances[0]);
+			//	break;
+			//case 'm': //number of heroes
+			//	std::cout<<"Number of heroes: "<<CGI->heroh->heroInstances.size()<<std::endl;
+			//	break;
+			//case 'H': //position of hero
+			//	readed>>heronum;
+			//	std::cout<<"Position of hero "<<heronum<<": "<<CGI->heroh->heroInstances[heronum]->getPosition(false)<<std::endl;
+			//	break;
+			case 'M': //move heroa
+				{
+					readed>>heronum>>dest;
+					const CGHeroInstance * hero = cb->getHeroInfo(0,heronum,0);
+					p = CGI->pathf->GetPath(Coordinate(hero->getPosition(false)),Coordinate(dest),hero);
+					cb->moveHero(heronum, CGI->pathf->ConvertToOldFormat(p), 0, 0);
+					//LOCPLINT->adventureInt->terrain.currentPath = CGI->pathf->getPath(src,dst,CGI->heroh->heroInstances[0]);
+					break;
+				}
+			case 'D': //pos description
+				readed>>src;
+				CGI->mh->getObjDescriptions(src);
 				break;
-			}
-		case 'T': //test rect
-			readed>>src;
-			for(int g=0; g<8; ++g)
-			{
-				for(int v=0; v<8; ++v)
+			case 'I': 
 				{
-					int3 csrc = src;
-					csrc.y+=g;
-					csrc.x+=v;
-					if(CGI->mh->getObjDescriptions(csrc).size())
-						std::cout<<'x';
-					else
-						std::cout<<'o';
+					SDL_Surface * temp = LOCPLINT->infoWin(NULL);
+					blitAtWR(temp,605,389);
+					SDL_FreeSurface(temp);
+					break;
 				}
-				std::cout<<std::endl;
-			}
-			break;
-		case 'A':  //hide everything from map
-			for(int c=0; c<CGI->mh->map->objects.size(); ++c)
-			{
-				CGI->mh->hideObject(CGI->mh->map->objects[c]);
-			}
-			break;
-		case 'R': //restora all objects after A has been pressed
-			for(int c=0; c<CGI->mh->map->objects.size(); ++c)
-			{
-				CGI->mh->printObject(CGI->mh->map->objects[c]);
+			case 'T': //test rect
+				readed>>src;
+				for(int g=0; g<8; ++g)
+				{
+					for(int v=0; v<8; ++v)
+					{
+						int3 csrc = src;
+						csrc.y+=g;
+						csrc.x+=v;
+						if(CGI->mh->getObjDescriptions(csrc).size())
+							std::cout<<'x';
+						else
+							std::cout<<'o';
+					}
+					std::cout<<std::endl;
+				}
+				break;
+			//case 'A':  //hide everything from map
+			//	for(int c=0; c<CGI->objh->objInstances.size(); ++c)
+			//	{
+			//		CGI->mh->hideObject(CGI->objh->objInstances[c]);
+			//	}
+			//	break;
+			//case 'R': //restora all objects after A has been pressed
+			//	for(int c=0; c<CGI->objh->objInstances.size(); ++c)
+			//	{
+			//		CGI->mh->printObject(CGI->objh->objInstances[c]);
+			//	}
+			//	break;
 			}
-			break;
+			//SDL_Delay(100);
+			delete p;
 		}
-		//SDL_Delay(100);
-		delete p;
 	}
 	return -1;
 }
 
+SDL_Thread * consoleReadingThread;
+
 void CConsoleHandler::runConsole()
 {
-	SDL_Thread * myth = SDL_CreateThread(&internalFunc, cb);
+	consoleReadingThread = SDL_CreateThread(&internalFunc, cb);
 }

+ 52 - 8
CGameState.cpp

@@ -4,6 +4,7 @@
 #include <algorithm>
 #include "SDL_Thread.h"
 #include "SDL_Extensions.h"
+#include "CBattleInterface.h" //for CBattleHex
 #include <queue>
 
 
@@ -161,7 +162,7 @@ void CGameState::battle(CCreatureSet * army1, CCreatureSet * army2, int3 tile, C
 			else if(j->first == curB->side2) //player is defender
 				side = true;
 			else 
-				return; //no witnesses
+				continue; //no witnesses
 			if(CGI->playerint[j->second.serial]->human)
 			{
 				((CPlayerInterface*)( CGI->playerint[j->second.serial] ))->battleStart(army1, army2, tile, curB->hero1, curB->hero2, side);
@@ -283,9 +284,12 @@ bool CGameState::battleMoveCreatureStack(int ID, int dest)
 			|| (curB->stacks[g]->creature->isDoubleWide() && curB->stacks[g]->attackerOwned && curB->stacks[g]->position-1 == dest)
 			|| (curB->stacks[g]->creature->isDoubleWide() && !curB->stacks[g]->attackerOwned && curB->stacks[g]->position+1 == dest))
 		{
-			stackAtEnd = true;
-			numberOfStackAtEnd = g;
-			break;
+			if(curB->stacks[g]->alive)
+			{
+				stackAtEnd = true;
+				numberOfStackAtEnd = g;
+				break;
+			}
 		}
 	}
 
@@ -307,7 +311,7 @@ bool CGameState::battleMoveCreatureStack(int ID, int dest)
 		accessibility[k] = true;
 	for(int g=0; g<curB->stacks.size(); ++g)
 	{
-		if(curB->stacks[g]->ID != ID) //we don't want to lock enemy's positions and this units' position
+		if(curB->stacks[g]->ID != ID && curB->stacks[g]->alive) //we don't want to lock enemy's positions and this units' position
 		{
 			accessibility[curB->stacks[g]->position] = false;
 			if(curB->stacks[g]->creature->isDoubleWide()) //if it's a double hex creature
@@ -402,7 +406,7 @@ bool CGameState::battleMoveCreatureStack(int ID, int dest)
 		}
 	}
 	//following the Path
-	if(dists[dest] > curStack->creature->speed)
+	if(dists[dest] > curStack->creature->speed && !(stackAtEnd && dists[dest] == curStack->creature->speed+1)) //we can attack a stack if we can go to adjacent hex
 		return false;
 	std::vector<int> path;
 	int curElem = dest;
@@ -544,7 +548,7 @@ std::vector<int> CGameState::battleGetRange(int ID)
 		accessibility[k] = true;
 	for(int g=0; g<curB->stacks.size(); ++g)
 	{
-		if(curB->stacks[g]->ID != ID) //we don't want to lock current unit's position
+		if(curB->stacks[g]->ID != ID && curB->stacks[g]->alive) //we don't want to lock current unit's position
 		{
 			accessibility[curB->stacks[g]->position] = false;
 			if(curB->stacks[g]->creature->isDoubleWide()) //if it's a double hex creature
@@ -637,6 +641,46 @@ std::vector<int> CGameState::battleGetRange(int ID)
 			ret.push_back(i);
 		}
 	}
-	return ret;
+
+	std::vector<int> additionals;
+
+	//adding enemies' positions
+	for(int c=0; c<curB->stacks.size(); ++c)
+	{
+		if(curB->stacks[c]->alive && curB->stacks[c]->owner != owner)
+		{
+			for(int g=0; g<ret.size(); ++g)
+			{
+				if(CBattleHex::mutualPosition(ret[g], curB->stacks[c]->position) != -1)
+				{
+					additionals.push_back(curB->stacks[c]->position);
+				}
+				if(curB->stacks[c]->creature->isDoubleWide() && curB->stacks[c]->attackerOwned && CBattleHex::mutualPosition(ret[g], curB->stacks[c]->position-1) != -1)
+				{
+					additionals.push_back(curB->stacks[c]->position-1);
+				}
+				if(curB->stacks[c]->creature->isDoubleWide() && !curB->stacks[c]->attackerOwned && CBattleHex::mutualPosition(ret[g], curB->stacks[c]->position+1) != -1)
+				{
+					additionals.push_back(curB->stacks[c]->position+1);
+				}
+			}
+		}
+	}
+	for(int g=0; g<additionals.size(); ++g)
+	{
+		ret.push_back(additionals[g]);
+	}
+
+	std::sort(ret.begin(), ret.end());
+	std::vector<int>::iterator nend = std::unique(ret.begin(), ret.end());
+
+	std::vector<int> ret2;
+
+	for(std::vector<int>::iterator it = ret.begin(); it != nend; ++it)
+	{
+		ret2.push_back(*it);
+	}
+
+	return ret2;
 }
 

+ 6 - 4
CGameState.h

@@ -13,6 +13,7 @@ class CCreatureSet;
 class CStack;
 class CGHeroInstance;
 class CArmedInstance;
+struct Mapa;
 
 struct PlayerState
 {
@@ -56,12 +57,13 @@ public:
 class CGameState
 {
 private:
-	int currentPlayer;
+	int currentPlayer; //ID of player currently having turn
 	BattleInfo *curB; //current battle
 	int day; //total number of days in game
-	std::map<int,PlayerState> players; //color <-> playerstate
-	std::set<CCPPObjectScript *> cppscripts;
-	std::map<int, std::map<std::string, CObjectScript*> > objscr; //custom user scripts (as for now only Lua)
+	Mapa * map;
+	std::map<int,PlayerState> players; //ID <-> playerstate
+	std::set<CCPPObjectScript *> cppscripts; //C++ scripts
+	std::map<int, std::map<std::string, CObjectScript*> > objscr; //non-C++ scripts 
 	
 
 	bool checkFunc(int obid, std::string name)

+ 4 - 1
CHeroWindow.cpp

@@ -43,8 +43,9 @@ CHeroWindow::CHeroWindow(int playerColor):
 	gar1button = new AdventureMapButton(CGI->generaltexth->heroscrn[23], CGI->generaltexth->heroscrn[29], boost::bind(&CHeroWindow::gar1,this), 546, 491, "hsbtns6.def", false, NULL, false);
 	gar2button = new AdventureMapButton(std::string(), std::string(), boost::bind(&CHeroWindow::gar2,this), 604, 491, "hsbtns8.def", false, NULL, false);
 	gar3button = new AdventureMapButton(CGI->generaltexth->heroscrn[24], CGI->generaltexth->heroscrn[30], boost::bind(&CHeroWindow::gar3,this), 546, 527, "hsbtns7.def", false, NULL, false);
-	gar4button = new AdventureMapButton(std::string(), CGI->generaltexth->heroscrn[32], boost::bind(&CGarrisonInt::splitClick,garInt), 604, 527, "hsbtns9.def", false, NULL, false);
+	gar4button = new AdventureMapButton(std::string(), CGI->generaltexth->heroscrn[32], boost::function<void()>(), 604, 527, "hsbtns9.def", false, NULL, false);
 
+	//boost::bind(&CGarrisonInt::splitClick,garInt)
 	leftArtRoll = new AdventureMapButton(std::string(), std::string(), boost::bind(&CHeroWindow::leftArtRoller,this), 379, 364, "hsbtns3.def", false, NULL, false);
 	rightArtRoll = new AdventureMapButton(std::string(), std::string(), boost::bind(&CHeroWindow::rightArtRoller,this), 632, 364, "hsbtns5.def", false, NULL, false);
 
@@ -207,6 +208,8 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
 	delete garInt;
 	/*gar4button->owner = */garInt = new CGarrisonInt(80, 493, 8, 0, curBack, 13, 482, curHero);
 	garInt->update = false;
+	gar4button->callback =  boost::bind(&CGarrisonInt::splitClick,garInt);//actualization of callback function
+
 	for(int g=0; g<primSkillAreas.size(); ++g)
 	{
 		primSkillAreas[g]->bonus = hero->primSkills[g];

+ 4 - 7
CMT.cpp

@@ -492,21 +492,18 @@ int _tmain(int argc, _TCHAR* argv[])
 			initTable[ss] = mapstr[ss];
 		}
 		std::cout<<"done."<<std::endl;
-
-		CAmbarCendamo * ac = new CAmbarCendamo(initTable);
-		THC std::cout<<"Reading file: "<<tmh.getDif()<<std::endl;
-		ac->deh3m();
-		THC std::cout<<"Detecting file (together): "<<tmh.getDif()<<std::endl;
+		Mapa * mapa = new Mapa(initTable);
+		THC std::cout<<"Reading and detecting map file (together): "<<tmh.getDif()<<std::endl;
 		CMapHandler * mh = new CMapHandler();
 		cgi->mh = mh;
-		mh->map = &ac->map;
+		mh->map = mapa;
 		THC std::cout<<"Creating mapHandler: "<<tmh.getDif()<<std::endl;
 		mh->loadDefs();
 		THC std::cout<<"Reading terrain defs: "<<tmh.getDif()<<std::endl;
 		mh->init();
 		THC std::cout<<"Initializing mapHandler (together): "<<tmh.getDif()<<std::endl;
 
-		initGameState(&ac->map,cgi);
+		initGameState(mapa,cgi);
 		THC std::cout<<"Initializing GameState (together): "<<tmh.getDif()<<std::endl;
 		for (int i=0; i<cgi->scenarioOps.playerInfos.size();i++) //initializing interfaces
 		{ 

+ 16 - 20
CPathfinder.cpp

@@ -149,33 +149,33 @@ void CPathfinder::AddNeighbors(vector<Coordinate>* branch)
 	//   6  7  8
 
 	Coordinate node = branch->back();
-	Coordinate* c;
+	Coordinate c;
 
 	for(int i = node.x-1; i<node.x+2;i++)
 	{
 		for(int j = node.y-1; j < node.y+2; j++)
 		{
-			if(i > 0 && j > 0 && i < CGI->mh->sizes.x-1 && j < CGI->mh->sizes.y-1)
+			if(i >= 0 && j >= 0 && i < CGI->mh->sizes.x && j < CGI->mh->sizes.y)
 			{
-				c = new Coordinate(i,j,node.z);
+				c = Coordinate(i,j,node.z);
 
 				//Calculate the distance from the end node
-				CalcG(c);
+				CalcG(&c);
 
 				//Calculate the movement cost
-				CalcH(c);
+				CalcH(&c);
 
-				if(c->g != -1 && c->h != -1)
+				if(c.g != -1 && c.h != -1)
 				{
 					vector<Coordinate> toAdd = *branch;
-					toAdd.push_back(*c);
+					toAdd.push_back(c);
 					Open.push(toAdd);
 				}
+				//delete c;
 			}
 		}
 	}
 
-	delete c;
 }
 
 /*
@@ -238,6 +238,8 @@ CPath* CPathfinder::ConvertToOldFormat(vector<Coordinate>* p)
 
 	CPath* path = new CPath();
 
+	std::vector<int> costs; //vector with costs of tiles
+
 	for(int i = 0; i < p->size(); i++)
 	{
 		CPathNode temp;
@@ -256,19 +258,16 @@ CPath* CPathfinder::ConvertToOldFormat(vector<Coordinate>* p)
 		}
 		//set diagonality
 		float diagonal = 1.0f; //by default
-		if(i+1<p->size())
+		if(i>0)
 		{
-			if(p->at(i+1).x != temp.coord.x && p->at(i+1).y != temp.coord.y)
+			if(p->at(i-1).x != temp.coord.x && p->at(i-1).y != temp.coord.y)
 			{
 				diagonal = sqrt(2.0f);
 			}
 		}
 
 		//Set distance
-		if(i == 0)
-			temp.dist = p->at(i).h * diagonal;
-		else
-			temp.dist = p->at(i).h * diagonal + path->nodes.back().dist;
+		costs.push_back( i==0 ? 0 : p->at(i - 1).h * diagonal );
 
 		//theNodeBefore is never used outside of pathfinding?
 
@@ -278,13 +277,10 @@ CPath* CPathfinder::ConvertToOldFormat(vector<Coordinate>* p)
 		path->nodes.push_back(temp);
 	}
 
-	//YOU ARE ALL BACKWARDS!! =P
-	//Flip the distances.
-	for(int i = 0; i < path->nodes.size()/2;i++)
+	costs.push_back(0);
+	for(int i=path->nodes.size()-1; i>=0; --i)
 	{
-		int t = path->nodes[i].dist;
-		path->nodes[i].dist = path->nodes[path->nodes.size()-i-1].dist;
-		path->nodes[path->nodes.size()-i-1].dist = t;
+		path->nodes[i].dist = costs[i+1] + ((i == path->nodes.size()-1) ? 0 : path->nodes[i+1].dist);
 	}
 
 	return path;

+ 2 - 0
CPlayerInterface.cpp

@@ -31,6 +31,7 @@
 using namespace CSDL_Ext;
 
 extern TTF_Font * GEOR16;
+extern bool continueReadingConsole;
 
 class OCM_HLP_CGIN
 {
@@ -1705,6 +1706,7 @@ void CPlayerInterface::handleKeyDown(SDL_Event *sEvent)
 		}
 	case (SDLK_q):
 		{
+			continueReadingConsole = false;
 			exit(0);
 			break;
 		}

+ 43 - 2095
hch/CAmbarCendamo.cpp

@@ -1,2095 +1,43 @@
-#define VCMI_DLL
-#include "../stdafx.h"
-#include "CAmbarCendamo.h"
-#include "CObjectHandler.h"
-#include "CDefObjInfoHandler.h"
-#include <set>
-#include <sstream>
-#include <fstream>
-#include "../lib/VCMI_Lib.h"
-std::string nameFromType (EterrainType typ);
-int readInt(unsigned char * bufor, int bytCon)
-{
-	int ret=0;
-	int amp=1;
-	for (int i=0; i<bytCon; i++)
-	{
-		ret+=bufor[i]*amp;
-		amp*=256;
-	}
-	return ret;
-}
-unsigned int intPow(unsigned int a, unsigned int b)
-{
-	unsigned int ret=1;
-	for(int i=0; i<b; ++i)
-		ret*=a;
-	return ret;
-}
-unsigned char reverse(unsigned char arg)
-{
-	unsigned char ret = 0;
-	for (int i=0; i<8;i++)
-	{
-		if(((arg)&(1<<i))>>i)
-		{
-			ret |= (128>>i);
-		}
-	}
-	return ret;
-}
-CAmbarCendamo::CAmbarCendamo (unsigned char * map)
-{
-	bufor=map;
-}
-CAmbarCendamo::CAmbarCendamo (const char * tie)
-{
-	std::ifstream * is = new std::ifstream();
-	is -> open(tie,std::ios::binary);
-	is->seekg(0,std::ios::end); // na koniec
-	int andame = is->tellg();  // read length
-	is->seekg(0,std::ios::beg); // wracamy na poczatek
-	bufor = new unsigned char[andame]; // allocate memory 
-	is->read((char*)bufor, andame); // read map file to buffer
-	is->close();
-	delete is;
-}
-CAmbarCendamo::~CAmbarCendamo () 
-{// free memory
-	for (int ii=0;ii<map.width;ii++)
-		delete map.terrain[ii] ; 
-	delete map.terrain;
-	delete[] bufor;
-}
-std::set<int> convertBuildings(const std::set<int> h3m, int castleID)
-{
-	std::map<int,int> mapa;
-	std::set<int> ret;
-	std::ifstream b5("config/buildings5.txt");
-	while(!b5.eof())
-	{
-		int a, b;
-		b5 >> a >> b;
-		if(castleID==8 && b==17) //magic university ID 17 (h3m) => 21 (vcmi)
-			b=21;
-		mapa[a]=b;
-	}
-
-	for(std::set<int>::const_iterator i=h3m.begin();i!=h3m.end();i++)
-	{
-		if(mapa[*i]>=0)
-			ret.insert(mapa[*i]);
-		else if(mapa[*i]  >=  (-CREATURES_PER_TOWN)) // horde buildings
-		{
-			int level = (-mapa[*i]);
-			if(h3m.find(20+(level*3)) != h3m.end()) //upgraded creature horde building
-			{
-				if(((castleID==1) || (castleID==3)) && ((level==3) || (level==5)))
-					ret.insert(25);
-				else
-					ret.insert(19);
-			}
-			else
-			{
-				if(((castleID==1) || (castleID==3)) && ((level==3) || (level==5)))
-					ret.insert(24);
-				else
-					ret.insert(18);
-			}
-		}
-		else
-		{
-			std::cout<<"Conversion warning: unknown building "<<*i<<" in castle "<<castleID<<std::endl;
-		}
-	}
-
-	ret.insert(10); //village hall is always present
-	ret.insert(-1); //houses near v.hall / eyecandies
-	ret.insert(-2); //terrain eyecandy, if -1 is used
-
-	if(ret.find(11)!=ret.end())
-		ret.insert(27);
-	if(ret.find(12)!=ret.end())
-		ret.insert(28);
-	if(ret.find(13)!=ret.end())
-		ret.insert(29);
-
-	return ret;
-}
-void CAmbarCendamo::deh3m()
-{
-	THC timeHandler th;
-	th.getDif();
-	i=0;
-	map.version = (Eformat)(readNormalNr(i)); i+=4; //map version
-	map.areAnyPLayers = readChar(); //invalid on some maps
-	map.height = map.width = (readNormalNr(i)); i+=4; // wymiary mapy
-	map.twoLevel = readChar(); //czy sa lochy
-	map.terrain = new TerrainTile*[map.width]; // allocate memory 
-	for (int ii=0;ii<map.width;ii++)
-		map.terrain[ii] = new TerrainTile[map.height]; // allocate memory 
-	if (map.twoLevel)
-	{
-		map.undergroungTerrain = new TerrainTile*[map.width]; // allocate memory 
-		for (int ii=0;ii<map.width;ii++)
-			map.undergroungTerrain[ii] = new TerrainTile[map.height]; // allocate memory 
-	}
-	int pom;
-	map.name = readString();
-	map.description= readString();
-	map.difficulty = readChar(); // reading map difficulty
-	if(map.version != Eformat::RoE)
-		map.levelLimit = readChar(); // hero level limit
-	else
-		map.levelLimit = 0;
-	for (pom=0;pom<8;pom++)
-	{
-		map.players[pom].canHumanPlay = bufor[i++];
-		map.players[pom].canComputerPlay = bufor[i++];
-		if ((!(map.players[pom].canHumanPlay || map.players[pom].canComputerPlay)))
-		{
-			switch(map.version)
-			{
-			case Eformat::SoD: case Eformat::WoG: 
-				i+=13;
-				break;
-			case Eformat::AB:
-				i+=12;
-				break;
-			case Eformat::RoE:
-				i+=6;
-				break;
-			}
-			continue;
-		}
-
-		map.players[pom].AITactic = bufor[i++];
-
-		if(map.version == Eformat::SoD || map.version == Eformat::WoG)
-			map.players[pom].p7= bufor[i++];	
-
-		map.players[pom].allowedFactions = 0;
-		map.players[pom].allowedFactions += bufor[i++];
-		if(map.version != Eformat::RoE)
-			map.players[pom].allowedFactions += (bufor[i++])*256;
-
-		map.players[pom].isFactionRandom = bufor[i++];
-		map.players[pom].hasMainTown = bufor[i++];
-		if (map.players[pom].hasMainTown)
-		{
-			if(map.version != Eformat::RoE)
-			{
-				map.players[pom].generateHeroAtMainTown = bufor[i++];
-				map.players[pom].generateHero = bufor[i++];
-			}
-			else
-			{
-				map.players[pom].generateHeroAtMainTown = false;
-				map.players[pom].generateHero = false;
-			}
-
-			map.players[pom].posOfMainTown.x = bufor[i++];
-			map.players[pom].posOfMainTown.y = bufor[i++];
-			map.players[pom].posOfMainTown.z = bufor[i++];
-
-			
-		}
-		map.players[pom].p8= bufor[i++];
-		map.players[pom].p9= bufor[i++];		
-		if(map.players[pom].p9!=0xff)
-		{
-			map.players[pom].mainHeroPortrait = bufor[i++];
-			int nameLength = bufor[i++];
-			i+=3; 
-			for (int pp=0;pp<nameLength;pp++)
-				map.players[pom].mainHeroName+=bufor[i++];
-		}
-
-		if(map.version != Eformat::RoE)
-		{
-			i++; ////unknown byte
-			int heroCount = bufor[i++];
-			i+=3;
-			for (int pp=0;pp<heroCount;pp++)
-			{
-				SheroName vv;
-				vv.heroID=bufor[i++];
-				int hnl = bufor[i++];
-				i+=3;
-				for (int zz=0;zz<hnl;zz++)
-				{
-					vv.heroName+=bufor[i++];
-				}
-				map.players[pom].heroesNames.push_back(vv);
-			}
-		}
-	}
-	map.victoryCondition = (EvictoryConditions)bufor[i++];
-	if (map.victoryCondition != winStandard) //specific victory conditions
-	{
-		int nr;
-		switch (map.victoryCondition) //read victory conditions
-		{
-		case artifact:
-			{
-				map.vicConDetails = new VicCon0();
-				((VicCon0*)map.vicConDetails)->ArtifactID = bufor[i+2];
-				nr=(map.version==RoE ? 1 : 2);
-				break;
-			}
-		case gatherTroop:
-			{
-				map.vicConDetails = new VicCon1();
-				int temp1 = bufor[i+2];
-				int temp2 = bufor[i+3];
-				((VicCon1*)map.vicConDetails)->monsterID = bufor[i+2];
-				((VicCon1*)map.vicConDetails)->neededQuantity=readNormalNr(i+(map.version==RoE ? 3 : 4));
-				nr=(map.version==RoE ? 5 : 6);
-				break;
-			}
-		case gatherResource:
-			{
-				map.vicConDetails = new VicCon2();
-				((VicCon2*)map.vicConDetails)->resourceID = bufor[i+2];
-				((VicCon2*)map.vicConDetails)->neededQuantity=readNormalNr(i+3);
-				nr=5;
-				break;
-			}
-		case buildCity:
-			{
-				map.vicConDetails = new VicCon3();
-				((VicCon3*)map.vicConDetails)->posOfCity.x = bufor[i+2];
-				((VicCon3*)map.vicConDetails)->posOfCity.y = bufor[i+3];
-				((VicCon3*)map.vicConDetails)->posOfCity.z = bufor[i+4];
-				((VicCon3*)map.vicConDetails)->councilNeededLevel = bufor[i+5];
-				((VicCon3*)map.vicConDetails)->fortNeededLevel = bufor[i+6];
-				nr=5;
-				break;
-			}
-		case buildGrail:
-			{
-				map.vicConDetails = new VicCon4();
-				if (bufor[i+4]>2)
-					((VicCon4*)map.vicConDetails)->anyLocation = true;
-				else
-				{
-					((VicCon4*)map.vicConDetails)->whereBuildGrail.x = bufor[i+2];
-					((VicCon4*)map.vicConDetails)->whereBuildGrail.y = bufor[i+3];
-					((VicCon4*)map.vicConDetails)->whereBuildGrail.z = bufor[i+4];
-				}
-				nr=3;
-				break;
-			}
-		case beatHero:
-			{
-				map.vicConDetails = new VicCon5();
-				((VicCon5*)map.vicConDetails)->locationOfHero.x = bufor[i+2];
-				((VicCon5*)map.vicConDetails)->locationOfHero.y = bufor[i+3];
-				((VicCon5*)map.vicConDetails)->locationOfHero.z = bufor[i+4];				
-				nr=3;
-				break;
-			}
-		case captureCity:
-			{
-				map.vicConDetails = new VicCon6();
-				((VicCon6*)map.vicConDetails)->locationOfTown.x = bufor[i+2];
-				((VicCon6*)map.vicConDetails)->locationOfTown.y = bufor[i+3];
-				((VicCon6*)map.vicConDetails)->locationOfTown.z = bufor[i+4];				
-				nr=3;
-				break;
-			}
-		case beatMonster:
-			{
-				map.vicConDetails = new VicCon7();
-				((VicCon7*)map.vicConDetails)->locationOfMonster.x = bufor[i+2];
-				((VicCon7*)map.vicConDetails)->locationOfMonster.y = bufor[i+3];
-				((VicCon7*)map.vicConDetails)->locationOfMonster.z = bufor[i+4];				
-				nr=3;
-				break;
-			}
-		case takeDwellings:
-			{		
-				map.vicConDetails = new CspecificVictoryConidtions();
-				nr=0;
-				break;
-			}
-		case takeMines:
-			{	
-				map.vicConDetails = new CspecificVictoryConidtions();	
-				nr=0;
-				break;
-			}
-		case transportItem:
-			{
-				map.vicConDetails = new VicCona();
-				((VicCona*)map.vicConDetails)->artifactID =  bufor[i+2];
-				((VicCona*)map.vicConDetails)->destinationPlace.x = bufor[i+3];
-				((VicCona*)map.vicConDetails)->destinationPlace.y = bufor[i+4];
-				((VicCona*)map.vicConDetails)->destinationPlace.z = bufor[i+5];				
-				nr=4;
-				break;
-			}
-		}
-		map.vicConDetails->allowNormalVictory = bufor[i++];
-		map.vicConDetails->appliesToAI = bufor[i++];
-		i+=nr;
-	}
-	map.lossCondition.typeOfLossCon = (ElossCon)bufor[i++];
-	switch (map.lossCondition.typeOfLossCon) //read loss conditions
-	{
-	case lossCastle:
-		  {
-			  map.lossCondition.castlePos.x=bufor[i++];
-			  map.lossCondition.castlePos.y=bufor[i++];
-			  map.lossCondition.castlePos.z=bufor[i++];
-			  break;
-		  }
-	case lossHero:
-		  {
-			  map.lossCondition.heroPos.x=bufor[i++];
-			  map.lossCondition.heroPos.y=bufor[i++];
-			  map.lossCondition.heroPos.z=bufor[i++];
-			  break;
-		  }
-	case timeExpires:
-		{
-			map.lossCondition.timeLimit = readNormalNr(i++,2);
-			i++;
-			 break;
-		}
-	}
-	map.howManyTeams=bufor[i++]; //read number of teams
-	if(map.howManyTeams>0) //read team numbers
-	{
-		for(int rr=0; rr<8; ++rr)
-		{
-			map.players[rr].team=bufor[i++];
-		}
-	}
-	//reading allowed heroes (20 bytes)
-	int ist;
-
-	ist=i; //starting i for loop
-
-	map.allowedHeroes.resize(HEROES_QUANTITY);
-	for(int xx=0;xx<HEROES_QUANTITY;xx++)
-		map.allowedHeroes[xx] = true;
-
-	for(i; i<ist+ (map.version == Eformat::RoE ? 16 : 20) ; ++i)
-	{
-		unsigned char c = bufor[i];
-		for(int yy=0; yy<8; ++yy)
-			if((i-ist)*8+yy < HEROES_QUANTITY)
-				if(c != (c|((unsigned char)intPow(2, yy))))
-					map.allowedHeroes[(i-ist)*8+yy] = false;
-	}
-	if(map.version>RoE) //probably reserved for further heroes
-		i+=4;
-	unsigned char disp = 0;
-	if(map.version>=SoD)
-	{
-		disp = bufor[i++];
-		map.disposedHeroes.resize(disp);
-		for(int g=0; g<disp; ++g)
-		{
-			map.disposedHeroes[g].ID = bufor[i++];
-			map.disposedHeroes[g].portrait = bufor[i++];
-			int lenbuf = readNormalNr(i); i+=4;
-			for (int zz=0; zz<lenbuf; zz++)
-				map.disposedHeroes[g].name+=bufor[i++];
-			int players = bufor[i++];
-			for(int zz=0;zz<8;zz++)
-			{
-				int por = (1<<zz);
-				if(players & por)
-					map.disposedHeroes[g].players[zz] = true;
-				else 
-					map.disposedHeroes[g].players[zz] = false;
-			}
-		}
-	}
-
-	i+=31; //omitting NULLS
-
-	map.allowedArtifact.resize(ARTIFACTS_QUANTITY);
-	for(int x=0;x<map.allowedArtifact.size();x++)
-		map.allowedArtifact[x] = true;
-
-	//reading allowed artifacts:  17 or 18 bytes
-	if(map.version!=RoE)
-	{
-		ist=i; //starting i for loop
-		for(i; i<ist+(map.version==AB ? 17 : 18); ++i)
-		{
-			unsigned char c = bufor[i];
-			for(int yy=0; yy<8; ++yy)
-			{
-				if((i-ist)*8+yy < ARTIFACTS_QUANTITY)
-				{
-					if(c == (c|((unsigned char)intPow(2, yy))))
-						map.allowedArtifact[(i-ist)*8+yy] = false;
-				}
-			}
-		}//allowed artifacts have been read
-	}
-
-
-	map.allowedSpell.resize(SPELLS_QUANTITY);
-	for(int x=0;x<map.allowedSpell.size();x++)
-		map.allowedSpell[x] = true;
-
-	map.allowedAbilities.resize(SKILL_QUANTITY);
-	for(int x=0;x<map.allowedAbilities.size();x++)
-		map.allowedAbilities[x] = true;
-
-	if(map.version>=SoD)
-	{
-		//reading allowed spells (9 bytes)
-		ist=i; //starting i for loop
-		for(i; i<ist+9; ++i)
-		{
-			unsigned char c = bufor[i];
-			for(int yy=0; yy<8; ++yy)
-				if((i-ist)*8+yy < SPELLS_QUANTITY)
-					if(c == (c|((unsigned char)intPow(2, yy))))
-						map.allowedSpell[(i-ist)*8+yy] = false;
-		}
-
-
-		//allowed hero's abilities (4 bytes)
-		ist=i; //starting i for loop
-		for(i; i<ist+4; ++i)
-		{
-			unsigned char c = bufor[i];
-			for(int yy=0; yy<8; ++yy)
-			{
-				if((i-ist)*8+yy < SKILL_QUANTITY)
-				{
-					if(c == (c|((unsigned char)intPow(2, yy))))
-						map.allowedAbilities[(i-ist)*8+yy] = false;
-				}
-			}
-		}
-	}
-	THC std::cout<<"\tReading header: "<<th.getDif()<<std::endl;
-
-	int rumNr = readNormalNr(i,4);i+=4;
-	for (int it=0;it<rumNr;it++)
-	{
-		Rumor ourRumor;
-		int nameL = readNormalNr(i,4);i+=4; //read length of name of rumor
-		for (int zz=0; zz<nameL; zz++)
-			ourRumor.name+=bufor[i++];
-		nameL = readNormalNr(i,4);i+=4; //read length of rumor
-		for (int zz=0; zz<nameL; zz++)
-			ourRumor.text+=bufor[i++];
-		map.rumors.push_back(ourRumor); //add to our list
-	}
-	THC std::cout<<"\tReading rumors: "<<th.getDif()<<std::endl;
-	switch(map.version)
-	{
-	case WoG: case SoD:
-		{
-			for(int z=0;z<HEROES_QUANTITY;z++) //disposed heroes
-			{
-				int custom =  bufor[i++];
-				if(!custom)
-					continue;
-				CGHeroInstance * cgh = new CGHeroInstance;
-				cgh->ID = 34;
-				cgh->subID = z;
-				if(readChar())//true if hore's experience is greater than 0
-				{	cgh->exp = readNormalNr(i); i+=4;	}
-				else
-					cgh->exp = 0;
-				if(readChar())//true if hero has specified abilities
-				{
-					int howMany = readNormalNr(i); i+=4;
-					cgh->secSkills.resize(howMany);
-					for(int yy=0; yy<howMany; ++yy)
-					{
-						cgh->secSkills[yy].first = readNormalNr(i, 1); ++i;
-						cgh->secSkills[yy].second = readNormalNr(i, 1); ++i;
-					}
-				}
-				bool artSet = bufor[i]; ++i; //true if artifact set is not default (hero has some artifacts)
-				int artmask = map.version == RoE ? 0xff : 0xffff;
-				int artidlen = map.version == RoE ? 1 : 2;
-				if(artSet)
-				{
-					for(int pom=0;pom<16;pom++)
-					{
-						int id = readNormalNr(i, artidlen); i+=artidlen;
-						if(id!=artmask)
-							cgh->artifWorn[pom] = id;
-					}
-					//misc5 art //17
-					if(map.version>=SoD)
-					{
-						i+=2;
-						//int id = readNormalNr(i, artidlen); i+=artidlen;
-						//if(id!=artmask)
-						//	spec->artifWorn[16] = id;
-					}
-					//spellbook
-					int id = readNormalNr(i, artidlen); i+=artidlen;
-					if(id!=artmask)
-						cgh->artifWorn[17] = id;
-					//19 //???what is that? gap in file or what? - it's probably fifth slot..
-					if(map.version>RoE)
-					{
-						id = readNormalNr(i, artidlen); i+=artidlen;
-						if(id!=artmask)
-							cgh->artifWorn[18] = id;
-					}
-					else
-						i+=1;
-					//bag artifacts //20
-					int amount = readNormalNr(i, 2); i+=2; //number of artifacts in hero's bag
-					if(amount>0)
-					{
-						for(int ss=0; ss<amount; ++ss)
-						{
-							id = readNormalNr(i, artidlen); i+=artidlen;
-							if(id!=artmask)
-								cgh->artifacts.push_back(id);
-						}
-					}
-				} //artifacts
-				if(readChar())//customBio
-					cgh->biography = readString();
-				int sex = bufor[i++]; // 0xFF is default, 00 male, 01 female
-				if(readChar())//are spells
-				{
-					int ist = i;
-					for(i; i<ist+9; ++i)
-					{
-						unsigned char c = bufor[i];
-						for(int yy=0; yy<8; ++yy)
-						{
-							if((i-ist)*8+yy < SPELLS_QUANTITY)
-							{
-								if(c == (c|((unsigned char)intPow(2, yy))))
-									cgh->spells.insert((i-ist)*8+yy);
-							}
-						}
-					}
-				}
-				if(readChar())//customPrimSkills
-				{
-					cgh->primSkills.resize(4);
-					for(int xx=0;xx<4;xx++)
-						cgh->primSkills[xx] = bufor[i++];
-				}
-				map.predefinedHeroes.push_back(cgh);
-			}
-			break;
-		}
-	case RoE:
-		i+=0;
-		break;
-	}
-	for (int c=0; c<map.width; c++) // reading terrain
-	{
-		for (int z=0; z<map.height; z++)
-		{
-			map.terrain[z][c].tertype = (EterrainType)(bufor[i++]);
-			map.terrain[z][c].terview = bufor[i++];
-			map.terrain[z][c].nuine = (Eriver)bufor[i++];
-			map.terrain[z][c].rivDir = bufor[i++];
-			map.terrain[z][c].malle = (Eroad)bufor[i++];
-			map.terrain[z][c].roadDir = bufor[i++];
-			map.terrain[z][c].siodmyTajemniczyBajt = bufor[i++];
-		}
-	}
-	if (map.twoLevel) // read underground terrain
-	{
-		for (int c=0; c<map.width; c++) // reading terrain
-		{
-			for (int z=0; z<map.height; z++)
-			{
-				map.undergroungTerrain[z][c].tertype = (EterrainType)(bufor[i++]);
-				map.undergroungTerrain[z][c].terview = bufor[i++];
-				map.undergroungTerrain[z][c].nuine = (Eriver)bufor[i++];
-				map.undergroungTerrain[z][c].rivDir = bufor[i++];
-				map.undergroungTerrain[z][c].malle = (Eroad)bufor[i++];
-				map.undergroungTerrain[z][c].roadDir = bufor[i++];
-				map.undergroungTerrain[z][c].siodmyTajemniczyBajt = bufor[i++];
-			}
-		}
-	}
-	THC std::cout<<"\tReading terrain: "<<th.getDif()<<std::endl;
-
-	//////READING DEF INFO///////
-	int defAmount = readNormalNr(i); i+=4;
-	map.defy.reserve(defAmount);
-
-	for (int idd = 0 ; idd<defAmount; idd++) // reading defs
-	{
-		CGDefInfo * vinya = new CGDefInfo(); // info about new def 
-
-		//reading name
-		int nameLength = readNormalNr(i,4);i+=4;
-		vinya->name.reserve(nameLength);
-		for (int cd=0;cd<nameLength;cd++)
-		{
-			vinya->name += bufor[i++];
-		}
-		std::transform(vinya->name.begin(),vinya->name.end(),vinya->name.begin(),(int(*)(int))toupper);
-
-
-		unsigned char bytes[12];
-		for (int v=0; v<12; v++) // read info
-		{
-			bytes[v] = bufor[i++];
-		}
-		vinya->terrainAllowed = readNormalNr(i,2);i+=2;
-		vinya->terrainMenu = readNormalNr(i,2);i+=2;
-		vinya->id = readNormalNr(i,4);i+=4;
-		vinya->subid = readNormalNr(i,4);i+=4;
-		vinya->type = bufor[i++];
-		vinya->printPriority = bufor[i++];
-		for (int zi=0; zi<6; zi++)
-		{
-			vinya->blockMap[zi] = reverse(bytes[zi]);
-		}
-		for (int zi=0; zi<6; zi++)
-		{
-			vinya->visitMap[zi] = reverse(bytes[6+zi]);
-		}
-		i+=16;
-		map.defy.push_back(vinya); // add this def to the vector
-	}
-	THC std::cout<<"\tReading defs info: "<<th.getDif()<<std::endl;
-
-	////loading objects
-	int howManyObjs = readNormalNr(i, 4); i+=4;
-	for(int ww=0; ww<howManyObjs; ++ww) //comment this line to turn loading objects off
-	{
-		//std::cout << "object nr "<<ww<<"\ti= "<<i<<std::endl;
-		CGObjectInstance * nobj = new CGObjectInstance(); //we will read this object
-		nobj->id = map.objects.size();
-		nobj->pos.x = bufor[i++];
-		nobj->pos.y = bufor[i++];
-		nobj->pos.z = bufor[i++];
-
-		int tempd = readNormalNr(i, 4); i+=4;
-		nobj->defInfo = map.defy[tempd];
-		nobj->ID = nobj->defInfo->id;
-		nobj->subID = nobj->defInfo->subid;
-
-		//if (((nobj.x==0)&&(nobj.y==0)) || nobj.x>map.width || nobj.y>map.height || nobj.z>1 || nobj.defNumber>map.defy.size())	std::cout << "Alarm!!! Obiekt "<<ww<<" jest kopniety (lub wystaje poza mape)\n";
-
-		i+=5;
-		unsigned char buff [30];
-		for(int ccc=0; ccc<30; ++ccc)
-		{
-			buff[ccc] = bufor[i+ccc];
-		}
-		int j = nobj->defInfo->id;
-		int p = 99;
-		switch(getDefType(nobj->defInfo))
-		{
-		case EDefType::EVENTOBJ_DEF: //for event - objects
-			{
-				CEventObjInfo * spec = new CEventObjInfo;
-				bool guardMess;
-				guardMess = bufor[i]; ++i;
-				if(guardMess)
-				{
-					int messLong = readNormalNr(i, 4); i+=4;
-					if(messLong>0)
-					{
-						spec->isMessage = true;
-						for(int yy=0; yy<messLong; ++yy)
-						{
-							spec->message +=bufor[i+yy];
-						}
-						i+=messLong;
-					}
-					spec->areGuarders = bufor[i]; ++i;
-					if(spec->areGuarders)
-					{
-						spec->guarders = readCreatureSet(); 
-					}
-					i+=4;
-				}
-				else
-				{
-					spec->isMessage = false;
-					spec->areGuarders = false;
-					spec->message = std::string("");
-				}
-				spec->gainedExp = readNormalNr(i, 4); i+=4;
-				spec->manaDiff = readNormalNr(i, 4); i+=4;
-				spec->moraleDiff = readNormalNr(i, 1, true); ++i;
-				spec->luckDiff = readNormalNr(i, 1, true); ++i;
-				spec->wood = readNormalNr(i); i+=4;
-				spec->mercury = readNormalNr(i); i+=4;
-				spec->ore = readNormalNr(i); i+=4;
-				spec->sulfur = readNormalNr(i); i+=4;
-				spec->crystal = readNormalNr(i); i+=4;
-				spec->gems = readNormalNr(i); i+=4;
-				spec->gold = readNormalNr(i); i+=4;
-				spec->attack = readNormalNr(i, 1); ++i;
-				spec->defence = readNormalNr(i, 1); ++i;
-				spec->power = readNormalNr(i, 1); ++i;
-				spec->knowledge = readNormalNr(i, 1); ++i;
-				int gabn; //number of gained abilities
-				gabn = readNormalNr(i, 1); ++i;
-				for(int oo = 0; oo<gabn; ++oo)
-				{
-					spec->abilities.push_back(readNormalNr(i, 1)); ++i;
-					spec->abilityLevels.push_back(readNormalNr(i, 1)); ++i;
-				}
-				int gart = readNormalNr(i, 1); ++i; //number of gained artifacts
-				for(int oo = 0; oo<gart; ++oo)
-				{
-					spec->artifacts.push_back(readNormalNr(i, (map.version == RoE ? 1 : 2))); i+=(map.version == RoE ? 1 : 2);
-				}
-				int gspel = readNormalNr(i, 1); ++i; //number of gained spells
-				for(int oo = 0; oo<gspel; ++oo)
-				{
-					spec->spells.push_back(readNormalNr(i, 1)); ++i;
-				}
-				int gcre = readNormalNr(i, 1); ++i; //number of gained creatures
-				spec->creatures = readCreatureSet(gcre);
-				if(map.version>RoE)
-					i+=gcre;
-				i+=8;
-				spec->availableFor = readNormalNr(i, 1); ++i;
-				spec->computerActivate = readNormalNr(i, 1); ++i;
-				spec->humanActivate = readNormalNr(i, 1); ++i;
-				i+=4;
-				nobj->info = spec;
-				break;
-			}
-		case EDefType::HERO_DEF:
-			{
-				CGHeroInstance * nhi = new CGHeroInstance;
-				(*(static_cast<CGObjectInstance*>(nhi))) = *nobj;
-				delete nobj;
-				nobj=nhi;
-				if(map.version>RoE)
-				{
-					nhi->identifier = readNormalNr(i, 4); i+=4;
-				}
-				nhi->setOwner(bufor[i]); ++i;
-				nhi->subID = readNormalNr(i, 1); ++i;
-				if(readChar())//true if hero has nonstandard name
-					nhi->name = readString();
-				if(map.version>AB)
-				{
-					if(readChar())//true if hore's experience is greater than 0
-					{	nhi->exp = readNormalNr(i); i+=4;	}
-					else
-						nhi->exp = -1;
-				}
-				else
-				{	nhi->exp = readNormalNr(i); i+=4;	}
-
-				bool portrait=bufor[i]; ++i;
-				if (portrait)
-					i++; //TODO read portrait nr, save, open
-				
-				if(readChar())//true if hero has specified abilities
-				{
-					int howMany = readNormalNr(i); i+=4;
-					nhi->secSkills.resize(howMany);
-					for(int yy=0; yy<howMany; ++yy)
-					{
-						nhi->secSkills[yy].first = readNormalNr(i, 1); ++i;
-						nhi->secSkills[yy].second = readNormalNr(i, 1); ++i;
-					}
-				}
-				if(readChar())//true if hero has nonstandard garrison
-					nhi->army = readCreatureSet();
-				nhi->army.formation =bufor[i]; ++i; //formation
-				bool artSet = bufor[i]; ++i; //true if artifact set is not default (hero has some artifacts)
-				int artmask = map.version == RoE ? 0xff : 0xffff;
-				int artidlen = map.version == RoE ? 1 : 2;
-				if(artSet)
-				{
-					for(int pom=0;pom<16;pom++)
-					{
-						int id = readNormalNr(i, artidlen); i+=artidlen;
-						if(id!=artmask)
-							nhi->artifWorn[pom] = id;
-					}
-					//misc5 art //17
-					if(map.version>=SoD)
-					{
-						int id = readNormalNr(i, artidlen); i+=artidlen;
-						if(id!=artmask)
-							nhi->artifWorn[16] = id;
-					}
-					//spellbook
-					int id = readNormalNr(i, artidlen); i+=artidlen;
-					if(id!=artmask)
-						nhi->artifWorn[17] = id;
-					//19 //???what is that? gap in file or what? - it's probably fifth slot..
-					if(map.version>RoE)
-					{
-						id = readNormalNr(i, artidlen); i+=artidlen;
-						if(id!=artmask)
-							nhi->artifWorn[18] = id;
-					}
-					else
-						i+=1;
-					//bag artifacts //20
-					int amount = readNormalNr(i, 2); i+=2; //number of artifacts in hero's bag
-					if(amount>0)
-					{
-						for(int ss=0; ss<amount; ++ss)
-						{
-							id = readNormalNr(i, artidlen); i+=artidlen;
-							if(id!=artmask)
-								nhi->artifacts.push_back(id);
-						}
-					}
-				} //artifacts
-
-				nhi->patrol.patrolRadious = readNormalNr(i, 1); ++i;
-				if(nhi->patrol.patrolRadious == 0xff)
-					nhi->patrol.patrolling = false;
-				else 
-					nhi->patrol.patrolling = true;
-
-				if(map.version>RoE)
-				{
-					if(readChar())//true if hero has nonstandard (mapmaker defined) biography
-						nhi->biography = readString();
-					nhi->sex = !(bufor[i]); ++i;
-				}
-				//spells
-				if(map.version>AB)
-				{
-					bool areSpells = bufor[i]; ++i;
-
-					if(areSpells) //TODO: sprawdziæ //seems to be ok - tow
-					{
-						int ist = i;
-						for(i; i<ist+9; ++i)
-						{
-							unsigned char c = bufor[i];
-							for(int yy=0; yy<8; ++yy)
-							{
-								if((i-ist)*8+yy < SPELLS_QUANTITY)
-								{
-									if(c == (c|((unsigned char)intPow(2, yy))))
-										nhi->spells.insert((i-ist)*8+yy);
-								}
-							}
-						}
-					}
-				}
-				else if(map.version==AB) //we can read one spell
-				{
-					unsigned char buff = bufor[i]; ++i;
-					if(buff!=254)
-					{
-						nhi->spells.insert(buff);
-					}
-				}
-				//spells loaded
-				if(map.version>AB)
-				{
-					if(readChar())//customPrimSkills
-					{
-						nhi->primSkills.resize(4);
-						for(int xx=0;xx<4;xx++)
-							nhi->primSkills[xx] = bufor[i++];
-					}
-				}
-				i+=16;
-				nhi->moveDir = 4;
-				nhi->isStanding = true;
-				nhi->level = -1;
-				nhi->mana = -1;
-				nhi->movement = -1;
-				if(nhi->ID==34)
-					map.heroes.push_back(nhi);
-				//else
-				//	CGI->objh->objInstances.push_back(nhi);
-
-				break;
-			}
-		case CREATURES_DEF:
-			{
-				CCreatureObjInfo * spec = new CCreatureObjInfo;
-				if(map.version>RoE)
-				{
-					spec->bytes[0] = bufor[i]; ++i;
-					spec->bytes[1] = bufor[i]; ++i;
-					spec->bytes[2] = bufor[i]; ++i;
-					spec->bytes[3] = bufor[i]; ++i;
-				}
-				spec->number = readNormalNr(i, 2); i+=2;
-				spec->character = bufor[i]; ++i;
-				bool isMesTre = bufor[i]; ++i; //true if there is message or treasury
-				if(isMesTre)
-				{
-					int messLength = readNormalNr(i); i+=4;
-					if(messLength>0)
-					{
-						for(int tt=0; tt<messLength; ++tt)
-						{
-							spec->message += bufor[i]; ++i;
-						}
-					}
-					spec->wood = readNormalNr(i); i+=4;
-					spec->mercury = readNormalNr(i); i+=4;
-					spec->ore = readNormalNr(i); i+=4;
-					spec->sulfur = readNormalNr(i); i+=4;
-					spec->crytal = readNormalNr(i); i+=4;
-					spec->gems = readNormalNr(i); i+=4;
-					spec->gold = readNormalNr(i); i+=4;
-					int artID = readNormalNr(i, (map.version == RoE ? 1 : 2)); i+=(map.version == RoE ? 1 : 2);
-					if(map.version==RoE)
-					{
-						if(artID!=0xff)
-							spec->gainedArtifact = artID;
-						else
-							spec->gainedArtifact = -1;
-					}
-					else
-					{
-						if(artID!=0xffff)
-							spec->gainedArtifact = artID;
-						else
-							spec->gainedArtifact = -1;
-					}
-				}
-				spec->neverFlees = bufor[i]; ++i;
-				spec->notGrowingTeam = bufor[i]; ++i;
-				i+=2;
-				nobj->info = spec;
-				break;
-			}
-		case EDefType::SIGN_DEF:
-			{
-				CSignObjInfo * spec = new CSignObjInfo;
-				int length = readNormalNr(i); i+=4;
-				for(int rr=0; rr<length; ++rr)
-				{
-					spec->message += bufor[i]; ++i;
-				}
-				i+=4;
-				nobj->info = spec;
-				break;
-			}
-		case EDefType::SEERHUT_DEF:
-			{
-				CSeerHutObjInfo * spec = new CSeerHutObjInfo;
-				if(map.version>RoE)
-				{
-					spec->missionType = bufor[i]; ++i;
-					switch(spec->missionType)
-					{
-					case 0:
-						i+=3;
-						continue;
-					case 1:
-						{
-							spec->m1level = readNormalNr(i); i+=4;
-							int limit = readNormalNr(i); i+=4;
-							if(limit == ((int)0xffffffff))
-							{
-								spec->isDayLimit = false;
-								spec->lastDay = -1;
-							}
-							else
-							{
-								spec->isDayLimit = true;
-								spec->lastDay = limit;
-							}
-							break;
-						}
-					case 2:
-						{
-							spec->m2attack = bufor[i]; ++i;
-							spec->m2defence = bufor[i]; ++i;
-							spec->m2power = bufor[i]; ++i;
-							spec->m2knowledge = bufor[i]; ++i;
-							int limit = readNormalNr(i); i+=4;
-							if(limit == ((int)0xffffffff))
-							{
-								spec->isDayLimit = false;
-								spec->lastDay = -1;
-							}
-							else
-							{
-								spec->isDayLimit = true;
-								spec->lastDay = limit;
-							}
-							break;
-						}
-					case 3:
-						{
-							spec->m3bytes[0] = bufor[i]; ++i;
-							spec->m3bytes[1] = bufor[i]; ++i;
-							spec->m3bytes[2] = bufor[i]; ++i;
-							spec->m3bytes[3] = bufor[i]; ++i;
-							int limit = readNormalNr(i); i+=4;
-							if(limit == ((int)0xffffffff))
-							{
-								spec->isDayLimit = false;
-								spec->lastDay = -1;
-							}
-							else
-							{
-								spec->isDayLimit = true;
-								spec->lastDay = limit;
-							}
-							break;
-						}
-					case 4:
-						{
-							spec->m4bytes[0] = bufor[i]; ++i;
-							spec->m4bytes[1] = bufor[i]; ++i;
-							spec->m4bytes[2] = bufor[i]; ++i;
-							spec->m4bytes[3] = bufor[i]; ++i;
-							int limit = readNormalNr(i); i+=4;
-							if(limit == ((int)0xffffffff))
-							{
-								spec->isDayLimit = false;
-								spec->lastDay = -1;
-							}
-							else
-							{
-								spec->isDayLimit = true;
-								spec->lastDay = limit;
-							}
-							break;
-						}
-					case 5:
-						{
-							int artNumber = bufor[i]; ++i;
-							for(int yy=0; yy<artNumber; ++yy)
-							{
-								int artid = readNormalNr(i, 2); i+=2;
-								spec->m5arts.push_back(artid);
-							}
-							int limit = readNormalNr(i); i+=4;
-							if(limit == ((int)0xffffffff))
-							{
-								spec->isDayLimit = false;
-								spec->lastDay = -1;
-							}
-							else
-							{
-								spec->isDayLimit = true;
-								spec->lastDay = limit;
-							}
-							break;
-						}
-					case 6:
-						{
-							int typeNumber = bufor[i]; ++i;
-							for(int hh=0; hh<typeNumber; ++hh)
-							{
-								int creType = readNormalNr(i, 2); i+=2;
-								int creNumb = readNormalNr(i, 2); i+=2;
-								spec->m6cre.push_back(&(VLC->creh->creatures[creType]));
-								spec->m6number.push_back(creNumb);
-							}
-							int limit = readNormalNr(i); i+=4;
-							if(limit == ((int)0xffffffff))
-							{
-								spec->isDayLimit = false;
-								spec->lastDay = -1;
-							}
-							else
-							{
-								spec->isDayLimit = true;
-								spec->lastDay = limit;
-							}
-							break;
-						}
-					case 7:
-						{
-							spec->m7wood = readNormalNr(i); i+=4;
-							spec->m7mercury = readNormalNr(i); i+=4;
-							spec->m7ore = readNormalNr(i); i+=4;
-							spec->m7sulfur = readNormalNr(i); i+=4;
-							spec->m7crystal = readNormalNr(i); i+=4;
-							spec->m7gems = readNormalNr(i); i+=4;
-							spec->m7gold = readNormalNr(i); i+=4;
-							int limit = readNormalNr(i); i+=4;
-							if(limit == ((int)0xffffffff))
-							{
-								spec->isDayLimit = false;
-								spec->lastDay = -1;
-							}
-							else
-							{
-								spec->isDayLimit = true;
-								spec->lastDay = limit;
-							}
-							break;
-						}
-					case 8:
-						{
-							int heroType = bufor[i]; ++i;
-							spec->m8hero = heroType;
-							int limit = readNormalNr(i); i+=4;
-							if(limit == ((int)0xffffffff))
-							{
-								spec->isDayLimit = false;
-								spec->lastDay = -1;
-							}
-							else
-							{
-								spec->isDayLimit = true;
-								spec->lastDay = limit;
-							}
-							break;
-						}
-					case 9:
-						{
-							spec->m9player = bufor[i]; ++i;
-							int limit = readNormalNr(i); i+=4;
-							if(limit == ((int)0xffffffff))
-							{
-								spec->isDayLimit = false;
-								spec->lastDay = -1;
-							}
-							else
-							{
-								spec->isDayLimit = true;
-								spec->lastDay = limit;
-							}
-							break;
-						}
-					}//internal switch end (seer huts)
-
-					int len1 = readNormalNr(i); i+=4;
-					for(int ee=0; ee<len1; ++ee)
-					{
-						spec->firstVisitText += bufor[i]; ++i;
-					}
-
-					int len2 = readNormalNr(i); i+=4;
-					for(int ee=0; ee<len2; ++ee)
-					{
-						spec->nextVisitText += bufor[i]; ++i;
-					}
-
-					int len3 = readNormalNr(i); i+=4;
-					for(int ee=0; ee<len3; ++ee)
-					{
-						spec->completedText += bufor[i]; ++i;
-					}
-				}
-				else //RoE
-				{
-					int artID = bufor[i]; ++i;
-					if(artID!=255) //not none quest
-					{
-						spec->m5arts.push_back(artID);
-						spec->missionType = 5;
-					}
-					else
-					{
-						spec->missionType = 255;
-					}
-				}
-
-				if(spec->missionType!=255)
-				{
-					unsigned char rewardType = bufor[i]; ++i;
-					spec->rewardType = rewardType;
-
-					switch(rewardType)
-					{
-					case 1:
-						{
-							spec->r1exp = readNormalNr(i); i+=4;
-							break;
-						}
-					case 2:
-						{
-							spec->r2mana = readNormalNr(i); i+=4;
-							break;
-						}
-					case 3:
-						{
-							spec->r3morale = bufor[i]; ++i;
-							break;
-						}
-					case 4:
-						{
-							spec->r4luck = bufor[i]; ++i;
-							break;
-						}
-					case 5:
-						{
-							spec->r5type = bufor[i]; ++i;
-							spec->r5amount = readNormalNr(i, 3); i+=3;
-							i+=1;
-							break;
-						}
-					case 6:
-						{
-							spec->r6type = bufor[i]; ++i;
-							spec->r6amount = bufor[i]; ++i;
-							break;
-						}
-					case 7:
-						{
-							spec->r7ability = bufor[i]; ++i;
-							spec->r7level = bufor[i]; ++i;
-							break;
-						}
-					case 8:
-						{
-							spec->r8art = readNormalNr(i, (map.version == RoE ? 1 : 2)); i+=(map.version == RoE ? 1 : 2);
-							break;
-						}
-					case 9:
-						{
-							spec->r9spell = bufor[i]; ++i;
-							break;
-						}
-					case 10:
-						{
-							if(map.version>RoE)
-							{
-								spec->r10creature = readNormalNr(i, 2); i+=2;
-								spec->r10amount = readNormalNr(i, 2); i+=2;
-							}
-							else
-							{
-								spec->r10creature = bufor[i]; ++i;
-								spec->r10amount = readNormalNr(i, 2); i+=2;
-							}
-							break;
-						}
-					}// end of internal switch
-					i+=2;
-				}
-				else //missionType==255
-				{
-					i+=3;
-				}
-				nobj->info = spec;
-				break;
-			}
-		case EDefType::WITCHHUT_DEF:
-			{
-				CWitchHutObjInfo * spec = new CWitchHutObjInfo;
-				if(map.version>RoE) //in reo we cannot specify it - all are allowed (I hope)
-				{
-					ist=i; //starting i for loop
-					for(i; i<ist+4; ++i)
-					{
-						unsigned char c = bufor[i];
-						for(int yy=0; yy<8; ++yy)
-						{
-							if((i-ist)*8+yy < SKILL_QUANTITY)
-							{
-								if(c == (c|((unsigned char)intPow(2, yy))))
-									spec->allowedAbilities.push_back((i-ist)*8+yy);
-							}
-						}
-					}
-				}
-				else //(RoE map)
-				{
-					for(int gg=0; gg<SKILL_QUANTITY; ++gg)
-					{
-						spec->allowedAbilities.push_back(gg);
-					}
-				}
-				
-				nobj->info = spec;
-				break;
-			}
-		case EDefType::SCHOLAR_DEF:
-			{
-				CScholarObjInfo * spec = new CScholarObjInfo;
-				spec->bonusType = bufor[i]; ++i;
-				switch(spec->bonusType)
-				{
-				case 0xff:
-					++i;
-					break;
-				case 0:
-					spec->r0type = bufor[i]; ++i;
-					break;
-				case 1:
-					spec->r1 = bufor[i]; ++i;
-					break;
-				case 2:
-					spec->r2 = bufor[i]; ++i;
-					break;
-				}
-				i+=6;
-				nobj->info = spec;
-				break;
-			}
-		case EDefType::GARRISON_DEF:
-			{
-				CGarrisonObjInfo * spec = new CGarrisonObjInfo;
-				spec->player = bufor[i]; ++i;
-				i+=3;
-				spec->units = readCreatureSet();
-				if(map.version > RoE)
-				{
-					spec->movableUnits = bufor[i]; ++i;
-				}
-				else
-					spec->movableUnits = true;
-				i+=8;
-				nobj->setOwner(spec->player);
-				nobj->info = spec;
-				break;
-			}
-		case EDefType::ARTIFACT_DEF:
-			{
-				CArtifactObjInfo * spec = new CArtifactObjInfo;
-				bool areSettings = bufor[i]; ++i;
-				if(areSettings)
-				{
-					int messLength = readNormalNr(i, 4); i+=4;
-					for(int hh=0; hh<messLength; ++hh)
-					{
-						spec->message += bufor[i]; ++i;
-					}
-					bool areGuards = bufor[i]; ++i;
-					if(areGuards)
-					{
-						spec->areGuards = true;
-						spec->guards = readCreatureSet();
-					}
-					else
-						spec->areGuards = false;
-					i+=4;
-				}
-				nobj->info = spec;
-				break;
-			}
-		case EDefType::RESOURCE_DEF:
-			{
-				CResourceObjInfo * spec = new CResourceObjInfo;
-				bool isMessGuard = bufor[i]; ++i;
-				if(isMessGuard)
-				{
-					int messLength = readNormalNr(i); i+=4;
-					for(int mm=0; mm<messLength; ++mm)
-					{
-						spec->message+=bufor[i]; ++i;
-					}
-					spec->areGuards = bufor[i]; ++i;
-					if(spec->areGuards)
-					{
-						spec->guards = readCreatureSet();
-					}
-					i+=4;
-				}
-				else
-				{
-					spec->areGuards = false;
-				}
-				spec->amount = readNormalNr(i); i+=4;
-				i+=4;
-				nobj->info = spec;
-				break;
-			}
-		case EDefType::TOWN_DEF:
-			{
-				CGTownInstance * nt = new CGTownInstance();
-				(*(static_cast<CGObjectInstance*>(nt))) = *nobj;
-				delete nobj;
-				nobj = nt;
-				nt->identifier = 0;
-				if(map.version>RoE)
-				{	
-					readNormalNr(i); i+=4;
-				}
-				nt->tempOwner = bufor[i]; ++i;
-				if(readChar()) //has name
-					nt->name = readString();
-				if(readChar())//true if garrison isn't empty
-					nt->army = readCreatureSet();
-				nt->army.formation = bufor[i]; ++i;
-				if(readChar()) //unusualBuildings
-				{
-					//built buildings
-					for(int byte=0;byte<6;byte++)
-					{
-						for(int bit=0;bit<8;bit++)
-							if(bufor[i] & (1<<bit))
-								nt->builtBuildings.insert(byte*8+bit);
-						i++;
-					}
-					//forbidden buildings
-					for(int byte=6;byte<12;byte++)
-					{
-						for(int bit=0;bit<8;bit++)
-							if(bufor[i] & (1<<bit))
-								nt->forbiddenBuildings.insert(byte*8+bit);
-						i++;
-					}
-					nt->builtBuildings = convertBuildings(nt->builtBuildings,nt->subID);
-					nt->forbiddenBuildings = convertBuildings(nt->forbiddenBuildings,nt->subID);
-				}
-				else //standard buildings
-				{
-					if(readChar()) //has fort
-						nt->builtBuildings.insert(7);
-					nt->builtBuildings.insert(-50); //means that set of standard building should be included
-				}
-
-				int ist = i;
-				if(map.version>RoE)
-				{
-					for(i; i<ist+9; ++i)
-					{
-						unsigned char c = bufor[i];
-						for(int yy=0; yy<8; ++yy)
-						{
-							if((i-ist)*8+yy < SPELLS_QUANTITY)
-							{
-								if(c == (c|((unsigned char)intPow(2, yy))))
-									nt->obligatorySpells.push_back((i-ist)*8+yy);
-							}
-						}
-					}
-				}
-
-				ist = i;
-				for(i; i<ist+9; ++i)
-				{
-					unsigned char c = bufor[i];
-					for(int yy=0; yy<8; ++yy)
-					{
-						if((i-ist)*8+yy < SPELLS_QUANTITY)
-						{
-							if(c != (c|((unsigned char)intPow(2, yy))))
-								nt->possibleSpells.push_back((i-ist)*8+yy);
-						}
-					}
-				}
-
-				/////// reading castle events //////////////////////////////////
-
-				int numberOfEvent = readNormalNr(i); i+=4;
-
-				for(int gh = 0; gh<numberOfEvent; ++gh)
-				{
-					CCastleEvent nce;
-					int nameLen = readNormalNr(i); i+=4;
-					for(int ll=0; ll<nameLen; ++ll)
-					{
-						nce.name += bufor[i]; ++i;
-					}
-
-					int messLen = readNormalNr(i); i+=4;
-					for(int ll=0; ll<messLen; ++ll)
-					{
-						nce.message += bufor[i]; ++i;
-					}
-
-					nce.wood = readNormalNr(i); i+=4;
-					nce.mercury = readNormalNr(i); i+=4;
-					nce.ore = readNormalNr(i); i+=4;
-					nce.sulfur = readNormalNr(i); i+=4;
-					nce.crystal = readNormalNr(i); i+=4;
-					nce.gems = readNormalNr(i); i+=4;
-					nce.gold = readNormalNr(i); i+=4;
-
-					nce.players = bufor[i]; ++i;
-					if(map.version > AB)
-					{
-						nce.forHuman = bufor[i]; ++i;
-					}
-					else
-						nce.forHuman = true;
-					nce.forComputer = bufor[i]; ++i;
-					nce.firstShow = readNormalNr(i, 2); i+=2;
-					nce.forEvery = bufor[i]; ++i;
-
-					i+=17;
-
-					for(int kk=0; kk<6; ++kk)
-					{
-						nce.bytes[kk] = bufor[i]; ++i;
-					}
-
-					for(int vv=0; vv<7; ++vv)
-					{
-						nce.gen[vv] = readNormalNr(i, 2); i+=2;
-					}
-					i+=4;
-					nt->events.insert(nce);
-				}//castle events have been read 
-
-				if(map.version > AB)
-				{
-					nt->alignment = bufor[i]; ++i;
-				}
-				else
-					nt->alignment = 0xff;
-				i+=3;
-
-				nt->builded = 0;
-				nt->destroyed = 0;
-				nt->garrisonHero = NULL;
-				map.towns.push_back(nt);
-				break;
-			}
-		case EDefType::PLAYERONLY_DEF:
-			{
-				CPlayerOnlyObjInfo * spec = new CPlayerOnlyObjInfo;
-				spec->player = bufor[i]; ++i;
-				i+=3;
-				nobj->setOwner(spec->player);
-				nobj->info = spec;
-				break;
-			}
-		case EDefType::SHRINE_DEF:
-			{
-				CShrineObjInfo * spec = new CShrineObjInfo;
-				spec->spell = bufor[i]; i+=4;
-				nobj->info = spec;
-				break;
-			}
-		case EDefType::SPELLSCROLL_DEF:
-			{
-				CSpellScrollObjinfo * spec = new CSpellScrollObjinfo;
-				bool messg = bufor[i]; ++i;
-				if(messg)
-				{
-					int mLength = readNormalNr(i); i+=4;
-					for(int vv=0; vv<mLength; ++vv)
-					{
-						spec->message += bufor[i]; ++i;
-					}
-					spec->areGuarders = bufor[i]; ++i;
-					if(spec->areGuarders)
-					{
-						spec->guarders = readCreatureSet();
-					}
-					i+=4;
-				}
-				spec->spell = bufor[i]; ++i;
-				i+=3;
-				nobj->info = spec;
-				break;
-			}
-		case EDefType::PANDORA_DEF:
-			{
-				CPandorasBoxObjInfo * spec = new CPandorasBoxObjInfo;
-				bool messg = bufor[i]; ++i;
-				if(messg)
-				{
-					int mLength = readNormalNr(i); i+=4;
-					for(int vv=0; vv<mLength; ++vv)
-					{
-						spec->message += bufor[i]; ++i;
-					}
-					spec->areGuarders = bufor[i]; ++i;
-					if(spec->areGuarders)
-					{
-						spec->guarders = readCreatureSet();
-					}
-					i+=4;
-				}
-				////// copied form event handling (seems to be similar)
-				spec->gainedExp = readNormalNr(i, 4); i+=4;
-				spec->manaDiff = readNormalNr(i, 4); i+=4;
-				spec->moraleDiff = readNormalNr(i, 1, true); ++i;
-				spec->luckDiff = readNormalNr(i, 1, true); ++i;
-				spec->wood = readNormalNr(i); i+=4;
-				spec->mercury = readNormalNr(i); i+=4;
-				spec->ore = readNormalNr(i); i+=4;
-				spec->sulfur = readNormalNr(i); i+=4;
-				spec->crystal = readNormalNr(i); i+=4;
-				spec->gems = readNormalNr(i); i+=4;
-				spec->gold = readNormalNr(i); i+=4;
-				spec->attack = readNormalNr(i, 1); ++i;
-				spec->defence = readNormalNr(i, 1); ++i;
-				spec->power = readNormalNr(i, 1); ++i;
-				spec->knowledge = readNormalNr(i, 1); ++i;
-				int gabn; //number of gained abilities
-				gabn = readNormalNr(i, 1); ++i;
-				for(int oo = 0; oo<gabn; ++oo)
-				{
-					spec->abilities.push_back(readNormalNr(i, 1)); ++i;
-					spec->abilityLevels.push_back(readNormalNr(i, 1)); ++i;
-				}
-				int gart = readNormalNr(i, 1); ++i; //number of gained artifacts
-				for(int oo = 0; oo<gart; ++oo)
-				{
-					if(map.version > RoE)
-					{
-						spec->artifacts.push_back(readNormalNr(i, 2)); i+=2;
-					}
-					else
-					{
-						spec->artifacts.push_back(readNormalNr(i, 1)); i+=1;
-					}
-				}
-				int gspel = readNormalNr(i, 1); ++i; //number of gained spells
-				for(int oo = 0; oo<gspel; ++oo)
-				{
-					spec->spells.push_back(readNormalNr(i, 1)); ++i;
-				}
-				int gcre = readNormalNr(i, 1); ++i; //number of gained creatures
-				spec->creatures = readCreatureSet(gcre);
-				if(map.version > RoE)
-					i+=gcre;
-				i+=8;
-				nobj->info = spec;
-				///////end of copied fragment
-				break;
-			}
-		case EDefType::GRAIL_DEF:
-			{
-				CGrailObjInfo * spec = new CGrailObjInfo;
-				spec->radius = readNormalNr(i); i+=4;
-				nobj->info = spec;
-				break;
-			}
-		case EDefType::CREGEN_DEF:
-			{
-				CCreGenObjInfo * spec = new CCreGenObjInfo;
-				spec->player = readNormalNr(i); i+=4;
-				spec->identifier =  readNormalNr(i); i+=4;
-				if(!spec->identifier)
-				{
-					spec->asCastle = false;
-					spec->castles[0] = bufor[i]; ++i;
-					spec->castles[1] = bufor[i]; ++i;
-				}
-				else
-				{
-					spec->asCastle = true;
-				}
-				nobj->setOwner(spec->player);
-				nobj->info = spec;
-				break;
-			}
-		case EDefType::CREGEN2_DEF:
-			{
-				CCreGen2ObjInfo * spec = new CCreGen2ObjInfo;
-				spec->player = readNormalNr(i); i+=4;
-				spec->identifier =  readNormalNr(i); i+=4;
-				if(!spec->identifier)
-				{
-					spec->asCastle = false;
-					spec->castles[0] = bufor[i]; ++i;
-					spec->castles[1] = bufor[i]; ++i;
-				}
-				else
-				{
-					spec->asCastle = true;
-				}
-				spec->minLevel = bufor[i]; ++i;
-				spec->maxLevel = bufor[i]; ++i;
-				//if(spec->maxLevel>7)
-				//	spec->maxLevel = 7;
-				//if(spec->minLevel<1)
-				//	spec->minLevel = 1;
-				nobj->setOwner(spec->player);
-				nobj->info = spec;
-				break;
-			}
-		case EDefType::CREGEN3_DEF:
-			{
-				CCreGen3ObjInfo * spec = new CCreGen3ObjInfo;
-				spec->player = bufor[i]; ++i;
-				i+=3;
-				spec->minLevel = bufor[i]; ++i;
-				spec->maxLevel = bufor[i]; ++i;
-				if(spec->maxLevel>7)
-					spec->maxLevel = 7;
-				if(spec->minLevel<1)
-					spec->minLevel = 1;
-				nobj->setOwner(spec->player);
-				nobj->info = spec;
-				break;
-			}
-		case EDefType::BORDERGUARD_DEF:
-			{
-				CBorderGuardObjInfo * spec = new CBorderGuardObjInfo;
-				spec->missionType = bufor[i]; ++i;
-				switch(spec->missionType)
-				{
-				case 0:
-					{
-						goto borderguardend;
-						break;
-					}
-				case 1:
-					{
-						spec->m1level = readNormalNr(i); i+=4;
-						int limit = readNormalNr(i); i+=4;
-						if(limit == ((int)0xffffffff))
-						{
-							spec->isDayLimit = false;
-							spec->lastDay = -1;
-						}
-						else
-						{
-							spec->isDayLimit = true;
-							spec->lastDay = limit;
-						}
-						break;
-					}
-				case 2:
-					{
-						spec->m2attack = bufor[i]; ++i;
-						spec->m2defence = bufor[i]; ++i;
-						spec->m2power = bufor[i]; ++i;
-						spec->m2knowledge = bufor[i]; ++i;
-						int limit = readNormalNr(i); i+=4;
-						if(limit == ((int)0xffffffff))
-						{
-							spec->isDayLimit = false;
-							spec->lastDay = -1;
-						}
-						else
-						{
-							spec->isDayLimit = true;
-							spec->lastDay = limit;
-						}
-						break;
-					}
-				case 3:
-					{
-						spec->m3bytes[0] = bufor[i]; ++i;
-						spec->m3bytes[1] = bufor[i]; ++i;
-						spec->m3bytes[2] = bufor[i]; ++i;
-						spec->m3bytes[3] = bufor[i]; ++i;
-						int limit = readNormalNr(i); i+=4;
-						if(limit == ((int)0xffffffff))
-						{
-							spec->isDayLimit = false;
-							spec->lastDay = -1;
-						}
-						else
-						{
-							spec->isDayLimit = true;
-							spec->lastDay = limit;
-						}
-						break;
-					}
-				case 4:
-					{
-						spec->m4bytes[0] = bufor[i]; ++i;
-						spec->m4bytes[1] = bufor[i]; ++i;
-						spec->m4bytes[2] = bufor[i]; ++i;
-						spec->m4bytes[3] = bufor[i]; ++i;
-						int limit = readNormalNr(i); i+=4;
-						if(limit == ((int)0xffffffff))
-						{
-							spec->isDayLimit = false;
-							spec->lastDay = -1;
-						}
-						else
-						{
-							spec->isDayLimit = true;
-							spec->lastDay = limit;
-						}
-						break;
-					}
-				case 5:
-					{
-						int artNumber = bufor[i]; ++i;
-						for(int yy=0; yy<artNumber; ++yy)
-						{
-							spec->m5arts.push_back(readNormalNr(i, 2)); i+=2;
-						}
-						int limit = readNormalNr(i); i+=4;
-						if(limit == ((int)0xffffffff))
-						{
-							spec->isDayLimit = false;
-							spec->lastDay = -1;
-						}
-						else
-						{
-							spec->isDayLimit = true;
-							spec->lastDay = limit;
-						}
-						break;
-					}
-				case 6:
-					{
-						int typeNumber = bufor[i]; ++i;
-						for(int hh=0; hh<typeNumber; ++hh)
-						{
-							int creType = readNormalNr(i, 2); i+=2;
-							int creNumb = readNormalNr(i, 2); i+=2;
-							spec->m6cre.push_back(&(VLC->creh->creatures[creType]));
-							spec->m6number.push_back(creNumb);
-						}
-						int limit = readNormalNr(i); i+=4;
-						if(limit == ((int)0xffffffff))
-						{
-							spec->isDayLimit = false;
-							spec->lastDay = -1;
-						}
-						else
-						{
-							spec->isDayLimit = true;
-							spec->lastDay = limit;
-						}
-						break;
-					}
-				case 7:
-					{
-						spec->m7wood = readNormalNr(i); i+=4;
-						spec->m7mercury = readNormalNr(i); i+=4;
-						spec->m7ore = readNormalNr(i); i+=4;
-						spec->m7sulfur = readNormalNr(i); i+=4;
-						spec->m7crystal = readNormalNr(i); i+=4;
-						spec->m7gems = readNormalNr(i); i+=4;
-						spec->m7gold = readNormalNr(i); i+=4;
-						int limit = readNormalNr(i); i+=4;
-						if(limit == ((int)0xffffffff))
-						{
-							spec->isDayLimit = false;
-							spec->lastDay = -1;
-						}
-						else
-						{
-							spec->isDayLimit = true;
-							spec->lastDay = limit;
-						}
-						break;
-					}
-				case 8:
-					{
-						int heroType = bufor[i]; ++i;
-						spec->m8hero = heroType;
-						int limit = readNormalNr(i); i+=4;
-						if(limit == ((int)0xffffffff))
-						{
-							spec->isDayLimit = false;
-							spec->lastDay = -1;
-						}
-						else
-						{
-							spec->isDayLimit = true;
-							spec->lastDay = limit;
-						}
-						break;
-					}
-				case 9:
-					{
-						spec->m9player = bufor[i]; ++i;
-						int limit = readNormalNr(i); i+=4;
-						if(limit == ((int)0xffffffff))
-						{
-							spec->isDayLimit = false;
-							spec->lastDay = -1;
-						}
-						else
-						{
-							spec->isDayLimit = true;
-							spec->lastDay = limit;
-						}
-						break;
-					}
-				}//internal switch end (seer huts)
-
-				int len1 = readNormalNr(i); i+=4;
-				for(int ee=0; ee<len1; ++ee)
-				{
-					spec->firstVisitText += bufor[i]; ++i;
-				}
-
-				int len2 = readNormalNr(i); i+=4;
-				for(int ee=0; ee<len2; ++ee)
-				{
-					spec->nextVisitText += bufor[i]; ++i;
-				}
-
-				int len3 = readNormalNr(i); i+=4;
-				for(int ee=0; ee<len3; ++ee)
-				{
-					spec->completedText += bufor[i]; ++i;
-				}
-				nobj->info = spec;
-borderguardend:
-				break;
-			}
-		case EDefType::HEROPLACEHOLDER_DEF:
-			{
-				i+=3; //TODO: handle it more properly
-				break;
-			}
-		} //end of main switch
-		map.objects.push_back(nobj);
-	}//end of loading objects
-	THC std::cout<<"\tReading objects: "<<th.getDif()<<std::endl;
-	
-	//loading events
-	int numberOfEvents = readNormalNr(i); i+=4;
-	for(int yyoo=0; yyoo<numberOfEvents; ++yyoo)
-	{
-		CMapEvent ne;
-		ne.name = std::string();
-		ne.message = std::string();
-		int nameLen = readNormalNr(i); i+=4;
-		for(int qq=0; qq<nameLen; ++qq)
-		{
-			ne.name += bufor[i]; ++i;
-		}
-		int messLen = readNormalNr(i); i+=4;
-		for(int qq=0; qq<messLen; ++qq)
-		{
-			ne.message +=bufor[i]; ++i;
-		}
-		ne.wood = readNormalNr(i); i+=4;
-		ne.mercury = readNormalNr(i); i+=4;
-		ne.ore = readNormalNr(i); i+=4;
-		ne.sulfur = readNormalNr(i); i+=4;
-		ne.crystal = readNormalNr(i); i+=4;
-		ne.gems = readNormalNr(i); i+=4;
-		ne.gold = readNormalNr(i); i+=4;
-		ne.players = bufor[i]; ++i;
-		if(map.version>AB)
-		{
-			ne.humanAffected = bufor[i]; ++i;
-		}
-		else
-			ne.humanAffected = true;
-		ne.computerAffected = bufor[i]; ++i;
-		ne.firstOccurence = bufor[i]; ++i;
-		ne.nextOccurence = bufor[i]; ++i;
-		i+=18;
-		map.events.push_back(ne);
-	}
-
-	//map readed, bufor no longer needed
-	delete[] bufor; bufor=NULL;
-}
-int CAmbarCendamo::readNormalNr (int pos, int bytCon, bool cyclic)
-{
-	int ret=0;
-	int amp=1;
-	for (int ir=0; ir<bytCon; ir++)
-	{
-		ret+=bufor[pos+ir]*amp;
-		amp*=256;
-	}
-	if(cyclic && bytCon<4 && ret>=amp/2)
-	{
-		ret = ret-amp;
-	}
-	return ret;
-}
-
-EDefType CAmbarCendamo::getDefType(CGDefInfo * a)
-{
-	switch(a->id)
-	{
-	case 5: case 65: case 66: case 67: case 68: case 69:
-		return EDefType::ARTIFACT_DEF; //handled
-	case 6:
-		return EDefType::PANDORA_DEF; //hanled
-	case 26:
-		return EDefType::EVENTOBJ_DEF; //handled
-	case 33:
-		return EDefType::GARRISON_DEF; //handled
-	case 34: case 70: case 62: //70 - random hero //62 - prison
-		return EDefType::HERO_DEF; //handled
-	case 36:
-		return EDefType::GRAIL_DEF; //hanled
-	case 53: case 17: case 18: case 19: case 20: case 42: case 87: case 220://cases 17 - 20 and 42 - tests
-		return EDefType::PLAYERONLY_DEF; //handled
-	case 54: case 71: case 72: case 73: case 74: case 75: case 162: case 163: case 164:
-		return EDefType::CREATURES_DEF; //handled
-	case 59:
-		return EDefType::SIGN_DEF; //handled
-	case 77:
-		return EDefType::TOWN_DEF; //can be problematic, but handled
-	case 79: case 76:
-		return EDefType::RESOURCE_DEF; //handled
-	case 81:
-		return EDefType::SCHOLAR_DEF; //handled
-	case 83:
-		return EDefType::SEERHUT_DEF; //handled
-	case 91:
-		return EDefType::SIGN_DEF; //handled
-	case 88: case 89: case 90:
-		return SHRINE_DEF; //handled
-	case 93:
-		return SPELLSCROLL_DEF; //handled
-	case 98:
-		return EDefType::TOWN_DEF; //handled
-	case 113:
-		return EDefType::WITCHHUT_DEF; //handled
-	case 214:
-		return EDefType::HEROPLACEHOLDER_DEF; //partially handled
-	case 215:
-		return EDefType::BORDERGUARD_DEF; //handled by analogy to seer huts ;]
-	case 216:
-		return EDefType::CREGEN2_DEF; //handled
-	case 217:
-		return EDefType::CREGEN_DEF; //handled
-	case 218:
-		return EDefType::CREGEN3_DEF; //handled
-	case 219:
-		return EDefType::GARRISON_DEF; //handled
-	default:
-		return EDefType::TERRAINOBJ_DEF; // nothing to be handled
-	}
-}
-
-CCreatureSet CAmbarCendamo::readCreatureSet(int number)
-{
-	if(map.version>RoE)
-	{
-		CCreatureSet ret;
-		std::pair<CCreature *, int> ins;
-		for(int ir=0;ir<number;ir++)
-		{
-			int rettt = readNormalNr(i+ir*4, 2);
-			if(rettt==0xffff) continue;
-			if(rettt>32768)
-				rettt = 65536-rettt+VLC->creh->creatures.size()-16;
-			ins.first = &(VLC->creh->creatures[rettt]);
-			ins.second = readNormalNr(i+ir*4+2, 2);
-			std::pair<int,std::pair<CCreature *, int> > tt(ir,ins);
-			ret.slots.insert(tt);
-		}
-		i+=number*4;
-		return ret;
-	}
-	else
-	{
-		CCreatureSet ret;
-		std::pair<CCreature *, int> ins;
-		for(int ir=0;ir<number;ir++)
-		{
-			int rettt = readNormalNr(i+ir*3, 1);
-			if(rettt==0xff) continue;
-			if(rettt>220)
-				rettt = 256-rettt+VLC->creh->creatures.size()-16;
-			ins.first = &(VLC->creh->creatures[rettt]);
-			ins.second = readNormalNr(i+ir*3+1, 2);
-			std::pair<int,std::pair<CCreature *, int> > tt(ir,ins);
-			ret.slots.insert(tt);
-		}
-		i+=number*3;
-		return ret;
-	}
-}
-char CAmbarCendamo::readChar()
-{
-	return bufor[i++];
-}
-std::string CAmbarCendamo::readString()
-{					
-	int len = readNormalNr(i); i+=4;
-	std::string ret; ret.reserve(len);
-	for(int gg=0; gg<len; ++gg)
-	{
-		ret += bufor[i++];
-	}
-	return ret;
-}
+//#define VCMI_DLL
+//#include "../stdafx.h"
+//#include "CAmbarCendamo.h"
+//#include "CObjectHandler.h"
+//#include "CDefObjInfoHandler.h"
+//#include <set>
+//#include <sstream>
+//#include <fstream>
+//#include "../lib/VCMI_Lib.h"
+//std::string nameFromType (EterrainType typ);
+//int readInt(unsigned char * bufor, int bytCon)
+//{
+//	int ret=0;
+//	int amp=1;
+//	for (int i=0; i<bytCon; i++)
+//	{
+//		ret+=bufor[i]*amp;
+//		amp*=256;
+//	}
+//	return ret;
+//}
+//CAmbarCendamo::CAmbarCendamo (unsigned char * data)
+////:map(data)
+//{}
+////CAmbarCendamo::CAmbarCendamo (const char * tie)
+////{
+////	std::ifstream * is = new std::ifstream();
+////	is -> open(tie,std::ios::binary);
+////	is->seekg(0,std::ios::end); // na koniec
+////	int andame = is->tellg();  // read length
+////	is->seekg(0,std::ios::beg); // wracamy na poczatek
+////	bufor = new unsigned char[andame]; // allocate memory 
+////	is->read((char*)bufor, andame); // read map file to buffer
+////	is->close();
+////	delete is;
+////}
+//CAmbarCendamo::~CAmbarCendamo () 
+//{// free memory
+//	for (int ii=0;ii<map.width;ii++)
+//		delete map.terrain[ii] ; 
+//	delete map.terrain;
+//	delete[] bufor;
+//}

+ 3 - 16
hch/CAmbarCendamo.h

@@ -7,26 +7,13 @@
 #include "../map.h"
 #include "CCreatureHandler.h"
 
-enum EDefType {TOWN_DEF, HERO_DEF, CREATURES_DEF, SEERHUT_DEF, RESOURCE_DEF, TERRAINOBJ_DEF, EVENTOBJ_DEF, SIGN_DEF, GARRISON_DEF, ARTIFACT_DEF, WITCHHUT_DEF, SCHOLAR_DEF, PLAYERONLY_DEF, SHRINE_DEF, SPELLSCROLL_DEF, PANDORA_DEF, GRAIL_DEF, CREGEN_DEF, CREGEN2_DEF, CREGEN3_DEF, BORDERGUARD_DEF, HEROPLACEHOLDER_DEF};
-
 class DLL_EXPORT CAmbarCendamo 
 {
 public:
 /////////////////member variables
-	Mapa map;
-
-	//map file 
-	unsigned char * bufor; // here we store map bytecode
-	int i; //our pos in the file
+	//Mapa* map;
 
-	CAmbarCendamo (const char * tie); // c-tor; tie is the path of the map file
-	CAmbarCendamo (unsigned char * map); // c-tor; map is pointer to array containing map; it is not copied, so don't delete
-	~CAmbarCendamo (); // d-tor
-	int readNormalNr (int pos, int bytCon=4, bool cyclic = false); //read number from bytCon bytes starting from pos position in buffer ; if cyclic is true, number is treated as it were signed number with bytCon bytes
-	void deh3m(); // decode file, results are stored in map
-	EDefType getDefType(CGDefInfo * a); //returns type of object in def
-	CCreatureSet readCreatureSet(int number = 7); //reads creature set in most recently encountered format; reades number units (default is 7)
-	char readChar();
-	std::string readString();
+	//CAmbarCendamo (unsigned char * data); // c-tor; data is pointer to decompressed h3m data
+	//~CAmbarCendamo (); // d-tor
 };
 #endif //CAMBARCENDAMO_H

+ 2044 - 4
map.cpp

@@ -1,18 +1,207 @@
 #define VCMI_DLL
 #include "stdafx.h"
 #include "map.h"
+#include "hch/CObjectHandler.h"
+#include "hch/CDefObjInfoHandler.h"
+#include "lib/VCMI_Lib.h"
+std::set<int> convertBuildings(const std::set<int> h3m, int castleID)
+{
+	std::map<int,int> mapa;
+	std::set<int> ret;
+	std::ifstream b5("config/buildings5.txt");
+	while(!b5.eof())
+	{
+		int a, b;
+		b5 >> a >> b;
+		if(castleID==8 && b==17) //magic university ID 17 (h3m) => 21 (vcmi)
+			b=21;
+		mapa[a]=b;
+	}
+
+	for(std::set<int>::const_iterator i=h3m.begin();i!=h3m.end();i++)
+	{
+		if(mapa[*i]>=0)
+			ret.insert(mapa[*i]);
+		else if(mapa[*i]  >=  (-CREATURES_PER_TOWN)) // horde buildings
+		{
+			int level = (-mapa[*i]);
+			if(h3m.find(20+(level*3)) != h3m.end()) //upgraded creature horde building
+			{
+				if(((castleID==1) || (castleID==3)) && ((level==3) || (level==5)))
+					ret.insert(25);
+				else
+					ret.insert(19);
+			}
+			else
+			{
+				if(((castleID==1) || (castleID==3)) && ((level==3) || (level==5)))
+					ret.insert(24);
+				else
+					ret.insert(18);
+			}
+		}
+		else
+		{
+			std::cout<<"Conversion warning: unknown building "<<*i<<" in castle "<<castleID<<std::endl;
+		}
+	}
+
+	ret.insert(10); //village hall is always present
+	ret.insert(-1); //houses near v.hall / eyecandies
+	ret.insert(-2); //terrain eyecandy, if -1 is used
 
-int readNormalNr (unsigned char * bufor, int pos, int bytCon = 4)
+	if(ret.find(11)!=ret.end())
+		ret.insert(27);
+	if(ret.find(12)!=ret.end())
+		ret.insert(28);
+	if(ret.find(13)!=ret.end())
+		ret.insert(29);
+
+	return ret;
+}
+unsigned int intPow(unsigned int a, unsigned int b)
+{
+	unsigned int ret=1;
+	for(int i=0; i<b; ++i)
+		ret*=a;
+	return ret;
+}
+unsigned char reverse(unsigned char arg)
+{
+	unsigned char ret = 0;
+	for (int i=0; i<8;i++)
+	{
+		if(((arg)&(1<<i))>>i)
+		{
+			ret |= (128>>i);
+		}
+	}
+	return ret;
+}
+EDefType getDefType(CGDefInfo * a)
+{
+	switch(a->id)
+	{
+	case 5: case 65: case 66: case 67: case 68: case 69:
+		return EDefType::ARTIFACT_DEF; //handled
+	case 6:
+		return EDefType::PANDORA_DEF; //hanled
+	case 26:
+		return EDefType::EVENTOBJ_DEF; //handled
+	case 33:
+		return EDefType::GARRISON_DEF; //handled
+	case 34: case 70: case 62: //70 - random hero //62 - prison
+		return EDefType::HERO_DEF; //handled
+	case 36:
+		return EDefType::GRAIL_DEF; //hanled
+	case 53: case 17: case 18: case 19: case 20: case 42: case 87: case 220://cases 17 - 20 and 42 - tests
+		return EDefType::PLAYERONLY_DEF; //handled
+	case 54: case 71: case 72: case 73: case 74: case 75: case 162: case 163: case 164:
+		return EDefType::CREATURES_DEF; //handled
+	case 59:
+		return EDefType::SIGN_DEF; //handled
+	case 77:
+		return EDefType::TOWN_DEF; //can be problematic, but handled
+	case 79: case 76:
+		return EDefType::RESOURCE_DEF; //handled
+	case 81:
+		return EDefType::SCHOLAR_DEF; //handled
+	case 83:
+		return EDefType::SEERHUT_DEF; //handled
+	case 91:
+		return EDefType::SIGN_DEF; //handled
+	case 88: case 89: case 90:
+		return SHRINE_DEF; //handled
+	case 93:
+		return SPELLSCROLL_DEF; //handled
+	case 98:
+		return EDefType::TOWN_DEF; //handled
+	case 113:
+		return EDefType::WITCHHUT_DEF; //handled
+	case 214:
+		return EDefType::HEROPLACEHOLDER_DEF; //partially handled
+	case 215:
+		return EDefType::BORDERGUARD_DEF; //handled by analogy to seer huts ;]
+	case 216:
+		return EDefType::CREGEN2_DEF; //handled
+	case 217:
+		return EDefType::CREGEN_DEF; //handled
+	case 218:
+		return EDefType::CREGEN3_DEF; //handled
+	case 219:
+		return EDefType::GARRISON_DEF; //handled
+	default:
+		return EDefType::TERRAINOBJ_DEF; // nothing to be handled
+	}
+}
+int readNormalNr (unsigned char * bufor, int pos, int bytCon = 4, bool cyclic = false)
 {
 	int ret=0;
 	int amp=1;
-	for (int i=0; i<bytCon; i++)
+	for (int ir=0; ir<bytCon; ir++)
 	{
-		ret+=bufor[pos+i]*amp;
-		amp<<=8;
+		ret+=bufor[pos+ir]*amp;
+		amp*=256;
+	}
+	if(cyclic && bytCon<4 && ret>=amp/2)
+	{
+		ret = ret-amp;
 	}
 	return ret;
 }
+char readChar(unsigned char * bufor, int &i)
+{
+	return bufor[i++];
+}
+std::string readString(unsigned char * bufor, int &i)
+{					
+	int len = readNormalNr(bufor,i); i+=4;
+	std::string ret; ret.reserve(len);
+	for(int gg=0; gg<len; ++gg)
+	{
+		ret += bufor[i++];
+	}
+	return ret;
+}
+CCreatureSet readCreatureSet(unsigned char * bufor, int &i, int number, bool version) //version==true for >RoE maps
+{
+	if(version)
+	{
+		CCreatureSet ret;
+		std::pair<CCreature *, int> ins;
+		for(int ir=0;ir<number;ir++)
+		{
+			int rettt = readNormalNr(bufor,i+ir*4, 2);
+			if(rettt==0xffff) continue;
+			if(rettt>32768)
+				rettt = 65536-rettt+VLC->creh->creatures.size()-16;
+			ins.first = &(VLC->creh->creatures[rettt]);
+			ins.second = readNormalNr(bufor,i+ir*4+2, 2);
+			std::pair<int,std::pair<CCreature *, int> > tt(ir,ins);
+			ret.slots.insert(tt);
+		}
+		i+=number*4;
+		return ret;
+	}
+	else
+	{
+		CCreatureSet ret;
+		std::pair<CCreature *, int> ins;
+		for(int ir=0;ir<number;ir++)
+		{
+			int rettt = readNormalNr(bufor,i+ir*3, 1);
+			if(rettt==0xff) continue;
+			if(rettt>220)
+				rettt = 256-rettt+VLC->creh->creatures.size()-16;
+			ins.first = &(VLC->creh->creatures[rettt]);
+			ins.second = readNormalNr(bufor,i+ir*3+1, 2);
+			std::pair<int,std::pair<CCreature *, int> > tt(ir,ins);
+			ret.slots.insert(tt);
+		}
+		i+=number*3;
+		return ret;
+	}
+}
 CMapHeader::CMapHeader(unsigned char *map)
 {
 	this->version = (Eformat)map[0]; //wersja mapy
@@ -250,4 +439,1855 @@ CMapHeader::CMapHeader(unsigned char *map)
 			this->players[rr].team=map[i++];
 		}
 	}
+}
+Mapa::Mapa(unsigned char * bufor)
+{
+	THC timeHandler th;
+	th.getDif();
+	int i=0;
+	version = (Eformat)(readNormalNr(bufor,i)); i+=4; //map version
+	areAnyPLayers = readChar(bufor,i); //invalid on some maps
+	height = width = (readNormalNr(bufor,i)); i+=4; // wymiary mapy
+	twoLevel = readChar(bufor,i); //czy sa lochy
+	terrain = new TerrainTile*[width]; // allocate memory 
+	for (int ii=0;ii<width;ii++)
+		terrain[ii] = new TerrainTile[height]; // allocate memory 
+	if (twoLevel)
+	{
+		undergroungTerrain = new TerrainTile*[width]; // allocate memory 
+		for (int ii=0;ii<width;ii++)
+			undergroungTerrain[ii] = new TerrainTile[height]; // allocate memory 
+	}
+	int pom;
+	name = readString(bufor,i);
+	description= readString(bufor,i);
+	difficulty = readChar(bufor,i); // reading map difficulty
+	if(version != Eformat::RoE)
+		levelLimit = readChar(bufor,i); // hero level limit
+	else
+		levelLimit = 0;
+	for (pom=0;pom<8;pom++)
+	{
+		players[pom].canHumanPlay = bufor[i++];
+		players[pom].canComputerPlay = bufor[i++];
+		if ((!(players[pom].canHumanPlay || players[pom].canComputerPlay)))
+		{
+			switch(version)
+			{
+			case Eformat::SoD: case Eformat::WoG: 
+				i+=13;
+				break;
+			case Eformat::AB:
+				i+=12;
+				break;
+			case Eformat::RoE:
+				i+=6;
+				break;
+			}
+			continue;
+		}
+
+		players[pom].AITactic = bufor[i++];
+
+		if(version == Eformat::SoD || version == Eformat::WoG)
+			players[pom].p7= bufor[i++];	
+
+		players[pom].allowedFactions = 0;
+		players[pom].allowedFactions += bufor[i++];
+		if(version != Eformat::RoE)
+			players[pom].allowedFactions += (bufor[i++])*256;
+
+		players[pom].isFactionRandom = bufor[i++];
+		players[pom].hasMainTown = bufor[i++];
+		if (players[pom].hasMainTown)
+		{
+			if(version != Eformat::RoE)
+			{
+				players[pom].generateHeroAtMainTown = bufor[i++];
+				players[pom].generateHero = bufor[i++];
+			}
+			else
+			{
+				players[pom].generateHeroAtMainTown = false;
+				players[pom].generateHero = false;
+			}
+
+			players[pom].posOfMainTown.x = bufor[i++];
+			players[pom].posOfMainTown.y = bufor[i++];
+			players[pom].posOfMainTown.z = bufor[i++];
+
+			
+		}
+		players[pom].p8= bufor[i++];
+		players[pom].p9= bufor[i++];		
+		if(players[pom].p9!=0xff)
+		{
+			players[pom].mainHeroPortrait = bufor[i++];
+			int nameLength = bufor[i++];
+			i+=3; 
+			for (int pp=0;pp<nameLength;pp++)
+				players[pom].mainHeroName+=bufor[i++];
+		}
+
+		if(version != Eformat::RoE)
+		{
+			i++; ////unknown byte
+			int heroCount = bufor[i++];
+			i+=3;
+			for (int pp=0;pp<heroCount;pp++)
+			{
+				SheroName vv;
+				vv.heroID=bufor[i++];
+				int hnl = bufor[i++];
+				i+=3;
+				for (int zz=0;zz<hnl;zz++)
+				{
+					vv.heroName+=bufor[i++];
+				}
+				players[pom].heroesNames.push_back(vv);
+			}
+		}
+	}
+	victoryCondition = (EvictoryConditions)bufor[i++];
+	if (victoryCondition != winStandard) //specific victory conditions
+	{
+		int nr;
+		switch (victoryCondition) //read victory conditions
+		{
+		case artifact:
+			{
+				vicConDetails = new VicCon0();
+				((VicCon0*)vicConDetails)->ArtifactID = bufor[i+2];
+				nr=(version==RoE ? 1 : 2);
+				break;
+			}
+		case gatherTroop:
+			{
+				vicConDetails = new VicCon1();
+				int temp1 = bufor[i+2];
+				int temp2 = bufor[i+3];
+				((VicCon1*)vicConDetails)->monsterID = bufor[i+2];
+				((VicCon1*)vicConDetails)->neededQuantity=readNormalNr(bufor,i+(version==RoE ? 3 : 4));
+				nr=(version==RoE ? 5 : 6);
+				break;
+			}
+		case gatherResource:
+			{
+				vicConDetails = new VicCon2();
+				((VicCon2*)vicConDetails)->resourceID = bufor[i+2];
+				((VicCon2*)vicConDetails)->neededQuantity=readNormalNr(bufor,i+3);
+				nr=5;
+				break;
+			}
+		case buildCity:
+			{
+				vicConDetails = new VicCon3();
+				((VicCon3*)vicConDetails)->posOfCity.x = bufor[i+2];
+				((VicCon3*)vicConDetails)->posOfCity.y = bufor[i+3];
+				((VicCon3*)vicConDetails)->posOfCity.z = bufor[i+4];
+				((VicCon3*)vicConDetails)->councilNeededLevel = bufor[i+5];
+				((VicCon3*)vicConDetails)->fortNeededLevel = bufor[i+6];
+				nr=5;
+				break;
+			}
+		case buildGrail:
+			{
+				vicConDetails = new VicCon4();
+				if (bufor[i+4]>2)
+					((VicCon4*)vicConDetails)->anyLocation = true;
+				else
+				{
+					((VicCon4*)vicConDetails)->whereBuildGrail.x = bufor[i+2];
+					((VicCon4*)vicConDetails)->whereBuildGrail.y = bufor[i+3];
+					((VicCon4*)vicConDetails)->whereBuildGrail.z = bufor[i+4];
+				}
+				nr=3;
+				break;
+			}
+		case beatHero:
+			{
+				vicConDetails = new VicCon5();
+				((VicCon5*)vicConDetails)->locationOfHero.x = bufor[i+2];
+				((VicCon5*)vicConDetails)->locationOfHero.y = bufor[i+3];
+				((VicCon5*)vicConDetails)->locationOfHero.z = bufor[i+4];				
+				nr=3;
+				break;
+			}
+		case captureCity:
+			{
+				vicConDetails = new VicCon6();
+				((VicCon6*)vicConDetails)->locationOfTown.x = bufor[i+2];
+				((VicCon6*)vicConDetails)->locationOfTown.y = bufor[i+3];
+				((VicCon6*)vicConDetails)->locationOfTown.z = bufor[i+4];				
+				nr=3;
+				break;
+			}
+		case beatMonster:
+			{
+				vicConDetails = new VicCon7();
+				((VicCon7*)vicConDetails)->locationOfMonster.x = bufor[i+2];
+				((VicCon7*)vicConDetails)->locationOfMonster.y = bufor[i+3];
+				((VicCon7*)vicConDetails)->locationOfMonster.z = bufor[i+4];				
+				nr=3;
+				break;
+			}
+		case takeDwellings:
+			{		
+				vicConDetails = new CspecificVictoryConidtions();
+				nr=0;
+				break;
+			}
+		case takeMines:
+			{	
+				vicConDetails = new CspecificVictoryConidtions();	
+				nr=0;
+				break;
+			}
+		case transportItem:
+			{
+				vicConDetails = new VicCona();
+				((VicCona*)vicConDetails)->artifactID =  bufor[i+2];
+				((VicCona*)vicConDetails)->destinationPlace.x = bufor[i+3];
+				((VicCona*)vicConDetails)->destinationPlace.y = bufor[i+4];
+				((VicCona*)vicConDetails)->destinationPlace.z = bufor[i+5];				
+				nr=4;
+				break;
+			}
+		}
+		vicConDetails->allowNormalVictory = bufor[i++];
+		vicConDetails->appliesToAI = bufor[i++];
+		i+=nr;
+	}
+	lossCondition.typeOfLossCon = (ElossCon)bufor[i++];
+	switch (lossCondition.typeOfLossCon) //read loss conditions
+	{
+	case lossCastle:
+		  {
+			  lossCondition.castlePos.x=bufor[i++];
+			  lossCondition.castlePos.y=bufor[i++];
+			  lossCondition.castlePos.z=bufor[i++];
+			  break;
+		  }
+	case lossHero:
+		  {
+			  lossCondition.heroPos.x=bufor[i++];
+			  lossCondition.heroPos.y=bufor[i++];
+			  lossCondition.heroPos.z=bufor[i++];
+			  break;
+		  }
+	case timeExpires:
+		{
+			lossCondition.timeLimit = readNormalNr(bufor,i++,2);
+			i++;
+			 break;
+		}
+	}
+	howManyTeams=bufor[i++]; //read number of teams
+	if(howManyTeams>0) //read team numbers
+	{
+		for(int rr=0; rr<8; ++rr)
+		{
+			players[rr].team=bufor[i++];
+		}
+	}
+	//reading allowed heroes (20 bytes)
+	int ist;
+
+	ist=i; //starting i for loop
+
+	allowedHeroes.resize(HEROES_QUANTITY);
+	for(int xx=0;xx<HEROES_QUANTITY;xx++)
+		allowedHeroes[xx] = true;
+
+	for(i; i<ist+ (version == Eformat::RoE ? 16 : 20) ; ++i)
+	{
+		unsigned char c = bufor[i];
+		for(int yy=0; yy<8; ++yy)
+			if((i-ist)*8+yy < HEROES_QUANTITY)
+				if(c != (c|((unsigned char)intPow(2, yy))))
+					allowedHeroes[(i-ist)*8+yy] = false;
+	}
+	if(version>RoE) //probably reserved for further heroes
+		i+=4;
+	unsigned char disp = 0;
+	if(version>=SoD)
+	{
+		disp = bufor[i++];
+		disposedHeroes.resize(disp);
+		for(int g=0; g<disp; ++g)
+		{
+			disposedHeroes[g].ID = bufor[i++];
+			disposedHeroes[g].portrait = bufor[i++];
+			int lenbuf = readNormalNr(bufor,i); i+=4;
+			for (int zz=0; zz<lenbuf; zz++)
+				disposedHeroes[g].name+=bufor[i++];
+			int players = bufor[i++];
+			for(int zz=0;zz<8;zz++)
+			{
+				int por = (1<<zz);
+				if(players & por)
+					disposedHeroes[g].players[zz] = true;
+				else 
+					disposedHeroes[g].players[zz] = false;
+			}
+		}
+	}
+
+	i+=31; //omitting NULLS
+
+	allowedArtifact.resize(ARTIFACTS_QUANTITY);
+	for(int x=0;x<allowedArtifact.size();x++)
+		allowedArtifact[x] = true;
+
+	//reading allowed artifacts:  17 or 18 bytes
+	if(version!=RoE)
+	{
+		ist=i; //starting i for loop
+		for(i; i<ist+(version==AB ? 17 : 18); ++i)
+		{
+			unsigned char c = bufor[i];
+			for(int yy=0; yy<8; ++yy)
+			{
+				if((i-ist)*8+yy < ARTIFACTS_QUANTITY)
+				{
+					if(c == (c|((unsigned char)intPow(2, yy))))
+						allowedArtifact[(i-ist)*8+yy] = false;
+				}
+			}
+		}//allowed artifacts have been read
+	}
+
+
+	allowedSpell.resize(SPELLS_QUANTITY);
+	for(int x=0;x<allowedSpell.size();x++)
+		allowedSpell[x] = true;
+
+	allowedAbilities.resize(SKILL_QUANTITY);
+	for(int x=0;x<allowedAbilities.size();x++)
+		allowedAbilities[x] = true;
+
+	if(version>=SoD)
+	{
+		//reading allowed spells (9 bytes)
+		ist=i; //starting i for loop
+		for(i; i<ist+9; ++i)
+		{
+			unsigned char c = bufor[i];
+			for(int yy=0; yy<8; ++yy)
+				if((i-ist)*8+yy < SPELLS_QUANTITY)
+					if(c == (c|((unsigned char)intPow(2, yy))))
+						allowedSpell[(i-ist)*8+yy] = false;
+		}
+
+
+		//allowed hero's abilities (4 bytes)
+		ist=i; //starting i for loop
+		for(i; i<ist+4; ++i)
+		{
+			unsigned char c = bufor[i];
+			for(int yy=0; yy<8; ++yy)
+			{
+				if((i-ist)*8+yy < SKILL_QUANTITY)
+				{
+					if(c == (c|((unsigned char)intPow(2, yy))))
+						allowedAbilities[(i-ist)*8+yy] = false;
+				}
+			}
+		}
+	}
+	THC std::cout<<"\tReading header: "<<th.getDif()<<std::endl;
+
+	int rumNr = readNormalNr(bufor,i,4);i+=4;
+	for (int it=0;it<rumNr;it++)
+	{
+		Rumor ourRumor;
+		int nameL = readNormalNr(bufor,i,4);i+=4; //read length of name of rumor
+		for (int zz=0; zz<nameL; zz++)
+			ourRumor.name+=bufor[i++];
+		nameL = readNormalNr(bufor,i,4);i+=4; //read length of rumor
+		for (int zz=0; zz<nameL; zz++)
+			ourRumor.text+=bufor[i++];
+		rumors.push_back(ourRumor); //add to our list
+	}
+	THC std::cout<<"\tReading rumors: "<<th.getDif()<<std::endl;
+	switch(version)
+	{
+	case WoG: case SoD:
+		{
+			for(int z=0;z<HEROES_QUANTITY;z++) //disposed heroes
+			{
+				int custom =  bufor[i++];
+				if(!custom)
+					continue;
+				CGHeroInstance * cgh = new CGHeroInstance;
+				cgh->ID = 34;
+				cgh->subID = z;
+				if(readChar(bufor,i))//true if hore's experience is greater than 0
+				{	cgh->exp = readNormalNr(bufor,i); i+=4;	}
+				else
+					cgh->exp = 0;
+				if(readChar(bufor,i))//true if hero has specified abilities
+				{
+					int howMany = readNormalNr(bufor,i); i+=4;
+					cgh->secSkills.resize(howMany);
+					for(int yy=0; yy<howMany; ++yy)
+					{
+						cgh->secSkills[yy].first = readNormalNr(bufor,i, 1); ++i;
+						cgh->secSkills[yy].second = readNormalNr(bufor,i, 1); ++i;
+					}
+				}
+				bool artSet = bufor[i]; ++i; //true if artifact set is not default (hero has some artifacts)
+				int artmask = version == RoE ? 0xff : 0xffff;
+				int artidlen = version == RoE ? 1 : 2;
+				if(artSet)
+				{
+					for(int pom=0;pom<16;pom++)
+					{
+						int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
+						if(id!=artmask)
+							cgh->artifWorn[pom] = id;
+					}
+					//misc5 art //17
+					if(version>=SoD)
+					{
+						i+=2;
+						//int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
+						//if(id!=artmask)
+						//	spec->artifWorn[16] = id;
+					}
+					//spellbook
+					int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
+					if(id!=artmask)
+						cgh->artifWorn[17] = id;
+					//19 //???what is that? gap in file or what? - it's probably fifth slot..
+					if(version>RoE)
+					{
+						id = readNormalNr(bufor,i, artidlen); i+=artidlen;
+						if(id!=artmask)
+							cgh->artifWorn[18] = id;
+					}
+					else
+						i+=1;
+					//bag artifacts //20
+					int amount = readNormalNr(bufor,i, 2); i+=2; //number of artifacts in hero's bag
+					if(amount>0)
+					{
+						for(int ss=0; ss<amount; ++ss)
+						{
+							id = readNormalNr(bufor,i, artidlen); i+=artidlen;
+							if(id!=artmask)
+								cgh->artifacts.push_back(id);
+						}
+					}
+				} //artifacts
+				if(readChar(bufor,i))//customBio
+					cgh->biography = readString(bufor,i);
+				int sex = bufor[i++]; // 0xFF is default, 00 male, 01 female
+				if(readChar(bufor,i))//are spells
+				{
+					int ist = i;
+					for(i; i<ist+9; ++i)
+					{
+						unsigned char c = bufor[i];
+						for(int yy=0; yy<8; ++yy)
+						{
+							if((i-ist)*8+yy < SPELLS_QUANTITY)
+							{
+								if(c == (c|((unsigned char)intPow(2, yy))))
+									cgh->spells.insert((i-ist)*8+yy);
+							}
+						}
+					}
+				}
+				if(readChar(bufor,i))//customPrimSkills
+				{
+					cgh->primSkills.resize(4);
+					for(int xx=0;xx<4;xx++)
+						cgh->primSkills[xx] = bufor[i++];
+				}
+				predefinedHeroes.push_back(cgh);
+			}
+			break;
+		}
+	case RoE:
+		i+=0;
+		break;
+	}
+	for (int c=0; c<width; c++) // reading terrain
+	{
+		for (int z=0; z<height; z++)
+		{
+			terrain[z][c].tertype = (EterrainType)(bufor[i++]);
+			terrain[z][c].terview = bufor[i++];
+			terrain[z][c].nuine = (Eriver)bufor[i++];
+			terrain[z][c].rivDir = bufor[i++];
+			terrain[z][c].malle = (Eroad)bufor[i++];
+			terrain[z][c].roadDir = bufor[i++];
+			terrain[z][c].siodmyTajemniczyBajt = bufor[i++];
+		}
+	}
+	if (twoLevel) // read underground terrain
+	{
+		for (int c=0; c<width; c++) // reading terrain
+		{
+			for (int z=0; z<height; z++)
+			{
+				undergroungTerrain[z][c].tertype = (EterrainType)(bufor[i++]);
+				undergroungTerrain[z][c].terview = bufor[i++];
+				undergroungTerrain[z][c].nuine = (Eriver)bufor[i++];
+				undergroungTerrain[z][c].rivDir = bufor[i++];
+				undergroungTerrain[z][c].malle = (Eroad)bufor[i++];
+				undergroungTerrain[z][c].roadDir = bufor[i++];
+				undergroungTerrain[z][c].siodmyTajemniczyBajt = bufor[i++];
+			}
+		}
+	}
+	THC std::cout<<"\tReading terrain: "<<th.getDif()<<std::endl;
+
+	//////READING DEF INFO///////
+	int defAmount = readNormalNr(bufor,i); i+=4;
+	defy.reserve(defAmount);
+
+	for (int idd = 0 ; idd<defAmount; idd++) // reading defs
+	{
+		CGDefInfo * vinya = new CGDefInfo(); // info about new def 
+
+		//reading name
+		int nameLength = readNormalNr(bufor,i,4);i+=4;
+		vinya->name.reserve(nameLength);
+		for (int cd=0;cd<nameLength;cd++)
+		{
+			vinya->name += bufor[i++];
+		}
+		std::transform(vinya->name.begin(),vinya->name.end(),vinya->name.begin(),(int(*)(int))toupper);
+
+
+		unsigned char bytes[12];
+		for (int v=0; v<12; v++) // read info
+		{
+			bytes[v] = bufor[i++];
+		}
+		vinya->terrainAllowed = readNormalNr(bufor,i,2);i+=2;
+		vinya->terrainMenu = readNormalNr(bufor,i,2);i+=2;
+		vinya->id = readNormalNr(bufor,i,4);i+=4;
+		vinya->subid = readNormalNr(bufor,i,4);i+=4;
+		vinya->type = bufor[i++];
+		vinya->printPriority = bufor[i++];
+		for (int zi=0; zi<6; zi++)
+		{
+			vinya->blockMap[zi] = reverse(bytes[zi]);
+		}
+		for (int zi=0; zi<6; zi++)
+		{
+			vinya->visitMap[zi] = reverse(bytes[6+zi]);
+		}
+		i+=16;
+		defy.push_back(vinya); // add this def to the vector
+	}
+	THC std::cout<<"\tReading defs info: "<<th.getDif()<<std::endl;
+
+	////loading objects
+	int howManyObjs = readNormalNr(bufor,i, 4); i+=4;
+	for(int ww=0; ww<howManyObjs; ++ww) //comment this line to turn loading objects off
+	{
+		//std::cout << "object nr "<<ww<<"\ti= "<<i<<std::endl;
+		CGObjectInstance * nobj = new CGObjectInstance(); //we will read this object
+		nobj->id = objects.size();
+		nobj->pos.x = bufor[i++];
+		nobj->pos.y = bufor[i++];
+		nobj->pos.z = bufor[i++];
+
+		int tempd = readNormalNr(bufor,i, 4); i+=4;
+		nobj->defInfo = defy[tempd];
+		nobj->ID = nobj->defInfo->id;
+		nobj->subID = nobj->defInfo->subid;
+
+		//if (((nobj.x==0)&&(nobj.y==0)) || nobj.x>width || nobj.y>height || nobj.z>1 || nobj.defNumber>defy.size())	std::cout << "Alarm!!! Obiekt "<<ww<<" jest kopniety (lub wystaje poza mape)\n";
+
+		i+=5;
+		unsigned char buff [30];
+		for(int ccc=0; ccc<30; ++ccc)
+		{
+			buff[ccc] = bufor[i+ccc];
+		}
+		int j = nobj->defInfo->id;
+		int p = 99;
+		switch(getDefType(nobj->defInfo))
+		{
+		case EDefType::EVENTOBJ_DEF: //for event - objects
+			{
+				CEventObjInfo * spec = new CEventObjInfo;
+				bool guardMess;
+				guardMess = bufor[i]; ++i;
+				if(guardMess)
+				{
+					int messLong = readNormalNr(bufor,i, 4); i+=4;
+					if(messLong>0)
+					{
+						spec->isMessage = true;
+						for(int yy=0; yy<messLong; ++yy)
+						{
+							spec->message +=bufor[i+yy];
+						}
+						i+=messLong;
+					}
+					spec->areGuarders = bufor[i]; ++i;
+					if(spec->areGuarders)
+					{
+						spec->guarders = readCreatureSet(bufor,i,7,(version>RoE)); 
+					}
+					i+=4;
+				}
+				else
+				{
+					spec->isMessage = false;
+					spec->areGuarders = false;
+					spec->message = std::string("");
+				}
+				spec->gainedExp = readNormalNr(bufor,i, 4); i+=4;
+				spec->manaDiff = readNormalNr(bufor,i, 4); i+=4;
+				spec->moraleDiff = readNormalNr(bufor,i, 1, true); ++i;
+				spec->luckDiff = readNormalNr(bufor,i, 1, true); ++i;
+				spec->wood = readNormalNr(bufor,i); i+=4;
+				spec->mercury = readNormalNr(bufor,i); i+=4;
+				spec->ore = readNormalNr(bufor,i); i+=4;
+				spec->sulfur = readNormalNr(bufor,i); i+=4;
+				spec->crystal = readNormalNr(bufor,i); i+=4;
+				spec->gems = readNormalNr(bufor,i); i+=4;
+				spec->gold = readNormalNr(bufor,i); i+=4;
+				spec->attack = readNormalNr(bufor,i, 1); ++i;
+				spec->defence = readNormalNr(bufor,i, 1); ++i;
+				spec->power = readNormalNr(bufor,i, 1); ++i;
+				spec->knowledge = readNormalNr(bufor,i, 1); ++i;
+				int gabn; //number of gained abilities
+				gabn = readNormalNr(bufor,i, 1); ++i;
+				for(int oo = 0; oo<gabn; ++oo)
+				{
+					spec->abilities.push_back(readNormalNr(bufor,i, 1)); ++i;
+					spec->abilityLevels.push_back(readNormalNr(bufor,i, 1)); ++i;
+				}
+				int gart = readNormalNr(bufor,i, 1); ++i; //number of gained artifacts
+				for(int oo = 0; oo<gart; ++oo)
+				{
+					spec->artifacts.push_back(readNormalNr(bufor,i, (version == RoE ? 1 : 2))); i+=(version == RoE ? 1 : 2);
+				}
+				int gspel = readNormalNr(bufor,i, 1); ++i; //number of gained spells
+				for(int oo = 0; oo<gspel; ++oo)
+				{
+					spec->spells.push_back(readNormalNr(bufor,i, 1)); ++i;
+				}
+				int gcre = readNormalNr(bufor,i, 1); ++i; //number of gained creatures
+				spec->creatures = readCreatureSet(bufor,i,gcre,(version>RoE));
+				if(version>RoE)
+					i+=gcre;
+				i+=8;
+				spec->availableFor = readNormalNr(bufor,i, 1); ++i;
+				spec->computerActivate = readNormalNr(bufor,i, 1); ++i;
+				spec->humanActivate = readNormalNr(bufor,i, 1); ++i;
+				i+=4;
+				nobj->info = spec;
+				break;
+			}
+		case EDefType::HERO_DEF:
+			{
+				CGHeroInstance * nhi = new CGHeroInstance;
+				(*(static_cast<CGObjectInstance*>(nhi))) = *nobj;
+				delete nobj;
+				nobj=nhi;
+				if(version>RoE)
+				{
+					nhi->identifier = readNormalNr(bufor,i, 4); i+=4;
+				}
+				nhi->setOwner(bufor[i]); ++i;
+				nhi->subID = readNormalNr(bufor,i, 1); ++i;
+				if(readChar(bufor,i))//true if hero has nonstandard name
+					nhi->name = readString(bufor,i);
+				if(version>AB)
+				{
+					if(readChar(bufor,i))//true if hore's experience is greater than 0
+					{	nhi->exp = readNormalNr(bufor,i); i+=4;	}
+					else
+						nhi->exp = -1;
+				}
+				else
+				{	nhi->exp = readNormalNr(bufor,i); i+=4;	}
+
+				bool portrait=bufor[i]; ++i;
+				if (portrait)
+					i++; //TODO read portrait nr, save, open
+				
+				if(readChar(bufor,i))//true if hero has specified abilities
+				{
+					int howMany = readNormalNr(bufor,i); i+=4;
+					nhi->secSkills.resize(howMany);
+					for(int yy=0; yy<howMany; ++yy)
+					{
+						nhi->secSkills[yy].first = readNormalNr(bufor,i, 1); ++i;
+						nhi->secSkills[yy].second = readNormalNr(bufor,i, 1); ++i;
+					}
+				}
+				if(readChar(bufor,i))//true if hero has nonstandard garrison
+					nhi->army = readCreatureSet(bufor,i,7,(version>RoE));
+				nhi->army.formation =bufor[i]; ++i; //formation
+				bool artSet = bufor[i]; ++i; //true if artifact set is not default (hero has some artifacts)
+				int artmask = version == RoE ? 0xff : 0xffff;
+				int artidlen = version == RoE ? 1 : 2;
+				if(artSet)
+				{
+					for(int pom=0;pom<16;pom++)
+					{
+						int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
+						if(id!=artmask)
+							nhi->artifWorn[pom] = id;
+					}
+					//misc5 art //17
+					if(version>=SoD)
+					{
+						int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
+						if(id!=artmask)
+							nhi->artifWorn[16] = id;
+					}
+					//spellbook
+					int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
+					if(id!=artmask)
+						nhi->artifWorn[17] = id;
+					//19 //???what is that? gap in file or what? - it's probably fifth slot..
+					if(version>RoE)
+					{
+						id = readNormalNr(bufor,i, artidlen); i+=artidlen;
+						if(id!=artmask)
+							nhi->artifWorn[18] = id;
+					}
+					else
+						i+=1;
+					//bag artifacts //20
+					int amount = readNormalNr(bufor,i, 2); i+=2; //number of artifacts in hero's bag
+					if(amount>0)
+					{
+						for(int ss=0; ss<amount; ++ss)
+						{
+							id = readNormalNr(bufor,i, artidlen); i+=artidlen;
+							if(id!=artmask)
+								nhi->artifacts.push_back(id);
+						}
+					}
+				} //artifacts
+
+				nhi->patrol.patrolRadious = readNormalNr(bufor,i, 1); ++i;
+				if(nhi->patrol.patrolRadious == 0xff)
+					nhi->patrol.patrolling = false;
+				else 
+					nhi->patrol.patrolling = true;
+
+				if(version>RoE)
+				{
+					if(readChar(bufor,i))//true if hero has nonstandard (mapmaker defined) biography
+						nhi->biography = readString(bufor,i);
+					nhi->sex = !(bufor[i]); ++i;
+				}
+				//spells
+				if(version>AB)
+				{
+					bool areSpells = bufor[i]; ++i;
+
+					if(areSpells) //TODO: sprawdziæ //seems to be ok - tow
+					{
+						int ist = i;
+						for(i; i<ist+9; ++i)
+						{
+							unsigned char c = bufor[i];
+							for(int yy=0; yy<8; ++yy)
+							{
+								if((i-ist)*8+yy < SPELLS_QUANTITY)
+								{
+									if(c == (c|((unsigned char)intPow(2, yy))))
+										nhi->spells.insert((i-ist)*8+yy);
+								}
+							}
+						}
+					}
+				}
+				else if(version==AB) //we can read one spell
+				{
+					unsigned char buff = bufor[i]; ++i;
+					if(buff!=254)
+					{
+						nhi->spells.insert(buff);
+					}
+				}
+				//spells loaded
+				if(version>AB)
+				{
+					if(readChar(bufor,i))//customPrimSkills
+					{
+						nhi->primSkills.resize(4);
+						for(int xx=0;xx<4;xx++)
+							nhi->primSkills[xx] = bufor[i++];
+					}
+				}
+				i+=16;
+				nhi->moveDir = 4;
+				nhi->isStanding = true;
+				nhi->level = -1;
+				nhi->mana = -1;
+				nhi->movement = -1;
+				if(nhi->ID==34)
+					heroes.push_back(nhi);
+				//else
+				//	CGI->objh->objInstances.push_back(nhi);
+
+				break;
+			}
+		case CREATURES_DEF:
+			{
+				CCreatureObjInfo * spec = new CCreatureObjInfo;
+				if(version>RoE)
+				{
+					spec->bytes[0] = bufor[i]; ++i;
+					spec->bytes[1] = bufor[i]; ++i;
+					spec->bytes[2] = bufor[i]; ++i;
+					spec->bytes[3] = bufor[i]; ++i;
+				}
+				spec->number = readNormalNr(bufor,i, 2); i+=2;
+				spec->character = bufor[i]; ++i;
+				bool isMesTre = bufor[i]; ++i; //true if there is message or treasury
+				if(isMesTre)
+				{
+					int messLength = readNormalNr(bufor,i); i+=4;
+					if(messLength>0)
+					{
+						for(int tt=0; tt<messLength; ++tt)
+						{
+							spec->message += bufor[i]; ++i;
+						}
+					}
+					spec->wood = readNormalNr(bufor,i); i+=4;
+					spec->mercury = readNormalNr(bufor,i); i+=4;
+					spec->ore = readNormalNr(bufor,i); i+=4;
+					spec->sulfur = readNormalNr(bufor,i); i+=4;
+					spec->crytal = readNormalNr(bufor,i); i+=4;
+					spec->gems = readNormalNr(bufor,i); i+=4;
+					spec->gold = readNormalNr(bufor,i); i+=4;
+					int artID = readNormalNr(bufor,i, (version == RoE ? 1 : 2)); i+=(version == RoE ? 1 : 2);
+					if(version==RoE)
+					{
+						if(artID!=0xff)
+							spec->gainedArtifact = artID;
+						else
+							spec->gainedArtifact = -1;
+					}
+					else
+					{
+						if(artID!=0xffff)
+							spec->gainedArtifact = artID;
+						else
+							spec->gainedArtifact = -1;
+					}
+				}
+				spec->neverFlees = bufor[i]; ++i;
+				spec->notGrowingTeam = bufor[i]; ++i;
+				i+=2;
+				nobj->info = spec;
+				break;
+			}
+		case EDefType::SIGN_DEF:
+			{
+				CSignObjInfo * spec = new CSignObjInfo;
+				int length = readNormalNr(bufor,i); i+=4;
+				for(int rr=0; rr<length; ++rr)
+				{
+					spec->message += bufor[i]; ++i;
+				}
+				i+=4;
+				nobj->info = spec;
+				break;
+			}
+		case EDefType::SEERHUT_DEF:
+			{
+				CSeerHutObjInfo * spec = new CSeerHutObjInfo;
+				if(version>RoE)
+				{
+					spec->missionType = bufor[i]; ++i;
+					switch(spec->missionType)
+					{
+					case 0:
+						i+=3;
+						continue;
+					case 1:
+						{
+							spec->m1level = readNormalNr(bufor,i); i+=4;
+							int limit = readNormalNr(bufor,i); i+=4;
+							if(limit == ((int)0xffffffff))
+							{
+								spec->isDayLimit = false;
+								spec->lastDay = -1;
+							}
+							else
+							{
+								spec->isDayLimit = true;
+								spec->lastDay = limit;
+							}
+							break;
+						}
+					case 2:
+						{
+							spec->m2attack = bufor[i]; ++i;
+							spec->m2defence = bufor[i]; ++i;
+							spec->m2power = bufor[i]; ++i;
+							spec->m2knowledge = bufor[i]; ++i;
+							int limit = readNormalNr(bufor,i); i+=4;
+							if(limit == ((int)0xffffffff))
+							{
+								spec->isDayLimit = false;
+								spec->lastDay = -1;
+							}
+							else
+							{
+								spec->isDayLimit = true;
+								spec->lastDay = limit;
+							}
+							break;
+						}
+					case 3:
+						{
+							spec->m3bytes[0] = bufor[i]; ++i;
+							spec->m3bytes[1] = bufor[i]; ++i;
+							spec->m3bytes[2] = bufor[i]; ++i;
+							spec->m3bytes[3] = bufor[i]; ++i;
+							int limit = readNormalNr(bufor,i); i+=4;
+							if(limit == ((int)0xffffffff))
+							{
+								spec->isDayLimit = false;
+								spec->lastDay = -1;
+							}
+							else
+							{
+								spec->isDayLimit = true;
+								spec->lastDay = limit;
+							}
+							break;
+						}
+					case 4:
+						{
+							spec->m4bytes[0] = bufor[i]; ++i;
+							spec->m4bytes[1] = bufor[i]; ++i;
+							spec->m4bytes[2] = bufor[i]; ++i;
+							spec->m4bytes[3] = bufor[i]; ++i;
+							int limit = readNormalNr(bufor,i); i+=4;
+							if(limit == ((int)0xffffffff))
+							{
+								spec->isDayLimit = false;
+								spec->lastDay = -1;
+							}
+							else
+							{
+								spec->isDayLimit = true;
+								spec->lastDay = limit;
+							}
+							break;
+						}
+					case 5:
+						{
+							int artNumber = bufor[i]; ++i;
+							for(int yy=0; yy<artNumber; ++yy)
+							{
+								int artid = readNormalNr(bufor,i, 2); i+=2;
+								spec->m5arts.push_back(artid);
+							}
+							int limit = readNormalNr(bufor,i); i+=4;
+							if(limit == ((int)0xffffffff))
+							{
+								spec->isDayLimit = false;
+								spec->lastDay = -1;
+							}
+							else
+							{
+								spec->isDayLimit = true;
+								spec->lastDay = limit;
+							}
+							break;
+						}
+					case 6:
+						{
+							int typeNumber = bufor[i]; ++i;
+							for(int hh=0; hh<typeNumber; ++hh)
+							{
+								int creType = readNormalNr(bufor,i, 2); i+=2;
+								int creNumb = readNormalNr(bufor,i, 2); i+=2;
+								spec->m6cre.push_back(&(VLC->creh->creatures[creType]));
+								spec->m6number.push_back(creNumb);
+							}
+							int limit = readNormalNr(bufor,i); i+=4;
+							if(limit == ((int)0xffffffff))
+							{
+								spec->isDayLimit = false;
+								spec->lastDay = -1;
+							}
+							else
+							{
+								spec->isDayLimit = true;
+								spec->lastDay = limit;
+							}
+							break;
+						}
+					case 7:
+						{
+							spec->m7wood = readNormalNr(bufor,i); i+=4;
+							spec->m7mercury = readNormalNr(bufor,i); i+=4;
+							spec->m7ore = readNormalNr(bufor,i); i+=4;
+							spec->m7sulfur = readNormalNr(bufor,i); i+=4;
+							spec->m7crystal = readNormalNr(bufor,i); i+=4;
+							spec->m7gems = readNormalNr(bufor,i); i+=4;
+							spec->m7gold = readNormalNr(bufor,i); i+=4;
+							int limit = readNormalNr(bufor,i); i+=4;
+							if(limit == ((int)0xffffffff))
+							{
+								spec->isDayLimit = false;
+								spec->lastDay = -1;
+							}
+							else
+							{
+								spec->isDayLimit = true;
+								spec->lastDay = limit;
+							}
+							break;
+						}
+					case 8:
+						{
+							int heroType = bufor[i]; ++i;
+							spec->m8hero = heroType;
+							int limit = readNormalNr(bufor,i); i+=4;
+							if(limit == ((int)0xffffffff))
+							{
+								spec->isDayLimit = false;
+								spec->lastDay = -1;
+							}
+							else
+							{
+								spec->isDayLimit = true;
+								spec->lastDay = limit;
+							}
+							break;
+						}
+					case 9:
+						{
+							spec->m9player = bufor[i]; ++i;
+							int limit = readNormalNr(bufor,i); i+=4;
+							if(limit == ((int)0xffffffff))
+							{
+								spec->isDayLimit = false;
+								spec->lastDay = -1;
+							}
+							else
+							{
+								spec->isDayLimit = true;
+								spec->lastDay = limit;
+							}
+							break;
+						}
+					}//internal switch end (seer huts)
+
+					int len1 = readNormalNr(bufor,i); i+=4;
+					for(int ee=0; ee<len1; ++ee)
+					{
+						spec->firstVisitText += bufor[i]; ++i;
+					}
+
+					int len2 = readNormalNr(bufor,i); i+=4;
+					for(int ee=0; ee<len2; ++ee)
+					{
+						spec->nextVisitText += bufor[i]; ++i;
+					}
+
+					int len3 = readNormalNr(bufor,i); i+=4;
+					for(int ee=0; ee<len3; ++ee)
+					{
+						spec->completedText += bufor[i]; ++i;
+					}
+				}
+				else //RoE
+				{
+					int artID = bufor[i]; ++i;
+					if(artID!=255) //not none quest
+					{
+						spec->m5arts.push_back(artID);
+						spec->missionType = 5;
+					}
+					else
+					{
+						spec->missionType = 255;
+					}
+				}
+
+				if(spec->missionType!=255)
+				{
+					unsigned char rewardType = bufor[i]; ++i;
+					spec->rewardType = rewardType;
+
+					switch(rewardType)
+					{
+					case 1:
+						{
+							spec->r1exp = readNormalNr(bufor,i); i+=4;
+							break;
+						}
+					case 2:
+						{
+							spec->r2mana = readNormalNr(bufor,i); i+=4;
+							break;
+						}
+					case 3:
+						{
+							spec->r3morale = bufor[i]; ++i;
+							break;
+						}
+					case 4:
+						{
+							spec->r4luck = bufor[i]; ++i;
+							break;
+						}
+					case 5:
+						{
+							spec->r5type = bufor[i]; ++i;
+							spec->r5amount = readNormalNr(bufor,i, 3); i+=3;
+							i+=1;
+							break;
+						}
+					case 6:
+						{
+							spec->r6type = bufor[i]; ++i;
+							spec->r6amount = bufor[i]; ++i;
+							break;
+						}
+					case 7:
+						{
+							spec->r7ability = bufor[i]; ++i;
+							spec->r7level = bufor[i]; ++i;
+							break;
+						}
+					case 8:
+						{
+							spec->r8art = readNormalNr(bufor,i, (version == RoE ? 1 : 2)); i+=(version == RoE ? 1 : 2);
+							break;
+						}
+					case 9:
+						{
+							spec->r9spell = bufor[i]; ++i;
+							break;
+						}
+					case 10:
+						{
+							if(version>RoE)
+							{
+								spec->r10creature = readNormalNr(bufor,i, 2); i+=2;
+								spec->r10amount = readNormalNr(bufor,i, 2); i+=2;
+							}
+							else
+							{
+								spec->r10creature = bufor[i]; ++i;
+								spec->r10amount = readNormalNr(bufor,i, 2); i+=2;
+							}
+							break;
+						}
+					}// end of internal switch
+					i+=2;
+				}
+				else //missionType==255
+				{
+					i+=3;
+				}
+				nobj->info = spec;
+				break;
+			}
+		case EDefType::WITCHHUT_DEF:
+			{
+				CWitchHutObjInfo * spec = new CWitchHutObjInfo;
+				if(version>RoE) //in reo we cannot specify it - all are allowed (I hope)
+				{
+					ist=i; //starting i for loop
+					for(i; i<ist+4; ++i)
+					{
+						unsigned char c = bufor[i];
+						for(int yy=0; yy<8; ++yy)
+						{
+							if((i-ist)*8+yy < SKILL_QUANTITY)
+							{
+								if(c == (c|((unsigned char)intPow(2, yy))))
+									spec->allowedAbilities.push_back((i-ist)*8+yy);
+							}
+						}
+					}
+				}
+				else //(RoE map)
+				{
+					for(int gg=0; gg<SKILL_QUANTITY; ++gg)
+					{
+						spec->allowedAbilities.push_back(gg);
+					}
+				}
+				
+				nobj->info = spec;
+				break;
+			}
+		case EDefType::SCHOLAR_DEF:
+			{
+				CScholarObjInfo * spec = new CScholarObjInfo;
+				spec->bonusType = bufor[i]; ++i;
+				switch(spec->bonusType)
+				{
+				case 0xff:
+					++i;
+					break;
+				case 0:
+					spec->r0type = bufor[i]; ++i;
+					break;
+				case 1:
+					spec->r1 = bufor[i]; ++i;
+					break;
+				case 2:
+					spec->r2 = bufor[i]; ++i;
+					break;
+				}
+				i+=6;
+				nobj->info = spec;
+				break;
+			}
+		case EDefType::GARRISON_DEF:
+			{
+				CGarrisonObjInfo * spec = new CGarrisonObjInfo;
+				spec->player = bufor[i]; ++i;
+				i+=3;
+				spec->units = readCreatureSet(bufor,i,7,(version>RoE));
+				if(version > RoE)
+				{
+					spec->movableUnits = bufor[i]; ++i;
+				}
+				else
+					spec->movableUnits = true;
+				i+=8;
+				nobj->setOwner(spec->player);
+				nobj->info = spec;
+				break;
+			}
+		case EDefType::ARTIFACT_DEF:
+			{
+				CArtifactObjInfo * spec = new CArtifactObjInfo;
+				bool areSettings = bufor[i]; ++i;
+				if(areSettings)
+				{
+					int messLength = readNormalNr(bufor,i, 4); i+=4;
+					for(int hh=0; hh<messLength; ++hh)
+					{
+						spec->message += bufor[i]; ++i;
+					}
+					bool areGuards = bufor[i]; ++i;
+					if(areGuards)
+					{
+						spec->areGuards = true;
+						spec->guards = readCreatureSet(bufor,i,7,(version>RoE));
+					}
+					else
+						spec->areGuards = false;
+					i+=4;
+				}
+				nobj->info = spec;
+				break;
+			}
+		case EDefType::RESOURCE_DEF:
+			{
+				CResourceObjInfo * spec = new CResourceObjInfo;
+				bool isMessGuard = bufor[i]; ++i;
+				if(isMessGuard)
+				{
+					int messLength = readNormalNr(bufor,i); i+=4;
+					for(int mm=0; mm<messLength; ++mm)
+					{
+						spec->message+=bufor[i]; ++i;
+					}
+					spec->areGuards = bufor[i]; ++i;
+					if(spec->areGuards)
+					{
+						spec->guards = readCreatureSet(bufor,i,7,(version>RoE));
+					}
+					i+=4;
+				}
+				else
+				{
+					spec->areGuards = false;
+				}
+				spec->amount = readNormalNr(bufor,i); i+=4;
+				i+=4;
+				nobj->info = spec;
+				break;
+			}
+		case EDefType::TOWN_DEF:
+			{
+				CGTownInstance * nt = new CGTownInstance();
+				(*(static_cast<CGObjectInstance*>(nt))) = *nobj;
+				delete nobj;
+				nobj = nt;
+				nt->identifier = 0;
+				if(version>RoE)
+				{	
+					readNormalNr(bufor,i); i+=4;
+				}
+				nt->tempOwner = bufor[i]; ++i;
+				if(readChar(bufor,i)) //has name
+					nt->name = readString(bufor,i);
+				if(readChar(bufor,i))//true if garrison isn't empty
+					nt->army = readCreatureSet(bufor,i,7,(version>RoE));
+				nt->army.formation = bufor[i]; ++i;
+				if(readChar(bufor,i)) //unusualBuildings
+				{
+					//built buildings
+					for(int byte=0;byte<6;byte++)
+					{
+						for(int bit=0;bit<8;bit++)
+							if(bufor[i] & (1<<bit))
+								nt->builtBuildings.insert(byte*8+bit);
+						i++;
+					}
+					//forbidden buildings
+					for(int byte=6;byte<12;byte++)
+					{
+						for(int bit=0;bit<8;bit++)
+							if(bufor[i] & (1<<bit))
+								nt->forbiddenBuildings.insert(byte*8+bit);
+						i++;
+					}
+					nt->builtBuildings = convertBuildings(nt->builtBuildings,nt->subID);
+					nt->forbiddenBuildings = convertBuildings(nt->forbiddenBuildings,nt->subID);
+				}
+				else //standard buildings
+				{
+					if(readChar(bufor,i)) //has fort
+						nt->builtBuildings.insert(7);
+					nt->builtBuildings.insert(-50); //means that set of standard building should be included
+				}
+
+				int ist = i;
+				if(version>RoE)
+				{
+					for(i; i<ist+9; ++i)
+					{
+						unsigned char c = bufor[i];
+						for(int yy=0; yy<8; ++yy)
+						{
+							if((i-ist)*8+yy < SPELLS_QUANTITY)
+							{
+								if(c == (c|((unsigned char)intPow(2, yy))))
+									nt->obligatorySpells.push_back((i-ist)*8+yy);
+							}
+						}
+					}
+				}
+
+				ist = i;
+				for(i; i<ist+9; ++i)
+				{
+					unsigned char c = bufor[i];
+					for(int yy=0; yy<8; ++yy)
+					{
+						if((i-ist)*8+yy < SPELLS_QUANTITY)
+						{
+							if(c != (c|((unsigned char)intPow(2, yy))))
+								nt->possibleSpells.push_back((i-ist)*8+yy);
+						}
+					}
+				}
+
+				/////// reading castle events //////////////////////////////////
+
+				int numberOfEvent = readNormalNr(bufor,i); i+=4;
+
+				for(int gh = 0; gh<numberOfEvent; ++gh)
+				{
+					CCastleEvent nce;
+					int nameLen = readNormalNr(bufor,i); i+=4;
+					for(int ll=0; ll<nameLen; ++ll)
+					{
+						nce.name += bufor[i]; ++i;
+					}
+
+					int messLen = readNormalNr(bufor,i); i+=4;
+					for(int ll=0; ll<messLen; ++ll)
+					{
+						nce.message += bufor[i]; ++i;
+					}
+
+					nce.wood = readNormalNr(bufor,i); i+=4;
+					nce.mercury = readNormalNr(bufor,i); i+=4;
+					nce.ore = readNormalNr(bufor,i); i+=4;
+					nce.sulfur = readNormalNr(bufor,i); i+=4;
+					nce.crystal = readNormalNr(bufor,i); i+=4;
+					nce.gems = readNormalNr(bufor,i); i+=4;
+					nce.gold = readNormalNr(bufor,i); i+=4;
+
+					nce.players = bufor[i]; ++i;
+					if(version > AB)
+					{
+						nce.forHuman = bufor[i]; ++i;
+					}
+					else
+						nce.forHuman = true;
+					nce.forComputer = bufor[i]; ++i;
+					nce.firstShow = readNormalNr(bufor,i, 2); i+=2;
+					nce.forEvery = bufor[i]; ++i;
+
+					i+=17;
+
+					for(int kk=0; kk<6; ++kk)
+					{
+						nce.bytes[kk] = bufor[i]; ++i;
+					}
+
+					for(int vv=0; vv<7; ++vv)
+					{
+						nce.gen[vv] = readNormalNr(bufor,i, 2); i+=2;
+					}
+					i+=4;
+					nt->events.insert(nce);
+				}//castle events have been read 
+
+				if(version > AB)
+				{
+					nt->alignment = bufor[i]; ++i;
+				}
+				else
+					nt->alignment = 0xff;
+				i+=3;
+
+				nt->builded = 0;
+				nt->destroyed = 0;
+				nt->garrisonHero = NULL;
+				towns.push_back(nt);
+				break;
+			}
+		case EDefType::PLAYERONLY_DEF:
+			{
+				CPlayerOnlyObjInfo * spec = new CPlayerOnlyObjInfo;
+				spec->player = bufor[i]; ++i;
+				i+=3;
+				nobj->setOwner(spec->player);
+				nobj->info = spec;
+				break;
+			}
+		case EDefType::SHRINE_DEF:
+			{
+				CShrineObjInfo * spec = new CShrineObjInfo;
+				spec->spell = bufor[i]; i+=4;
+				nobj->info = spec;
+				break;
+			}
+		case EDefType::SPELLSCROLL_DEF:
+			{
+				CSpellScrollObjinfo * spec = new CSpellScrollObjinfo;
+				bool messg = bufor[i]; ++i;
+				if(messg)
+				{
+					int mLength = readNormalNr(bufor,i); i+=4;
+					for(int vv=0; vv<mLength; ++vv)
+					{
+						spec->message += bufor[i]; ++i;
+					}
+					spec->areGuarders = bufor[i]; ++i;
+					if(spec->areGuarders)
+					{
+						spec->guarders = readCreatureSet(bufor,i,7,(version>RoE));
+					}
+					i+=4;
+				}
+				spec->spell = bufor[i]; ++i;
+				i+=3;
+				nobj->info = spec;
+				break;
+			}
+		case EDefType::PANDORA_DEF:
+			{
+				CPandorasBoxObjInfo * spec = new CPandorasBoxObjInfo;
+				bool messg = bufor[i]; ++i;
+				if(messg)
+				{
+					int mLength = readNormalNr(bufor,i); i+=4;
+					for(int vv=0; vv<mLength; ++vv)
+					{
+						spec->message += bufor[i]; ++i;
+					}
+					spec->areGuarders = bufor[i]; ++i;
+					if(spec->areGuarders)
+					{
+						spec->guarders = readCreatureSet(bufor,i,7,(version>RoE));
+					}
+					i+=4;
+				}
+				////// copied form event handling (seems to be similar)
+				spec->gainedExp = readNormalNr(bufor,i, 4); i+=4;
+				spec->manaDiff = readNormalNr(bufor,i, 4); i+=4;
+				spec->moraleDiff = readNormalNr(bufor,i, 1, true); ++i;
+				spec->luckDiff = readNormalNr(bufor,i, 1, true); ++i;
+				spec->wood = readNormalNr(bufor,i); i+=4;
+				spec->mercury = readNormalNr(bufor,i); i+=4;
+				spec->ore = readNormalNr(bufor,i); i+=4;
+				spec->sulfur = readNormalNr(bufor,i); i+=4;
+				spec->crystal = readNormalNr(bufor,i); i+=4;
+				spec->gems = readNormalNr(bufor,i); i+=4;
+				spec->gold = readNormalNr(bufor,i); i+=4;
+				spec->attack = readNormalNr(bufor,i, 1); ++i;
+				spec->defence = readNormalNr(bufor,i, 1); ++i;
+				spec->power = readNormalNr(bufor,i, 1); ++i;
+				spec->knowledge = readNormalNr(bufor,i, 1); ++i;
+				int gabn; //number of gained abilities
+				gabn = readNormalNr(bufor,i, 1); ++i;
+				for(int oo = 0; oo<gabn; ++oo)
+				{
+					spec->abilities.push_back(readNormalNr(bufor,i, 1)); ++i;
+					spec->abilityLevels.push_back(readNormalNr(bufor,i, 1)); ++i;
+				}
+				int gart = readNormalNr(bufor,i, 1); ++i; //number of gained artifacts
+				for(int oo = 0; oo<gart; ++oo)
+				{
+					if(version > RoE)
+					{
+						spec->artifacts.push_back(readNormalNr(bufor,i, 2)); i+=2;
+					}
+					else
+					{
+						spec->artifacts.push_back(readNormalNr(bufor,i, 1)); i+=1;
+					}
+				}
+				int gspel = readNormalNr(bufor,i, 1); ++i; //number of gained spells
+				for(int oo = 0; oo<gspel; ++oo)
+				{
+					spec->spells.push_back(readNormalNr(bufor,i, 1)); ++i;
+				}
+				int gcre = readNormalNr(bufor,i, 1); ++i; //number of gained creatures
+				spec->creatures = readCreatureSet(bufor,i,gcre,(version>RoE));
+				if(version > RoE)
+					i+=gcre;
+				i+=8;
+				nobj->info = spec;
+				///////end of copied fragment
+				break;
+			}
+		case EDefType::GRAIL_DEF:
+			{
+				CGrailObjInfo * spec = new CGrailObjInfo;
+				spec->radius = readNormalNr(bufor,i); i+=4;
+				nobj->info = spec;
+				break;
+			}
+		case EDefType::CREGEN_DEF:
+			{
+				CCreGenObjInfo * spec = new CCreGenObjInfo;
+				spec->player = readNormalNr(bufor,i); i+=4;
+				spec->identifier =  readNormalNr(bufor,i); i+=4;
+				if(!spec->identifier)
+				{
+					spec->asCastle = false;
+					spec->castles[0] = bufor[i]; ++i;
+					spec->castles[1] = bufor[i]; ++i;
+				}
+				else
+				{
+					spec->asCastle = true;
+				}
+				nobj->setOwner(spec->player);
+				nobj->info = spec;
+				break;
+			}
+		case EDefType::CREGEN2_DEF:
+			{
+				CCreGen2ObjInfo * spec = new CCreGen2ObjInfo;
+				spec->player = readNormalNr(bufor,i); i+=4;
+				spec->identifier =  readNormalNr(bufor,i); i+=4;
+				if(!spec->identifier)
+				{
+					spec->asCastle = false;
+					spec->castles[0] = bufor[i]; ++i;
+					spec->castles[1] = bufor[i]; ++i;
+				}
+				else
+				{
+					spec->asCastle = true;
+				}
+				spec->minLevel = bufor[i]; ++i;
+				spec->maxLevel = bufor[i]; ++i;
+				//if(spec->maxLevel>7)
+				//	spec->maxLevel = 7;
+				//if(spec->minLevel<1)
+				//	spec->minLevel = 1;
+				nobj->setOwner(spec->player);
+				nobj->info = spec;
+				break;
+			}
+		case EDefType::CREGEN3_DEF:
+			{
+				CCreGen3ObjInfo * spec = new CCreGen3ObjInfo;
+				spec->player = bufor[i]; ++i;
+				i+=3;
+				spec->minLevel = bufor[i]; ++i;
+				spec->maxLevel = bufor[i]; ++i;
+				if(spec->maxLevel>7)
+					spec->maxLevel = 7;
+				if(spec->minLevel<1)
+					spec->minLevel = 1;
+				nobj->setOwner(spec->player);
+				nobj->info = spec;
+				break;
+			}
+		case EDefType::BORDERGUARD_DEF:
+			{
+				CBorderGuardObjInfo * spec = new CBorderGuardObjInfo;
+				spec->missionType = bufor[i]; ++i;
+				switch(spec->missionType)
+				{
+				case 0:
+					{
+						goto borderguardend;
+						break;
+					}
+				case 1:
+					{
+						spec->m1level = readNormalNr(bufor,i); i+=4;
+						int limit = readNormalNr(bufor,i); i+=4;
+						if(limit == ((int)0xffffffff))
+						{
+							spec->isDayLimit = false;
+							spec->lastDay = -1;
+						}
+						else
+						{
+							spec->isDayLimit = true;
+							spec->lastDay = limit;
+						}
+						break;
+					}
+				case 2:
+					{
+						spec->m2attack = bufor[i]; ++i;
+						spec->m2defence = bufor[i]; ++i;
+						spec->m2power = bufor[i]; ++i;
+						spec->m2knowledge = bufor[i]; ++i;
+						int limit = readNormalNr(bufor,i); i+=4;
+						if(limit == ((int)0xffffffff))
+						{
+							spec->isDayLimit = false;
+							spec->lastDay = -1;
+						}
+						else
+						{
+							spec->isDayLimit = true;
+							spec->lastDay = limit;
+						}
+						break;
+					}
+				case 3:
+					{
+						spec->m3bytes[0] = bufor[i]; ++i;
+						spec->m3bytes[1] = bufor[i]; ++i;
+						spec->m3bytes[2] = bufor[i]; ++i;
+						spec->m3bytes[3] = bufor[i]; ++i;
+						int limit = readNormalNr(bufor,i); i+=4;
+						if(limit == ((int)0xffffffff))
+						{
+							spec->isDayLimit = false;
+							spec->lastDay = -1;
+						}
+						else
+						{
+							spec->isDayLimit = true;
+							spec->lastDay = limit;
+						}
+						break;
+					}
+				case 4:
+					{
+						spec->m4bytes[0] = bufor[i]; ++i;
+						spec->m4bytes[1] = bufor[i]; ++i;
+						spec->m4bytes[2] = bufor[i]; ++i;
+						spec->m4bytes[3] = bufor[i]; ++i;
+						int limit = readNormalNr(bufor,i); i+=4;
+						if(limit == ((int)0xffffffff))
+						{
+							spec->isDayLimit = false;
+							spec->lastDay = -1;
+						}
+						else
+						{
+							spec->isDayLimit = true;
+							spec->lastDay = limit;
+						}
+						break;
+					}
+				case 5:
+					{
+						int artNumber = bufor[i]; ++i;
+						for(int yy=0; yy<artNumber; ++yy)
+						{
+							spec->m5arts.push_back(readNormalNr(bufor,i, 2)); i+=2;
+						}
+						int limit = readNormalNr(bufor,i); i+=4;
+						if(limit == ((int)0xffffffff))
+						{
+							spec->isDayLimit = false;
+							spec->lastDay = -1;
+						}
+						else
+						{
+							spec->isDayLimit = true;
+							spec->lastDay = limit;
+						}
+						break;
+					}
+				case 6:
+					{
+						int typeNumber = bufor[i]; ++i;
+						for(int hh=0; hh<typeNumber; ++hh)
+						{
+							int creType = readNormalNr(bufor,i, 2); i+=2;
+							int creNumb = readNormalNr(bufor,i, 2); i+=2;
+							spec->m6cre.push_back(&(VLC->creh->creatures[creType]));
+							spec->m6number.push_back(creNumb);
+						}
+						int limit = readNormalNr(bufor,i); i+=4;
+						if(limit == ((int)0xffffffff))
+						{
+							spec->isDayLimit = false;
+							spec->lastDay = -1;
+						}
+						else
+						{
+							spec->isDayLimit = true;
+							spec->lastDay = limit;
+						}
+						break;
+					}
+				case 7:
+					{
+						spec->m7wood = readNormalNr(bufor,i); i+=4;
+						spec->m7mercury = readNormalNr(bufor,i); i+=4;
+						spec->m7ore = readNormalNr(bufor,i); i+=4;
+						spec->m7sulfur = readNormalNr(bufor,i); i+=4;
+						spec->m7crystal = readNormalNr(bufor,i); i+=4;
+						spec->m7gems = readNormalNr(bufor,i); i+=4;
+						spec->m7gold = readNormalNr(bufor,i); i+=4;
+						int limit = readNormalNr(bufor,i); i+=4;
+						if(limit == ((int)0xffffffff))
+						{
+							spec->isDayLimit = false;
+							spec->lastDay = -1;
+						}
+						else
+						{
+							spec->isDayLimit = true;
+							spec->lastDay = limit;
+						}
+						break;
+					}
+				case 8:
+					{
+						int heroType = bufor[i]; ++i;
+						spec->m8hero = heroType;
+						int limit = readNormalNr(bufor,i); i+=4;
+						if(limit == ((int)0xffffffff))
+						{
+							spec->isDayLimit = false;
+							spec->lastDay = -1;
+						}
+						else
+						{
+							spec->isDayLimit = true;
+							spec->lastDay = limit;
+						}
+						break;
+					}
+				case 9:
+					{
+						spec->m9player = bufor[i]; ++i;
+						int limit = readNormalNr(bufor,i); i+=4;
+						if(limit == ((int)0xffffffff))
+						{
+							spec->isDayLimit = false;
+							spec->lastDay = -1;
+						}
+						else
+						{
+							spec->isDayLimit = true;
+							spec->lastDay = limit;
+						}
+						break;
+					}
+				}//internal switch end (seer huts)
+
+				int len1 = readNormalNr(bufor,i); i+=4;
+				for(int ee=0; ee<len1; ++ee)
+				{
+					spec->firstVisitText += bufor[i]; ++i;
+				}
+
+				int len2 = readNormalNr(bufor,i); i+=4;
+				for(int ee=0; ee<len2; ++ee)
+				{
+					spec->nextVisitText += bufor[i]; ++i;
+				}
+
+				int len3 = readNormalNr(bufor,i); i+=4;
+				for(int ee=0; ee<len3; ++ee)
+				{
+					spec->completedText += bufor[i]; ++i;
+				}
+				nobj->info = spec;
+borderguardend:
+				break;
+			}
+		case EDefType::HEROPLACEHOLDER_DEF:
+			{
+				i+=3; //TODO: handle it more properly
+				break;
+			}
+		} //end of main switch
+		objects.push_back(nobj);
+	}//end of loading objects
+	THC std::cout<<"\tReading objects: "<<th.getDif()<<std::endl;
+	
+	//loading events
+	int numberOfEvents = readNormalNr(bufor,i); i+=4;
+	for(int yyoo=0; yyoo<numberOfEvents; ++yyoo)
+	{
+		CMapEvent ne;
+		ne.name = std::string();
+		ne.message = std::string();
+		int nameLen = readNormalNr(bufor,i); i+=4;
+		for(int qq=0; qq<nameLen; ++qq)
+		{
+			ne.name += bufor[i]; ++i;
+		}
+		int messLen = readNormalNr(bufor,i); i+=4;
+		for(int qq=0; qq<messLen; ++qq)
+		{
+			ne.message +=bufor[i]; ++i;
+		}
+		ne.wood = readNormalNr(bufor,i); i+=4;
+		ne.mercury = readNormalNr(bufor,i); i+=4;
+		ne.ore = readNormalNr(bufor,i); i+=4;
+		ne.sulfur = readNormalNr(bufor,i); i+=4;
+		ne.crystal = readNormalNr(bufor,i); i+=4;
+		ne.gems = readNormalNr(bufor,i); i+=4;
+		ne.gold = readNormalNr(bufor,i); i+=4;
+		ne.players = bufor[i]; ++i;
+		if(version>AB)
+		{
+			ne.humanAffected = bufor[i]; ++i;
+		}
+		else
+			ne.humanAffected = true;
+		ne.computerAffected = bufor[i]; ++i;
+		ne.firstOccurence = bufor[i]; ++i;
+		ne.nextOccurence = bufor[i]; ++i;
+		i+=18;
+		events.push_back(ne);
+	}
+
+	//map readed, bufor no longer needed
+	delete[] bufor; bufor=NULL;
 }

+ 6 - 1
map.h

@@ -10,7 +10,10 @@ class CGObjectInstance;
 class CGHeroInstance;
 class CGTownInstance;
 enum ESortBy{name,playerAm,size,format, viccon,loscon};
-
+enum EDefType {TOWN_DEF, HERO_DEF, CREATURES_DEF, SEERHUT_DEF, RESOURCE_DEF, TERRAINOBJ_DEF, 
+	EVENTOBJ_DEF, SIGN_DEF, GARRISON_DEF, ARTIFACT_DEF, WITCHHUT_DEF, SCHOLAR_DEF, PLAYERONLY_DEF, 
+	SHRINE_DEF, SPELLSCROLL_DEF, PANDORA_DEF, GRAIL_DEF, CREGEN_DEF, CREGEN2_DEF, CREGEN3_DEF, 
+	BORDERGUARD_DEF, HEROPLACEHOLDER_DEF};
 class DLL_EXPORT CSpecObjInfo //class with object - specific info (eg. different information for creatures and heroes); use inheritance to make object - specific classes
 {
 };
@@ -391,6 +394,8 @@ struct DLL_EXPORT Mapa
 	std::vector<CGObjectInstance*> objects;
 	std::vector<CGHeroInstance*> heroes;
 	std::vector<CGTownInstance*> towns;
+
+	Mapa(unsigned char * bufor); //creates map from decompressed .h3m data
 };
 class DLL_EXPORT CMapHeader
 {