浏览代码

Fixed #471.
Bonuses from artifacts are now inherited. Some work on artifacts set GUI. CArtifactsOfHero now operates on its own hero copy when picking artifact. Still more fixes are needed though.

Michał W. Urbańczyk 15 年之前
父节点
当前提交
7ae02b7c5a

+ 0 - 5
client/CHeroWindow.cpp

@@ -171,10 +171,6 @@ CHeroWindow::~CHeroWindow()
 
 
 	delete garr;
 	delete garr;
 	delete ourBar;
 	delete ourBar;
-
-	artifs->rollback();
-	delete artifs->commonInfo;
-	artifs->commonInfo = NULL; //to prevent heap corruption
 	delete artifs;
 	delete artifs;
 
 
 	delete portraitArea;
 	delete portraitArea;
@@ -532,7 +528,6 @@ void CHeroWindow::dispose()
 	curBack = NULL;
 	curBack = NULL;
 	curHero = NULL;
 	curHero = NULL;
 
 
-	artifs->rollback();
 	artifs->dispose();
 	artifs->dispose();
 }
 }
 
 

+ 4 - 3
client/CPlayerInterface.cpp

@@ -945,10 +945,10 @@ void CPlayerInterface::openHeroWindow(const CGHeroInstance *hero)
 void CPlayerInterface::heroArtifactSetChanged(const CGHeroInstance*hero)
 void CPlayerInterface::heroArtifactSetChanged(const CGHeroInstance*hero)
 {
 {
 	boost::unique_lock<boost::recursive_mutex> un(*pim);
 	boost::unique_lock<boost::recursive_mutex> un(*pim);
-	if(adventureInt->heroWindow->curHero) //hero window is opened
+	if(adventureInt->heroWindow->curHero && adventureInt->heroWindow->curHero->id == hero->id) //hero window is opened
 	{
 	{
 		adventureInt->heroWindow->deactivate();
 		adventureInt->heroWindow->deactivate();
-		adventureInt->heroWindow->setHero(adventureInt->heroWindow->curHero);
+		adventureInt->heroWindow->setHero(hero);
 		adventureInt->heroWindow->activate();
 		adventureInt->heroWindow->activate();
 		return;
 		return;
 	}
 	}
@@ -957,8 +957,9 @@ void CPlayerInterface::heroArtifactSetChanged(const CGHeroInstance*hero)
 		cew->deactivate();
 		cew->deactivate();
 		for(int g=0; g<ARRAY_COUNT(cew->heroInst); ++g)
 		for(int g=0; g<ARRAY_COUNT(cew->heroInst); ++g)
 		{
 		{
-			if(cew->heroInst[g] == hero)
+			if(cew->heroInst[g]->id == hero->id)
 			{
 			{
+				cew->heroInst[g] = hero;
 				cew->artifs[g]->updateState = true;
 				cew->artifs[g]->updateState = true;
 				cew->artifs[g]->setHero(hero);
 				cew->artifs[g]->setHero(hero);
 				cew->artifs[g]->updateState = false;
 				cew->artifs[g]->updateState = false;

+ 77 - 170
client/GUIClasses.cpp

@@ -4367,10 +4367,12 @@ void CArtPlace::clickLeft(tribool down, bool previousState)
 			GH.pushInt(spellWindow);
 			GH.pushInt(spellWindow);
 		}
 		}
 	}
 	}
+
 	if (!down && previousState)
 	if (!down && previousState)
 	{
 	{
 		if(ourArt && ourArt->id == 0)
 		if(ourArt && ourArt->id == 0)
 			return; //this is handled separately
 			return; //this is handled separately
+
 		if(!ourOwner->commonInfo->srcAOH) //nothing has been clicked
 		if(!ourOwner->commonInfo->srcAOH) //nothing has been clicked
 		{
 		{
 			if(ourArt) //to prevent selecting empty slots (bugfix to what GrayFace reported)
 			if(ourArt) //to prevent selecting empty slots (bugfix to what GrayFace reported)
@@ -4431,10 +4433,11 @@ void CArtPlace::clickLeft(tribool down, bool previousState)
 				ourOwner->commonInfo->destArtifact = ourArt;
 				ourOwner->commonInfo->destArtifact = ourArt;
 
 
 				// Special case when the dest artifact can't be fit into the src slot.
 				// Special case when the dest artifact can't be fit into the src slot.
-				//CGI->arth->unequipArtifact(ourOwner->curHero->artifWorn, slotID);
+				CGI->arth->unequipArtifact(ourOwner->curHero->artifWorn, slotID);
 				const CArtifactsOfHero* srcAOH = ourOwner->commonInfo->srcAOH;
 				const CArtifactsOfHero* srcAOH = ourOwner->commonInfo->srcAOH;
 				ui16 srcSlotID = ourOwner->commonInfo->srcSlotID;
 				ui16 srcSlotID = ourOwner->commonInfo->srcSlotID;
-				if (ourArt && srcSlotID < 19 && !ourArt->fitsAt(srcAOH->curHero->artifWorn, srcSlotID)) {
+				if (ourArt && srcSlotID < 19 && !ourArt->fitsAt(srcAOH->curHero->artifWorn, srcSlotID)) 
+				{
 					// Put dest artifact into owner's backpack.
 					// Put dest artifact into owner's backpack.
 					ourOwner->commonInfo->srcAOH = ourOwner;
 					ourOwner->commonInfo->srcAOH = ourOwner;
 					ourOwner->commonInfo->srcSlotID = ourOwner->curHero->artifacts.size() + 19;
 					ourOwner->commonInfo->srcSlotID = ourOwner->curHero->artifacts.size() + 19;
@@ -4448,19 +4451,14 @@ void CArtPlace::clickLeft(tribool down, bool previousState)
 			}
 			}
 		}
 		}
 	}
 	}
-	/*else if(!down && clicked)
-	{
-		if(ourArt && ourArt->id == 0)
-			return; //this is handled separately
-		deselect();
-	}*/
-	//ClickableL::clickLeft(down);
 }
 }
 
 
 void CArtPlace::clickRight(tribool down, bool previousState)
 void CArtPlace::clickRight(tribool down, bool previousState)
 {
 {
-	if(down && ourArt && !locked() && text.size()) { //if there is no description or it's a lock, do nothing ;]
-		if (slotID < 19) {
+	if(down && ourArt && !locked() && text.size())  //if there is no description or it's a lock, do nothing ;]
+	{
+		if (slotID < 19) 
+		{
 			selectedNo = false;
 			selectedNo = false;
 
 
 			// If the artifact can be assembled, display dialog.
 			// If the artifact can be assembled, display dialog.
@@ -4480,7 +4478,8 @@ void CArtPlace::clickRight(tribool down, bool previousState)
 			}
 			}
 
 
 			// Otherwise if the artifact can be diasassembled, display dialog.
 			// Otherwise if the artifact can be diasassembled, display dialog.
-			if (ourArt->constituents != NULL) {
+			if (ourArt->constituents != NULL) 
+			{
 				LOCPLINT->showArtifactAssemblyDialog(
 				LOCPLINT->showArtifactAssemblyDialog(
 					ourArt->id,
 					ourArt->id,
 					0,
 					0,
@@ -4522,11 +4521,11 @@ void CArtPlace::select ()
 	ourOwner->commonInfo->srcAOH = ourOwner;
 	ourOwner->commonInfo->srcAOH = ourOwner;
 
 
 	// Temporarily remove artifact from hero.
 	// Temporarily remove artifact from hero.
-	//if (slotID < 19)
-	//	CGI->arth->unequipArtifact(ourOwner->curHero->artifWorn, slotID);
-	//else
-	//	ourOwner->curHero->artifacts.erase(ourOwner->curHero->artifacts.begin() + (slotID - 19));
-	//ourOwner->markPossibleSlots(ourArt);
+	if (slotID < 19)
+		CGI->arth->unequipArtifact(ourOwner->curHero->artifWorn, slotID);
+	else
+		ourOwner->curHero->artifacts.erase(ourOwner->curHero->artifacts.begin() + (slotID - 19));
+	ourOwner->markPossibleSlots(ourArt);
 	//ourOwner->curHero->recreateArtBonuses();
 	//ourOwner->curHero->recreateArtBonuses();
 
 
 	// Update the hero bonuses.
 	// Update the hero bonuses.
@@ -4548,6 +4547,13 @@ void CArtPlace::select ()
 				cew->artifs[g]->setHero(ourOwner->curHero);
 				cew->artifs[g]->setHero(ourOwner->curHero);
 			}
 			}
 		}
 		}
+
+		//use our copy of hero to draw window
+		if(cew->heroInst[0]->id == ourOwner->curHero->id)
+			cew->heroInst[0] = ourOwner->curHero;
+		else
+			cew->heroInst[1] = ourOwner->curHero;
+
 		cew->prepareBackground();
 		cew->prepareBackground();
 		cew->activate();
 		cew->activate();
 	}
 	}
@@ -4694,61 +4700,23 @@ void LRClickableAreaOpenTown::clickRight(tribool down, bool previousState)
 		LOCPLINT->openTownWindow(town);//TODO: popup?
 		LOCPLINT->openTownWindow(town);//TODO: popup?
 }
 }
 
 
