Browse Source

* Changed artifact handling so bonuses from constituent artifacts in combinational ones are added implicitly.
* Discovered bug when attacking guarded visitables. Needs to wait before battle is over.

OnionKnight 15 years ago
parent
commit
87e66fff31
9 changed files with 105 additions and 73 deletions
  1. 5 4
      client/NetPacksClient.cpp
  2. 59 25
      hch/CArtHandler.cpp
  3. 4 2
      hch/CArtHandler.h
  4. 10 7
      hch/CObjectHandler.cpp
  5. 1 2
      lib/CGameState.cpp
  6. 1 1
      lib/NetPacks.h
  7. 5 18
      lib/NetPacksLib.cpp
  8. 8 8
      lib/map.cpp
  9. 12 6
      server/CGameHandler.cpp

+ 5 - 4
client/NetPacksClient.cpp

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

+ 59 - 25
hch/CArtHandler.cpp

@@ -3,6 +3,8 @@
 #include "CArtHandler.h"
 #include "CArtHandler.h"
 #include "CLodHandler.h"
 #include "CLodHandler.h"
 #include "CGeneralTextHandler.h"
 #include "CGeneralTextHandler.h"
+#include <boost/bind.hpp>
+#include <boost/foreach.hpp>
 #include <boost/assign/std/vector.hpp>
 #include <boost/assign/std/vector.hpp>
 #include <boost/assign/list_of.hpp>
 #include <boost/assign/list_of.hpp>
 #include <boost/lexical_cast.hpp>
 #include <boost/lexical_cast.hpp>
