瀏覽代碼

Merge pull request #92 from Fayth/mantis-2104

Thanks!
DjWarmonger 10 年之前
父節點
當前提交
9427dacc5d
共有 2 個文件被更改,包括 29 次插入10 次删除
  1. 3 3
      client/CPlayerInterface.cpp
  2. 26 7
      client/mapHandler.cpp

+ 3 - 3
client/CPlayerInterface.cpp

@@ -205,7 +205,7 @@ STRONG_INLINE void subRect(const int & x, const int & y, const int & z, const SD
 {
 	TerrainTile2 & hlp = CGI->mh->ttiles[x][y][z];
 	for(auto & elem : hlp.objects)
-		if(elem.obj->id == hid)
+		if(elem.obj && elem.obj->id == hid)
 		{
 			elem.rect = r;
 			return;
@@ -216,7 +216,7 @@ STRONG_INLINE void delObjRect(const int & x, const int & y, const int & z, const
 {
 	TerrainTile2 & hlp = CGI->mh->ttiles[x][y][z];
 	for(int h=0; h<hlp.objects.size(); ++h)
-		if(hlp.objects[h].obj->id == hid)
+		if(hlp.objects[h].obj && hlp.objects[h].obj->id == hid)
 		{
 			hlp.objects.erase(hlp.objects.begin()+h);
 			return;
@@ -239,7 +239,7 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
 		// TODO -> we should not need full CGHeroInstance structure to display animation or it should not be handled by playerint (but by the client itself)
 		const TerrainTile2 &tile = CGI->mh->ttiles[hp.x-1][hp.y][hp.z];
 		for(auto & elem : tile.objects)
-			if(elem.obj->id == details.id)
+			if(elem.obj && elem.obj->id == details.id)
 				hero = dynamic_cast<const CGHeroInstance *>(elem.obj);
 
 		if(!hero) //still nothing...

+ 26 - 7
client/mapHandler.cpp

@@ -812,9 +812,17 @@ void CMapHandler::CMapBlitter::drawObjects(SDL_Surface * targetSurf, const Terra
 				fade->draw(targetSurf, nullptr, &r2);
 				continue;
 			}
+			logGlobal->errorStream() << "Fading map object with missing fade anim : " << object.fadeAnimKey;
+			continue;
 		}
 		
 		const CGObjectInstance * obj = object.obj;
+		if (!obj)
+		{
+			logGlobal->errorStream() << "Stray map object that isn't fading";
+			continue;
+		}
+		
 		if (!graphics->getDef(obj))
 			processDef(obj->appearance);
 		if (!graphics->getDef(obj) && !obj->appearance.animationFile.empty())
@@ -1176,6 +1184,7 @@ bool CMapHandler::updateObjectsFade()
 			{
 				if ((*objIter).fadeAnimKey == (*iter).first)
 				{						
+					logAnim->traceStream() << "Fade anim finished for obj at " << pos << "; remaining: " << (fadeAnims.size() - 1);
 					if (anim->fadingMode == CFadeAnimation::EMode::OUT)
 						objs.erase(objIter); // if this was fadeout, remove the object from the map
 					else
@@ -1184,7 +1193,6 @@ bool CMapHandler::updateObjectsFade()
 				}
 			}
 			iter = fadeAnims.erase(iter);
-			logAnim->traceStream() << "Fade anim finished, remaining: " << fadeAnims.size();
 		}
 	}
 	
@@ -1194,6 +1202,7 @@ bool CMapHandler::updateObjectsFade()
 bool CMapHandler::startObjectFade(TerrainTileObject & obj, bool in, int3 pos)
 {
 	SDL_Surface * fadeBitmap;
+	assert(obj.obj);
 	
 	auto objData = normalBlitter->findObjectBitmap(obj.obj, 0);
 	if (objData.objBitmap)
@@ -1219,6 +1228,9 @@ bool CMapHandler::startObjectFade(TerrainTileObject & obj, bool in, int3 pos)
 		anim->init(in ? CFadeAnimation::EMode::IN : CFadeAnimation::EMode::OUT, fadeBitmap, true);
 		fadeAnims[++fadeAnimCounter] = std::pair<int3, CFadeAnimation*>(pos, anim);
 		obj.fadeAnimKey = fadeAnimCounter;
+		
+		logAnim->traceStream() << "Fade anim started for obj " << obj.obj->ID 
+							   << " at " << pos << "; anim count: " << fadeAnims.size();
 		return true;
 	}
 	
@@ -1284,17 +1296,20 @@ bool CMapHandler::hideObject(const CGObjectInstance *obj, bool fadeout /* = fals
 		{
 			for (size_t k=0; k<(map->twoLevel ? 2 : 1); k++)
 			{
-				for(size_t x=0; x < ttiles[i][j][k].objects.size(); x++)
+				auto &objs = ttiles[i][j][k].objects;
+				for(size_t x=0; x < objs.size(); x++)
 				{
-					if (ttiles[i][j][k].objects[x].obj->id == obj->id)
+					if (objs[x].obj && objs[x].obj->id == obj->id)
 					{
 						if (fadeout && ADVOPT.objectFading) // object should be faded == erase is delayed until the end of fadeout
 						{
-							if (!startObjectFade(ttiles[i][j][k].objects[x], false, int3(i, j, k)))
-								ttiles[i][j][k].objects.erase(ttiles[i][j][k].objects.begin() + x);
+							if (startObjectFade(objs[x], false, int3(i, j, k)))
+								objs[x].obj = nullptr;
+							else
+								objs.erase(objs.begin() + x);
 						}
 						else
-							ttiles[i][j][k].objects.erase(ttiles[i][j][k].objects.begin() + x);
+							objs.erase(objs.begin() + x);
 						break;
 					}
 				}
@@ -1474,7 +1489,7 @@ void CMapHandler::getTerrainDescr( const int3 &pos, std::string & out, bool terN
 	const TerrainTile &t = map->getTile(pos);
 	for(auto & elem : tt.objects)
 	{
-		if(elem.obj->ID == Obj::HOLE) //Hole
+		if(elem.obj && elem.obj->ID == Obj::HOLE) //Hole
 		{
 			out = elem.obj->getObjectName();
 			return;
@@ -1567,6 +1582,10 @@ TerrainTile2::TerrainTile2()
 
 bool CMapHandler::compareObjectBlitOrder(const CGObjectInstance * a, const CGObjectInstance * b)
 {
+	if (!a)
+		return true;
+	if (!b)
+		return false;
 	if (a->appearance.printPriority != b->appearance.printPriority)
 		return a->appearance.printPriority > b->appearance.printPriority;