-void CArtifactsOfHero::activate()
-{
-	for(size_t f=0; f<artWorn.size(); ++f)
-	{
-		if(artWorn[f])
-			artWorn[f]->activate();
-	}
-	for(size_t f=0; f<backpack.size(); ++f)
-	{
-		if(backpack[f])
-			backpack[f]->activate();
-	}
-	
-	leftArtRoll->activate();
-	rightArtRoll->activate();
-}
-
-void CArtifactsOfHero::deactivate()
+void CArtifactsOfHero::SCommonPart::reset()
 {
 {
-	for(size_t f=0; f<artWorn.size(); ++f)
-	{
-		if(artWorn[f])
-			artWorn[f]->deactivate();
-	}
-	for(size_t f=0; f<backpack.size(); ++f)
-	{
-		if(backpack[f])
-			backpack[f]->deactivate();
-	}
-	
-	leftArtRoll->deactivate();
-	rightArtRoll->deactivate();
-}
-
-void CArtifactsOfHero::show(SDL_Surface * to)
-{
-	for(size_t d=0; d<artWorn.size(); ++d)
-	{
-		artWorn[d]->show(to);
-	}
-	for(size_t d=0; d<backpack.size(); ++d)
-	{
-		backpack[d]->show(to);
-	}
-
-	leftArtRoll->show(to);
-	rightArtRoll->show(to);
+	destAOH = srcAOH = NULL;
+	destArtifact = srcArtifact = NULL;
+	destSlotID = srcSlotID = -1;
 }
 }
 
 
 void CArtifactsOfHero::setHero(const CGHeroInstance * hero)
 void CArtifactsOfHero::setHero(const CGHeroInstance * hero)
 {
 {
 	// An update is made, rather than initialization.
 	// An update is made, rather than initialization.
-	if (curHero == hero) 
+	if (curHero && curHero->id == hero->id) 
 	{
 	{
-		curHero = hero;
+		if(curHero != hero)
+		{
+			delete	curHero;
+			curHero = new CGHeroInstance(*hero);
+		}
 
 
 		// Compensate backpack pos if an artifact was insertad before it.
 		// Compensate backpack pos if an artifact was insertad before it.
 		if (commonInfo->destSlotID >= 19 && commonInfo->destAOH == this
 		if (commonInfo->destSlotID >= 19 && commonInfo->destAOH == this
@@ -4757,14 +4725,16 @@ void CArtifactsOfHero::setHero(const CGHeroInstance * hero)
 			backpackPos++;
 			backpackPos++;
 		}
 		}
 
 
-		if (updateState && commonInfo->srcAOH == this) {
+		if (updateState && commonInfo->srcAOH == this) 
+		{
 			// A swap was made, make the replaced artifact the current selected.
 			// A swap was made, make the replaced artifact the current selected.
-			if (commonInfo->destSlotID < 19 && commonInfo->destArtifact) {
+			if (commonInfo->destSlotID < 19 && commonInfo->destArtifact) 
+			{
 				// Temporarily remove artifact from hero.
 				// Temporarily remove artifact from hero.
-				//if (commonInfo->srcSlotID < 19)
-				//	CGI->arth->unequipArtifact(curHero->artifWorn, commonInfo->srcSlotID);
-				//else
-				//	curHero->artifacts.erase(curHero->artifacts.begin() + (commonInfo->srcSlotID - 19));
+				if (commonInfo->srcSlotID < 19)
+					CGI->arth->unequipArtifact(curHero->artifWorn, commonInfo->srcSlotID);
+				else
+					curHero->artifacts.erase(curHero->artifacts.begin() + (commonInfo->srcSlotID - 19));
 				//curHero->recreateArtBonuses();
 				//curHero->recreateArtBonuses();
 
 
 				// Source <- Dest
 				// Source <- Dest
@@ -4775,20 +4745,13 @@ void CArtifactsOfHero::setHero(const CGHeroInstance * hero)
 				commonInfo->destArtifact = NULL;
 				commonInfo->destArtifact = NULL;
 				commonInfo->destSlotID = -1;
 				commonInfo->destSlotID = -1;
 
 
-				CGI->curh->dragAndDropCursor(
-					graphics->artDefs->ourImages[commonInfo->srcArtifact->id].bitmap);
+				CGI->curh->dragAndDropCursor(graphics->artDefs->ourImages[commonInfo->srcArtifact->id].bitmap);
 				markPossibleSlots(commonInfo->srcArtifact);
 				markPossibleSlots(commonInfo->srcArtifact);
 			} 
 			} 
 			else if (commonInfo->destAOH != NULL) 
 			else if (commonInfo->destAOH != NULL) 
 			{
 			{
 				// Reset all parameters.
 				// Reset all parameters.
-				commonInfo->srcAOH = NULL;
-				commonInfo->srcArtifact = NULL;
-				commonInfo->srcSlotID = -1;
-				commonInfo->destAOH = NULL;
-				commonInfo->destArtifact = NULL;
-				commonInfo->destSlotID = -1;
-
+				commonInfo->reset();
 				CGI->curh->dragAndDropCursor(NULL);
 				CGI->curh->dragAndDropCursor(NULL);
 				unmarkSlots();
 				unmarkSlots();
 			}
 			}
@@ -4796,10 +4759,14 @@ void CArtifactsOfHero::setHero(const CGHeroInstance * hero)
 	} 
 	} 
 	else 
 	else 
 	{
 	{
-		rollback();
+		commonInfo->reset();
 	}
 	}
 
 
-	curHero = const_cast<CGHeroInstance *>(hero);
+	if(hero != curHero)
+	{
+		delete curHero;
+		curHero = new CGHeroInstance(*hero);
+	}
 
 
 	if (curHero->artifacts.size() > 0)
 	if (curHero->artifacts.size() > 0)
 		backpackPos %= curHero->artifacts.size();
 		backpackPos %= curHero->artifacts.size();
@@ -4816,67 +4783,16 @@ void CArtifactsOfHero::setHero(const CGHeroInstance * hero)
 	rightArtRoll->block(curHero->artifacts.size() <= backpack.size());
 	rightArtRoll->block(curHero->artifacts.size() <= backpack.size());
 }
 }
 
 
-/**
- * Any held artifacts, marked slots etc. will be restored to it's original way.
- */
-void CArtifactsOfHero::rollback()
-{
-	if (curHero != NULL) 
-	{
-		// Restore any held artifact to it's original position.
-		if (commonInfo->srcArtifact && commonInfo->srcAOH == this) 
-		{
-			if (commonInfo->srcSlotID != -1) {
-				// Put a held artifact back to it's spot.
-				//if (commonInfo->srcSlotID < 19)
-				//	CGI->arth->equipArtifact(curHero->artifWorn, commonInfo->srcSlotID, commonInfo->srcArtifact->id);
-				//else
-				//	curHero->artifacts.insert(curHero->artifacts.begin() + (commonInfo->srcSlotID - 19), commonInfo->srcArtifact->id);
-			} 
-			else  // Held swapped artifact.
-			{
-				// Wear the artifact in a suitable spot.
-				ui16 i = 0;
-				for (; i < 19; i++) 
-				{
-					if (artWorn[i]->fitsHere(commonInfo->srcArtifact) && !vstd::contains(curHero->artifWorn, i)) 
-					{
-						//CGI->arth->equipArtifact(curHero->artifWorn, i, commonInfo->srcArtifact->id);
-						break;
-					}
-				}
-
-				// If it can't be worn, put it in the backpack.
-				if (i == 19)
-					;//curHero->artifacts.push_back(commonInfo->srcArtifact->id);
-			}
-
-			//curHero->recreateArtBonuses();
-		}
-	}
-
-	unmarkSlots();
-	backpackPos = 0;
-
-	commonInfo->srcAOH = NULL;
-	commonInfo->srcArtifact = NULL;
-	commonInfo->srcSlotID = -1;
-	commonInfo->destAOH = NULL;
-	commonInfo->destArtifact = NULL;
-	commonInfo->destSlotID = -1;
-
-	CGI->curh->dragAndDropCursor(NULL);
-}
-
 void CArtifactsOfHero::dispose()
 void CArtifactsOfHero::dispose()
 {
 {
-	curHero = NULL;
+	delNull(curHero);
 }
 }
 
 
 void CArtifactsOfHero::scrollBackpack(int dir)
 void CArtifactsOfHero::scrollBackpack(int dir)
 {
 {
 	backpackPos += dir;
 	backpackPos += dir;
-	if (curHero->artifacts.size() > 0) {
+	if (curHero->artifacts.size() > 0) 
+	{
 		if (backpackPos < 0) { // No guarantee of modulus behavior with negative operands.
 		if (backpackPos < 0) { // No guarantee of modulus behavior with negative operands.
 			do {
 			do {
 				backpackPos += curHero->artifacts.size();
 				backpackPos += curHero->artifacts.size();
@@ -4887,7 +4803,8 @@ void CArtifactsOfHero::scrollBackpack(int dir)
 	}
 	}
 
 
 	//set new data
 	//set new data
-	for (size_t s = 0; s < backpack.size(); ++s) {
+	for (size_t s = 0; s < backpack.size(); ++s) 
+	{
 		if (s < curHero->artifacts.size())
 		if (s < curHero->artifacts.size())
 			setSlotData(backpack[s], 19 + (s + backpackPos)%curHero->artifacts.size());
 			setSlotData(backpack[s], 19 + (s + backpackPos)%curHero->artifacts.size());
 		else
 		else
@@ -4906,7 +4823,8 @@ void CArtifactsOfHero::markPossibleSlots (const CArtifact* art)
 		it != commonInfo->participants.end();
 		it != commonInfo->participants.end();
 		++it)
 		++it)
 	{
 	{
-		for (int i = 0; i < (*it)->artWorn.size(); i++) {
+		for (int i = 0; i < (*it)->artWorn.size(); i++) 
+		{
 			if ((*it)->artWorn[i]->fitsHere(art))
 			if ((*it)->artWorn[i]->fitsHere(art))
 				(*it)->artWorn[i]->marked = true;
 				(*it)->artWorn[i]->marked = true;
 			else
 			else
@@ -4924,7 +4842,8 @@ void CArtifactsOfHero::unmarkSlots ()
 		it != commonInfo->participants.end();
 		it != commonInfo->participants.end();
 		++it)
 		++it)
 	{
 	{
-		for (int i = 0; i < (*it)->artWorn.size(); i++) {
+		for (int i = 0; i < (*it)->artWorn.size(); i++) 
+		{
 			(*it)->artWorn[i]->marked = false;
 			(*it)->artWorn[i]->marked = false;
 		}
 		}
 	}
 	}
@@ -4938,13 +4857,16 @@ void CArtifactsOfHero::setSlotData (CArtPlace* artPlace, int slotID)
 	artPlace->slotID = slotID;
 	artPlace->slotID = slotID;
 	artPlace->ourArt = curHero->getArt(slotID);
 	artPlace->ourArt = curHero->getArt(slotID);
 
 
-	if (artPlace->ourArt) {
+	if (artPlace->ourArt) 
+	{
 		artPlace->text = artPlace->ourArt->Description();
 		artPlace->text = artPlace->ourArt->Description();
 		if (artPlace->locked()) // Locks should appear as empty.
 		if (artPlace->locked()) // Locks should appear as empty.
 			artPlace->hoverText = CGI->generaltexth->allTexts[507];
 			artPlace->hoverText = CGI->generaltexth->allTexts[507];
 		else
 		else
 			artPlace->hoverText = boost::str(boost::format(CGI->generaltexth->heroscrn[1].c_str()) % artPlace->ourArt->Name().c_str());
 			artPlace->hoverText = boost::str(boost::format(CGI->generaltexth->heroscrn[1].c_str()) % artPlace->ourArt->Name().c_str());
-	} else {
+	} 
+	else 
+	{
 		eraseSlotData(artPlace, slotID);
 		eraseSlotData(artPlace, slotID);
 	}
 	}
 }
 }
@@ -4961,25 +4883,26 @@ void CArtifactsOfHero::eraseSlotData (CArtPlace* artPlace, int slotID)
 }
 }
 
 
 CArtifactsOfHero::CArtifactsOfHero(const Point &position) :
 CArtifactsOfHero::CArtifactsOfHero(const Point &position) :
-	backpackPos(0), updateState(false), commonInfo(NULL)
+	backpackPos(0), updateState(false), commonInfo(NULL), curHero(NULL)
 {
 {
+	OBJ_CONSTRUCTION_CAPTURING_ALL;
 	pos += position;
 	pos += position;
 	artWorn.resize(19);
 	artWorn.resize(19);
 	
 	
-	std::vector<SDL_Rect> slotPos;
-	slotPos += genRect(44,44,pos.x+509,pos.y+30), genRect(44,44,pos.x+567,pos.y+240), genRect(44,44,pos.x+509,pos.y+80), 
-		genRect(44,44,pos.x+383,pos.y+68), genRect(44,44,pos.x+564,pos.y+183), genRect(44,44,pos.x+509,pos.y+130), 
-		genRect(44,44,pos.x+431,pos.y+68), genRect(44,44,pos.x+610,pos.y+183), genRect(44,44,pos.x+515,pos.y+295), 
-		genRect(44,44,pos.x+383,pos.y+143), genRect(44,44,pos.x+399,pos.y+194), genRect(44,44,pos.x+415,pos.y+245),
-		genRect(44,44,pos.x+431,pos.y+296), genRect(44,44,pos.x+564,pos.y+30), genRect(44,44,pos.x+610,pos.y+30), 
-		genRect(44,44,pos.x+610,pos.y+76), genRect(44,44,pos.x+610,pos.y+122), genRect(44,44,pos.x+610,pos.y+310),	
-		genRect(44,44,pos.x+381,pos.y+296);
+	std::vector<Rect> slotPos;
+	slotPos += genRect(44,44,509,30), genRect(44,44,567,240), genRect(44,44,509,80), 
+		genRect(44,44,383,68), genRect(44,44,564,183), genRect(44,44,509,130), 
+		genRect(44,44,431,68), genRect(44,44,610,183), genRect(44,44,515,295), 
+		genRect(44,44,383,143), genRect(44,44,399,194), genRect(44,44,415,245),
+		genRect(44,44,431,296), genRect(44,44,564,30), genRect(44,44,610,30), 
+		genRect(44,44,610,76), genRect(44,44,610,122), genRect(44,44,610,310),	
+		genRect(44,44,381,296);
 
 
 	// Create slots for worn artifacts.
 	// Create slots for worn artifacts.
 	for (int g = 0; g < 19 ; g++)
 	for (int g = 0; g < 19 ; g++)
 	{	
 	{	
 		artWorn[g] = new CArtPlace(NULL);
 		artWorn[g] = new CArtPlace(NULL);
-		artWorn[g]->pos = slotPos[g];
+		artWorn[g]->pos = slotPos[g] + pos;
 		artWorn[g]->ourOwner = this;
 		artWorn[g]->ourOwner = this;
 		eraseSlotData(artWorn[g], g);
 		eraseSlotData(artWorn[g], g);
 	}
 	}
@@ -4998,28 +4921,14 @@ CArtifactsOfHero::CArtifactsOfHero(const Point &position) :
 		backpack.push_back(add);
 		backpack.push_back(add);
 	}
 	}
 
 
-	leftArtRoll = new AdventureMapButton(std::string(), std::string(), boost::bind(&CArtifactsOfHero::scrollBackpack,this,-1), pos.x+379, pos.y+364, "hsbtns3.def", SDLK_LEFT);
-	rightArtRoll = new AdventureMapButton(std::string(), std::string(), boost::bind(&CArtifactsOfHero::scrollBackpack,this,+1), pos.x+632, pos.y+364, "hsbtns5.def", SDLK_RIGHT);
+	leftArtRoll = new AdventureMapButton(std::string(), std::string(), boost::bind(&CArtifactsOfHero::scrollBackpack,this,-1), 379, 364, "hsbtns3.def", SDLK_LEFT);
+	rightArtRoll = new AdventureMapButton(std::string(), std::string(), boost::bind(&CArtifactsOfHero::scrollBackpack,this,+1), 632, 364, "hsbtns5.def", SDLK_RIGHT);
 }
 }
 
 
 CArtifactsOfHero::~CArtifactsOfHero()
 CArtifactsOfHero::~CArtifactsOfHero()
 {
 {
 	dispose();
 	dispose();
-	for(size_t g=0; g<artWorn.size(); ++g)
-	{
-		delete artWorn[g];
-		artWorn[g] = NULL;
-	}
-	for(size_t g=0; g<backpack.size(); ++g)
-	{
-		delete backpack[g];
-		backpack[g] = NULL;
-	}
-	backpack.clear();
-	artWorn.clear();
-
-	delete leftArtRoll;
-	delete rightArtRoll;
+	CGI->curh->dragAndDropCursor(NULL);
 }
 }
 
 
 void CExchangeWindow::close()
 void CExchangeWindow::close()
@@ -5324,8 +5233,6 @@ CExchangeWindow::~CExchangeWindow() //d-tor
 	delete quit;
 	delete quit;
 
 
 	//warning: don't experiment with these =NULL lines, they prevent heap corruption!
 	//warning: don't experiment with these =NULL lines, they prevent heap corruption!
-	artifs[0]->rollback();
-	artifs[1]->rollback();
 	delete artifs[0]->commonInfo;
 	delete artifs[0]->commonInfo;
 	artifs[0]->commonInfo = NULL;
 	artifs[0]->commonInfo = NULL;
 	delete artifs[0];
 	delete artifs[0];

+ 3 - 6
client/GUIClasses.h

@@ -909,7 +909,7 @@ inline bool CArtPlace::locked () const
 
 
 class CArtifactsOfHero : public CIntObject
 class CArtifactsOfHero : public CIntObject
 {
 {
-	const CGHeroInstance * curHero;
+	CGHeroInstance * curHero; //local copy of hero on which we operate
 
 
 	std::vector<CArtPlace *> artWorn; // 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5
 	std::vector<CArtPlace *> artWorn; // 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5
 	std::vector<CArtPlace *> backpack; //hero's visible backpack (only 5 elements!)
 	std::vector<CArtPlace *> backpack; //hero's visible backpack (only 5 elements!)
@@ -925,19 +925,16 @@ public:
 		const CArtifactsOfHero * destAOH; // For swapping. (i.e. changing what is held)
 		const CArtifactsOfHero * destAOH; // For swapping. (i.e. changing what is held)
 		int destSlotID;	                  // Needed to determine what kind of action was last taken in setHero
 		int destSlotID;	                  // Needed to determine what kind of action was last taken in setHero
 		const CArtifact * destArtifact;   // For swapping.
 		const CArtifact * destArtifact;   // For swapping.
+
+		void reset();
 	} * commonInfo; //when we have more than one CArtifactsOfHero in one window with exchange possibility, we use this (eg. in exchange window); to be provided externally
 	} * commonInfo; //when we have more than one CArtifactsOfHero in one window with exchange possibility, we use this (eg. in exchange window); to be provided externally
 
 
 	bool updateState; // Whether the commonInfo should be updated on setHero or not.
 	bool updateState; // Whether the commonInfo should be updated on setHero or not.
 
 
 	AdventureMapButton * leftArtRoll, * rightArtRoll;
 	AdventureMapButton * leftArtRoll, * rightArtRoll;
 
 
-	void activate();
-	void deactivate();
-	void show(SDL_Surface * to);
-
 	void setHero(const CGHeroInstance * hero);
 	void setHero(const CGHeroInstance * hero);
 	void dispose(); //free resources not needed after closing windows and reset state
 	void dispose(); //free resources not needed after closing windows and reset state
-	void rollback();
 	void scrollBackpack(int dir); //dir==-1 => to left; dir==1 => to right
 	void scrollBackpack(int dir); //dir==-1 => to left; dir==1 => to right
 	void markPossibleSlots (const CArtifact* art);
 	void markPossibleSlots (const CArtifact* art);
 	void unmarkSlots ();
 	void unmarkSlots ();

+ 9 - 9
client/NetPacksClient.cpp

@@ -326,17 +326,17 @@ void SetHeroArtifacts::applyCl( CClient *cl )
 	if(!player)
 	if(!player)
 		return;
 		return;
 
 
-	h->recreateArtBonuses();
+	//h->recreateArtBonuses();
 	player->heroArtifactSetChanged(h);
 	player->heroArtifactSetChanged(h);
 
 
-	BOOST_FOREACH(Bonus bonus, gained)
-	{
-		player->heroBonusChanged(h,bonus,true);
-	}
-	BOOST_FOREACH(Bonus bonus, lost)
-	{
-		player->heroBonusChanged(h,bonus,false);
-	}
+// 	BOOST_FOREACH(Bonus bonus, gained)
+// 	{
+// 		player->heroBonusChanged(h,bonus,true);
+// 	}
+// 	BOOST_FOREACH(Bonus bonus, lost)
+// 	{
+// 		player->heroBonusChanged(h,bonus,false);
+// 	}
 }
 }
 
 
 void HeroRecruited::applyCl( CClient *cl )
 void HeroRecruited::applyCl( CClient *cl )

+ 16 - 49
hch/CArtHandler.cpp

@@ -87,7 +87,8 @@ bool CArtifact::fitsAt (const std::map<ui16, ui32> &artifWorn, ui16 slotID) cons
 		}
 		}
 
 
 		// Ensure enough ring slots are free
 		// Ensure enough ring slots are free
