浏览代码

First part of object instance API cleanup

- removed passability() method in favour of passableFor(PlayerColor)
- moved operator < code to map handler
- updated class documentation
Ivan Savenko 11 年之前
父节点
当前提交
5ebc0e8614

+ 43 - 49
client/CPlayerInterface.cpp

@@ -91,16 +91,10 @@ CondSh<EMoveState> stillMoveHero; //used during hero movement
 
 int CPlayerInterface::howManyPeople = 0;
 
-
-struct OCM_HLP_CGIN
+static bool objectBlitOrderSorter(const std::pair<const CGObjectInstance*,SDL_Rect>  & a, const std::pair<const CGObjectInstance*,SDL_Rect> & b)
 {
-	bool inline operator ()(const std::pair<const CGObjectInstance*,SDL_Rect>  & a, const std::pair<const CGObjectInstance*,SDL_Rect> & b) const
-	{
-		return (*a.first)<(*b.first);
-	}
-} ocmptwo_cgin ;
-
-
+	return CMapHandler::compareObjectBlitOrder(a.first, b.first);
+}
 
 CPlayerInterface::CPlayerInterface(PlayerColor Player)
 {
@@ -1708,14 +1702,14 @@ void CPlayerInterface::initMovement( const TryMoveHero &details, const CGHeroIns
 		subRect(hp.x-1, hp.y, hp.z, genRect(32, 32, 33, 33), ho->id);
 		subRect(hp.x, hp.y, hp.z, genRect(32, 32, 65, 33), ho->id);
 
-		std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y-2][hp.z].objects.end(), ocmptwo_cgin);
-		std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.end(), ocmptwo_cgin);
-		std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.end(), ocmptwo_cgin);
-		std::stable_sort(CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.end(), ocmptwo_cgin);
+		std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter);
+		std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter);
+		std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter);
+		std::stable_sort(CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter);
 
-		std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.end(), ocmptwo_cgin);
+		std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.end(), objectBlitOrderSorter);
 
-		std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.end(), ocmptwo_cgin);
+		std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.end(), objectBlitOrderSorter);
 	}
 	else if(details.end.x == details.start.x && details.end.y+1 == details.start.y) //t
 	{
@@ -1733,9 +1727,9 @@ void CPlayerInterface::initMovement( const TryMoveHero &details, const CGHeroIns
 		subRect(hp.x-1, hp.y, hp.z, genRect(32, 32, 32, 33), ho->id);
 		subRect(hp.x, hp.y, hp.z, genRect(32, 32, 64, 33), ho->id);
 
-		std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.end(), ocmptwo_cgin);
-		std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.end(), ocmptwo_cgin);
-		std::stable_sort(CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.end(), ocmptwo_cgin);
+		std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter);
+		std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter);
+		std::stable_sort(CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter);
 	}
 	else if(details.end.x-1 == details.start.x && details.end.y+1 == details.start.y) //tr
 	{
@@ -1756,14 +1750,14 @@ void CPlayerInterface::initMovement( const TryMoveHero &details, const CGHeroIns
 		subRect(hp.x, hp.y, hp.z, genRect(32, 32, 63, 33), ho->id);
 		CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.push_back(std::make_pair(ho, genRect(32, 32, 95, 33)));
 
-		std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.end(), ocmptwo_cgin);
-		std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.end(), ocmptwo_cgin);
-		std::stable_sort(CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.end(), ocmptwo_cgin);
-		std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y-2][hp.z].objects.end(), ocmptwo_cgin);
+		std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter);
+		std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter);
+		std::stable_sort(CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter);
+		std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter);
 
-		std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.end(), ocmptwo_cgin);
+		std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.end(), objectBlitOrderSorter);
 