@@ -123,6 +125,44 @@ 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
+{
+	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);
+		}
+	}
+}
+
+/**
+ * Removes all the bonuses of this artifact, including possible constituents, from
+ * a bonus list.
+ */
+void CArtifact::removeBonusesFrom (BonusList *otherBonuses) const
+{
+	if (constituents != NULL) {
+		BOOST_FOREACH(ui32 artifactID, *constituents) {
+			VLC->arth->artifacts[artifactID].removeBonusesFrom(otherBonuses);
+		}
+	}
+
+	while (1) {
+		std::list<Bonus>::const_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()
 {
 {
 	VLC->arth = this;
 	VLC->arth = this;
@@ -521,23 +561,17 @@ void CArtHandler::addBonuses()
 	ART_PRIM_SKILL(128, 3, +6);
 	ART_PRIM_SKILL(128, 3, +6);
 
 
 	//Angelic Alliance
 	//Angelic Alliance
-	ART_ALL_PRIM_SKILLS(129, +21);
 	giveArtBonus(129, Bonus::NONEVIL_ALIGNMENT_MIX, 0);
 	giveArtBonus(129, Bonus::NONEVIL_ALIGNMENT_MIX, 0);
 	giveArtBonus(129, Bonus::OPENING_BATTLE_SPELL, 10, 29); // Prayer
 	giveArtBonus(129, Bonus::OPENING_BATTLE_SPELL, 10, 29); // Prayer
 
 
 	//Cloak of the Undead King
 	//Cloak of the Undead King
-	giveArtBonus(130, Bonus::SECONDARY_SKILL_PREMY, +30, 12);
-	giveArtBonus(130, Bonus::SECONDARY_SKILL_PREMY, +30, 12);
 	giveArtBonus(130, Bonus::IMPROVED_NECROMANCY, 0);
 	giveArtBonus(130, Bonus::IMPROVED_NECROMANCY, 0);
 
 
 	//Elixir of Life
 	//Elixir of Life
-	giveArtBonus(131, Bonus::STACK_HEALTH, +4);
 	giveArtBonus(131, Bonus::STACK_HEALTH, +25, -1, Bonus::PERCENT_TO_BASE);
 	giveArtBonus(131, Bonus::STACK_HEALTH, +25, -1, Bonus::PERCENT_TO_BASE);
 	giveArtBonus(131, Bonus::HP_REGENERATION, +50);
 	giveArtBonus(131, Bonus::HP_REGENERATION, +50);
 
 
 	//Armor of the Damned
 	//Armor of the Damned
-	ART_ATTACK_AND_DEFENSE(132, +3);
-	ART_POWER_AND_KNOWLEDGE(132, +2);
 	giveArtBonus(132, Bonus::OPENING_BATTLE_SPELL, 50, 54); // Slow
 	giveArtBonus(132, Bonus::OPENING_BATTLE_SPELL, 50, 54); // Slow
 	giveArtBonus(132, Bonus::OPENING_BATTLE_SPELL, 50, 47); // Disrupting Ray
 	giveArtBonus(132, Bonus::OPENING_BATTLE_SPELL, 50, 47); // Disrupting Ray
 	giveArtBonus(132, Bonus::OPENING_BATTLE_SPELL, 50, 45); // Weakness
 	giveArtBonus(132, Bonus::OPENING_BATTLE_SPELL, 50, 45); // Weakness
@@ -547,26 +581,16 @@ void CArtHandler::addBonuses()
 	giveArtBonus(133, Bonus::CREATURE_GROWTH_PERCENT, 50);
 	giveArtBonus(133, Bonus::CREATURE_GROWTH_PERCENT, 50);
 
 
 	//Power of the Dragon Father
 	//Power of the Dragon Father
-	ART_ALL_PRIM_SKILLS(134, +16);
-	giveArtBonus(134, Bonus::MORALE, +1);
-	giveArtBonus(134, Bonus::LUCK, +1);
 	giveArtBonus(134, Bonus::LEVEL_SPELL_IMMUNITY, 4);
 	giveArtBonus(134, Bonus::LEVEL_SPELL_IMMUNITY, 4);
 
 
 	//Titan's Thunder
 	//Titan's Thunder
-	// should also add a permanent spell book, somehow.
-	ART_ATTACK_AND_DEFENSE(135, +9);
-	ART_POWER_AND_KNOWLEDGE(135, +8);
+	// FIXME: should also add a permanent spell book, somehow.
 	giveArtBonus(135, Bonus::SPELL, 3, 57);
 	giveArtBonus(135, Bonus::SPELL, 3, 57);
 
 
 	//Admiral's Hat
 	//Admiral's Hat
-	giveArtBonus(136, Bonus::SEA_MOVEMENT, +1500);
-	giveArtBonus(136, Bonus::WHIRLPOOL_PROTECTION, 0);
-	giveArtBonus(136, Bonus::SPELL, 3, 0);
-	giveArtBonus(136, Bonus::SPELL, 3, 1);
 	giveArtBonus(136, Bonus::FREE_SHIP_BOARDING, 0);
 	giveArtBonus(136, Bonus::FREE_SHIP_BOARDING, 0);
 
 
 	//Bow of the Sharpshooter
 	//Bow of the Sharpshooter
-	giveArtBonus(137, Bonus::SECONDARY_SKILL_PREMY, +30, 1);
 	giveArtBonus(137, Bonus::NO_SHOTING_PENALTY, 0);
 	giveArtBonus(137, Bonus::NO_SHOTING_PENALTY, 0);
 	giveArtBonus(137, Bonus::FREE_SHOOTING, 0);
 	giveArtBonus(137, Bonus::FREE_SHOOTING, 0);
 
 
@@ -574,13 +598,13 @@ void CArtHandler::addBonuses()
 	giveArtBonus(138, Bonus::FULL_MANA_REGENERATION, 0);
 	giveArtBonus(138, Bonus::FULL_MANA_REGENERATION, 0);
 
 
 	//Ring of the Magi
 	//Ring of the Magi
-	giveArtBonus(139, Bonus::SPELL_DURATION, +56);
+	giveArtBonus(139, Bonus::SPELL_DURATION, +50);
 
 
 	//Cornucopia
 	//Cornucopia
-	giveArtBonus(140, Bonus::GENERATE_RESOURCE, +5, 1);
-	giveArtBonus(140, Bonus::GENERATE_RESOURCE, +5, 3);
-	giveArtBonus(140, Bonus::GENERATE_RESOURCE, +5, 4);
-	giveArtBonus(140, Bonus::GENERATE_RESOURCE, +5, 5);
+	giveArtBonus(140, Bonus::GENERATE_RESOURCE, +4, 1);
+	giveArtBonus(140, Bonus::GENERATE_RESOURCE, +4, 3);
+	giveArtBonus(140, Bonus::GENERATE_RESOURCE, +4, 4);
+	giveArtBonus(140, Bonus::GENERATE_RESOURCE, +4, 5);
 }
 }
 
 
 void CArtHandler::clear()
 void CArtHandler::clear()
@@ -596,10 +620,12 @@ void CArtHandler::clear()
  * Locally equips an artifact to a hero's worn slots. Unequips an already present artifact.
  * Locally equips an artifact to a hero's worn slots. Unequips an already present artifact.
  * Does not test if the operation is legal.
  * Does not test if the operation is legal.
  * @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.
  */
  */
-void CArtHandler::equipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID, ui32 artifactID)
+void CArtHandler::equipArtifact
+	(std::map<ui16, ui32> &artifWorn, ui16 slotID, ui32 artifactID, BonusList *bonuses)
 {
 {
-	unequipArtifact(artifWorn, slotID);
+	unequipArtifact(artifWorn, slotID, bonuses);
 
 
 	const CArtifact &artifact = artifacts[artifactID];
 	const CArtifact &artifact = artifacts[artifactID];
 
 
@@ -625,14 +651,19 @@ void CArtHandler::equipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID, u
 			}
 			}
 		}
 		}
 	}
 	}
