Browse Source

* updated project files for MSVC
* fixed a few includes paths
* it's possible to enter Tavern via Brotherhood of Sword
* fixes for statusbar
* fixes for townlist
* fixed crashes on building / clicking some buildings
* bumped version number to 0.71c
* bonuses from wearing more than one same artifact won't cumulate

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

+ 41 - 6
client/CCastleInterface.cpp

@@ -149,13 +149,16 @@ void CBuildingRect::clickRight (tribool down)
 		return;
 		return;
 	if((CSDL_Ext::SDL_GetPixel(area,LOCPLINT->current->motion.x-pos.x,LOCPLINT->current->motion.y-pos.y) != 0)) //na polu
 	if((CSDL_Ext::SDL_GetPixel(area,LOCPLINT->current->motion.x-pos.x,LOCPLINT->current->motion.y-pos.y) != 0)) //na polu
 	{
 	{
+		CBuilding *bld = CGI->buildh->buildings[str->townID][str->ID];
+		assert(bld);
+
 		CInfoPopup *vinya = new CInfoPopup();
 		CInfoPopup *vinya = new CInfoPopup();
 		vinya->free = true;
 		vinya->free = true;
 		vinya->bitmap = CMessage::drawBoxTextBitmapSub
 		vinya->bitmap = CMessage::drawBoxTextBitmapSub
 			(LOCPLINT->playerID,
 			(LOCPLINT->playerID,
-			CGI->buildh->buildings[str->townID][str->ID]->Description(),
+			bld->Description(),
 			LOCPLINT->castleInt->bicons->ourImages[str->ID].bitmap,
 			LOCPLINT->castleInt->bicons->ourImages[str->ID].bitmap,
-			CGI->buildh->buildings[str->townID][str->ID]->Name());
+			bld->Name());
 		vinya->pos.x = screen->w/2 - vinya->bitmap->w/2;
 		vinya->pos.x = screen->w/2 - vinya->bitmap->w/2;
 		vinya->pos.y = screen->h/2 - vinya->bitmap->h/2;
 		vinya->pos.y = screen->h/2 - vinya->bitmap->h/2;
 		LOCPLINT->pushInt(vinya);
 		LOCPLINT->pushInt(vinya);
@@ -551,11 +554,11 @@ void CCastleInterface::buildingClicked(int building)
 			}
 			}
 		case 5: //tavern
 		case 5: //tavern
 			{
 			{
-				std::vector<const CGHeroInstance*> h = LOCPLINT->cb->getAvailableHeroes(town);
-				CTavernWindow *tv = new CTavernWindow(h[0],h[1],"GOSSIP TEST");
-				LOCPLINT->pushInt(tv);
+				enterTavern();
+
 				break;
 				break;
 			}
 			}
+		//TODO: case 6: //shipyard
 		case 7: case 8: case 9: //fort/citadel/castle
 		case 7: case 8: case 9: //fort/citadel/castle
 			{
 			{
 				CFortScreen *fs = new CFortScreen(this);
 				CFortScreen *fs = new CFortScreen(this);
@@ -573,7 +576,7 @@ void CCastleInterface::buildingClicked(int building)
 			}
 			}
 		case 15: //resource silo
 		case 15: //resource silo
 			{
 			{
-				LOCPLINT->showInfoDialog(CGI->buildh->buildings[town->subID][15]->description,std::vector<SComponent*>(), soundBase::sound_todo);
+				LOCPLINT->showInfoDialog(CGI->buildh->buildings[town->subID][15]->Description(),std::vector<SComponent*>(), soundBase::sound_todo);
 				break;
 				break;
 			}
 			}
 		case 16: //blacksmith
 		case 16: //blacksmith
@@ -595,6 +598,29 @@ void CCastleInterface::buildingClicked(int building)
 				LOCPLINT->pushInt(new CBlacksmithDialog(possible,CArtHandler::convertMachineID(aid,false),aid,hero->id));
 				LOCPLINT->pushInt(new CBlacksmithDialog(possible,CArtHandler::convertMachineID(aid,false),aid,hero->id));
 				break;
 				break;
 			}
 			}