-		std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.end(), ocmptwo_cgin);
+		std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.end(), objectBlitOrderSorter);
 	}
 	else if(details.end.x-1 == details.start.x && details.end.y == details.start.y) //r
 	{
@@ -1779,9 +1773,9 @@ void CPlayerInterface::initMovement( const TryMoveHero &details, const CGHeroIns
 		subRect(hp.x, hp.y, hp.z, genRect(32, 32, 63, 32), ho->id);
 		CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.push_back(std::make_pair(ho, genRect(32, 32, 95, 32)));
 
-		std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.end(), ocmptwo_cgin);
+		std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.end(), objectBlitOrderSorter);
 
-		std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.end(), ocmptwo_cgin);
+		std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.end(), objectBlitOrderSorter);
 	}
 	else if(details.end.x-1 == details.start.x && details.end.y-1 == details.start.y) //br
 	{
@@ -1802,14 +1796,14 @@ void CPlayerInterface::initMovement( const TryMoveHero &details, const CGHeroIns
 		CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.push_back(std::make_pair(ho, genRect(32, 32, 63, 63)));
 		CGI->mh->ttiles[hp.x+1][hp.y+1][hp.z].objects.push_back(std::make_pair(ho, genRect(32, 32, 95, 63)));
 
-		std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.end(), ocmptwo_cgin);
+		std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.end(), objectBlitOrderSorter);
 
-		std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.end(), ocmptwo_cgin);
+		std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.end(), objectBlitOrderSorter);
 
-		std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.end(), ocmptwo_cgin);
-		std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.end(), ocmptwo_cgin);
-		std::stable_sort(CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.end(), ocmptwo_cgin);
-		std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y+1][hp.z].objects.end(), ocmptwo_cgin);
+		std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter);
+		std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter);
+		std::stable_sort(CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter);
+		std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter);
 	}
 	else if(details.end.x == details.start.x && details.end.y-1 == details.start.y) //b
 	{
@@ -1827,9 +1821,9 @@ void CPlayerInterface::initMovement( const TryMoveHero &details, const CGHeroIns
 		CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.push_back(std::make_pair(ho, genRect(32, 32, 32, 63)));
 		CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.push_back(std::make_pair(ho, genRect(32, 32, 64, 63)));
 
-		std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.end(), ocmptwo_cgin);
-		std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.end(), ocmptwo_cgin);
-		std::stable_sort(CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.end(), ocmptwo_cgin);
+		std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter);
+		std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter);
+		std::stable_sort(CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter);
 	}
 	else if(details.end.x+1 == details.start.x && details.end.y-1 == details.start.y) //bl
 	{
@@ -1850,14 +1844,14 @@ void CPlayerInterface::initMovement( const TryMoveHero &details, const CGHeroIns
 		CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.push_back(std::make_pair(ho, genRect(32, 32, 33, 63)));
 		CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.push_back(std::make_pair(ho, genRect(32, 32, 65, 63)));
 
-		std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.end(), ocmptwo_cgin);
+		std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.end(), objectBlitOrderSorter);
 
-		std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.end(), ocmptwo_cgin);
+		std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.end(), objectBlitOrderSorter);
 
-		std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y+1][hp.z].objects.end(), ocmptwo_cgin);
-		std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.end(), ocmptwo_cgin);
-		std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.end(), ocmptwo_cgin);
-		std::stable_sort(CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.end(), ocmptwo_cgin);
+		std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter);
+		std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter);
+		std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter);
+		std::stable_sort(CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter);
 	}
 	else if(details.end.x+1 == details.start.x && details.end.y == details.start.y) //l
 	{
@@ -1873,9 +1867,9 @@ void CPlayerInterface::initMovement( const TryMoveHero &details, const CGHeroIns
 		subRect(hp.x-1, hp.y, hp.z, genRect(32, 32, 33, 32), ho->id);
 		subRect(hp.x, hp.y, hp.z, genRect(32, 32, 65, 32), ho->id);
 
-		std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.end(), ocmptwo_cgin);
+		std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.end(), objectBlitOrderSorter);
 
-		std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.end(), ocmptwo_cgin);
+		std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.end(), objectBlitOrderSorter);
 	}
 }
 