+
+	if (bonuses != NULL)
+		artifact.addBonusesTo(bonuses);
 }
 }
 
 
 /**
 /**
  * Locally unequips an artifact from a hero's worn slots.
  * Locally unequips an artifact from a hero's worn slots.
  * Does not test if the operation is legal.
  * Does not test if the operation is legal.
  * @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.
  */
  */
-void CArtHandler::unequipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID)
+void CArtHandler::unequipArtifact
+	(std::map<ui16, ui32> &artifWorn, ui16 slotID, BonusList *bonuses)
 {
 {
 	if (!vstd::contains(artifWorn, slotID))
 	if (!vstd::contains(artifWorn, slotID))
 		return;
 		return;
@@ -661,4 +692,7 @@ void CArtHandler::unequipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID)
 			}
 			}
 		}
 		}
 	}
 	}
+
+	if (bonuses != NULL)
+		artifact.removeBonusesFrom(bonuses);
 }
 }

+ 4 - 2
hch/CArtHandler.h

@@ -28,6 +28,8 @@ public:
 	bool isBig () const;
 	bool isBig () const;
 	bool fitsAt (const std::map<ui16, ui32> &artifWorn, ui16 slot) const;
 	bool fitsAt (const std::map<ui16, ui32> &artifWorn, ui16 slot) const;
 	bool canBeAssembledTo (const std::map<ui16, ui32> &artifWorn, ui32 artifactID) const;
 	bool canBeAssembledTo (const std::map<ui16, ui32> &artifWorn, ui32 artifactID) const;
+	void addBonusesTo (BonusList *otherBonuses) const;
+	void removeBonusesFrom (BonusList *otherBonuses) const;
 
 
 	ui32 price;
 	ui32 price;
 	std::vector<ui16> possibleSlots; //ids of slots where artifact can be placed
 	std::vector<ui16> possibleSlots; //ids of slots where artifact can be placed
@@ -56,8 +58,8 @@ public:
 	void addBonuses();
 	void addBonuses();
 	void clear();
 	void clear();
 	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);
-	void unequipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID);
+	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);
 	static int convertMachineID(int id, bool creToArt);
 	static int convertMachineID(int id, bool creToArt);
 	CArtHandler();
 	CArtHandler();
 	~CArtHandler();
 	~CArtHandler();

+ 10 - 7
hch/CObjectHandler.cpp

@@ -722,9 +722,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); //give spellbook
+		VLC->arth->equipArtifact(artifWorn, 17, 0, &bonuses); //give spellbook
 	}
 	}
-	VLC->arth->equipArtifact(artifWorn, 16, 3); //everyone has a catapult
+	VLC->arth->equipArtifact(artifWorn, 16, 3, &bonuses); //everyone has a catapult
 
 
 	if(portrait < 0 || portrait == 255)
 	if(portrait < 0 || portrait == 255)
 		portrait = subID;
 		portrait = subID;
