Pārlūkot izejas kodu

* hero in siege won't be blitted below wall
* obstacles and units should be printed in better order (not tested)
* animations of attack and defense will follow general speed of animations

mateuszb 16 gadi atpakaļ
vecāks
revīzija
4ba26635b6
3 mainītis faili ar 39 papildinājumiem un 20 dzēšanām
  1. 26 14
      client/CBattleInterface.cpp
  2. 9 3
      hch/CHeroHandler.cpp
  3. 4 3
      hch/CHeroHandler.h

+ 26 - 14
client/CBattleInterface.cpp

@@ -1495,23 +1495,15 @@ void CBattleInterface::show(SDL_Surface * to)
 	SDL_GetClipRect(to, &buf);
 	SDL_GetClipRect(to, &buf);
 	SDL_SetClipRect(to, &pos);
 	SDL_SetClipRect(to, &pos);
 
 
-	//showing obstacles
+	//preparing obstacles to be shown
 	std::vector<CObstacleInstance> obstacles = LOCPLINT->cb->battleGetAllObstacles();
 	std::vector<CObstacleInstance> obstacles = LOCPLINT->cb->battleGetAllObstacles();
+	std::multimap<int, int> hexToObstacle;
 	for(int b=0; b<obstacles.size(); ++b)
 	for(int b=0; b<obstacles.size(); ++b)
 	{
 	{
-		std::pair<si16, si16> shift = CGI->heroh->obstacles[obstacles[b].ID].posShift;
-		int x = ((obstacles[b].pos/BFIELD_WIDTH)%2==0 ? 22 : 0) + 44*(obstacles[b].pos%BFIELD_WIDTH) + pos.x + shift.first;
-		int y = 86 + 42 * (obstacles[b].pos/BFIELD_WIDTH) + pos.y + shift.second;
-		std::vector<Cimage> &images = idToObstacle[obstacles[b].ID]->ourImages; //reference to animation of obstacle
-		blitAt(images[((animCount+1)/(4/LOCPLINT->sysOpts.animSpeed))%images.size()].bitmap, x, y, to);
+		int position = CGI->heroh->obstacles[obstacles[b].ID].getMaxBlocked(obstacles[b].pos);
+		hexToObstacle.insert(std::make_pair(position, b));
 	}
 	}
 
 
-	//showing hero animations
-	if(attackingHero)
-		attackingHero->show(to);
-	if(defendingHero)
-		defendingHero->show(to);
-
 	////showing units //a lot of work...
 	////showing units //a lot of work...
 	std::vector<int> stackAliveByHex[BFIELD_SIZE];
 	std::vector<int> stackAliveByHex[BFIELD_SIZE];
 	//double loop because dead stacks should be printed first
 	//double loop because dead stacks should be printed first
@@ -1589,9 +1581,31 @@ void CBattleInterface::show(SDL_Surface * to)
 			showAliveStack(stackAliveByHex[b][v], stacks, to);
 			showAliveStack(stackAliveByHex[b][v], stacks, to);
 		}
 		}
 
 
+		//showing obstacles
+		std::pair<std::multimap<int, int>::const_iterator, std::multimap<int, int>::const_iterator> obstRange =
+			hexToObstacle.equal_range(b);
+
+		for(std::multimap<int, int>::const_iterator it = obstRange.first; it != obstRange.second; ++it)
+		{
+			CObstacleInstance & curOb = obstacles[it->second];
+			std::pair<si16, si16> shift = CGI->heroh->obstacles[curOb.ID].posShift;
+			int x = ((curOb.pos/BFIELD_WIDTH)%2==0 ? 22 : 0) + 44*(curOb.pos%BFIELD_WIDTH) + pos.x + shift.first;
+			int y = 86 + 42 * (curOb.pos/BFIELD_WIDTH) + pos.y + shift.second;
+			std::vector<Cimage> &images = idToObstacle[curOb.ID]->ourImages; //reference to animation of obstacle
+			blitAt(images[((animCount+1)/(4/LOCPLINT->sysOpts.animSpeed))%images.size()].bitmap, x, y, to);
+		}
+
+		//showing wall pieces
 		showPieceOfWall(to, b, stacks);
 		showPieceOfWall(to, b, stacks);
 	}
 	}
 	//units shown
 	//units shown
+
+	//showing hero animations
+	if(attackingHero)
+		attackingHero->show(to);
+	if(defendingHero)
+		defendingHero->show(to);
+
 	projectileShowHelper(to);//showing projectiles
 	projectileShowHelper(to);//showing projectiles
 
 
 	//showing spell effects
 	//showing spell effects