-		for (int i = 0; i < sizeof(ringSlots)/sizeof(*ringSlots); i++) {
+		for (int i = 0; i < sizeof(ringSlots)/sizeof(*ringSlots); i++) 
+		{
 			if (tempArtifWorn.find(ringSlots[i]) == tempArtifWorn.end() || ringSlots[i] == slotID)
 			if (tempArtifWorn.find(ringSlots[i]) == tempArtifWorn.end() || ringSlots[i] == slotID)
 				rings--;
 				rings--;
 		}
 		}
@@ -95,7 +96,8 @@ bool CArtifact::fitsAt (const std::map<ui16, ui32> &artifWorn, ui16 slotID) cons
 			return false;
 			return false;
 
 
 		// Ensure enough misc slots are free.
 		// Ensure enough misc slots are free.
-		for (int i = 0; i < sizeof(miscSlots)/sizeof(*miscSlots); i++) {
+		for (int i = 0; i < sizeof(miscSlots)/sizeof(*miscSlots); i++) 
+		{
 			if (tempArtifWorn.find(miscSlots[i]) == tempArtifWorn.end() || miscSlots[i] == slotID)
 			if (tempArtifWorn.find(miscSlots[i]) == tempArtifWorn.end() || miscSlots[i] == slotID)
 				misc--;
 				misc--;
 		}
 		}
