ソースを参照

* 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 年 前
コミット
4ba26635b6
3 ファイル変更39 行追加20 行削除
  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_SetClipRect(to, &pos);
 
-	//showing obstacles
+	//preparing obstacles to be shown
 	std::vector<CObstacleInstance> obstacles = LOCPLINT->cb->battleGetAllObstacles();
+	std::multimap<int, int> hexToObstacle;
 	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...
 	std::vector<int> stackAliveByHex[BFIELD_SIZE];
 	//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);
 		}
 
+		//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);
 	}
 	//units shown
+
+	//showing hero animations
+	if(attackingHero)
+		attackingHero->show(to);
+	if(defendingHero)
+		defendingHero->show(to);
+
 	projectileShowHelper(to);//showing projectiles
 
 	//showing spell effects
@@ -2734,8 +2748,6 @@ void CBattleInterface::showAliveStack(int ID, const std::map<int, CStack> & stac
 	int affectingSpeed = LOCPLINT->sysOpts.animSpeed;
 	if(animType == 1 || animType == 2) //standing stacks should not stand faster :)
 		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;
 
 	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!");
 }
 
-int CObstacleInfo::getWidth()
+int CObstacleInfo::getWidth() const
 {
 	int ret = 1;
 	int line = 1;
@@ -67,7 +67,7 @@ int CObstacleInfo::getWidth()
 	return ret;
 }
 
-int CObstacleInfo::getHeight()
+int CObstacleInfo::getHeight() const
 {
 	int ret = 1;
 	for(int h=0; h<blockmap.size(); ++h)
@@ -80,7 +80,7 @@ int CObstacleInfo::getHeight()
 	return ret;
 }
 
-std::vector<int> CObstacleInfo::getBlocked(int hex)
+std::vector<int> CObstacleInfo::getBlocked(int hex) const
 {
 	std::vector<int> ret;
 	int cur = hex; //currently browsed hex
@@ -113,6 +113,12 @@ std::vector<int> CObstacleInfo::getBlocked(int hex)
 	return ret;
 }
 
+int CObstacleInfo::getMaxBlocked(int hex) const
+{
+	std::vector<int> blocked = getBlocked(hex);
+	return *std::max_element(blocked.begin(), blocked.end());
+}
+
 CHeroHandler::~CHeroHandler()
 {
 	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 
 			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
-	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)
 	{
 		h & ID & defName & blockmap & allowedTerrains & posShift;