@@ -2734,8 +2748,6 @@ void CBattleInterface::showAliveStack(int ID, const std::map<int, CStack> & stac
 	int affectingSpeed = LOCPLINT->sysOpts.animSpeed;
 	int affectingSpeed = LOCPLINT->sysOpts.animSpeed;
 	if(animType == 1 || animType == 2) //standing stacks should not stand faster :)
 	if(animType == 1 || animType == 2) //standing stacks should not stand faster :)
 		affectingSpeed = 2;
 		affectingSpeed = 2;
-	if(animType == 3 || animType == 7 || animType == 8 || animType == 9 || animType == 10 || animType == 11 || animType == 12 || animType == 13) //defend & attack should be slower
-		affectingSpeed = 1;
 	bool incrementFrame = (animCount%(4/affectingSpeed)==0) && animType!=5 && animType!=20 && animType!=2;
 	bool incrementFrame = (animCount%(4/affectingSpeed)==0) && animType!=5 && animType!=20 && animType!=2;
 
 
 	if(animType == 2)
 	if(animType == 2)

+ 9 - 3
hch/CHeroHandler.cpp

@@ -45,7 +45,7 @@ int CHeroClass::chooseSecSkill(const std::set<int> & possibles) const //picks se
 	throw std::string("Cannot pick secondary skill!");
 	throw std::string("Cannot pick secondary skill!");
 }
 }
 
 
-int CObstacleInfo::getWidth()
+int CObstacleInfo::getWidth() const
 {
 {
 	int ret = 1;
 	int ret = 1;
 	int line = 1;
 	int line = 1;
@@ -67,7 +67,7 @@ int CObstacleInfo::getWidth()
 	return ret;
 	return ret;
 }
 }
 
 
-int CObstacleInfo::getHeight()
+int CObstacleInfo::getHeight() const
 {
 {
 	int ret = 1;
 	int ret = 1;
 	for(int h=0; h<blockmap.size(); ++h)
 	for(int h=0; h<blockmap.size(); ++h)
@@ -80,7 +80,7 @@ int CObstacleInfo::getHeight()
 	return ret;
 	return ret;
 }
 }
 
 
-std::vector<int> CObstacleInfo::getBlocked(int hex)
+std::vector<int> CObstacleInfo::getBlocked(int hex) const
 {
 {
 	std::vector<int> ret;
 	std::vector<int> ret;
 	int cur = hex; //currently browsed hex
 	int cur = hex; //currently browsed hex
@@ -113,6 +113,12 @@ std::vector<int> CObstacleInfo::getBlocked(int hex)
 	return ret;
 	return ret;
 }
 }
 
 
+int CObstacleInfo::getMaxBlocked(int hex) const
+{
+	std::vector<int> blocked = getBlocked(hex);
+	return *std::max_element(blocked.begin(), blocked.end());
+}
+
 CHeroHandler::~CHeroHandler()
 CHeroHandler::~CHeroHandler()
 {
 {
 	for (int i = 0; i < heroes.size(); i++)
 	for (int i = 0; i < heroes.size(); i++)

+ 4 - 3
hch/CHeroHandler.h

@@ -80,9 +80,10 @@ struct DLL_EXPORT CObstacleInfo
 			20. evil fog   21. "favourable winds" text on magic plains background   22. cursed ground   23. rough 
 			20. evil fog   21. "favourable winds" text on magic plains background   22. cursed ground   23. rough 
 			24. ship to ship   25. ship*/
 			24. ship to ship   25. ship*/
 	std::pair<si16, si16> posShift; //shift of obstacle's position in the battlefield <x shift, y shift>, eg. if it's <-1, 2> obstacle will be printed one pixel to the left and two to the bottom
 	std::pair<si16, si16> posShift; //shift of obstacle's position in the battlefield <x shift, y shift>, eg. if it's <-1, 2> obstacle will be printed one pixel to the left and two to the bottom
-	int getWidth(); //returns width of obstacle in hexes
-	int getHeight(); //returns height of obstacle in hexes
-	std::vector<int> getBlocked(int hex); //returns vector of hexes blocked by obstacle when it's placed on hex 'hex'
+	int getWidth() const; //returns width of obstacle in hexes
+	int getHeight() const; //returns height of obstacle in hexes
+	std::vector<int> getBlocked(int hex) const; //returns vector of hexes blocked by obstacle when it's placed on hex 'hex'
+	int getMaxBlocked(int hex) const; //returns maximal hex (max number) covered by this obstacle
 	template <typename Handler> void serialize(Handler &h, const int version)
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 	{
 		h & ID & defName & blockmap & allowedTerrains & posShift;
 		h & ID & defName & blockmap & allowedTerrains & posShift;