@@ -2105,13 +2099,13 @@ void CPlayerInterface::finishMovement( const TryMoveHero &details, const int3 &h
 	subRect(details.end.x, details.end.y, details.end.z, genRect(32, 32, 64, 32), ho->id);
 
 	//restoring good order of objects
-	std::stable_sort(CGI->mh->ttiles[details.end.x-2][details.end.y-1][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x-2][details.end.y-1][details.end.z].objects.end(), ocmptwo_cgin);
-	std::stable_sort(CGI->mh->ttiles[details.end.x-1][details.end.y-1][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x-1][details.end.y-1][details.end.z].objects.end(), ocmptwo_cgin);
-	std::stable_sort(CGI->mh->ttiles[details.end.x][details.end.y-1][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x][details.end.y-1][details.end.z].objects.end(), ocmptwo_cgin);
+	std::stable_sort(CGI->mh->ttiles[details.end.x-2][details.end.y-1][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x-2][details.end.y-1][details.end.z].objects.end(), objectBlitOrderSorter);
+	std::stable_sort(CGI->mh->ttiles[details.end.x-1][details.end.y-1][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x-1][details.end.y-1][details.end.z].objects.end(), objectBlitOrderSorter);
+	std::stable_sort(CGI->mh->ttiles[details.end.x][details.end.y-1][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x][details.end.y-1][details.end.z].objects.end(), objectBlitOrderSorter);
 
-	std::stable_sort(CGI->mh->ttiles[details.end.x-2][details.end.y][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x-2][details.end.y][details.end.z].objects.end(), ocmptwo_cgin);
-	std::stable_sort(CGI->mh->ttiles[details.end.x-1][details.end.y][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x-1][details.end.y][details.end.z].objects.end(), ocmptwo_cgin);
-	std::stable_sort(CGI->mh->ttiles[details.end.x][details.end.y][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x][details.end.y][details.end.z].objects.end(), ocmptwo_cgin);
+	std::stable_sort(CGI->mh->ttiles[details.end.x-2][details.end.y][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x-2][details.end.y][details.end.z].objects.end(), objectBlitOrderSorter);
+	std::stable_sort(CGI->mh->ttiles[details.end.x-1][details.end.y][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x-1][details.end.y][details.end.z].objects.end(), objectBlitOrderSorter);
+	std::stable_sort(CGI->mh->ttiles[details.end.x][details.end.y][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x][details.end.y][details.end.z].objects.end(), objectBlitOrderSorter);
 }
 
 void CPlayerInterface::gameOver(PlayerColor player, const EVictoryLossCheckResult & victoryLossCheckResult )

+ 27 - 16
client/mapHandler.cpp

@@ -75,21 +75,10 @@ std::string nameFromType (int typ)
 	return std::string();
 }
 
-struct OCM_HLP
+static bool objectBlitOrderSorter(const std::pair<const CGObjectInstance*,SDL_Rect>  & a, const std::pair<const CGObjectInstance*,SDL_Rect> & b)
 {
-	bool operator ()(const std::pair<const CGObjectInstance*, SDL_Rect> & a, const std::pair<const CGObjectInstance*, SDL_Rect> & b)
-	{
-		return (*a.first)<(*b.first);
-	}
-} ocmptwo ;
-
-// void alphaTransformDef(CGDefInfo * defInfo)
-// {	
-// 	for(int yy=0; yy<defInfo->handler->ourImages.size(); ++yy)
-// 	{
-// 		CSDL_Ext::alphaTransform(defInfo->handler->ourImages[yy].bitmap);
-// 	}
-// }
+	return CMapHandler::compareObjectBlitOrder(a.first, b.first);
+}
 
 void CMapHandler::prepareFOWDefs()
 {
@@ -308,7 +297,7 @@ void CMapHandler::initObjectRects()
 		{
 			for(int iz=0; iz<ttiles[0][0].size(); ++iz)
 			{
-				stable_sort(ttiles[ix][iy][iz].objects.begin(), ttiles[ix][iy][iz].objects.end(), ocmptwo);
+				stable_sort(ttiles[ix][iy][iz].objects.begin(), ttiles[ix][iy][iz].objects.end(), objectBlitOrderSorter);
 			}
 		}
 	}