@@ -775,10 +775,14 @@ void CGHeroInstance::initHero()
 				switch (creID)
 				switch (creID)
 				{
 				{
 				case 145: //catapult
 				case 145: //catapult
-					VLC->arth->equipArtifact(artifWorn, 16, 3);
+					VLC->arth->equipArtifact(artifWorn, 16, 3, &bonuses);
 					break;
 					break;
 				default:
 				default:
-					VLC->arth->equipArtifact(artifWorn, 9+CArtHandler::convertMachineID(creID,true), CArtHandler::convertMachineID(creID,true));
+					VLC->arth->equipArtifact(
+						artifWorn,
+						9+CArtHandler::convertMachineID(creID,true),
+						CArtHandler::convertMachineID(creID,true),
+						&bonuses);
 					break;
 					break;
 				}
 				}
 			}
 			}
@@ -1057,7 +1061,7 @@ void CGHeroInstance::giveArtifact (ui32 aid)
 	if (artifact.isBig()) {
 	if (artifact.isBig()) {
 		for (std::vector<ui16>::const_iterator it = artifact.possibleSlots.begin(); it != artifact.possibleSlots.end(); ++it) {
 		for (std::vector<ui16>::const_iterator it = artifact.possibleSlots.begin(); it != artifact.possibleSlots.end(); ++it) {
 			if (!vstd::contains(artifWorn, *it)) {
 			if (!vstd::contains(artifWorn, *it)) {
-				VLC->arth->equipArtifact(artifWorn, *it, aid);
+				VLC->arth->equipArtifact(artifWorn, *it, aid, &bonuses);
 				break;
 				break;
 			}
 			}
 		}
 		}
@@ -1073,8 +1077,7 @@ void CGHeroInstance::recreateArtBonuses()
 	for (std::map<ui16,ui32>::iterator ari = artifWorn.begin(); ari != artifWorn.end(); ari++)
 	for (std::map<ui16,ui32>::iterator ari = artifWorn.begin(); ari != artifWorn.end(); ari++)
 	{
 	{
 		CArtifact &art = VLC->arth->artifacts[ari->second];
 		CArtifact &art = VLC->arth->artifacts[ari->second];
-		for(std::list<Bonus>::iterator i = art.bonuses.begin(); i != art.bonuses.end(); i++)
-			bonuses.push_back(*i);
+		art.addBonusesTo(&bonuses);
 	}
 	}
 }
 }
 
 

+ 1 - 2
lib/CGameState.cpp

@@ -1464,8 +1464,7 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
 				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())
 				if(slot!=toGive->possibleSlots.end())
 				{
 				{
-					VLC->arth->equipArtifact(hero->artifWorn, *slot, toGive->id);
-					hero->recreateArtBonuses();
+					VLC->arth->equipArtifact(hero->artifWorn, *slot, toGive->id, &hero->bonuses);
 				}
 				}
 				else
 				else
 					hero->giveArtifact(toGive->id);
 					hero->giveArtifact(toGive->id);

+ 1 - 1
lib/NetPacks.h

@@ -575,7 +575,7 @@ struct SetHeroArtifacts : public CPackForClient //509
 		h & hid & artifacts & artifWorn;
 		h & hid & artifacts & artifWorn;
 	}
 	}
 
 
-	std::vector<Bonus*> gained, lost; //used locally as hlp when applying
+	BonusList gained, lost; //used locally as hlp when applying
 };   
 };   
 
 
 struct HeroRecruited : public CPackForClient //515
 struct HeroRecruited : public CPackForClient //515

+ 5 - 18
lib/NetPacksLib.cpp

@@ -462,11 +462,8 @@ DLL_EXPORT void SetHeroArtifacts::applyGs( CGameState *gs )
 			continue;
 			continue;
 
 
 		CArtifact &art = VLC->arth->artifacts[id];
 		CArtifact &art = VLC->arth->artifacts[id];
-		for(std::list<Bonus>::iterator i = art.bonuses.begin(); i != art.bonuses.end(); i++)
-		{
-			gained.push_back(&*i);
-			h->bonuses.push_back(*i);
-		}
+		art.addBonusesTo(&h->bonuses);
+		art.addBonusesTo(&gained);
 	}
 	}
 
 
 	//update hero data
 	//update hero data