@@ -114,10 +116,13 @@ bool CArtifact::canBeAssembledTo (const std::map<ui16, ui32> &artifWorn, ui32 ar
 	const CArtifact &artifact = *VLC->arth->artifacts[artifactID];
 	const CArtifact &artifact = *VLC->arth->artifacts[artifactID];
 	assert(artifact.constituents);
 	assert(artifact.constituents);
 
 
-	BOOST_FOREACH(ui32 constituentID, *artifact.constituents) {
+	BOOST_FOREACH(ui32 constituentID, *artifact.constituents) 
+	{
 		bool found = false;
 		bool found = false;
-		for (std::map<ui16, ui32>::const_iterator it = artifWorn.begin(); it != artifWorn.end(); ++it) {
-			if (it->second == constituentID) {
+		for (std::map<ui16, ui32>::const_iterator it = artifWorn.begin(); it != artifWorn.end(); ++it) 
+		{
+			if (it->second == constituentID) 
+			{
 				found = true;
 				found = true;
 				break;
 				break;
 			}
 			}
@@ -129,43 +134,13 @@ bool CArtifact::canBeAssembledTo (const std::map<ui16, ui32> &artifWorn, ui32 ar
 	return true;
 	return true;
 }
 }
 
 
-/**
- * Adds all the bonuses of this artifact, including possible constituents, to
- * a bonus list.
- */
-void CArtifact::addBonusesTo (BonusList *otherBonuses) const
+CArtifact::CArtifact()
 {
 {
-	for(std::list<Bonus>::const_iterator i = bonuses.begin(); i != bonuses.end(); i++)
-		otherBonuses->push_back(*i);
-
-	if (constituents != NULL) {
-		BOOST_FOREACH(ui32 artifactID, *constituents) 
-		{
-			VLC->arth->artifacts[artifactID]->addBonusesTo(otherBonuses);
-		}
-	}
+	nodeType = ARTIFACT;
 }
 }
 
 
-/**
- * Removes all the bonuses of this artifact, including possible constituents, from
- * a bonus list.
- */
-void CArtifact::removeBonusesFrom (BonusList *otherBonuses) const
+CArtifact::~CArtifact()
 {
 {
-	if (constituents != NULL) {
-		BOOST_FOREACH(ui32 artifactID, *constituents) {
-			VLC->arth->artifacts[artifactID]->removeBonusesFrom(otherBonuses);
-		}
-	}
-
-	while (1) {
-		std::list<Bonus>::iterator it = std::find_if(otherBonuses->begin(), otherBonuses->end(),boost::bind(Bonus::IsFrom,_1,Bonus::ARTIFACT,id));
-
-		if (it != otherBonuses->end())
-			otherBonuses->erase(it);
-		else
-			break;
-	}
 }
 }
 
 
 CArtHandler::CArtHandler()
 CArtHandler::CArtHandler()
@@ -709,10 +684,9 @@ void CArtHandler::clear()
  * @param artifWorn A hero's set of worn artifacts.
  * @param artifWorn A hero's set of worn artifacts.
  * @param bonuses Optional list of bonuses to update.
  * @param bonuses Optional list of bonuses to update.
  */
  */
-void CArtHandler::equipArtifact
-	(std::map<ui16, ui32> &artifWorn, ui16 slotID, ui32 artifactID, BonusList *bonuses)
+void CArtHandler::equipArtifact(std::map<ui16, ui32> &artifWorn, ui16 slotID, ui32 artifactID)
 {
 {
-	unequipArtifact(artifWorn, slotID, bonuses);
+	unequipArtifact(artifWorn, slotID);
 
 
 	const CArtifact &artifact = *artifacts[artifactID];
 	const CArtifact &artifact = *artifacts[artifactID];
 
 
@@ -745,9 +719,6 @@ void CArtHandler::equipArtifact
 			}
 			}
 		}
 		}
 	}
 	}