@@ -860,7 +849,7 @@ bool CMapHandler::printObject(const CGObjectInstance *obj)
 				auto i = curt.objects.begin();
 				for(; i != curt.objects.end(); i++)
 				{
-					if(ocmptwo(toAdd, *i))
+					if(objectBlitOrderSorter(toAdd, *i))
 					{
 						curt.objects.insert(i, toAdd);
 						i = curt.objects.begin(); //to validate and avoid adding it second time
@@ -1092,3 +1081,25 @@ ui8 CMapHandler::getPhaseShift(const CGObjectInstance *object) const
 TerrainTile2::TerrainTile2()
  :terbitmap(nullptr)
 {}
+
+bool CMapHandler::compareObjectBlitOrder(const CGObjectInstance * a, const CGObjectInstance * b)
+{
+	if (a->appearance.printPriority != b->appearance.printPriority)
+		return a->appearance.printPriority > b->appearance.printPriority;
+
+	if(a->pos.y != b->pos.y)
+		return a->pos.y < b->pos.y;
+
+	if(b->ID==Obj::HERO && a->ID!=Obj::HERO)
+		return true;
+	if(b->ID!=Obj::HERO && a->ID==Obj::HERO)
+		return false;
+
+	if(!a->isVisitable() && b->isVisitable())
+		return true;
+	if(!b->isVisitable() && a->isVisitable())
+		return false;
+	if(a->pos.x < b->pos.x)
+		return true;
+	return false;
+}

+ 2 - 0
client/mapHandler.h

@@ -127,4 +127,6 @@ public:
 	void validateRectTerr(SDL_Rect * val, const SDL_Rect * ext); //terrainRect helper
 	static ui8 getDir(const int3 & a, const int3 & b);  //returns direction number in range 0 - 7 (0 is left top, clockwise) [direction: form a to b]
 
+	static bool compareObjectBlitOrder(const CGObjectInstance * a, const CGObjectInstance * b);
+
 };

+ 2 - 2
lib/mapObjects/CGHeroInstance.cpp

@@ -999,11 +999,11 @@ void CGHeroInstance::showNecromancyDialog(const CStackBasicDescriptor &raisedSta
 
 	cb->showInfoDialog(&iw);
 }
-
+/*
 int3 CGHeroInstance::getSightCenter() const
 {
 	return getPosition(false);
-}
+}*/
 
 int CGHeroInstance::getSightRadious() const
 {

+ 1 - 1
lib/mapObjects/CGHeroInstance.h

@@ -113,7 +113,7 @@ public:
 		}
 	} skillsInfo;
 
-	int3 getSightCenter() const; //"center" tile from which the sight distance is calculated
+	//int3 getSightCenter() const; //"center" tile from which the sight distance is calculated
 	int getSightRadious() const; //sight distance (should be used if player-owned structure)
 	//////////////////////////////////////////////////////////////////////////
 

+ 8 - 11
lib/mapObjects/CGTownInstance.cpp

@@ -644,25 +644,22 @@ void CGTownInstance::newTurn() const
 			}
 	}
 }
-
+/*
 int3 CGTownInstance::getSightCenter() const
 {
 	return pos - int3(2,0,0);
 }
-
-ui8 CGTownInstance::getPassableness() const
+*/
+bool CGTownInstance::passableFor(PlayerColor color) const
 {
 	if (!armedGarrison())//empty castle - anyone can visit
-		return GameConstants::ALL_PLAYERS;
+		return true;
 	if ( tempOwner == PlayerColor::NEUTRAL )//neutral guarded - no one can visit
-		return 0;
-
-	ui8 mask = 0;
-	TeamState * ts = cb->gameState()->getPlayerTeam(tempOwner);
-	for(PlayerColor it : ts->players)
-		mask |= 1<<it.getNum();//allies - add to possible visitors
+		return false;
 
-	return mask;
+	if (cb->getPlayerRelations(tempOwner, color) != PlayerRelations::ENEMIES)
+		return true;
+	return false;
 }
 
 void CGTownInstance::getOutOffsets( std::vector<int3> &offsets ) const