+		//TODO: case 17: //special 1
+		//TODO: case 18: //basic horde 1
+		//TODO: case 19: //upg horde 1
+		//TODO: case 20: //ship at shipyard
+		//TODO: case 21: //special 2
+		case 22: //special 3
+			{
+				switch(town->subID)
+				{
+				case 0: //brotherhood of sword
+					enterTavern();
+					break;
+
+				default:
+					tlog4<<"This building isn't handled...\n";
+					break;
+				}
+				break;
+			}
+		//TODO: case 23: //special 4
+		//TODO: case 24: //basic horde 2
+		//TODO: case 25: //upg horde 2
+		//TODO: case 26: //grail
 		default:
 		default:
 			tlog4<<"This building isn't handled...\n";
 			tlog4<<"This building isn't handled...\n";
 		}
 		}
@@ -907,6 +933,14 @@ void CCastleInterface::enterMageGuild()
 {
 {
 	LOCPLINT->pushInt(new CMageGuildScreen(this));
 	LOCPLINT->pushInt(new CMageGuildScreen(this));
 }
 }
+
+void CCastleInterface::enterTavern()
+{
+	std::vector<const CGHeroInstance*> h = LOCPLINT->cb->getAvailableHeroes(town);
+	CTavernWindow *tv = new CTavernWindow(h[0],h[1],"GOSSIP TEST");
+	LOCPLINT->pushInt(tv);
+}
+
 void CHallInterface::CBuildingBox::hover(bool on)
 void CHallInterface::CBuildingBox::hover(bool on)
 {
 {
 	Hoverable::hover(on);
 	Hoverable::hover(on);
@@ -1083,6 +1117,7 @@ void CHallInterface::close()
 void CHallInterface::show(SDL_Surface * to)
 void CHallInterface::show(SDL_Surface * to)
 {
 {
 	blitAt(bg,pos,to);
 	blitAt(bg,pos,to);
+	LOCPLINT->castleInt->statusbar->show(to);
 	resdatabar->show(to);
 	resdatabar->show(to);
 	exit->show(to);
 	exit->show(to);
 	for(int i=0; i<5; i++)
 	for(int i=0; i<5; i++)

+ 1 - 0
client/CCastleInterface.h

@@ -101,6 +101,7 @@ public:
 	void show(SDL_Surface * to);
 	void show(SDL_Surface * to);
 	void showAll(SDL_Surface * to);
 	void showAll(SDL_Surface * to);
 	void buildingClicked(int building);
 	void buildingClicked(int building);
+	void enterTavern();
 	void enterMageGuild();
 	void enterMageGuild();
 	CRecruitmentWindow * showRecruitmentWindow(int building);
 	CRecruitmentWindow * showRecruitmentWindow(int building);
 	void enterHall();
 	void enterHall();

+ 15 - 7
client/GUIClasses.cpp

@@ -630,6 +630,13 @@ CInfoPopup::CInfoPopup(SDL_Surface * Bitmap, int x, int y, bool Free)
 	pos.h = bitmap->h;
 	pos.h = bitmap->h;
 	pos.w = bitmap->w;
 	pos.w = bitmap->w;
 }
 }
+
+CInfoPopup::CInfoPopup(SDL_Surface *Bitmap, bool Free)
+{
+	free=Free;
+	bitmap=Bitmap;
+}
+
 void CInfoPopup::close()
 void CInfoPopup::close()
 {
 {
 	if(free)
 	if(free)
@@ -975,7 +982,7 @@ void CStatusBar::print(const std::string & text)
 	if(LOCPLINT->cingconsole->enteredText == "" || text == LOCPLINT->cingconsole->enteredText) //for appropriate support for in-game console
 	if(LOCPLINT->cingconsole->enteredText == "" || text == LOCPLINT->cingconsole->enteredText) //for appropriate support for in-game console
 	{
 	{
 		current=text;
 		current=text;
-		show(screen);
+		show(LOCPLINT->topInt()==LOCPLINT->adventureInt ? screen : screen2); //if there are now windows opened, update statusbar on screen, else to cache surface
 	}
 	}
 }
 }
 
 
@@ -1418,6 +1425,7 @@ void CTownList::mouseMoved (const SDL_MouseMotionEvent & sEvent)
 
 
 void CTownList::clickLeft(tribool down)
 void CTownList::clickLeft(tribool down)
 {
 {
+	SDL_Surface *dst = (LOCPLINT->topInt()==LOCPLINT->adventureInt ? screen : screen2);
 	if (down)
 	if (down)
 	{
 	{
 		/***************************ARROWS*****************************************/
 		/***************************ARROWS*****************************************/
@@ -1425,7 +1433,7 @@ void CTownList::clickLeft(tribool down)
 		{
 		{
 			if(from>0)
 			if(from>0)
 			{
 			{
-				blitAt(arrup->ourImages[1].bitmap,arrupp.x,arrupp.y);
+				blitAt(arrup->ourImages[1].bitmap,arrupp.x,arrupp.y,dst);
 				pressed = true;
 				pressed = true;
 			}
 			}
 			return;
 			return;
@@ -1434,7 +1442,7 @@ void CTownList::clickLeft(tribool down)
 		{
 		{
 			if(items.size()-from > SIZE)
 			if(items.size()-from > SIZE)
 			{
 			{
-				blitAt(arrdo->ourImages[1].bitmap,arrdop.x,arrdop.y);
+				blitAt(arrdo->ourImages[1].bitmap,arrdop.x,arrdop.y,dst);
 				pressed = false;
 				pressed = false;
 			}
 			}
 			return;
 			return;
@@ -1460,7 +1468,7 @@ void CTownList::clickLeft(tribool down)
 			return;
 			return;
 		if (pressed) //up
 		if (pressed) //up
 		{
 		{
-			blitAt(arrup->ourImages[0].bitmap,arrupp.x,arrupp.y);
+			blitAt(arrup->ourImages[0].bitmap,arrupp.x,arrupp.y,dst);
 			pressed = indeterminate;
 			pressed = indeterminate;
 			if (!down)
 			if (!down)
 			{
 			{
@@ -1468,12 +1476,12 @@ void CTownList::clickLeft(tribool down)
 				if (from<0)
 				if (from<0)
 					from=0;
 					from=0;
 
 
-				draw(screen2);
+				draw(dst);
 			}
 			}
 		}
 		}
 		else if (!pressed) //down
 		else if (!pressed) //down
 		{
 		{
-			blitAt(arrdo->ourImages[0].bitmap,arrdop.x,arrdop.y);
+			blitAt(arrdo->ourImages[0].bitmap,arrdop.x,arrdop.y,dst);
 			pressed = indeterminate;
 			pressed = indeterminate;
 			if (!down)
 			if (!down)
 			{
 			{
@@ -1481,7 +1489,7 @@ void CTownList::clickLeft(tribool down)
 				//if (from<items.size()-5)
 				//if (from<items.size()-5)
 				//	from=items.size()-5;
 				//	from=items.size()-5;
 
 
-				draw(screen2);
+				draw(dst);
 			}
 			}
 		}
 		}
 		else
 		else

+ 2 - 2
client/GUIClasses.h

@@ -107,10 +107,10 @@ class CInfoPopup : public CRClickPopup
 public:
 public:
 	bool free; //TODO: comment me
 	bool free; //TODO: comment me
 	SDL_Surface * bitmap; //popup background
 	SDL_Surface * bitmap; //popup background
-	CInfoPopup(SDL_Surface * Bitmap, int x, int y, bool Free=false); //c-tor
 	void close();
 	void close();
 	void show(SDL_Surface * to);
 	void show(SDL_Surface * to);
-	CInfoPopup(){free=false;bitmap=NULL;} //default c-tor
+	CInfoPopup(SDL_Surface * Bitmap, int x, int y, bool Free=false); //c-tor
+	CInfoPopup(SDL_Surface *Bitmap = NULL, bool Free = false); //default c-tor
 	~CInfoPopup(){}; //d-tor
 	~CInfoPopup(){}; //d-tor
 };
 };
 
 

+ 42 - 26
client/VCMI_client.vcproj

@@ -271,15 +271,15 @@
 			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
 			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
 			>
 			>
 			<File
 			<File
-				RelativePath="..\AdventureMapButton.cpp"
+				RelativePath=".\AdventureMapButton.cpp"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\CAdvmapInterface.cpp"
+				RelativePath=".\CAdvmapInterface.cpp"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\CBattleInterface.cpp"
+				RelativePath=".\CBattleInterface.cpp"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
@@ -291,7 +291,7 @@
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\CCastleInterface.cpp"
+				RelativePath=".\CCastleInterface.cpp"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
@@ -303,7 +303,7 @@
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\CCursorHandler.cpp"
+				RelativePath=".\CCursorHandler.cpp"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
@@ -311,7 +311,7 @@
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\CGameInfo.cpp"
+				RelativePath=".\CGameInfo.cpp"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
@@ -319,7 +319,7 @@
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\CHeroWindow.cpp"
+				RelativePath=".\CHeroWindow.cpp"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
@@ -327,11 +327,11 @@
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\CMessage.cpp"
+				RelativePath=".\CMessage.cpp"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\CMT.cpp"
+				RelativePath=".\CMT.cpp"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
@@ -339,11 +339,11 @@
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\CPlayerInterface.cpp"
+				RelativePath=".\CPlayerInterface.cpp"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\CPreGame.cpp"
+				RelativePath=".\CPreGame.cpp"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
@@ -362,6 +362,14 @@
 				RelativePath=".\Graphics.cpp"
 				RelativePath=".\Graphics.cpp"
 				>
 				>
 			</File>
 			</File>
+			<File
+				RelativePath=".\GUIBase.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\GUIClasses.cpp"
+				>
+			</File>
 			<File
 			<File
 				RelativePath="..\mapHandler.cpp"
 				RelativePath="..\mapHandler.cpp"
 				>
 				>
@@ -371,11 +379,11 @@
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\SDL_Extensions.cpp"
+				RelativePath=".\SDL_Extensions.cpp"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\SDL_framerate.cpp"
+				RelativePath=".\SDL_framerate.cpp"
 				>
 				>
 			</File>
 			</File>
 		</Filter>
 		</Filter>
@@ -385,7 +393,7 @@
 			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
 			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
 			>
 			>
 			<File
 			<File
-				RelativePath="..\AdventureMapButton.h"
+				RelativePath=".\AdventureMapButton.h"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
@@ -393,7 +401,7 @@
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\CAdvmapInterface.h"
+				RelativePath=".\CAdvmapInterface.h"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
@@ -405,7 +413,7 @@
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\CBattleInterface.h"
+				RelativePath=".\CBattleInterface.h"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
@@ -421,7 +429,7 @@
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\CCastleInterface.h"
+				RelativePath=".\CCastleInterface.h"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
@@ -433,7 +441,7 @@
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\CCursorHandler.h"
+				RelativePath=".\CCursorHandler.h"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
@@ -441,7 +449,7 @@
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\CGameInfo.h"
+				RelativePath=".\CGameInfo.h"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
@@ -453,7 +461,7 @@
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\CHeroWindow.h"
+				RelativePath=".\CHeroWindow.h"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
@@ -461,7 +469,7 @@
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\CMessage.h"
+				RelativePath=".\CMessage.h"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
@@ -477,11 +485,11 @@
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\CPlayerInterface.h"
+				RelativePath=".\CPlayerInterface.h"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\CPreGame.h"
+				RelativePath=".\CPreGame.h"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
@@ -509,11 +517,15 @@
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\int3.h"
+				RelativePath=".\GUIBase.h"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\map.h"
+				RelativePath=".\GUIClasses.h"
+				>
+			</File>
+			<File
+				RelativePath="..\int3.h"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
@@ -525,7 +537,11 @@
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\SDL_framerate.h"
+				RelativePath=".\SDL_Extensions.h"
+				>
+			</File>
+			<File
+				RelativePath=".\SDL_framerate.h"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File

+ 1 - 1
global.h

@@ -19,7 +19,7 @@ typedef boost::int8_t si8; //signed int 8 bits (1 byte)
 #define THC
 #define THC
 #endif
 #endif
 
 
-#define NAME_VER ("VCMI 0.71b")
+#define NAME_VER ("VCMI 0.71c")
 #define CONSOLE_LOGGING_LEVEL 5
 #define CONSOLE_LOGGING_LEVEL 5
 #define FILE_LOGGING_LEVEL 6
 #define FILE_LOGGING_LEVEL 6
 
 

+ 10 - 0
hch/CBuildingHandler.cpp

@@ -78,6 +78,10 @@ void CBuildingHandler::loadBuildings()
 		delete nb;
 		delete nb;
 	}
 	}
 
 
+	//create Grail entries
+	for(int i=0; i<F_NUMBER; i++)
+		buildings[i][26] = new CBuilding(i,26);
+
 	//reading 14 per faction dwellings
 	//reading 14 per faction dwellings
 	temp = readTo(buf,it,'\n');temp = readTo(buf,it,'\n');//dwellings - skip 2 lines
 	temp = readTo(buf,it,'\n');temp = readTo(buf,it,'\n');//dwellings - skip 2 lines
 	for(int i=0;i<F_NUMBER;i++)
 	for(int i=0;i<F_NUMBER;i++)
@@ -163,4 +167,10 @@ const std::string & CBuilding::Description()
 		return VLC->generaltexth->buildings[tid][bid].second;
 		return VLC->generaltexth->buildings[tid][bid].second;
 	tlog2 << "Warning: Cannot find description text for building " << bid << "for " << tid << "town.\n";
 	tlog2 << "Warning: Cannot find description text for building " << bid << "for " << tid << "town.\n";
 	return "";
 	return "";
+}
+
+CBuilding::CBuilding( int TID, int BID )
+{
+	tid = TID;
+	bid = BID;
 }
 }

+ 3 - 2
hch/CBuildingHandler.h

@@ -18,8 +18,8 @@
 class DLL_EXPORT CBuilding //a typical building encountered in every castle ;]
 class DLL_EXPORT CBuilding //a typical building encountered in every castle ;]
 {
 {
 public:
 public:
-	int tid, bid; //town ID and structure ID
-	std::vector<int> resources;
+	si32 tid, bid; //town ID and structure ID
+	std::vector<si32> resources;
 	std::string name;
 	std::string name;
 	std::string description;
 	std::string description;
 
 
@@ -30,6 +30,7 @@ public:
 	{
 	{
 		h & tid & bid & resources & name & description;
 		h & tid & bid & resources & name & description;
 	}
 	}
+	CBuilding(int TID = -1, int BID = -1);
 };
 };
 
 
 class DLL_EXPORT CBuildingHandler
 class DLL_EXPORT CBuildingHandler

+ 12 - 0
hch/CGeneralTextHandler.cpp

@@ -160,6 +160,18 @@ void CGeneralTextHandler::load()
 		}
 		}
 	}
 	}
 
 