-
-	if (bonuses != NULL)
-		artifact.addBonusesTo(bonuses);
 }
 }
 
 
 /**
 /**
@@ -756,8 +727,7 @@ void CArtHandler::equipArtifact
  * @param artifWorn A hero's set of worn artifacts.
  * @param artifWorn A hero's set of worn artifacts.
  * @param bonuses Optional list of bonuses to update.
  * @param bonuses Optional list of bonuses to update.
  */
  */
-void CArtHandler::unequipArtifact
-	(std::map<ui16, ui32> &artifWorn, ui16 slotID, BonusList *bonuses)
+void CArtHandler::unequipArtifact(std::map<ui16, ui32> &artifWorn, ui16 slotID)
 {
 {
 	if (!vstd::contains(artifWorn, slotID))
 	if (!vstd::contains(artifWorn, slotID))
 		return;
 		return;
@@ -793,7 +763,4 @@ void CArtHandler::unequipArtifact
 			}
 			}
 		}
 		}
 	}
 	}
-
-	if (bonuses != NULL)
-		artifact.removeBonusesFrom(bonuses);
 }
 }

+ 8 - 5
hch/CArtHandler.h

@@ -18,7 +18,7 @@
  */
  */
 class CDefHandler;
 class CDefHandler;
 
 
-class DLL_EXPORT CArtifact //container for artifacts
+class DLL_EXPORT CArtifact : public CBonusSystemNode //container for artifacts
 {
 {
 	std::string name, description; //set if custom
 	std::string name, description; //set if custom
 public:
 public:
@@ -37,12 +37,15 @@ public:
 	std::vector<ui32> * constituentOf; // Reverse map of constituents.
 	std::vector<ui32> * constituentOf; // Reverse map of constituents.
 	EartClass aClass;
 	EartClass aClass;
 	si32 id;
 	si32 id;
-	std::list<Bonus> bonuses; //bonuses given by artifact
 
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 	{
-		h & name & description & price & possibleSlots & constituents & constituentOf & aClass & id & bonuses;
+		h & static_cast<CBonusSystemNode&>(*this);;
+		h & name & description & price & possibleSlots & constituents & constituentOf & aClass & id;
 	}
 	}
+
+	CArtifact();
+	~CArtifact();
 };
 };
 
 
 class DLL_EXPORT CArtHandler //handles artifacts
 class DLL_EXPORT CArtHandler //handles artifacts
@@ -64,8 +67,8 @@ public:
 	void getAllowed(std::vector<CArtifact*> &out, int flags);
 	void getAllowed(std::vector<CArtifact*> &out, int flags);
 	void erasePickedArt (si32 id);
 	void erasePickedArt (si32 id);
 	bool isBigArtifact (ui32 artID) {return bigArtifacts.find(artID) != bigArtifacts.end();}
 	bool isBigArtifact (ui32 artID) {return bigArtifacts.find(artID) != bigArtifacts.end();}
-	void equipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID, ui32 artifactID, BonusList *bonuses = NULL);
-	void unequipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID, BonusList *bonuses = NULL);
+	void equipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID, ui32 artifactID);
+	void unequipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID);
 	static int convertMachineID(int id, bool creToArt);
 	static int convertMachineID(int id, bool creToArt);
 	CArtHandler();
 	CArtHandler();
 	~CArtHandler();
 	~CArtHandler();

+ 10 - 20
hch/CObjectHandler.cpp

@@ -762,9 +762,9 @@ void CGHeroInstance::initHero()
 
 
 	if(!vstd::contains(artifWorn, 16) && type->startingSpell >= 0) //no catapult means we haven't read pre-existant set
 	if(!vstd::contains(artifWorn, 16) && type->startingSpell >= 0) //no catapult means we haven't read pre-existant set
 	{
 	{
-		VLC->arth->equipArtifact(artifWorn, 17, 0, &bonuses); //give spellbook
+		VLC->arth->equipArtifact(artifWorn, 17, 0); //give spellbook
 	}
 	}