+ 2 - 2
lib/mapObjects/CGTownInstance.h

@@ -200,8 +200,8 @@ public:
 
 	//////////////////////////////////////////////////////////////////////////
 
-	ui8 getPassableness() const; //bitmap - if the bit is set the corresponding player can pass through the visitable tiles of object, even if it's blockvis; if not set - default properties from definfo are used
-	int3 getSightCenter() const override; //"center" tile from which the sight distance is calculated
+	bool passableFor(PlayerColor color) const;
+	//int3 getSightCenter() const override; //"center" tile from which the sight distance is calculated
 	int getSightRadious() const override; //returns sight distance
 	int getBoatType() const; //0 - evil (if a ship can be evil...?), 1 - good, 2 - neutral
 	void getOutOffsets(std::vector<int3> &offsets) const; //offsets to obj pos when we boat can be placed

+ 3 - 36
lib/mapObjects/CObjectHandler.cpp

@@ -137,9 +137,6 @@ CGObjectInstance::CGObjectInstance():
 }
 CGObjectInstance::~CGObjectInstance()
 {
-	//if (state)
-	//	delete state;
-	//state=nullptr;
 }
 
 const std::string & CGObjectInstance::getHoverText() const
@@ -148,10 +145,7 @@ const std::string & CGObjectInstance::getHoverText() const
 }
 void CGObjectInstance::setOwner(PlayerColor ow)
 {
-	//if (state)
-	//	state->owner = ow;
-	//else
-		tempOwner = ow;
+	tempOwner = ow;
 }
 int CGObjectInstance::getWidth() const//returns width of object graphic in tiles
 {
@@ -203,29 +197,6 @@ std::set<int3> CGObjectInstance::getBlockedOffsets() const
 	return ret;
 }
 
-
-bool CGObjectInstance::operator<(const CGObjectInstance & cmp) const  //screen printing priority comparing
-{
-	if (appearance.printPriority != cmp.appearance.printPriority)
-		return appearance.printPriority > cmp.appearance.printPriority;
-
-	if(pos.y != cmp.pos.y)
-		return pos.y < cmp.pos.y;
-
-	if(cmp.ID==Obj::HERO && ID!=Obj::HERO)
-		return true;
-	if(cmp.ID!=Obj::HERO && ID==Obj::HERO)
-		return false;
-
-	if(!isVisitable() && cmp.isVisitable())
-		return true;
-	if(!cmp.isVisitable() && isVisitable())
-		return false;
-	if(this->pos.x<cmp.pos.x)
-		return true;
-	return false;
-}
-
 void CGObjectInstance::setType(si32 ID, si32 subID)
 {
 	const TerrainTile &tile = cb->gameState()->map->getTile(visitablePos());
@@ -291,6 +262,7 @@ void CGObjectInstance::getSightTiles(std::unordered_set<int3, ShashInt3> &tiles)
 {
 	cb->getTilesInRange(tiles, getSightCenter(), getSightRadious(), tempOwner, 1);
 }
+
 void CGObjectInstance::hideTiles(PlayerColor ourplayer, int radius) const
 {
 	for (auto i = cb->gameState()->teams.begin(); i != cb->gameState()->teams.end(); i++)
@@ -366,11 +338,6 @@ void CGObjectInstance::onHeroVisit( const CGHeroInstance * h ) const
 	}
 }
 