@@ -480,19 +477,9 @@ DLL_EXPORT void SetHeroArtifacts::applyGs( CGameState *gs )
 		if(h->getArtPos(id) >= 0)
 		if(h->getArtPos(id) >= 0)
 			continue;
 			continue;
 
 
-		while(1)
-		{
-			std::list<Bonus>::iterator hlp = std::find_if(h->bonuses.begin(),h->bonuses.end(),boost::bind(Bonus::IsFrom,_1,Bonus::ARTIFACT,id));
-			if(hlp != h->bonuses.end())
-			{
-				lost.push_back(&*hlp);
-				h->bonuses.erase(hlp);
-			}
-			else
-			{
-				break;
-			}
-		}
+		CArtifact &art = VLC->arth->artifacts[id];
+		art.removeBonusesFrom(&h->bonuses);
+		art.addBonusesTo(&lost);
 	}
 	}
 }
 }
 
 

+ 8 - 8
lib/map.cpp

@@ -904,27 +904,27 @@ void Mapa::loadHero( CGObjectInstance * &nobj, const unsigned char * bufor, int
 		{
 		{
 			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, pom, id);
+				VLC->arth->equipArtifact(nhi->artifWorn, pom, id, &nhi->bonuses);
 		}
 		}
 		//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);
+				VLC->arth->equipArtifact(nhi->artifWorn, 16, id, &nhi->bonuses);
 			else
 			else
-				VLC->arth->equipArtifact(nhi->artifWorn, 16, 3); //catapult by default
+				VLC->arth->equipArtifact(nhi->artifWorn, 16, 3, &nhi->bonuses); //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);
+			VLC->arth->equipArtifact(nhi->artifWorn, 17, id, &nhi->bonuses);
 		//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);
+				VLC->arth->equipArtifact(nhi->artifWorn, 18, id, &nhi->bonuses);
 		}
 		}
 		else
 		else
 			i+=1;
 			i+=1;
@@ -1143,7 +1143,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);
+							VLC->arth->equipArtifact(cgh->artifWorn, pom, id, &cgh->bonuses);
 					}
 					}
 					//misc5 art //17
 					//misc5 art //17
 					if(version>=SoD)
 					if(version>=SoD)
@@ -1156,13 +1156,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);
+						VLC->arth->equipArtifact(cgh->artifWorn, 17, id, &cgh->bonuses);
 					//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);
+							VLC->arth->equipArtifact(cgh->artifWorn, 18, id, &cgh->bonuses);
 					}
 					}
 					else
 					else
 						i+=1;
 						i+=1;

+ 12 - 6
server/CGameHandler.cpp

@@ -1700,6 +1700,18 @@ bool CGameHandler::moveHero( si32 hid, int3 dst, ui8 instant, ui8 asker /*= 255*
 			sendAndApply(&tmh);
 			sendAndApply(&tmh);
 			tlog5 << "Moved to " <<tmh.end<<std::endl;
 			tlog5 << "Moved to " <<tmh.end<<std::endl;
 
 
+			// If a creature guards the tile, block visit.
+			if (gs->map->isInTheMap(guardPos)) {
+				const TerrainTile &guardTile = gs->map->terrain[guardPos.x][guardPos.y][guardPos.z];
+				objectVisited(guardTile.visitableObjects.back(), h);
+
+				// TODO: Need to wait until battle is over.
+
+				// Do not visit anything else if hero died.
+				if (h->getArmy().stacksCount() == 0)
+					return true;
+			}
+
 			//call objects if they are visited
 			//call objects if they are visited
 
 
 			if(t.visitableObjects.size())
 			if(t.visitableObjects.size())
@@ -1715,12 +1727,6 @@ bool CGameHandler::moveHero( si32 hid, int3 dst, ui8 instant, ui8 asker /*= 255*
 // 				objectVisited(obj, h);
 // 				objectVisited(obj, h);
 // 			}
 // 			}
 
 
-			// If a creature guards the tile, block visit.
-			if (gs->map->isInTheMap(guardPos)) {
-				const TerrainTile &guardTile = gs->map->terrain[guardPos.x][guardPos.y][guardPos.z];
-				objectVisited(guardTile.visitableObjects.back(), h);
-			}
-
 			tlog5 << "Movement end!\n";
 			tlog5 << "Movement end!\n";
 			return true;
 			return true;
 		}
 		}