Browse Source

* fixed crash when there was no sabegames in Games/ subfolder
* fixed crash when loading map with a mine belonging to human player
* fixed crash on moving hero into town garrison
* fixed r-click infowindow for towns
* new sight radious calculation. Works as OH3 for heroes, towns and probably all objects. (to be tested)

Michał W. Urbańczyk 16 years ago
parent
commit
d6283fd1ca

+ 2 - 2
CAdvmapInterface.cpp

@@ -468,9 +468,9 @@ void CTerrainRect::clickRight(tribool down)
 		}
 	case 98:
 		{
-			if(!vstd::contains(graphics->townWins,obj->subID))
+			if(!vstd::contains(graphics->townWins,obj->id))
 			{
-				tlog3 << "Warning - no infowin for town " << obj->subID << std::endl;
+				tlog3 << "Warning - no infowin for town " << obj->id << std::endl;
 				break;
 			}
 			CInfoPopup * ip = new CInfoPopup(graphics->townWins[obj->id],

+ 1 - 1
CCallback.cpp

@@ -601,7 +601,7 @@ bool CCallback::battleCanShoot(int ID, int dest)
 void CCallback::swapGarrisonHero( const CGTownInstance *town )
 {
 	if(town->tempOwner != player) return;
-	*cl->serv << ui16(508) << si32(town->id);
+	*cl->serv << &GarrisonHeroSwap(town->id);
 }
 
 void CCallback::buyArtifact(const CGHeroInstance *hero, int aid)

+ 52 - 45
CGameState.cpp

@@ -997,20 +997,39 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
 			for(int h=0; h<map->height; ++h)
 				for(int v=0; v<map->twoLevel+1; ++v)
 					k->second.fogOfWarMap[g][h][v] = 0;
-		for(int xd=0; xd<map->width; ++xd) //revealing part of map around heroes
+
+		BOOST_FOREACH(CGObjectInstance *obj, map->objects)
 		{
-			for(int yd=0; yd<map->height; ++yd)
+			if(obj->tempOwner != k->first) continue; //not a flagged object
+
+			int3 objCenter = obj->getSightCenter();
+			int radious = obj->getSightRadious();
+
+			for (int xd = std::max<int>(objCenter.x - radious , 0); xd <= std::min<int>(objCenter.x + radious, map->width - 1); xd++)
 			{
-				for(int ch=0; ch<k->second.heroes.size(); ++ch)
+				for (int yd = std::max<int>(objCenter.y - radious, 0); yd <= std::min<int>(objCenter.y + radious, map->height - 1); yd++)
 				{
-					int deltaX = (k->second.heroes[ch]->getPosition(false).x-xd)*(k->second.heroes[ch]->getPosition(false).x-xd);
-					int deltaY = (k->second.heroes[ch]->getPosition(false).y-yd)*(k->second.heroes[ch]->getPosition(false).y-yd);
-					if(deltaX+deltaY<k->second.heroes[ch]->getSightDistance()*k->second.heroes[ch]->getSightDistance())
-						k->second.fogOfWarMap[xd][yd][k->second.heroes[ch]->getPosition(false).z] = 1;
+					double distance = objCenter.dist2d(int3(xd,yd,objCenter.z)) - 0.5;
+					if(distance <= radious)
+						k->second.fogOfWarMap[xd][yd][objCenter.z] = 1;
 				}
 			}
 		}
 
+		//for(int xd=0; xd<map->width; ++xd) //revealing part of map around heroes
+		//{
+		//	for(int yd=0; yd<map->height; ++yd)
+		//	{
+		//		for(int ch=0; ch<k->second.heroes.size(); ++ch)
+		//		{
+		//			int deltaX = (k->second.heroes[ch]->getPosition(false).x-xd)*(k->second.heroes[ch]->getPosition(false).x-xd);
+		//			int deltaY = (k->second.heroes[ch]->getPosition(false).y-yd)*(k->second.heroes[ch]->getPosition(false).y-yd);
+		//			if(deltaX+deltaY<k->second.heroes[ch]->getSightDistance()*k->second.heroes[ch]->getSightDistance())
+		//				k->second.fogOfWarMap[xd][yd][k->second.heroes[ch]->getPosition(false).z] = 1;
+		//		}
+		//	}
+		//}
+
 		//starting bonus
 		if(si->playerInfos[k->second.serial].bonus==brandom)
 			si->playerInfos[k->second.serial].bonus = ran()%3;
@@ -1125,19 +1144,19 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
 	{
 		if(k->first==-1 || k->first==255)
 			continue;
-		for(int xd=0; xd<map->width; ++xd) //revealing part of map around towns
-		{
-			for(int yd=0; yd<map->height; ++yd)
-			{
-				for(int ch=0; ch<k->second.towns.size(); ++ch)
-				{
-					int deltaX = (k->second.towns[ch]->pos.x-xd)*(k->second.towns[ch]->pos.x-xd);
-					int deltaY = (k->second.towns[ch]->pos.y-yd)*(k->second.towns[ch]->pos.y-yd);
-					if(deltaX+deltaY<k->second.towns[ch]->getSightDistance()*k->second.towns[ch]->getSightDistance())
-						k->second.fogOfWarMap[xd][yd][k->second.towns[ch]->pos.z] = 1;
-				}
-			}
-		}
+	//	for(int xd=0; xd<map->width; ++xd) //revealing part of map around towns
+	//	{
+	//		for(int yd=0; yd<map->height; ++yd)
+	//		{
+	//			for(int ch=0; ch<k->second.towns.size(); ++ch)
+	//			{
+	//				int deltaX = (k->second.towns[ch]->pos.x-xd)*(k->second.towns[ch]->pos.x-xd);
+	//				int deltaY = (k->second.towns[ch]->pos.y-yd)*(k->second.towns[ch]->pos.y-yd);
+	//				if(deltaX+deltaY<k->second.towns[ch]->getSightDistance()*k->second.towns[ch]->getSightDistance())
+	//					k->second.fogOfWarMap[xd][yd][k->second.towns[ch]->pos.z] = 1;
+	//			}
+	//		}
+	//	}
 
 		//init visiting and garrisoned heroes
 		for(int l=0; l<k->second.heroes.size();l++)
@@ -1307,33 +1326,21 @@ float CGameState::getMarketEfficiency( int player, int mode/*=0*/ )
 }
 
 std::set<int3> CGameState::tilesToReveal(int3 pos, int radious, int player) const
-{		
+{
 	std::set<int3> ret;
-	int xbeg = pos.x - radious - 2;
-	if(xbeg < 0)
-		xbeg = 0;
-	int xend = pos.x + radious + 2;
-	if(xend >= map->width)
-		xend = map->width;
-	int ybeg = pos.y - radious - 2;
-	if(ybeg < 0)
-		ybeg = 0;
-	int yend = pos.y + radious + 2;
-	if(yend >= map->height)
-		yend = map->height;
-	for(int xd=xbeg; xd<xend; ++xd) //revealing part of map around heroes
-	{
-		for(int yd=ybeg; yd<yend; ++yd)
+	if(player >= PLAYER_LIMIT)
+	{
+		tlog1 << "Illegal call to tilesToReveal!\n";
+		return ret;
+	}
+
+	for (int xd = std::max<int>(pos.x - radious , 0); xd <= std::min<int>(pos.x + radious, map->width); xd++)
+	{
+		for (int yd = std::max<int>(pos.y - radious, 0); std::min<int>(yd <= pos.y + radious, map->height); yd++)
 		{
-			int deltaX = (pos.x-xd)*(pos.x-xd);
-			int deltaY = (pos.y-yd)*(pos.y-yd);
-			if(deltaX+deltaY<radious*radious)
-			{
-				if(player<0 || players.find(player)->second.fogOfWarMap[xd][yd][pos.z]==0)
-				{
-					ret.insert(int3(xd,yd,pos.z));
-				}
-			}
+			double distance = pos.dist2d(int3(xd,yd,pos.z)) - 0.5;
+			if(distance <= radious  &&  (player<0 || players.find(player)->second.fogOfWarMap[xd][yd][pos.z]==0))
+				ret.insert(int3(xd,yd,pos.z));
 		}
 	}
 	return ret;

+ 2 - 0
CPlayerInterface.cpp

@@ -1943,6 +1943,8 @@ void CPlayerInterface::heroMovePointsChanged(const CGHeroInstance * hero)
 void CPlayerInterface::receivedResource(int type, int val)
 {
 	boost::unique_lock<boost::recursive_mutex> un(*pim);
+	if(!curint)
+		return;
 	if(curint==adventureInt  ||  screen->h > 600  ||  screen->w > 800)
 		adventureInt->resdatabar.draw();
 	if(curint==castleInt && !curint->subInt)

+ 43 - 9
hch/CObjectHandler.cpp

@@ -139,14 +139,21 @@ int CGObjectInstance::getWidth() const//returns width of object graphic in tiles
 }
 int CGObjectInstance::getHeight() const //returns height of object graphic in tiles
 {
-	return defInfo->width;
+	return defInfo->height;
 }
 bool CGObjectInstance::visitableAt(int x, int y) const //returns true if object is visitable at location (x, y) form left top tile of image (x, y in tiles)
 {
-	if(x<0 || y<0 || x>=getWidth() || y>=getHeight() || defInfo==NULL)
+	if(defInfo==NULL)
+	{
+		tlog2 << "Warning: VisitableAt for obj "<<id<<": NULL defInfo!\n";
 		return false;
-	if((defInfo->visitMap[y+6-getHeight()] >> (7-(8-getWidth()+x) )) & 1)
+	}
+
+	if((defInfo->visitMap[y] >> (7-x) ) & 1)
+	{
 		return true;
+	}
+
 	return false;
 }
 bool CGObjectInstance::blockingAt(int x, int y) const
@@ -204,6 +211,21 @@ void CGObjectInstance::setProperty( ui8 what, ui32 val )
 void CGObjectInstance::setPropertyDer( ui8 what, ui32 val )
 {}
 
+int3 CGObjectInstance::getSightCenter() const
+{
+	//return vistiable tile if possible
+	for(int i=0; i < 8; i++)
+		for(int j=0; j < 6; j++)
+			if(visitableAt(i,j))
+				return(pos + int3(i-7, j-5, 0));
+	return pos;
+}
+
+int CGObjectInstance::getSightRadious() const
+{
+	return 3;
+}
+
 int lowestSpeed(const CGHeroInstance * chi)
 {
 	if(!chi->army.slots.size())
@@ -288,10 +310,6 @@ int3 CGHeroInstance::getPosition(bool h3m) const //h3m=true - returns position o
 		return convertPosition(pos,false);
 	}
 }
-int CGHeroInstance::getSightDistance() const //returns sight distance of this hero
-{
-	return 5 + getSecSkillLevel(3); //default + scouting
-}
 
 si32 CGHeroInstance::manaLimit() const
 {
@@ -729,9 +747,20 @@ void CGHeroInstance::setPropertyDer( ui8 what, ui32 val )
 	if(what == 3)
 		army.slots[0].second = val;
 }
-int CGTownInstance::getSightDistance() const //returns sight distance
+
+int3 CGHeroInstance::getSightCenter() const
+{
+	return getPosition(false);
+}
+
+int CGHeroInstance::getSightRadious() const
+{
+	return 5 + getSecSkillLevel(3); //default + scouting
+}
+
+int CGTownInstance::getSightRadious() const //returns sight distance
 {
-	return 10;
+	return 5;
 }
 int CGTownInstance::fortLevel() const //0 - none, 1 - fort, 2 - citadel, 3 - castle
 {
@@ -870,6 +899,11 @@ void CGTownInstance::initObj()
 	hoverName = toString(ms);
 }
 
+int3 CGTownInstance::getSightCenter() const
+{
+	return pos - int3(2,0,0);
+}
+
 void CGVisitableOPH::onHeroVisit( const CGHeroInstance * h ) const
 {
 	if(visitors.find(h->id)==visitors.end())

+ 10 - 2
hch/CObjectHandler.h

@@ -107,6 +107,8 @@ public:
 	ui8 tempOwner;
 	ui8 blockVisit; //if non-zero then blocks the tile but is visitable from neighbouring tile
 
+	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)
 	int getOwner() const;
 	void setOwner(int ow);
 	int getWidth() const; //returns width of object graphic in tiles
@@ -206,6 +208,10 @@ public:
 			type = VLC->heroh->heroes[subID];
 		//visitied town pointer will be restored by map serialization method
 	}
+	//////////////////////////////////////////////////////////////////////////
+
+	int3 getSightCenter() const; //"center" tile from which the sight distance is calculated
+	int getSightRadious() const; //sight distance (should be used if player-owned structure)
 
 	//////////////////////////////////////////////////////////////////////////
 	const HeroBonus *getBonus(int from, int id) const;
@@ -216,7 +222,6 @@ public:
 	unsigned int getAdditiveMoveBonus() const;
 	float getMultiplicativeMoveBonus() const;
 	int3 getPosition(bool h3m) const; //h3m=true - returns position of hero object; h3m=false - returns position of hero 'manifestation'
-	int getSightDistance() const; //returns sight distance of this hero
 	si32 manaLimit() const; //maximum mana value for this hero (basically 10*knowledge)
 	bool canWalkOnSea() const;
 	int getCurrentLuck(int stack=-1, bool town=false) const;
@@ -294,9 +299,12 @@ public:
 
 	//////////////////////////////////////////////////////////////////////////
 
+	int3 getSightCenter() const; //"center" tile from which the sight distance is calculated
+	int getSightRadious() const; //returns sight distance
+
+	//////////////////////////////////////////////////////////////////////////
 
 	bool needsLastStack() const;
-	int getSightDistance() const; //returns sight distance
 	int fortLevel() const; //0 - none, 1 - fort, 2 - citadel, 3 - castle
 	int hallLevel() const; // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol
 	int mageGuildLevel() const; // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol

+ 1 - 1
lib/Connection.cpp

@@ -197,7 +197,7 @@ int CLoadFile::read( const void * data, unsigned size )
 
 CTypeList::CTypeList()
 {
-
+	registerTypes(*this);
 }
 
 ui16 CTypeList::registerType( const type_info *type )

+ 2 - 2
lib/Connection.h

@@ -56,7 +56,7 @@ enum SerializationLvl
 
 struct TypeComparer
 {
-	bool operator()(const type_info *a, const type_info *b)
+	bool operator()(const type_info *a, const type_info *b) const
 	{
 		return a->before(*b);
 	}
@@ -69,7 +69,7 @@ class DLL_EXPORT CTypeList
 public:
 	CTypeList();
 	ui16 registerType(const type_info *type);
-	template <typename T> ui16 registerType(const T * t)
+	template <typename T> ui16 registerType(const T * t = NULL)
 	{
 		return registerType(getTypeInfo(t));
 	}

+ 1 - 0
lib/RegisterTypes.cpp

@@ -16,4 +16,5 @@ void foofoofoo()
 	registerTypes((COSer<CConnection>&)*ccc);
 	registerTypes((CSaveFile&)*ccc);
 	registerTypes((CLoadFile&)*ccc);
+	registerTypes((CTypeList&)*ccc);
 }

+ 2 - 2
lib/VCMI_lib.vcproj

@@ -140,7 +140,7 @@
 				Name="VCLinkerTool"
 				AdditionalDependencies="zdll.lib"
 				Version=""
-				AdditionalLibraryDirectories=""
+				AdditionalLibraryDirectories="../../libs;"
 				GenerateDebugInformation="false"
 				OptimizeReferences="2"
 				EnableCOMDATFolding="2"
@@ -225,7 +225,7 @@
 				Name="VCLinkerTool"
 				AdditionalDependencies="zdll.lib"
 				Version=""
-				AdditionalLibraryDirectories=""
+				AdditionalLibraryDirectories="../../libs;"
 				GenerateDebugInformation="true"
 				GenerateMapFile="true"
 				OptimizeReferences="2"

+ 2 - 2
server/CGameHandler.cpp

@@ -1229,7 +1229,7 @@ void CGameHandler::moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker)
 			{
 				obj->onHeroLeave(h);
 			}
-			tmh.fowRevealed = gs->tilesToReveal(h->convertPosition(dst,false),h->getSightDistance(),h->tempOwner);
+			tmh.fowRevealed = gs->tilesToReveal(h->getSightCenter()+(tmh.end-tmh.start),h->getSightRadious(),h->tempOwner);
 			sendAndApply(&tmh);
 			tlog5 << "Moved to " <<tmh.end<<std::endl;
 
@@ -1256,7 +1256,7 @@ void CGameHandler::moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker)
 			}
 		}
 		tmh.result = instant+1;
-		tmh.fowRevealed = gs->tilesToReveal(h->convertPosition(dst,false),h->getSightDistance(),h->tempOwner);
+		tmh.fowRevealed = gs->tilesToReveal(h->getSightCenter()+(tmh.end-tmh.start),h->getSightRadious(),h->tempOwner);
 		sendAndApply(&tmh);
 	}
 }