-ui8 CGObjectInstance::getPassableness() const
-{
-	return 0;
-}
-
 int3 CGObjectInstance::visitablePos() const
 {
 	return pos - getVisitableOffset();
@@ -383,7 +350,7 @@ bool CGObjectInstance::isVisitable() const
 
 bool CGObjectInstance::passableFor(PlayerColor color) const
 {
-	return getPassableness() & 1<<color.getNum();
+	return false;
 }
 
 CGObjectInstanceBySubIdFinder::CGObjectInstanceBySubIdFinder(CGObjectInstance * obj) : obj(obj)

+ 50 - 23
lib/mapObjects/CObjectHandler.h

@@ -96,49 +96,72 @@ class DLL_LINKAGE CGObjectInstance : public IObjectInterface
 {
 public:
 	mutable std::string hoverName;
-	int3 pos; //h3m pos
+
+	/// Position of bottom-right corner of object on map
+	int3 pos;
+	/// Type of object, e.g. town, hero, creature.
 	Obj ID;
-	si32 subID; //normal subID (this one from OH3 maps ;])
-	ObjectInstanceID id;//number of object in map's vector
+	/// Subtype of object, depends on type
+	si32 subID;
+	/// Index of object in map's list of objects
+	ObjectInstanceID id;
+	/// Defines appearance of object on map (animation, blocked tiles, blit order, etc)
 	ObjectTemplate appearance;
-
+	/// Current owner of an object (when below PLAYER_LIMIT)
 	PlayerColor tempOwner;
-	bool blockVisit; //if non-zero then blocks the tile but is visitable from neighbouring tile
+	/// If true hero can visit this object only from neighbouring tiles and can't stand on this object
+	bool blockVisit;
+
+	CGObjectInstance();
+	~CGObjectInstance();
+
+	/// "center" tile from which the sight distance is calculated
+	int3 getSightCenter() const;
 
-	virtual ui8 getPassableness() const; //bitmap - if the bit is set the corresponding player can pass through the visitable tiles of object, even if it's blockvis; if not set - default properties from definfo are used
-	virtual int3 getSightCenter() const; //"center" tile from which the sight distance is calculated
-	virtual int getSightRadious() const; //sight distance (should be used if player-owned structure)
-	bool passableFor(PlayerColor color) const;
-	void getSightTiles(std::unordered_set<int3, ShashInt3> &tiles) const; //returns reference to the set
 	PlayerColor getOwner() const;
 	void setOwner(PlayerColor ow);
+
+	/// APPEARANCE ACCESSORS ///
+
 	int getWidth() const; //returns width of object graphic in tiles
 	int getHeight() const; //returns height of object graphic in tiles
-	virtual bool visitableAt(int x, int y) const; //returns true if object is visitable at location (x, y) (h3m pos)
-	virtual int3 getVisitableOffset() const; //returns (x,y,0) offset to first visitable tile from bottom right obj tile (0,0,0) (h3m pos)
+	bool visitableAt(int x, int y) const; //returns true if object is visitable at location (x, y) (h3m pos)
 	int3 visitablePos() const;
 	bool blockingAt(int x, int y) const; //returns true if object is blocking location (x, y) (h3m pos)
 	bool coveringAt(int x, int y) const; //returns true if object covers with picture location (x, y) (h3m pos)
 	std::set<int3> getBlockedPos() const; //returns set of positions blocked by this object
 	std::set<int3> getBlockedOffsets() const; //returns set of relative positions blocked by this object
 	bool isVisitable() const; //returns true if object is visitable
-	bool operator<(const CGObjectInstance & cmp) const;  //screen printing priority comparing
+
+	/// HELPERS THAT SHOULD BE REMOVED ///
+
+	/// fills set with tiles which are visible from this object. TODO: remove?
+	void getSightTiles(std::unordered_set<int3, ShashInt3> &tiles) const;
+	/// Hides tiles visible for any player but ours. TODO: move to callback/game state?
 	void hideTiles(PlayerColor ourplayer, int radius) const;
-	CGObjectInstance();
-	virtual ~CGObjectInstance();
-	//CGObjectInstance(const CGObjectInstance & right);
-	//CGObjectInstance& operator=(const CGObjectInstance & right);
-	virtual const std::string & getHoverText() const;
 
+	/// VIRTUAL METHODS ///
+
+	/// Returns true if player can pass through visitable tiles of this object
+	virtual bool passableFor(PlayerColor color) const;
+	/// Range of revealed map around this object, counting from getSightCenter()
+	virtual int getSightRadious() const;
+	/// returns (x,y,0) offset to a visitable tile of object
+	virtual int3 getVisitableOffset() const;
+	/// returns text visible in status bar
+	/// TODO: should accept selected hero as parameter and possibly - moved into object handler
+	virtual const std::string & getHoverText() const;
+	/// Called mostly during map randomization to turn random object into a regular one (e.g. "Random Monster" into "Pikeman")
 	virtual void setType(si32 ID, si32 subID);
 
-	///IObjectInterface
+	///IObjectInterface OVERRIDES
+
 	void initObj() override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
-	void setProperty(ui8 what, ui32 val) override;//synchr
-
-	friend class CGameHandler;
+	/// method for synchronous update. Note: For new properties classes should override setPropertyDer instead
+	void setProperty(ui8 what, ui32 val) override;
 
+	//friend class CGameHandler;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
@@ -146,9 +169,13 @@ public:
 		//definfo is handled by map serializer
 	}
 protected:
-	virtual void setPropertyDer(ui8 what, ui32 val);//synchr
+	/// virtual method that allows synchronously update object state on server and all clients
+	virtual void setPropertyDer(ui8 what, ui32 val);
 
+	/// Adds (visited) text if selected hero has visited object
+	/// TODO: remove?
 	void getNameVis(std::string &hname) const;
+	/// Gives dummy bonus from this object to hero. Can be used to track visited state
 	void giveDummyBonus(ObjectInstanceID heroID, ui8 duration = Bonus::ONE_DAY) const;
 };
 