-	VLC->arth->equipArtifact(artifWorn, 16, 3, &bonuses); //everyone has a catapult
+	VLC->arth->equipArtifact(artifWorn, 16, 3); //everyone has a catapult
 
 
 	if(portrait < 0 || portrait == 255)
 	if(portrait < 0 || portrait == 255)
 		portrait = subID;
 		portrait = subID;
@@ -800,7 +800,6 @@ void CGHeroInstance::initHero()
 	boost::algorithm::replace_first(hoverName,"%s",name);
 	boost::algorithm::replace_first(hoverName,"%s",name);
 	boost::algorithm::replace_first(hoverName,"%s", type->heroClass->name);
 	boost::algorithm::replace_first(hoverName,"%s", type->heroClass->name);
 
 
-	recreateArtBonuses();
 	if(mana < 0)
 	if(mana < 0)
 		mana = manaLimit(); //after all bonuses are taken into account
 		mana = manaLimit(); //after all bonuses are taken into account
 }
 }
@@ -833,14 +832,13 @@ void CGHeroInstance::initArmy(CCreatureSet *dst /*= NULL*/)
 			switch (creID)
 			switch (creID)
 			{
 			{
 			case 145: //catapult
 			case 145: //catapult
-				VLC->arth->equipArtifact(artifWorn, 16, 3, &bonuses);
+				VLC->arth->equipArtifact(artifWorn, 16, 3);
 				break;
 				break;
 			default:
 			default:
 				VLC->arth->equipArtifact(
 				VLC->arth->equipArtifact(
 					artifWorn,
 					artifWorn,
 					9+CArtHandler::convertMachineID(creID,true),
 					9+CArtHandler::convertMachineID(creID,true),
-					CArtHandler::convertMachineID(creID,true),
-					&bonuses);
+					  CArtHandler::convertMachineID(creID,true));
 				break;
 				break;
 			}
 			}
 		}
 		}
@@ -937,7 +935,7 @@ void CGHeroInstance::initObj()
 	if(!type)
 	if(!type)
 		return; //TODO support prison
 		return; //TODO support prison
 
 
-	for (std::vector<specialInfo>::iterator it = type->spec.begin(); it != type->spec.end(); it++)
+	for (std::vector<specialInfo>::const_iterator it = type->spec.begin(); it != type->spec.end(); it++)
 	{
 	{
 		bonus.val = it->val;
 		bonus.val = it->val;
 		bonus.id = id; //from the hero, speciality has no unique id
 		bonus.id = id; //from the hero, speciality has no unique id
@@ -1386,7 +1384,7 @@ void CGHeroInstance::giveArtifact (ui32 aid)
 		{
 		{
 			if (!vstd::contains(artifWorn, *it)) 
 			if (!vstd::contains(artifWorn, *it)) 
 			{
 			{
-				VLC->arth->equipArtifact(artifWorn, *it, aid, &bonuses);
+				VLC->arth->equipArtifact(artifWorn, *it, aid);
 				break;
 				break;
 			}
 			}
 		}
 		}
@@ -1397,17 +1395,6 @@ void CGHeroInstance::giveArtifact (ui32 aid)
 	}
 	}
 }
 }
 
 
