瀏覽代碼

Fixed crash on opening thieves guild window when player has no heroes.
Fixed #384, #385, maybe #381

Michał W. Urbańczyk 15 年之前
父節點
當前提交
d7ba3571bd
共有 6 個文件被更改,包括 32 次插入17 次删除
  1. 4 0
      client/CPlayerInterface.cpp
  2. 8 10
      client/GUIBase.cpp
  3. 4 2
      client/GUIClasses.cpp
  4. 1 0
      hch/CLodHandler.cpp
  5. 8 3
      lib/CGameState.cpp
  6. 7 2
      mapHandler.cpp

+ 4 - 0
client/CPlayerInterface.cpp

@@ -169,6 +169,7 @@ void CPlayerInterface::yourTurn()
 
 		LOCPLINT = this;
 		GH.curInt = this;
+		adventureInt->selection = NULL;
 
 		if(firstCall)
 		{
@@ -1060,8 +1061,11 @@ bool CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path )
 
 		int3 endpos(path.nodes[i-1].coord.x, path.nodes[i-1].coord.y, h->pos.z);
 		cb->moveHero(h,endpos);
+
+		eventsM.unlock();
 		while(stillMoveHero.data != STOP_MOVE  &&  stillMoveHero.data != CONTINUE_MOVE)
 			stillMoveHero.cond.wait(un);
+		eventsM.lock();
 	}
 
 	CGI->soundh->stopSound(sh);

+ 8 - 10
client/GUIBase.cpp

@@ -123,17 +123,15 @@ void CGuiHandler::handleEvents()
 	while(true)
 	{
 		SDL_Event *ev = NULL;
+		boost::unique_lock<boost::mutex> lock(eventsM);
+		if(!events.size())
 		{
-			boost::unique_lock<boost::mutex> lock(eventsM);
-			if(!events.size())
-			{
-				return;
-			}
-			else
-			{
-				ev = events.front();
-				events.pop();
-			}
+			return;
+		}
+		else
+		{
+			ev = events.front();
+			events.pop();
 		}
 		handleEvent(ev);
 		delete ev;

+ 4 - 2
client/GUIClasses.cpp

@@ -5010,7 +5010,8 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner)
 	int counter = 0;
 	for(std::map<ui8, InfoAboutHero>::const_iterator it = tgi.colorToBestHero.begin(); it !=  tgi.colorToBestHero.end(); ++it)
 	{
-		blitAt(graphics->portraitSmall[it->second.portrait], 260 + 66 * counter, 360, background);
+		if(it->second.portrait >= 0)
+			blitAt(graphics->portraitSmall[it->second.portrait], 260 + 66 * counter, 360, background);
 		counter++;
 
 		//printing stats
@@ -5031,7 +5032,8 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner)
 	counter = 0;
 	for(std::map<ui8, si32>::const_iterator it = tgi.bestCreature.begin(); it !=  tgi.bestCreature.end(); ++it)
 	{
-		blitAt(graphics->bigImgs[it->second], 255 + 66 * counter, 479, background);
+		if(it->second >= 0)
+			blitAt(graphics->bigImgs[it->second], 255 + 66 * counter, 479, background);
 		counter++;
 	}
 

+ 1 - 0
hch/CLodHandler.cpp

@@ -51,6 +51,7 @@ char readChar(const unsigned char * bufor, int &i)
 std::string readString(const unsigned char * bufor, int &i)
 {					
 	int len = readNormalNr(bufor,i); i+=4;
+	assert(len >= 0 && len <= 500000); //not too long
 	std::string ret; ret.reserve(len);
 	for(int gg=0; gg<len; ++gg)
 	{

+ 8 - 3
lib/CGameState.cpp

@@ -3163,16 +3163,19 @@ struct statsHLP
 
 	static const CGHeroInstance * findBestHero(CGameState * gs, int color)
 	{
+		std::vector<CGHeroInstance *> &h = gs->players[color].heroes;
+		if(!h.size())
+			return NULL;
 		//best hero will be that with highest exp
 		int best = 0;
-		for(int b=1; b<gs->players[color].heroes.size(); ++b)
+		for(int b=1; b<h.size(); ++b)
 		{
-			if(gs->players[color].heroes[b]->exp > gs->players[color].heroes[best]->exp)
+			if(h[b]->exp > h[best]->exp)
 			{
 				best = b;
 			}
 		}
-		return gs->players[color].heroes[best];
+		return h[best];
 	}
 
 	//calculates total number of artifacts that belong to given player
@@ -3726,6 +3729,8 @@ InfoAboutHero::~InfoAboutHero()
 
 void InfoAboutHero::initFromHero( const CGHeroInstance *h, bool detailed )
 {
+	if(!h) return;
+
 	owner = h->tempOwner;
 	hclass = h->type->heroClass;
 	name = h->name;

+ 7 - 2
mapHandler.cpp

@@ -1101,16 +1101,21 @@ bool CMapHandler::printObject(const CGObjectInstance *obj)
 			if((obj->pos.x + fx - bitmap->w/32+1)>=0 && (obj->pos.x + fx - bitmap->w/32+1)<ttiles.size()-frameW && (obj->pos.y + fy - bitmap->h/32+1)>=0 && (obj->pos.y + fy - bitmap->h/32+1)<ttiles[0].size()-frameH)
 			{
 				TerrainTile2 & curt = ttiles[obj->pos.x + fx - bitmap->w/32+1][obj->pos.y + fy - bitmap->h/32+1][obj->pos.z];
-				for(std::vector< std::pair<const CGObjectInstance*,SDL_Rect> >::iterator i = curt.objects.begin(); i != curt.objects.end(); i++)
+
+				std::vector< std::pair<const CGObjectInstance*,SDL_Rect> >::iterator i = curt.objects.begin();
+				for(; i != curt.objects.end(); i++)
 				{
 					OCM_HLP cmp;
 					if(cmp(toAdd, *i))
 					{
 						curt.objects.insert(i, toAdd);
-						//curt.objects.push_back(toAdd)
+						i = curt.objects.begin(); //to validate and avoid adding it second time
 						break;
 					}
 				}
+
+				if(i == curt.objects.end())
+					curt.objects.insert(i, toAdd);
 			}
 
 		} // for(int fy=0; fy<bitmap->h/32; ++fy)