+ 2 - 5
lib/mapObjects/CQuest.cpp

@@ -853,10 +853,7 @@ void CGBorderGate::onHeroVisit( const CGHeroInstance * h ) const //TODO: passabi
 	}
 }
 
-ui8 CGBorderGate::getPassableness() const
+bool CGBorderGate::passableFor(PlayerColor color) const
 {
-	ui8 ret = 0;
-	for (int i = 0; i < PlayerColor::PLAYER_LIMIT_I; i++)
-		ret |= wasMyColorVisited(PlayerColor(i))<<i;
-	return ret;
+	return wasMyColorVisited(color);
 }

+ 1 - 1
lib/mapObjects/CQuest.h

@@ -189,7 +189,7 @@ public:
 	CGBorderGate() : CGBorderGuard(){};
 	void onHeroVisit(const CGHeroInstance * h) const override;
 
-	ui8 getPassableness() const override;
+	bool passableFor(PlayerColor color) const override;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{

+ 8 - 9
lib/mapObjects/MiscObjects.cpp

@@ -1250,19 +1250,18 @@ void CGGarrison::onHeroVisit (const CGHeroInstance *h) const
 	cb->showGarrisonDialog(id, h->id, removableUnits);
 }
 
-ui8 CGGarrison::getPassableness() const
+bool CGGarrison::passableFor(PlayerColor player) const
 {
+	//FIXME: identical to same method in CGTownInstance
+
 	if ( !stacksCount() )//empty - anyone can visit
-		return GameConstants::ALL_PLAYERS;
+		return true;
 	if ( tempOwner == PlayerColor::NEUTRAL )//neutral guarded - no one can visit
-		return 0;
-
-	ui8 mask = 0;
-	TeamState * ts = cb->gameState()->getPlayerTeam(tempOwner);
-	for(PlayerColor it : ts->players)
-		mask |= 1<<it.getNum(); //allies - add to possible visitors
+		return false;
 
-	return mask;
+	if (cb->getPlayerRelations(tempOwner, player) != PlayerRelations::ENEMIES)
+		return true;
+	return false;
 }
 
 void CGGarrison::battleFinished(const CGHeroInstance *hero, const BattleResult &result) const

+ 1 - 1
lib/mapObjects/MiscObjects.h

@@ -138,7 +138,7 @@ class DLL_LINKAGE CGGarrison : public CArmedInstance
 public:
 	bool removableUnits;
 
-	ui8 getPassableness() const;
+	bool passableFor(PlayerColor color) const override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;