-void CGHeroInstance::recreateArtBonuses()
-{
-	//clear all bonuses from artifacts (if present) and give them again
-	bonuses.remove_if(boost::bind(Bonus::IsFrom,_1,Bonus::ARTIFACT,0xffffff));
-	for (std::map<ui16,ui32>::iterator ari = artifWorn.begin(); ari != artifWorn.end(); ari++)
-	{
-		CArtifact &art = *VLC->arth->artifacts[ari->second];
-		art.addBonusesTo(&bonuses);
-	}
-}
-
 bool CGHeroInstance::hasArt( ui32 aid ) const
 bool CGHeroInstance::hasArt( ui32 aid ) const
 {
 {
 	if(vstd::contains(artifacts, aid))
 	if(vstd::contains(artifacts, aid))
@@ -1455,7 +1442,10 @@ void CGHeroInstance::getParents(TCNodes &out, const CBonusSystemNode *root /*= N
 	if((root == this || contains(static_cast<const CStackInstance *>(root))) &&  visitedTown)
 	if((root == this || contains(static_cast<const CStackInstance *>(root))) &&  visitedTown)
 		out.insert(visitedTown);
 		out.insert(visitedTown);
 
 
-	out.insert (&speciality);
+	for (std::map<ui16,ui32>::const_iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
+		out.insert(VLC->arth->artifacts[i->second]);
+
+	out.insert(&speciality);
 }
 }
 
 
 void CGHeroInstance::pushPrimSkill(int which, int val)
 void CGHeroInstance::pushPrimSkill(int which, int val)

+ 3 - 4
hch/CObjectHandler.h

@@ -275,7 +275,7 @@ public:
 
 
 	//////////////////////////////////////////////////////////////////////////
 	//////////////////////////////////////////////////////////////////////////
 
 
-	CHero * type;
+	const CHero * type;
 	ui64 exp; //experience points
 	ui64 exp; //experience points
 	si32 level; //current level of hero
 	si32 level; //current level of hero
 	std::string name; //may be custom
 	std::string name; //may be custom
@@ -286,8 +286,8 @@ public:
 	si32 movement; //remaining movement points
 	si32 movement; //remaining movement points
 	ui8 sex;
 	ui8 sex;
 	ui8 inTownGarrison; // if hero is in town garrison 
 	ui8 inTownGarrison; // if hero is in town garrison 
-	CGTownInstance * visitedTown; //set if hero is visiting town or in the town garrison
-	CGBoat *boat; //set to CGBoat when sailing
+	const CGTownInstance * visitedTown; //set if hero is visiting town or in the town garrison
+	const CGBoat *boat; //set to CGBoat when sailing
 	std::vector<ui32> artifacts; //hero's artifacts from bag
 	std::vector<ui32> artifacts; //hero's artifacts from bag
 	std::map<ui16,ui32> artifWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5
 	std::map<ui16,ui32> artifWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5
 	std::set<ui32> spells; //known spells (spell IDs)
 	std::set<ui32> spells; //known spells (spell IDs)
@@ -376,7 +376,6 @@ public:
 	void initHero(); 
 	void initHero(); 
 	void initHero(int SUBID); 
 	void initHero(int SUBID); 
 	void initArmy(CCreatureSet *dst = NULL);
 	void initArmy(CCreatureSet *dst = NULL);
-	void recreateArtBonuses();
 	void giveArtifact (ui32 aid);
 	void giveArtifact (ui32 aid);
 	void initHeroDefInfo();
 	void initHeroDefInfo();
 	void pushPrimSkill(int which, int val);
 	void pushPrimSkill(int which, int val);

+ 2 - 4
lib/CGameState.cpp

@@ -1484,10 +1484,8 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
 
 
 				CGHeroInstance *hero = k->second.heroes[0];
 				CGHeroInstance *hero = k->second.heroes[0];
 				std::vector<ui16>::iterator slot = vstd::findFirstNot (hero->artifWorn, toGive->possibleSlots);
 				std::vector<ui16>::iterator slot = vstd::findFirstNot (hero->artifWorn, toGive->possibleSlots);
-				if(slot!=toGive->possibleSlots.end())
-				{
-					VLC->arth->equipArtifact(hero->artifWorn, *slot, toGive->id, &hero->bonuses);
-				}
+				if(slot != toGive->possibleSlots.end())
+					VLC->arth->equipArtifact(hero->artifWorn, *slot, toGive->id);
 				else
 				else
  					hero->giveArtifact(toGive->id);
  					hero->giveArtifact(toGive->id);
 			}
 			}

+ 1 - 1
lib/HeroBonus.h

@@ -377,7 +377,7 @@ public:
 
 
 	enum ENodeTypes
 	enum ENodeTypes
 	{
 	{
-		UNKNOWN, STACK, SPECIALITY
+		UNKNOWN, STACK, SPECIALITY, ARTIFACT
 	};
 	};
 };
 };
 
 

+ 1 - 0
lib/NetPacks.h

@@ -588,6 +588,7 @@ struct SetHeroArtifacts : public CPackForClient //509
 		h & hid & artifacts & artifWorn;
 		h & hid & artifacts & artifWorn;
 	}
 	}
 
 
+	std::vector<ui32> equiped, unequiped; //used locally
 	BonusList gained, lost; //used locally as hlp when applying
 	BonusList gained, lost; //used locally as hlp when applying
 };   
 };   
 
 

+ 19 - 38
lib/NetPacksLib.cpp

@@ -301,12 +301,12 @@ DLL_EXPORT void RemoveObject::applyGs( CGameState *gs )
 		gs->getPlayer(player)->heroes.erase(nitr);
 		gs->getPlayer(player)->heroes.erase(nitr);
 		h->tempOwner = 255; //no one owns beaten hero
 		h->tempOwner = 255; //no one owns beaten hero
 
 
-		if(h->visitedTown)
+		if(CGTownInstance *t = const_cast<CGTownInstance *>(h->visitedTown))
 		{
 		{
 			if(h->inTownGarrison)
 			if(h->inTownGarrison)
-				h->visitedTown->garrisonHero = NULL;
+				t->garrisonHero = NULL;
 			else
 			else
-				h->visitedTown->visitingHero = NULL;
+				t->visitingHero = NULL;
 			h->visitedTown = NULL;
 			h->visitedTown = NULL;
 		}
 		}
 
 
@@ -382,10 +382,11 @@ void TryMoveHero::applyGs( CGameState *gs )
 	}
 	}
 	else if(result == DISEMBARK) //hero leaves boat to dest tile
 	else if(result == DISEMBARK) //hero leaves boat to dest tile
 	{
 	{
-		h->boat->direction = h->moveDir;
-		h->boat->pos = start;
-		h->boat->hero = NULL;
-		gs->map->addBlockVisTiles(h->boat);
+		CGBoat *b = const_cast<CGBoat *>(h->boat);
+		b->direction = h->moveDir;
+		b->pos = start;
+		b->hero = NULL;
+		gs->map->addBlockVisTiles(b);
 		h->boat = NULL;
 		h->boat = NULL;
 	}
 	}
 
 
@@ -393,8 +394,8 @@ void TryMoveHero::applyGs( CGameState *gs )
 	{
 	{
 		gs->map->removeBlockVisTiles(h);
 		gs->map->removeBlockVisTiles(h);
 		h->pos = end;
 		h->pos = end;
-		if(h->boat)
-			h->boat->pos = end;
+		if(CGBoat *b = const_cast<CGBoat *>(h->boat))
+			b->pos = end;
 		gs->map->addBlockVisTiles(h);
 		gs->map->addBlockVisTiles(h);
 	}
 	}
 
 
@@ -413,8 +414,9 @@ DLL_EXPORT void SetGarrisons::applyGs( CGameState *gs )
 		else if(ai->ID==HEROI_TYPE)
 		else if(ai->ID==HEROI_TYPE)
 		{
 		{
 			CGHeroInstance *h =  static_cast<CGHeroInstance*>(ai);
 			CGHeroInstance *h =  static_cast<CGHeroInstance*>(ai);
-			if(h->visitedTown && h->inTownGarrison)
-				h->visitedTown->setArmy(i->second);
+			CGTownInstance *t = const_cast<CGTownInstance *>(h->visitedTown);
+			if(t && h->inTownGarrison)
+				t->setArmy(i->second);
 		}
 		}
 	}
 	}
 }
 }
@@ -470,7 +472,6 @@ DLL_EXPORT void SetHeroesInTown::applyGs( CGameState *gs )
 DLL_EXPORT void SetHeroArtifacts::applyGs( CGameState *gs )
 DLL_EXPORT void SetHeroArtifacts::applyGs( CGameState *gs )
 {
 {
 	CGHeroInstance *h = gs->getHero(hid);
 	CGHeroInstance *h = gs->getHero(hid);
-	std::vector<ui32> equiped, unequiped;
 	for(std::map<ui16,ui32>::const_iterator i = h->artifWorn.begin(); i != h->artifWorn.end(); i++)
 	for(std::map<ui16,ui32>::const_iterator i = h->artifWorn.begin(); i != h->artifWorn.end(); i++)
 		if(!vstd::contains(artifWorn,i->first)  ||  artifWorn[i->first] != i->second)
 		if(!vstd::contains(artifWorn,i->first)  ||  artifWorn[i->first] != i->second)
 			unequiped.push_back(i->second);
 			unequiped.push_back(i->second);
@@ -479,37 +480,14 @@ 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];
-		art.addBonusesTo(&h->bonuses);
-		art.addBonusesTo(&gained);
-	}
-
 	//update hero data
 	//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)
-	{
-		//if hero still has equipped at least one artifact of that type, don't remove bonuses
-		if(h->getArtPos(id) >= 0)
-			continue;
-
-		CArtifact &art = *VLC->arth->artifacts[id];
-		art.removeBonusesFrom(&h->bonuses);
-		art.addBonusesTo(&lost);
-	}
 }
 }
 
 
 DLL_EXPORT void SetHeroArtifacts::setArtAtPos(ui16 pos, int art)
 DLL_EXPORT void SetHeroArtifacts::setArtAtPos(ui16 pos, int art)
 {
 {
-	if(art<0)
+	if(art < 0)
 	{
 	{
 		if(pos<19)
 		if(pos<19)
 			VLC->arth->unequipArtifact(artifWorn, pos);
 			VLC->arth->unequipArtifact(artifWorn, pos);
@@ -518,9 +496,12 @@ DLL_EXPORT void SetHeroArtifacts::setArtAtPos(ui16 pos, int art)
 	}
 	}
 	else
 	else
 	{
 	{
-		if (pos < 19) {
+		if (pos < 19) 
+		{
 			VLC->arth->equipArtifact(artifWorn, pos, (ui32) art);
 			VLC->arth->equipArtifact(artifWorn, pos, (ui32) art);
-		} else { // Goes into the backpack.
+		} 
+		else // Goes into the backpack.
+		{ 
 			if(pos - 19 < artifacts.size())
 			if(pos - 19 < artifacts.size())
 				artifacts.insert(artifacts.begin() + (pos - 19), art);
 				artifacts.insert(artifacts.begin() + (pos - 19), art);
 			else
 			else

+ 12 - 12
lib/map.cpp

@@ -920,39 +920,39 @@ void Mapa::loadHero( CGObjectInstance * &nobj, const unsigned char * bufor, int
 		for(int pom=0;pom<16;pom++)
 		for(int pom=0;pom<16;pom++)
 		{
 		{
 			int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 			int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
-			if(id!=artmask)
-				VLC->arth->equipArtifact(nhi->artifWorn, pom, id, &nhi->bonuses);
+			if(id != artmask)
+				VLC->arth->equipArtifact(nhi->artifWorn, pom, id);
 		}
 		}
 		//misc5 art //17
 		//misc5 art //17
 		if(version>=SoD)
 		if(version>=SoD)
 		{
 		{
 			int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 			int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 			if(id!=artmask)
 			if(id!=artmask)
-				VLC->arth->equipArtifact(nhi->artifWorn, 16, id, &nhi->bonuses);
+				VLC->arth->equipArtifact(nhi->artifWorn, 16, id);
 			else
 			else
-				VLC->arth->equipArtifact(nhi->artifWorn, 16, 3, &nhi->bonuses); //catapult by default
+				VLC->arth->equipArtifact(nhi->artifWorn, 16, 3); //catapult by default
 		}
 		}
 		//spellbook
 		//spellbook
 		int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 		int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 		if(id!=artmask)
 		if(id!=artmask)
-			VLC->arth->equipArtifact(nhi->artifWorn, 17, id, &nhi->bonuses);
+			VLC->arth->equipArtifact(nhi->artifWorn, 17, id);
 		//19 //???what is that? gap in file or what? - it's probably fifth slot..
 		//19 //???what is that? gap in file or what? - it's probably fifth slot..
 		if(version>RoE)
 		if(version>RoE)
 		{
 		{
 			id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 			id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 			if(id!=artmask)
 			if(id!=artmask)
-				VLC->arth->equipArtifact(nhi->artifWorn, 18, id, &nhi->bonuses);
+				VLC->arth->equipArtifact(nhi->artifWorn, 18, id);
 		}
 		}
 		else
 		else
 			i+=1;
 			i+=1;
 		//bag artifacts //20
 		//bag artifacts //20
 		int amount = readNormalNr(bufor,i, 2); i+=2; //number of artifacts in hero's bag
 		int amount = readNormalNr(bufor,i, 2); i+=2; //number of artifacts in hero's bag
-		if(amount>0)
+		if(amount > 0)
 		{
 		{
-			for(int ss=0; ss<amount; ++ss)
+			for(int ss = 0; ss < amount; ++ss)
 			{
 			{
 				id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 				id = readNormalNr(bufor,i, artidlen); i+=artidlen;
-				if(id!=artmask)
+				if(id != artmask)
 					nhi->giveArtifact(id);
 					nhi->giveArtifact(id);
 			}
 			}
 		}
 		}
@@ -1160,7 +1160,7 @@ void Mapa::readPredefinedHeroes( const unsigned char * bufor, int &i)
 					{
 					{
 						int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 						int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 						if(id!=artmask)
 						if(id!=artmask)
-							VLC->arth->equipArtifact(cgh->artifWorn, pom, id, &cgh->bonuses);
+							VLC->arth->equipArtifact(cgh->artifWorn, pom, id);
 					}
 					}
 					//misc5 art //17
 					//misc5 art //17
 					if(version>=SoD)
 					if(version>=SoD)
@@ -1173,13 +1173,13 @@ void Mapa::readPredefinedHeroes( const unsigned char * bufor, int &i)
 					//spellbook
 					//spellbook
 					int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 					int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 					if(id!=artmask)
 					if(id!=artmask)
-						VLC->arth->equipArtifact(cgh->artifWorn, 17, id, &cgh->bonuses);
+						VLC->arth->equipArtifact(cgh->artifWorn, 17, id);
 					//19 //???what is that? gap in file or what? - it's probably fifth slot..
 					//19 //???what is that? gap in file or what? - it's probably fifth slot..
 					if(version>RoE)
 					if(version>RoE)
 					{
 					{
 						id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 						id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 						if(id!=artmask)
 						if(id!=artmask)
-							VLC->arth->equipArtifact(cgh->artifWorn, 18, id, &cgh->bonuses);
+							VLC->arth->equipArtifact(cgh->artifWorn, 18, id);
 					}
 					}
 					else
 					else
 						i+=1;
 						i+=1;

+ 15 - 8
server/CGameHandler.cpp

@@ -2926,7 +2926,8 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
 	const CArtifact *srcArtifact = srcHero->getArt(srcSlot);
 	const CArtifact *srcArtifact = srcHero->getArt(srcSlot);
 	const CArtifact *destArtifact = destHero->getArt(destSlot);
 	const CArtifact *destArtifact = destHero->getArt(destSlot);
 
 
-	if (srcArtifact == NULL) {
+	if (srcArtifact == NULL)
+	{
 		complain("No artifact to swap!");
 		complain("No artifact to swap!");
 		return false;
 		return false;
 	}
 	}
@@ -2937,7 +2938,8 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
 	sha.artifWorn = srcHero->artifWorn;
 	sha.artifWorn = srcHero->artifWorn;
 
 
 	// Combinational artifacts needs to be removed first so they don't get denied movement because of their own locks.
 	// Combinational artifacts needs to be removed first so they don't get denied movement because of their own locks.
-	if (srcHeroID == destHeroID && srcSlot < 19 && destSlot < 19) {
+	if (srcHeroID == destHeroID && srcSlot < 19 && destSlot < 19) 
+	{
 		sha.setArtAtPos(srcSlot, -1);
 		sha.setArtAtPos(srcSlot, -1);
 		if (!vstd::contains(sha.artifWorn, destSlot))
 		if (!vstd::contains(sha.artifWorn, destSlot))
 			destArtifact = NULL;
 			destArtifact = NULL;
@@ -2952,17 +2954,20 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
 		return false;
 		return false;
 	}
 	}
 
 
-	if ((srcArtifact && srcArtifact->id == 145) || (destArtifact && destArtifact->id == 145)) {
+	if ((srcArtifact && srcArtifact->id == 145) || (destArtifact && destArtifact->id == 145)) 
+	{
 		complain("Cannot move artifact locks.");
 		complain("Cannot move artifact locks.");
 		return false;
 		return false;
 	}
 	}
 
 
-	if (destSlot >= 19 && srcArtifact->isBig()) {
+	if (destSlot >= 19 && srcArtifact->isBig()) 
+	{
 		complain("Cannot put big artifacts in backpack!");
 		complain("Cannot put big artifacts in backpack!");
 		return false;
 		return false;
 	}
 	}
 
 
-	if (srcSlot == 16 || destSlot == 16) {
+	if (srcSlot == 16 || destSlot == 16) 
+	{
 		complain("Cannot move catapult!");
 		complain("Cannot move catapult!");
 		return false;
 		return false;
 	}
 	}
@@ -2979,7 +2984,8 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
 		sha.setArtAtPos(srcSlot, destArtifact ? destArtifact->id : -1);
 		sha.setArtAtPos(srcSlot, destArtifact ? destArtifact->id : -1);
 
 
 	// Internal hero artifact arrangement.
 	// Internal hero artifact arrangement.
-	if(srcHero == destHero) {
+	if(srcHero == destHero) 
+	{
 		// Correction for destination from removing source artifact in backpack.
 		// Correction for destination from removing source artifact in backpack.
 		if (srcSlot >= 19 && destSlot >= 19 && srcSlot < destSlot)
 		if (srcSlot >= 19 && destSlot >= 19 && srcSlot < destSlot)
 			destSlot--;
 			destSlot--;
@@ -2987,7 +2993,8 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
 		sha.setArtAtPos(destSlot, srcHero->getArtAtPos(srcSlot));
 		sha.setArtAtPos(destSlot, srcHero->getArtAtPos(srcSlot));
 	}
 	}
 	sendAndApply(&sha);
 	sendAndApply(&sha);
-	if (srcHeroID != destHeroID) {
+	if (srcHeroID != destHeroID) 
+	{
 		// Exchange between two different heroes.
 		// Exchange between two different heroes.
 		sha.hid = destHeroID;
 		sha.hid = destHeroID;
 		sha.artifacts = destHero->artifacts;
 		sha.artifacts = destHero->artifacts;
@@ -3112,7 +3119,7 @@ bool CGameHandler::assembleArtifacts (si32 heroID, ui16 artifactSlot, bool assem
 bool CGameHandler::buyArtifact( ui32 hid, si32 aid )
 bool CGameHandler::buyArtifact( ui32 hid, si32 aid )
 {
 {
 	CGHeroInstance *hero = gs->getHero(hid);
 	CGHeroInstance *hero = gs->getHero(hid);
-	CGTownInstance *town = hero->visitedTown;
+	CGTownInstance *town = const_cast<CGTownInstance*>(hero->visitedTown);
 	if(aid==0) //spellbook
 	if(aid==0) //spellbook
 	{
 	{
 		if(!vstd::contains(town->builtBuildings,si32(0)) && complain("Cannot buy a spellbook, no mage guild in the town!")
 		if(!vstd::contains(town->builtBuildings,si32(0)) && complain("Cannot buy a spellbook, no mage guild in the town!")