+	//remove prceeding / trailing whitespaces nad quoation marks from buildings descriptions
+	for(std::map<int, std::map<int, std::pair<std::string, std::string> > >::iterator i = buildings.begin(); i != buildings.end(); i++)
+	{
+		for(std::map<int, std::pair<std::string, std::string> >::iterator j = i->second.begin(); j != i->second.end(); j++)
+		{
+			std::string &str = j->second.second;
+			boost::algorithm::trim(str);
+			if(str[0] == '"' && str[str.size()-1] == '"')
+				str = str.substr(1,str.size()-2);
+		}
+	}
+
 	buf = bitmaph->getTextFile("TCOMMAND.TXT");
 	buf = bitmaph->getTextFile("TCOMMAND.TXT");
 	itr=0;
 	itr=0;
 	while(itr<buf.length()-1)
 	while(itr<buf.length()-1)

+ 8 - 0
hch/CObjectHandler.cpp

@@ -882,6 +882,14 @@ bool CGHeroInstance::hasBonusOfType(HeroBonus::BonusType type, int subtype /*= -
 	return false;
 	return false;
 }
 }
 
 
+si32 CGHeroInstance::getArtPos(int aid) const
+{
+	for(std::map<ui16,ui32>::const_iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
+		if(i->second == aid)
+			return i->first;
+	return -1;
+}
+
 int CGTownInstance::getSightRadious() const //returns sight distance
 int CGTownInstance::getSightRadious() const //returns sight distance
 {
 {
 	return 5;
 	return 5;

+ 1 - 0
hch/CObjectHandler.h

@@ -260,6 +260,7 @@ public:
 	int maxMovePoints(bool onLand) const;
 	int maxMovePoints(bool onLand) const;
 	ui32 getArtAtPos(ui16 pos) const; //-1 - no artifact
 	ui32 getArtAtPos(ui16 pos) const; //-1 - no artifact
 	const CArtifact * getArt(int pos) const;
 	const CArtifact * getArt(int pos) const;
+	si32 getArtPos(int aid) const; //looks for equipped artifact with given ID and returns its slot ID or -1 if none(if more than one such artifact lower ID is returned)
 	int getSpellSecLevel(int spell) const; //returns level of secondary ability (fire, water, earth, air magic) known to this hero and applicable to given spell; -1 if error
 	int getSpellSecLevel(int spell) const; //returns level of secondary ability (fire, water, earth, air magic) known to this hero and applicable to given spell; -1 if error
 	static int3 convertPosition(int3 src, bool toh3m); //toh3m=true: manifest->h3m; toh3m=false: h3m->manifest
 	static int3 convertPosition(int3 src, bool toh3m); //toh3m=true: manifest->h3m; toh3m=false: h3m->manifest
 	double getHeroStrength() const;
 	double getHeroStrength() const;

+ 20 - 10
lib/NetPacksLib.cpp

@@ -316,11 +316,31 @@ DLL_EXPORT void SetHeroArtifacts::applyGs( CGameState *gs )
 		if(!vstd::contains(h->artifWorn,i->first)  ||  h->artifWorn[i->first] != i->second)
 		if(!vstd::contains(h->artifWorn,i->first)  ||  h->artifWorn[i->first] != i->second)
 			equiped.push_back(i->second);
 			equiped.push_back(i->second);
 
 
+	BOOST_FOREACH(ui32 id, equiped)
+	{
+		//if hero already had equipped at least one artifact of that type, don't give any new bonuses
+		if(h->getArtPos(id) >= 0)
+			continue;
+
+		CArtifact &art = VLC->arth->artifacts[id];
+		for(std::list<HeroBonus>::iterator i = art.bonuses.begin(); i != art.bonuses.end(); i++)
+		{
+			gained.push_back(&*i);
+			h->bonuses.push_back(*i);
+		}
+	}
+
+	//update hero data
 	h->artifacts = artifacts;
 	h->artifacts = artifacts;
 	h->artifWorn = artifWorn;
 	h->artifWorn = artifWorn;
 
 
+	//remove bonus from unequipped artifact
 	BOOST_FOREACH(ui32 id, unequiped)
 	BOOST_FOREACH(ui32 id, unequiped)
 	{
 	{
+		//if hero still has equipped at least one artifact of that type, don't remove bonuses
+		if(h->getArtPos(id) >= 0)
+			continue;
+
 		while(1)
 		while(1)
 		{
 		{
 			std::list<HeroBonus>::iterator hlp = std::find_if(h->bonuses.begin(),h->bonuses.end(),boost::bind(HeroBonus::IsFrom,_1,HeroBonus::ARTIFACT,id));
 			std::list<HeroBonus>::iterator hlp = std::find_if(h->bonuses.begin(),h->bonuses.end(),boost::bind(HeroBonus::IsFrom,_1,HeroBonus::ARTIFACT,id));
@@ -335,16 +355,6 @@ DLL_EXPORT void SetHeroArtifacts::applyGs( CGameState *gs )
 			}
 			}
 		}
 		}
 	}
 	}
-
-	BOOST_FOREACH(ui32 id, equiped)
-	{
-		CArtifact &art = VLC->arth->artifacts[id];
-		for(std::list<HeroBonus>::iterator i = art.bonuses.begin(); i != art.bonuses.end(); i++)
-		{
-			gained.push_back(&*i);
-			h->bonuses.push_back(*i);
-		}
-	}
 }
 }
 
 
 DLL_EXPORT void SetHeroArtifacts::setArtAtPos(ui16 pos, int art)
 DLL_EXPORT void SetHeroArtifacts::setArtAtPos(ui16 pos, int art)

+ 4 - 1
lib/VCMI_Lib.cpp

@@ -42,7 +42,10 @@ DLL_EXPORT void initDLL(CConsoleHandler *Console, std::ostream *Logfile)
 	console = Console;
 	console = Console;
 	logfile = Logfile;
 	logfile = Logfile;
 	VLC = new LibClasses;
 	VLC = new LibClasses;
-	VLC->init();
+	try
+	{
+		VLC->init();
+	} HANDLE_EXCEPTION
 }
 }
 
 
 DLL_EXPORT void loadToIt(std::string &dest, std::string &src, int &iter, int mode)
 DLL_EXPORT void loadToIt(std::string &dest, std::string &src, int &iter, int mode)

+ 10 - 10
lib/VCMI_lib.vcproj

@@ -282,10 +282,6 @@
 				RelativePath="..\hch\CDefObjInfoHandler.cpp"
 				RelativePath="..\hch\CDefObjInfoHandler.cpp"
 				>
 				>
 			</File>
 			</File>
-			<File
-				RelativePath="..\CGameState.cpp"
-				>
-			</File>
 			<File
 			<File
 				RelativePath="..\hch\CGeneralTextHandler.cpp"
 				RelativePath="..\hch\CGeneralTextHandler.cpp"
 				>
 				>
@@ -318,10 +314,6 @@
 				RelativePath=".\IGameCallback.cpp"
 				RelativePath=".\IGameCallback.cpp"
 				>
 				>
 			</File>
 			</File>
-			<File
-				RelativePath="..\map.cpp"
-				>
-			</File>
 			<File
 			<File
 				RelativePath=".\NetPacksLib.cpp"
 				RelativePath=".\NetPacksLib.cpp"
 				>
 				>
@@ -369,7 +361,7 @@
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\CGameState.h"
+				RelativePath=".\CGameState.h"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
@@ -421,7 +413,7 @@
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\map.h"
+				RelativePath=".\map.h"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
@@ -437,6 +429,14 @@
 				>
 				>
 			</File>
 			</File>
 		</Filter>
 		</Filter>
+		<File
+			RelativePath=".\CGameState.cpp"
+			>
+		</File>
+		<File
+			RelativePath=".\map.cpp"
+			>
+		</File>
 	</Files>
 	</Files>
 	<Globals>
 	<Globals>
 	</Globals>
 	</Globals>

+ 2 - 2
mapHandler.cpp

@@ -1,7 +1,7 @@
 #include "stdafx.h"
 #include "stdafx.h"
 #include "mapHandler.h"
 #include "mapHandler.h"
-#include "SDL_Extensions.h"
-#include "CGameInfo.h"
+#include "client/SDL_Extensions.h"
+#include "client/CGameInfo.h"
 #include <cstdlib>
 #include <cstdlib>
 #include "hch/CLodHandler.h"
 #include "hch/CLodHandler.h"
 #include "hch/CDefObjInfoHandler.h"
 #include "hch/CDefObjInfoHandler.h"