Browse Source

Reverted r1811, r1812, r1813

Michał W. Urbańczyk 15 năm trước cách đây
mục cha
commit
aa131bbf15

+ 0 - 1
CCallback.cpp

@@ -17,7 +17,6 @@
 #include <boost/thread.hpp>
 #include <boost/thread/shared_mutex.hpp>
 #include "hch/CSpellHandler.h"
-#include "hch/CArtHandler.h"
 #ifdef min
 #undef min
 #endif

+ 0 - 1
CCallback.h

@@ -43,7 +43,6 @@ class CMapHeader;
 struct CGPathNode;
 struct CGPath;
 class CGGarrison;
-class CArtifact;
 
 struct InfoAboutTown
 {

+ 5 - 5
client/CKingdomInterface.cpp

@@ -784,7 +784,7 @@ void CKingdomInterface::CHeroItem::setHero(const CGHeroInstance * newHero)
 
 	for (int i=0; i<artifacts.size(); i++)
 	{
-		artifacts[i]->type = hero->getArtAtPos(i)->id;
+		artifacts[i]->type = hero->getArtAtPos(i);
 		if (artifacts[i]->type<0 || artifacts[i]->type == 145 )
 			artifacts[i]->hoverText = CGI->generaltexth->heroscrn[11];
 		else
@@ -796,7 +796,7 @@ void CKingdomInterface::CHeroItem::setHero(const CGHeroInstance * newHero)
 
 	for (int i=0; i<backpack.size(); i++)
 	{
-		backpack[i]->type = hero->getArtAtPos(19+i)->id;
+		backpack[i]->type = hero->getArtAtPos(19+i);
 		if (backpack[i]->type<0)
 			backpack[i]->hoverText ="";
 		else
@@ -847,7 +847,7 @@ void CKingdomInterface::CHeroItem::scrollArts(int move)
 	backpackPos = ( backpackPos + move + hero->artifacts.size()) % hero->artifacts.size();
 	for (int i=0; i<backpack.size(); i++)
 	{
-		backpack[i]->type = hero->getArtAtPos(19+(backpackPos + i)%hero->artifacts.size())->id;
+		backpack[i]->type = hero->getArtAtPos(19+(backpackPos + i)%hero->artifacts.size());
 		if (backpack[i]->type<0)
 			backpack[i]->hoverText ="";
 		else
@@ -912,7 +912,7 @@ void CKingdomInterface::CHeroItem::showAll(SDL_Surface * to)
 		case 0://equipped arts
 			for (int i = iter ; i<iter+9;i++)
 			{
-				int artID = hero->getArtAtPos(i)->id;
+				int artID = hero->getArtAtPos(i);
 				if (artID>=0)
 					blitAt(graphics->artDefs->ourImages[artID].bitmap,pos.x+268+48*(i%9),pos.y+66,to);
 			}
@@ -923,7 +923,7 @@ void CKingdomInterface::CHeroItem::showAll(SDL_Surface * to)
 			int max = hero->artifacts.size();
 			iter = std::min(8, max);
 			for (size_t it = 0 ; it<iter;it++)
-				blitAt(graphics->artDefs->ourImages[hero->artifacts[(it+backpackPos)%max]->id].bitmap,pos.x+293+48*it,pos.y+66,to);
+				blitAt(graphics->artDefs->ourImages[hero->artifacts[(it+backpackPos)%max]].bitmap,pos.x+293+48*it,pos.y+66,to);
 			break;
 	}
 	show(to);

+ 1 - 1
client/Client.cpp

@@ -319,7 +319,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
 	CGI->state = new CGameState();
 	tlog0 <<"\tGamestate: "<<tmh.getDif()<<std::endl;
 	serv = con;
-CConnection &c(*con);
+	CConnection &c(*con);
 	////////////////////////////////////////////////////
 	ui8 pom8;
 	c << ui8(2) << ui8(1); //new game; one client

+ 1 - 2
client/Client.h

@@ -113,8 +113,7 @@ public:
 	void heroVisitCastle(int obj, int heroID){};
 	void stopHeroVisitCastle(int obj, int heroID){};
 	void giveHeroArtifact(int artid, int hid, int position){}; //pos==-1 - first free slot in backpack=0; pos==-2 - default if available or backpack
-	void giveNewArtifact(int hid, int position){};
-	bool removeArtifact(CArtifact* art, int hid){return false;};
+	bool removeArtifact(int artid, int hid){return false;};
 	void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank = false, boost::function<void(BattleResult*)> cb = 0, const CGTownInstance *town = NULL){}; //use hero=NULL for no hero
 	void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false){}; //if any of armies is hero, hero will be used
 	void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false){}; //if any of armies is hero, hero will be used, visitable tile of second obj is place of battle

+ 7 - 7
client/GUIClasses.cpp

@@ -2640,7 +2640,7 @@ void CTradeWindow::CTradeableItem::clickLeft(tribool down, bool previousState)
 				movedArt = CGI->arth->artifacts[id];
 				aw->arts->commonInfo->srcAOH = aw->arts;
 				aw->arts->commonInfo->srcArtifact = movedArt;
-				aw->arts->commonInfo->srcSlotID = 19 + vstd::findPos(aw->hero->artifacts, const_cast<CArtifact*>(movedArt));
+				aw->arts->commonInfo->srcSlotID = 19 + vstd::findPos(aw->hero->artifacts, movedArt->id);
 
 				aw->arts->commonInfo->destAOH = aw->arts;
 				CGI->curh->dragAndDropCursor(graphics->artDefs->ourImages[movedArt->id].bitmap);
@@ -3614,10 +3614,10 @@ void CAltarWindow::SacrificeAll()
 	}
 	else
 	{
-		for(std::map<ui16,CArtifact*>::const_iterator i = hero->artifWorn.begin(); i != hero->artifWorn.end(); i++)
+		for(std::map<ui16,ui32>::const_iterator i = hero->artifWorn.begin(); i != hero->artifWorn.end(); i++)
 		{
-			if(i->second->id != 145) //ignore locks from assembled artifacts
-				moveFromSlotToAltar(i->first, NULL, i->second->id);
+			if(i->second != 145) //ignore locks from assembled artifacts
+				moveFromSlotToAltar(i->first, NULL, i->second);
 		}
 
 		SacrificeBackpack();
@@ -3770,13 +3770,13 @@ void CAltarWindow::SacrificeBackpack()
 
 	for (int i = 0; i < hero->artifacts.size(); i++)
 	{
-		if(vstd::contains(toOmmit, hero->artifacts[i]->id))
+		if(vstd::contains(toOmmit, hero->artifacts[i]))
 		{
-			toOmmit -= hero->artifacts[i]->id;
+			toOmmit -= hero->artifacts[i];
 			continue;
 		}
 
-		putOnAltar(NULL, hero->artifacts[i]->id);
+		putOnAltar(NULL, hero->artifacts[i]);
 	}
 	arts->scrollBackpack(0);
 	calcTotalExp();

+ 33 - 70
hch/CArtHandler.cpp

@@ -10,7 +10,6 @@
 #include <boost/lexical_cast.hpp>
 #include <boost/foreach.hpp>
 #include <boost/random/linear_congruential.hpp>
-#include <boost/algorithm/string/replace.hpp>
 #include "../lib/VCMI_Lib.h"
 extern CLodHandler *bitmaph;
 using namespace boost::assign;
@@ -48,31 +47,25 @@ bool CArtifact::isBig () const
 	return VLC->arth->isBigArtifact(id);
 }
 
-bool CArtifact::isModable () const
-{
-	return (bool)dynamic_cast<const IModableArt *>(this);
-}
-
 /**
  * Checks whether the artifact fits at a given slot.
  * @param artifWorn A hero's set of worn artifacts.
  */
-bool CArtifact::fitsAt (const std::map<ui16, CArtifact*> &artifWorn, ui16 slotID) const
+bool CArtifact::fitsAt (const std::map<ui16, ui32> &artifWorn, ui16 slotID) const
 {
 	if (!vstd::contains(possibleSlots, slotID))
 		return false;
 
 	// Can't put an artifact in a locked slot.
-	std::map<ui16, CArtifact*>::const_iterator it = artifWorn.find(slotID);
-	if (it != artifWorn.end() && it->second->id == 145)
+	std::map<ui16, ui32>::const_iterator it = artifWorn.find(slotID);
+	if (it != artifWorn.end() && it->second == 145)
 		return false;
 
 	// Check if a combination artifact fits.
 	// TODO: Might want a more general algorithm?
 	//       Assumes that misc & rings fits only in their slots, and others in only one slot and no duplicates.
-	if (constituents != NULL)
-	{
-		std::map<ui16, CArtifact*> tempArtifWorn = artifWorn;
+	if (constituents != NULL) {
+		std::map<ui16, ui32> tempArtifWorn = artifWorn;
 		const ui16 ringSlots[] = {6, 7};
 		const ui16 miscSlots[] = {9, 10, 11, 12, 18};
 		int rings = 0;
@@ -115,7 +108,7 @@ bool CArtifact::fitsAt (const std::map<ui16, CArtifact*> &artifWorn, ui16 slotID
 	return true;
 }
 
-bool CArtifact::canBeAssembledTo (const std::map<ui16, CArtifact*> &artifWorn, ui32 artifactID) const
+bool CArtifact::canBeAssembledTo (const std::map<ui16, ui32> &artifWorn, ui32 artifactID) const
 {
 	if (constituentOf == NULL || !vstd::contains(*constituentOf, artifactID))
 		return false;
@@ -126,9 +119,9 @@ bool CArtifact::canBeAssembledTo (const std::map<ui16, CArtifact*> &artifWorn, u
 	BOOST_FOREACH(ui32 constituentID, *artifact.constituents) 
 	{
 		bool found = false;
-		for (std::map<ui16, CArtifact*>::const_iterator it = artifWorn.begin(); it != artifWorn.end(); ++it) 
+		for (std::map<ui16, ui32>::const_iterator it = artifWorn.begin(); it != artifWorn.end(); ++it) 
 		{
-			if (it->second->id == constituentID) 
+			if (it->second == constituentID) 
 			{
 				found = true;
 				break;
@@ -181,12 +174,6 @@ void CArtifact::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/
 	}
 }
 
-void CScroll::Init()
-{
-	bonuses.push_back (Bonus (Bonus::PERMANENT, Bonus::SPELL, Bonus::ARTIFACT, 1, id, spellid, Bonus::INDEPENDENT_MAX));
-	//boost::algorithm::replace_first(description, "[spell name]", VLC->spellh->spells[spellid].name);
-}
-
 CArtHandler::CArtHandler()
 {
 	VLC->arth = this;
@@ -194,13 +181,11 @@ CArtHandler::CArtHandler()
 	// War machines are the default big artifacts.
 	for (ui32 i = 3; i <= 6; i++)
 		bigArtifacts.insert(i);
-	modableArtifacts = boost::assign::map_list_of(1, 1)(146,3)(147,3)(148,3)(150,3)(151,3)(152,3)(154,3)(156,2);
 }
 
 CArtHandler::~CArtHandler()
 {
-	for (std::vector<CArtifact*>::iterator it = artifacts.begin(); it != artifacts.end(); ++it)
-	{
+	for (std::vector<CArtifact*>::iterator it = artifacts.begin(); it != artifacts.end(); ++it) {
 		delete (*it)->constituents;
 		delete (*it)->constituentOf;
 	}
@@ -220,28 +205,9 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
 	}
 	VLC->generaltexth->artifNames.resize(ARTIFACTS_QUANTITY);
 	VLC->generaltexth->artifDescriptions.resize(ARTIFACTS_QUANTITY);
-	std::map<ui32,ui8>::iterator itr;
 	for (int i=0; i<ARTIFACTS_QUANTITY; i++)
 	{
-		CArtifact *art;
-		if ((itr = modableArtifacts.find(i)) != modableArtifacts.end())
-		{
-			switch (itr->second)
-			{
-				case 1:
-					art = new CScroll;
-					break;
-				case 2:
-					art = new CCustomizableArt;
-					break;
-				case 3:
-					art = new CCommanderArt;
-					break;
-			};
-		}
-		else
-			art = new CArtifact;
-
+		CArtifact *art = new CArtifact;
 		CArtifact &nart = *art;
 		nart.id=i;
 		loadToIt(VLC->generaltexth->artifNames[i],buf,it,4);
@@ -752,39 +718,36 @@ void CArtHandler::clear()
  * @param artifWorn A hero's set of worn artifacts.
  * @param bonuses Optional list of bonuses to update.
  */
-void CArtHandler::equipArtifact(std::map<ui16, CArtifact*> &artifWorn, ui16 slotID, const CArtifact* newArtifact)
+void CArtHandler::equipArtifact(std::map<ui16, ui32> &artifWorn, ui16 slotID, ui32 artifactID)
 {
 	unequipArtifact(artifWorn, slotID);
 
-	if (newArtifact) //false when artifact is NULL -> slot set to empty
-	{
-		const CArtifact &artifact = *newArtifact;
+	const CArtifact &artifact = *artifacts[artifactID];
 
-		// Add artifact.
-		artifWorn[slotID] = const_cast<CArtifact*>(newArtifact);
+	// Add artifact.
+	artifWorn[slotID] = artifactID;
 
-		// Add locks, in reverse order of being removed.
-		if (artifact.constituents != NULL) 
+	// Add locks, in reverse order of being removed.
+	if (artifact.constituents != NULL) 
+	{
+		bool destConsumed = false; // Determines which constituent that will be counted for together with the artifact.
+
+		BOOST_FOREACH(ui32 constituentID, *artifact.constituents) 
 		{
-			bool destConsumed = false; // Determines which constituent that will be counted for together with the artifact.
+			const CArtifact &constituent = *artifacts[constituentID];
 
-			BOOST_FOREACH(ui32 constituentID, *artifact.constituents) 
+			if (!destConsumed && vstd::contains(constituent.possibleSlots, slotID)) 
 			{
-				const CArtifact &constituent = *artifacts[constituentID];
-
-				if (!destConsumed && vstd::contains(constituent.possibleSlots, slotID)) 
-				{
-					destConsumed = true;
-				} 
-				else 
+				destConsumed = true;
+			} 
+			else 
+			{
+				BOOST_FOREACH(ui16 slot, constituent.possibleSlots) 
 				{
-					BOOST_FOREACH(ui16 slot, constituent.possibleSlots) 
+					if (!vstd::contains(artifWorn, slot)) 
 					{
-						if (!vstd::contains(artifWorn, slot)) 
-						{
-							artifWorn[slot] = VLC->arth->artifacts[145]; //lock
-							break;
-						}
+						artifWorn[slot] = 145;
+						break;
 					}
 				}
 			}
@@ -798,12 +761,12 @@ void CArtHandler::equipArtifact(std::map<ui16, CArtifact*> &artifWorn, ui16 slot
  * @param artifWorn A hero's set of worn artifacts.
  * @param bonuses Optional list of bonuses to update.
  */
-void CArtHandler::unequipArtifact(std::map<ui16, CArtifact*> &artifWorn, ui16 slotID)
+void CArtHandler::unequipArtifact(std::map<ui16, ui32> &artifWorn, ui16 slotID)
 {
 	if (!vstd::contains(artifWorn, slotID))
 		return;
 
-	const CArtifact &artifact = *artifWorn[slotID];
+	const CArtifact &artifact = *artifacts[artifWorn[slotID]];
 
 	// Remove artifact, if it's not already removed.
 	artifWorn.erase(slotID);
@@ -825,7 +788,7 @@ void CArtHandler::unequipArtifact(std::map<ui16, CArtifact*> &artifWorn, ui16 sl
 			{
 				BOOST_REVERSE_FOREACH(ui16 slot, constituent.possibleSlots) 
 				{
-					if (vstd::contains(artifWorn, slot) && artifWorn[slot]->id == 145) 
+					if (vstd::contains(artifWorn, slot) && artifWorn[slot] == 145) 
 					{
 						artifWorn.erase(slot);
 						break;

+ 15 - 33
hch/CArtHandler.h

@@ -17,24 +17,19 @@
  *
  */
 class CDefHandler;
-class CArtifact;
 
 class DLL_EXPORT CArtifact : public CBonusSystemNode //container for artifacts
 {
-protected:
 	std::string name, description; //set if custom
 public:
 	enum EartClass {ART_SPECIAL=1, ART_TREASURE=2, ART_MINOR=4, ART_MAJOR=8, ART_RELIC=16}; //artifact classes
 	const std::string &Name() const; //getter
 	const std::string &Description() const; //getter
 	bool isBig () const;
-	bool isModable () const;
-	bool fitsAt (const std::map<ui16, CArtifact*> &artifWorn, ui16 slot) const;
-	bool canBeAssembledTo (const std::map<ui16, CArtifact*> &artifWorn, ui32 artifactID) const;
+	bool fitsAt (const std::map<ui16, ui32> &artifWorn, ui16 slot) const;
+	bool canBeAssembledTo (const std::map<ui16, ui32> &artifWorn, ui32 artifactID) const;
 	void addBonusesTo (BonusList *otherBonuses) const;
 	void removeBonusesFrom (BonusList *otherBonuses) const;
-	virtual void SetProperty (int mod){};
-	virtual void Init(){};
 	int getArtClassSerial() const; //0 - treasure, 1 - minor, 2 - major, 3 - relic, 4 - spell scroll, 5 - other
 
 	ui32 price;
@@ -57,58 +52,46 @@ public:
 	void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;
 };
 
-class DLL_EXPORT IModableArt : public CArtifact //artifact which can have different properties, such as scroll or banner
-{ //used only for dynamic cast :P
+class DLL_EXPORT IModableArt //artifact which can have different properties, such as scroll or banner
+{
 public:
-	si32 ID; //used for smart serialization
-
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & static_cast<CArtifact&>(*this);
-		h & ID;
-	}
+	virtual void Init() = 0;
 };
 
-class DLL_EXPORT CScroll : public IModableArt // Spell Scroll
+class DLL_EXPORT CScroll : public CArtifact, public IModableArt // Spell Scroll
 {
 public:
-	CScroll(){spellid=0;};
-	CScroll(spelltype sid){spellid = sid;};
 	spelltype spellid;
-	void Init();
-	void SetProperty (int mod){spellid = mod;};
+	void Init(){};
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
-		h & static_cast<IModableArt&>(*this);
+		h & static_cast<CArtifact&>(*this);
 		h & spellid;
 	}
 };
 
-class DLL_EXPORT CCustomizableArt : public IModableArt // Warlord's Banner with multiple options
+class DLL_EXPORT CCustomizableArt : public CArtifact, public IModableArt // Warlord's Banner with multiple options
 {
 public:
 	ui8 mode;
-	CCustomizableArt(){mode=0;};
 	void Init(){};
-	void SetProperty (int mod){};
+	void SelectMode (int mod){};
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
-		h & static_cast<IModableArt&>(*this);
+		h & static_cast<CArtifact&>(*this);
 		h & mode;
 	}
 };
 
-class DLL_EXPORT CCommanderArt : public IModableArt // Growing with time
+class DLL_EXPORT CCommanderArt : public CArtifact, public IModableArt // Growing with time
 {
 public:
 	ui32 level;
-	CCommanderArt(){level = 0;};
 	void Init(){};
-	void SetProperty (int mod){level = mod;};
 	void Upgrade(){level++;};
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
-		h & static_cast<IModableArt&>(*this);
+		h & static_cast<CArtifact&>(*this);
 		h & level;
 	}
 };
@@ -121,7 +104,6 @@ public:
 	std::vector<CArtifact *> artifacts;
 	std::vector<CArtifact *> allowedArtifacts;
 	std::set<ui32> bigArtifacts; // Artifacts that cannot be moved to backpack, e.g. war machines.
-	std::map<ui32, ui8> modableArtifacts; //1-scroll, 2-banner, 3-commander art with progressive bonus
 
 	void loadArtifacts(bool onlyTxt);
 	void sortArts();
@@ -134,8 +116,8 @@ public:
 	void getAllowed(std::vector<CArtifact*> &out, int flags);
 	void erasePickedArt (si32 id);
 	bool isBigArtifact (ui32 artID) {return bigArtifacts.find(artID) != bigArtifacts.end();}
-	void equipArtifact (std::map<ui16, CArtifact*> &artifWorn, ui16 slotID, const CArtifact* art);
-	void unequipArtifact (std::map<ui16, CArtifact*> &artifWorn, ui16 slotID);
+	void equipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID, ui32 artifactID);
+	void unequipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID);
 	void initAllowedArtifactsList(const std::vector<ui8> &allowed); //allowed[art_id] -> 0 if not allowed, 1 if allowed
 	static int convertMachineID(int id, bool creToArt);
 	CArtHandler();

+ 1 - 1
hch/CCampaignHandler.cpp

@@ -523,7 +523,7 @@ void CCampaignScenario::prepareCrossoverHeroes( std::vector<CGHeroInstance *> he
 			{
 				BOOST_FOREACH(CGHeroInstance * cgh, crossoverHeroes)
 				{
-					cgh->artifacts -= VLC->arth->artifacts[g];
+					cgh->artifacts -= g;
 				}
 			}
 		}

+ 42 - 60
hch/CObjectHandler.cpp

@@ -729,23 +729,27 @@ int CGHeroInstance::maxMovePoints(bool onLand) const
 	return int(base + base*modifier) + bonus;
 }
 
-CArtifact* CGHeroInstance::getArtAtPos(ui16 pos) const
+ui32 CGHeroInstance::getArtAtPos(ui16 pos) const
 {
 	if(pos<19)
 		if(vstd::contains(artifWorn,pos))
 			return artifWorn.find(pos)->second;
 		else
-			return NULL;
+			return -1;
 	else
 		if(pos-19 < artifacts.size())
 			return artifacts[pos-19];
 		else 
-			return NULL;
+			return -1;
 }
 
 const CArtifact * CGHeroInstance::getArt(int pos) const
 {
-	return getArtAtPos(pos);
+	int id = getArtAtPos(pos);
+	if(id>=0)
+		return VLC->arth->artifacts[id];
+	else
+		return NULL;
 }
 
 // int CGHeroInstance::getSpellSecLevel(int spell) const
@@ -810,9 +814,9 @@ void CGHeroInstance::initHero()
 
 	if(!vstd::contains(artifWorn, 16) && type->startingSpell >= 0) //no catapult means we haven't read pre-existant set
 	{
-		VLC->arth->equipArtifact(artifWorn, 17, VLC->arth->artifacts[0]); //give spellbook
+		VLC->arth->equipArtifact(artifWorn, 17, 0); //give spellbook
 	}
-	VLC->arth->equipArtifact(artifWorn, 16, VLC->arth->artifacts[3]); //everyone has a catapult
+	VLC->arth->equipArtifact(artifWorn, 16, 3); //everyone has a catapult
 
 	if(portrait < 0 || portrait == 255)
 		portrait = subID;
@@ -882,13 +886,13 @@ void CGHeroInstance::initArmy(CCreatureSet *dst /*= NULL*/)
 			switch (creID)
 			{
 			case 145: //catapult
-				VLC->arth->equipArtifact(artifWorn, 16, VLC->arth->artifacts[3]);
+				VLC->arth->equipArtifact(artifWorn, 16, 3);
 				break;
 			default:
 				VLC->arth->equipArtifact(
 					artifWorn,
 					9+CArtHandler::convertMachineID(creID,true),
-					  VLC->arth->artifacts[CArtHandler::convertMachineID(creID,true)]);
+					  CArtHandler::convertMachineID(creID,true));
 				break;
 			}
 		}
@@ -1417,8 +1421,8 @@ si32 CGHeroInstance::manaRegain() const
 
 si32 CGHeroInstance::getArtPos(int aid) const
 {
-	for(std::map<ui16,CArtifact*>::const_iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
-		if(i->second->id == aid)
+	for(std::map<ui16,ui32>::const_iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
+		if(i->second == aid)
 			return i->first;
 	return -1;
 }
@@ -1427,34 +1431,33 @@ si32 CGHeroInstance::getArtPos(int aid) const
  * Places an artifact in hero's backpack. If it's a big artifact equips it
  * or discards it if it cannot be equipped.
  */
-void CGHeroInstance::giveArtifact (ui32 aid) //use only for fixed artifacts
+void CGHeroInstance::giveArtifact (ui32 aid)
 {
-	CArtifact * const artifact = VLC->arth->artifacts[aid]; //pointer to constant object
+	const CArtifact &artifact = *VLC->arth->artifacts[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)) 
 			{
-				VLC->arth->equipArtifact(artifWorn, *it, artifact);
+				VLC->arth->equipArtifact(artifWorn, *it, aid);
 				break;
 			}
 		}
 	} 
 	else 
 	{
-		artifacts.push_back(artifact);
+		artifacts.push_back(aid);
 	}
 }
 
 bool CGHeroInstance::hasArt( ui32 aid ) const
 {
-	for(std::vector<CArtifact*>::const_iterator i = artifacts.begin(); i != artifacts.end(); i++)
-		if((*i)->id == aid)
-			return true;
-	for(std::map<ui16,CArtifact*>::const_iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
-		if(i->second->id == aid)
+	if(vstd::contains(artifacts, aid))
+		return true;
+	for(std::map<ui16,ui32>::const_iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
+		if(i->second == aid)
 			return true;
 
 	return false;
@@ -1497,8 +1500,8 @@ void CGHeroInstance::getParents(TCNodes &out, const CBonusSystemNode *root /*= N
 			out.insert(visitedTown);
 	}
 
-	for (std::map<ui16,CArtifact*>::const_iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
-		out.insert(i->second);
+	for (std::map<ui16,ui32>::const_iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
+		out.insert(VLC->arth->artifacts[i->second]);
 
 	out.insert(&speciality);
 }
@@ -3591,36 +3594,24 @@ void CGArtifact::initObj()
 	blockVisit = true;
 	if(ID == 5)
 		hoverName = VLC->arth->artifacts[subID]->Name();
-	if(ID == 93)
-		subID = 1;
 }
 
 void CGArtifact::onHeroVisit( const CGHeroInstance * h ) const
 {
 	if(!stacksCount())
 	{
-		InfoWindow iw;
-		iw.soundID = soundBase::treasure;
-		iw.player = h->tempOwner;
-		switch(ID)
+		if(ID == 5)
 		{
-			case 5:
-			{
-				iw.components.push_back(Component(4,subID,0,0));
-				if(message.length())
-					iw.text <<  message;
-				else
-					iw.text << std::pair<ui8,ui32>(12,subID);
-			}
-			break;
-			case 93:
-				iw.components.push_back (Component(Component::SPELL, spell,0,0));
-				iw.text.addTxt (MetaString::ADVOB_TXT,135);
-				iw.text.addReplacement(MetaString::SPELL_NAME, spell);
-			break;
-
+			InfoWindow iw;
+			iw.soundID = soundBase::treasure;
+			iw.player = h->tempOwner;
+			iw.components.push_back(Component(4,subID,0,0));
+			if(message.length())
+				iw.text <<  message;
+			else
+				iw.text << std::pair<ui8,ui32>(12,subID);
+			cb->showInfoDialog(&iw);
 		}
-		cb->showInfoDialog(&iw);
 		pick(h);
 	}
 	else
@@ -3641,23 +3632,14 @@ void CGArtifact::onHeroVisit( const CGHeroInstance * h ) const
 
 void CGArtifact::pick(const CGHeroInstance * h) const
 {
-	if (VLC->arth->artifacts[subID]->isModable())
-	{//TODO: create new instance, initialize it
-		if (ID == 93) //scroll
-		{
-			NewArtifact na;
-			na.value = spell;
-			na.artid = subID;
-			cb->sendAndApply(&na);
-			cb->giveNewArtifact(h->id, -2);
-		}
-		else
-			cb->giveNewArtifact(h->id, -2);; //nothing / zero / empty by default
-	}
-	else
+	if(ID == 5) //Artifact
 	{
 		cb->giveHeroArtifact(subID,h->id,-2);
 	}
+	else if(ID == 93) // Spell scroll 
+	{
+		//TODO: support for the spell scroll
+	}
 	cb->removeObject(id);
 }
 
@@ -4391,7 +4373,7 @@ void CGSeerHut::finishQuest (const CGHeroInstance * h, ui32 accept) const
 			case CQuest::MISSION_ART:
 				for (std::vector<ui16>::const_iterator it = m5arts.begin(); it != m5arts.end(); ++it)
 				{
-					cb->removeArtifact(VLC->arth->artifacts[*it], h->id);
+					cb->removeArtifact(*it, h->id);
 				}
 				break;
 			case CQuest::MISSION_ARMY:

+ 3 - 4
hch/CObjectHandler.h

@@ -47,7 +47,6 @@ struct InfoWindow;
 struct Component;
 struct BankConfig;
 struct UpdateHeroSpeciality;
-struct NewArtifact;
 class CGBoat;
 
 class DLL_EXPORT CQuest
@@ -267,8 +266,8 @@ public:
 	ui8 inTownGarrison; // if hero is in town garrison 
 	const CGTownInstance * visitedTown; //set if hero is visiting town or in the town garrison
 	const CGBoat *boat; //set to CGBoat when sailing
-	std::vector<CArtifact*> artifacts; //hero's artifacts from bag
-	std::map<ui16, CArtifact*> 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::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::set<ui32> spells; //known spells (spell IDs)
 
 	struct DLL_EXPORT Patrol
@@ -338,7 +337,7 @@ public:
 
 	int maxMovePoints(bool onLand) const;
 
-	CArtifact* getArtAtPos(ui16 pos) const; //NULL - no artifact
+	ui32 getArtAtPos(ui16 pos) const; //-1 - no artifact
 	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)
 	bool hasArt(ui32 aid) const; //checks if hero possess artifact of given id (either in backack or worn)

+ 1 - 1
lib/CGameState.cpp

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

+ 1 - 3
lib/CGameState.h

@@ -61,7 +61,6 @@ struct TerrainTile;
 class CHeroClass;
 class CCampaign;
 class CCampaignState;
-class IModableArt;
 
 namespace boost
 {
@@ -143,8 +142,7 @@ public:
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 		h & color & human & currentSelection & team & resources & status;
-		h & heroes & towns & availableHeroes & dwellings & bonuses;
-		h & status & daysWithoutCastle;
+		h & heroes & towns & availableHeroes & dwellings & bonuses & status & daysWithoutCastle;
 		h & enteredLosingCheatCode & enteredWinningCheatCode;
 		h & static_cast<CBonusSystemNode&>(*this);
 	}

+ 1 - 2
lib/Connection.cpp

@@ -385,9 +385,8 @@ CSerializer::CSerializer()
 void CSerializer::addStdVecItems(CGameState *gs, LibClasses *lib)
 {
 	registerVectoredType(&gs->map->objects, &CGObjectInstance::id);
-	registerVectoredType(&lib->heroh->heroes, &CHero::ID);
 	registerVectoredType(&lib->creh->creatures, &CCreature::idNumber);
 	registerVectoredType(&lib->arth->artifacts, &CArtifact::id);
-	registerVectoredType(&gs->map->artInstances, &IModableArt::ID);
+	registerVectoredType(&lib->heroh->heroes, &CHero::ID);
 	smartVectorMembersSerialization = true;
 }

+ 1 - 2
lib/IGameCallback.h

@@ -93,8 +93,7 @@ public:
 	virtual void heroVisitCastle(int obj, int heroID)=0;
 	virtual void stopHeroVisitCastle(int obj, int heroID)=0;
 	virtual void giveHeroArtifact(int artid, int hid, int position)=0; //pos==-1 - first free slot in backpack=0; pos==-2 - default if available or backpack
-	virtual void giveNewArtifact(int hid, int position)=0;
-	virtual bool removeArtifact(CArtifact* art, int hid) = 0;
+	virtual bool removeArtifact(int artid, int hid) = 0;
 	virtual void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank = false, boost::function<void(BattleResult*)> cb = 0, const CGTownInstance *town = NULL)=0; //use hero=NULL for no hero
 	virtual void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false)=0; //if any of armies is hero, hero will be used
 	virtual void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false)=0; //if any of armies is hero, hero will be used, visitable tile of second obj is place of battle

+ 4 - 19
lib/NetPacks.h

@@ -599,18 +599,18 @@ struct SetHeroArtifacts : public CPackForClient //509
 	SetHeroArtifacts(){type = 509;};
 	void applyCl(CClient *cl);
 	DLL_EXPORT void applyGs(CGameState *gs);
-	DLL_EXPORT void setArtAtPos(ui16 pos, const CArtifact* art);
+	DLL_EXPORT void setArtAtPos(ui16 pos, int art);
 
 	si32 hid;
-	std::vector<CArtifact*> artifacts; //hero's artifacts from bag
-	std::map<ui16,CArtifact*> 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::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
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 		h & hid & artifacts & artifWorn;
 	}
 
-	std::vector<CArtifact*> equiped, unequiped; //used locally
+	std::vector<ui32> equiped, unequiped; //used locally
 	BonusList gained, lost; //used locally as hlp when applying
 };   
 
@@ -694,21 +694,6 @@ struct SetAvailableArtifacts  : public CPackForClient //519
 	}
 };
 
-struct NewArtifact : public CPackForClient
-{
-	NewArtifact(){type = 520;};
-	//void applyCl(CClient *cl);
-	DLL_EXPORT void applyGs(CGameState *gs);
-
-	si32 artid;
-	si32 value; //initializing parameter
-
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & artid & value;
-	}
-};
-
 struct NewTurn : public CPackForClient //101
 {
 	enum weekType {NORMAL, DOUBLE_GROWTH, BONUS_GROWTH, DEITYOFFIRE, PLAGUE, CUSTOM, NO_ACTION, NONE};

+ 11 - 38
lib/NetPacksLib.cpp

@@ -451,22 +451,20 @@ DLL_EXPORT void SetHeroesInTown::applyGs( CGameState *gs )
 DLL_EXPORT void SetHeroArtifacts::applyGs( CGameState *gs )
 {
 	CGHeroInstance *h = gs->getHero(hid);
-	for(std::map<ui16,CArtifact*>::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)
 			unequiped.push_back(i->second);
 
-	for(std::map<ui16,CArtifact*>::iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
+	for(std::map<ui16,ui32>::const_iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
 		if(!vstd::contains(h->artifWorn,i->first)  ||  h->artifWorn[i->first] != i->second)
-		{
 			equiped.push_back(i->second);
-		}
 
 	//update hero data
 	h->artifacts = artifacts;
 	h->artifWorn = artifWorn;
 }
 
-DLL_EXPORT void SetHeroArtifacts::setArtAtPos(ui16 pos, const CArtifact* art)
+DLL_EXPORT void SetHeroArtifacts::setArtAtPos(ui16 pos, int art)
 {
 	if(art < 0)
 	{
@@ -479,14 +477,14 @@ DLL_EXPORT void SetHeroArtifacts::setArtAtPos(ui16 pos, const CArtifact* art)
 	{
 		if (pos < 19) 
 		{
-			VLC->arth->equipArtifact(artifWorn, pos, art);
+			VLC->arth->equipArtifact(artifWorn, pos, (ui32) art);
 		} 
 		else // Goes into the backpack.
 		{ 
 			if(pos - 19 < artifacts.size())
-				artifacts.insert(artifacts.begin() + (pos - 19), const_cast<CArtifact*>(art));
+				artifacts.insert(artifacts.begin() + (pos - 19), art);
 			else
-				artifacts.push_back(const_cast<CArtifact*>(art));
+				artifacts.push_back(art);
 		}
 	}
 }
@@ -586,31 +584,6 @@ DLL_EXPORT void NewObject::applyGs( CGameState *gs )
 	o->initObj();
 	assert(o->defInfo);
 }
-DLL_EXPORT void NewArtifact::applyGs( CGameState *gs )
-{
-	IModableArt * art;
-
-	std::map<ui32,ui8>::iterator itr = VLC->arth->modableArtifacts.find(artid);
-	switch (itr->second)
-	{
-			case 1:
-				art = new CScroll;
-				break;
-			case 2:
-				art = new CCustomizableArt;
-				break;
-			case 3:
-				art = new CCommanderArt;
-				break;
-			default:
-				tlog1<<"unhandled customizable artifact!\n";
-	};
-	*art = *static_cast<IModableArt*>(VLC->arth->artifacts[artid]); //copy properties
-	art->ID = gs->map->artInstances.size();
-	art->SetProperty (value); //init scroll, banner, commander art
-	art->Init(); //set bonuses for new instance
-	gs->map->artInstances.push_back(art);
-}
 
 DLL_EXPORT void SetAvailableArtifacts::applyGs( CGameState *gs )
 {
@@ -657,6 +630,11 @@ DLL_EXPORT void NewTurn::applyGs( CGameState *gs )
 		BOOST_FOREACH(CGHeroInstance *h, gs->map->heroes)
 			h->bonuses.remove_if(Bonus::OneDay);
 
+		if(resetBuilded) //reset amount of structures set in this turn in towns
+		{
+			BOOST_FOREACH(CGTownInstance* t, gs->map->towns)
+				t->builded = 0;
+		}
 		if(gs->getDate(1)) //new week, Monday that is
 		{
 			for( std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++)
@@ -712,11 +690,6 @@ DLL_EXPORT void NewTurn::applyGs( CGameState *gs )
 
 			i->second.bonuses.remove_if(Bonus::OneDay);
 		}
-		if(resetBuilded) //reset amount of structures set in this turn in towns
-		{
-			BOOST_FOREACH(CGTownInstance* t, gs->map->towns)
-				t->builded = 0;
-		}
 	}
 }
 

+ 0 - 1
lib/RegisterTypes.cpp

@@ -137,7 +137,6 @@ void registerTypes2(Serializer &s)
 	s.template registerType<AdvmapSpellCast>();
 	s.template registerType<OpenWindow>();
 	s.template registerType<NewObject>();
-	s.template registerType<NewArtifact>();
 	s.template registerType<SetAvailableArtifacts>();
 
 	s.template registerType<SaveGame>();

+ 8 - 8
lib/map.cpp

@@ -858,27 +858,27 @@ void Mapa::loadHero( CGObjectInstance * &nobj, const unsigned char * bufor, int
 		{
 			int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 			if(id != artmask)
-				VLC->arth->equipArtifact(nhi->artifWorn, pom, VLC->arth->artifacts[id]);
+				VLC->arth->equipArtifact(nhi->artifWorn, pom, id);
 		}
 		//misc5 art //17
 		if(version>=SoD)
 		{
 			int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 			if(id!=artmask)
-				VLC->arth->equipArtifact(nhi->artifWorn, 16, VLC->arth->artifacts[id]);
+				VLC->arth->equipArtifact(nhi->artifWorn, 16, id);
 			else
-				VLC->arth->equipArtifact(nhi->artifWorn, 16, VLC->arth->artifacts[3]); //catapult by default
+				VLC->arth->equipArtifact(nhi->artifWorn, 16, 3); //catapult by default
 		}
 		//spellbook
 		int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 		if(id!=artmask)
-			VLC->arth->equipArtifact(nhi->artifWorn, 17, VLC->arth->artifacts[id]);
+			VLC->arth->equipArtifact(nhi->artifWorn, 17, id);
 		//19 //???what is that? gap in file or what? - it's probably fifth slot..
 		if(version>RoE)
 		{
 			id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 			if(id!=artmask)
-				VLC->arth->equipArtifact(nhi->artifWorn, 18, VLC->arth->artifacts[id]);
+				VLC->arth->equipArtifact(nhi->artifWorn, 18, id);
 		}
 		else
 			i+=1;
@@ -1102,7 +1102,7 @@ void Mapa::readPredefinedHeroes( const unsigned char * bufor, int &i)
 					{
 						int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 						if(id!=artmask)
-							VLC->arth->equipArtifact(cgh->artifWorn, pom, VLC->arth->artifacts[id]);
+							VLC->arth->equipArtifact(cgh->artifWorn, pom, id);
 					}
 					//misc5 art //17
 					if(version>=SoD)
@@ -1115,13 +1115,13 @@ void Mapa::readPredefinedHeroes( const unsigned char * bufor, int &i)
 					//spellbook
 					int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 					if(id!=artmask)
-						VLC->arth->equipArtifact(cgh->artifWorn, 17, VLC->arth->artifacts[id]);
+						VLC->arth->equipArtifact(cgh->artifWorn, 17, id);
 					//19 //???what is that? gap in file or what? - it's probably fifth slot..
 					if(version>RoE)
 					{
 						id = readNormalNr(bufor,i, artidlen); i+=artidlen;
 						if(id!=artmask)
-							VLC->arth->equipArtifact(cgh->artifWorn, 18, VLC->arth->artifacts[id]);
+							VLC->arth->equipArtifact(cgh->artifWorn, 18, id);
 					}
 					else
 						i+=1;

+ 2 - 3
lib/map.h

@@ -30,7 +30,7 @@ class CGHeroInstance;
 class CGCreature;
 class CQuest;
 class CGTownInstance;
-class IModableArt;
+
 
 
 struct DLL_EXPORT TerrainTile
@@ -254,7 +254,6 @@ struct DLL_EXPORT Mapa : public CMapHeader
 	std::vector<CGObjectInstance*> objects;
 	std::vector<CGHeroInstance*> heroes;
 	std::vector<CGTownInstance*> towns;
-	std::vector<IModableArt *> artInstances; //stores single scrolls
 	std::map<ui16, CGCreature*> monsters;
 	std::map<ui16, CGHeroInstance*> heroesToBeat;
 
@@ -289,7 +288,7 @@ struct DLL_EXPORT Mapa : public CMapHeader
 	{
 		h & static_cast<CMapHeader&>(*this);
 		h & rumors & allowedSpell & allowedAbilities & allowedArtifact & allowedHeroes & events & grailPos;
-		h & monsters & heroesToBeat & artInstances; //hopefully serialization is now automagical?
+		h & monsters & heroesToBeat; //hoprfully serialization is now automagical?
 
 		//TODO: viccondetails
 		if(h.saving)

+ 56 - 126
server/CGameHandler.cpp

@@ -1211,7 +1211,6 @@ void CGameHandler::newTurn()
 		NewTurn n2; //just to handle  creature growths after bonuses are applied
 		n2.specialWeek = NewTurn::NO_ACTION;
 		n2.day = gs->day;
-		n2.resetBuilded = true;
 
 		for(std::vector<CGTownInstance *>::iterator j = gs->map->towns.begin(); j!=gs->map->towns.end(); j++)//handle towns
 		{
@@ -2222,7 +2221,7 @@ void CGameHandler::stopHeroVisitCastle(int obj, int heroID)
 void CGameHandler::giveHeroArtifact(int artid, int hid, int position) //pos==-1 - first free slot in backpack
 {
 	const CGHeroInstance* h = getHero(hid);
-	CArtifact * const art = VLC->arth->artifacts[artid];
+	const CArtifact &art = *VLC->arth->artifacts[artid];
 
 	SetHeroArtifacts sha;
 	sha.hid = hid;
@@ -2234,84 +2233,38 @@ void CGameHandler::giveHeroArtifact(int artid, int hid, int position) //pos==-1
 		if(position == -2)
 		{
 			int i;
-			for(i=0; i<art->possibleSlots.size(); i++) //try to put artifact into first available slot
+			for(i=0; i<art.possibleSlots.size(); i++) //try to put artifact into first available slot
 			{
-				if( !vstd::contains(sha.artifWorn, art->possibleSlots[i]) )
+				if( !vstd::contains(sha.artifWorn,art.possibleSlots[i]) )
 				{
 					//we've found a free suitable slot
-					VLC->arth->equipArtifact(sha.artifWorn, art->possibleSlots[i], VLC->arth->artifacts[artid]);
+					VLC->arth->equipArtifact(sha.artifWorn, art.possibleSlots[i], artid);
 					break;
 				}
 			}
-			if(i == art->possibleSlots.size() && !art->isBig()) //if haven't find proper slot, use backpack or discard big artifact
-				sha.artifacts.push_back(art);
+			if(i == art.possibleSlots.size() && !art.isBig()) //if haven't find proper slot, use backpack or discard big artifact
+				sha.artifacts.push_back(artid);
 		}
-		else if (!art->isBig()) //should be -1 => put artifact into backpack
+		else if (!art.isBig()) //should be -1 => put artifact into backpack
 		{
-			sha.artifacts.push_back(art);
+			sha.artifacts.push_back(artid);
 		}
 	}
 	else
 	{
 		if(!vstd::contains(sha.artifWorn,ui16(position)))
 		{
-			VLC->arth->equipArtifact(sha.artifWorn, position, art);
+			VLC->arth->equipArtifact(sha.artifWorn, position, artid);
 		}
-		else if (!art->isBig())
+		else if (!art.isBig())
 		{
-			sha.artifacts.push_back(art);
+			sha.artifacts.push_back(artid);
 		}
 	}
 
 	sendAndApply(&sha);
 }
-void CGameHandler::giveNewArtifact(int hid, int position)
-{
-	const CGHeroInstance* h = getHero(hid);
-	CArtifact * art = gs->map->artInstances.back(); //we use it only to immediatelly equip new artifact
-
-	SetHeroArtifacts sha;
-	sha.hid = hid;
-	sha.artifacts = h->artifacts;
-	sha.artifWorn = h->artifWorn;
-
-	if(position<0)
-	{
-		if(position == -2)
-		{
-			int i;
-			for(i=0; i<art->possibleSlots.size(); i++) //try to put artifact into first available slot
-			{
-				if( !vstd::contains(sha.artifWorn, art->possibleSlots[i]) )
-				{
-					//we've found a free suitable slot
-					VLC->arth->equipArtifact(sha.artifWorn, art->possibleSlots[i], art);
-					break;
-				}
-			}
-			if(i == art->possibleSlots.size() && !art->isBig()) //if haven't find proper slot, use backpack or discard big artifact
-				sha.artifacts.push_back(art);
-		}
-		else if (!art->isBig()) //should be -1 => put artifact into backpack
-		{
-			sha.artifacts.push_back(art);
-		}
-	}
-	else
-	{
-		if(!vstd::contains(sha.artifWorn,ui16(position)))
-		{
-			VLC->arth->equipArtifact(sha.artifWorn, position, art);
-		}
-		else if (!art->isBig())
-		{
-			sha.artifacts.push_back(art);
-		}
-	}
-
-	sendAndApply(&sha);
-}
-bool CGameHandler::removeArtifact(CArtifact* art, int hid)
+bool CGameHandler::removeArtifact(int artid, int hid)
 {
 	const CGHeroInstance* h = getHero(hid);
 
@@ -2320,15 +2273,15 @@ bool CGameHandler::removeArtifact(CArtifact* art, int hid)
 	sha.artifacts = h->artifacts;
 	sha.artifWorn = h->artifWorn;
 	
-	std::vector<CArtifact*>::iterator it;
-	if 	((it = std::find(sha.artifacts.begin(), sha.artifacts.end(), art)) != sha.artifacts.end()) //it is in backpack
+	std::vector<ui32>::iterator it;
+	if 	((it = std::find(sha.artifacts.begin(), sha.artifacts.end(), artid)) != sha.artifacts.end()) //it is in backpack
 		sha.artifacts.erase(it);
 	else //worn
 	{
-		std::map<ui16,CArtifact*>::iterator itr;
+		std::map<ui16,ui32>::iterator itr;
 		for (itr = sha.artifWorn.begin(); itr != sha.artifWorn.end(); ++itr)
 		{
-			if (itr->second == art)
+			if (itr->second == artid)
 			{
 				VLC->arth->unequipArtifact(sha.artifWorn, itr->first);
 				break;
@@ -2803,7 +2756,7 @@ bool CGameHandler::buildStructure( si32 tid, si32 bid, bool force /*=false*/ )
 			return false;
 		}
 
-		removeArtifact(VLC->arth->artifacts[2], t->visitingHero->id);
+		removeArtifact(2, t->visitingHero->id);
 	}
 
 	NewStructures ns;
@@ -3195,7 +3148,7 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
 	// 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) 
 	{
-		sha.setArtAtPos(srcSlot, NULL);
+		sha.setArtAtPos(srcSlot, -1);
 		if (!vstd::contains(sha.artifWorn, destSlot))
 			destArtifact = NULL;
 	}
@@ -3229,14 +3182,14 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
 
 	// If dest does not fit in src, put it in dest's backpack instead.
 	if (srcHeroID == destHeroID) // To avoid stumbling on own locks, remove artifact first.
-		sha.setArtAtPos(destSlot, NULL);
+		sha.setArtAtPos(destSlot, -1);
 	const bool destFits = !destArtifact || srcSlot >= 19 || destSlot >= 19 || destArtifact->fitsAt(sha.artifWorn, srcSlot);
 	if (srcHeroID == destHeroID && destArtifact)
-		sha.setArtAtPos(destSlot, destArtifact);
+		sha.setArtAtPos(destSlot, destArtifact->id);
 
-	sha.setArtAtPos(srcSlot, NULL);
+	sha.setArtAtPos(srcSlot, -1);
 	if (destSlot < 19 && (destArtifact || srcSlot < 19) && destFits)
-		sha.setArtAtPos(srcSlot, destArtifact ? destArtifact : NULL);
+		sha.setArtAtPos(srcSlot, destArtifact ? destArtifact->id : -1);
 
 	// Internal hero artifact arrangement.
 	if(srcHero == destHero) 
@@ -3254,7 +3207,7 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
 		sha2.hid = destHeroID;
 		sha2.artifacts = destHero->artifacts;
 		sha2.artifWorn = destHero->artifWorn;
-		sha2.setArtAtPos(destSlot, srcArtifact ? srcArtifact : NULL);
+		sha2.setArtAtPos(destSlot, srcArtifact ? srcArtifact->id : -1);
 		if (!destFits)
 			sha2.setArtAtPos(sha2.artifacts.size() + 19, destHero->getArtAtPos(destSlot));
 		sendAndApply(&sha2);
@@ -3286,24 +3239,20 @@ bool CGameHandler::assembleArtifacts (si32 heroID, ui16 artifactSlot, bool assem
 	sha.artifacts = hero->artifacts;
 	sha.artifWorn = hero->artifWorn;
 
-	if (assemble)
-	{
-		if (VLC->arth->artifacts.size() < assembleTo)
-		{
+	if (assemble) {
+		if (VLC->arth->artifacts.size() < assembleTo) {
 			complain("Illegal artifact to assemble to.");
 			return false;
 		}
 
-		if (!destArtifact->canBeAssembledTo(hero->artifWorn, assembleTo))
-		{
+		if (!destArtifact->canBeAssembledTo(hero->artifWorn, assembleTo)) {
 			complain("Artifact cannot be assembled.");
 			return false;
 		}
 
 		const CArtifact &artifact = *VLC->arth->artifacts[assembleTo];
 
-		if (artifact.constituents == NULL)
-		{
+		if (artifact.constituents == NULL) {
 			complain("Not a combinational artifact.");
 			return false;
 		}
@@ -3312,43 +3261,32 @@ bool CGameHandler::assembleArtifacts (si32 heroID, ui16 artifactSlot, bool assem
 		bool destConsumed = false; // Determines which constituent that will be counted for together with the artifact.
 		const bool destSpecific = vstd::contains(artifact.possibleSlots, artifactSlot); // Prefer the chosen slot as the location for the assembled artifact.
 
-		BOOST_FOREACH(ui32 constituentID, *artifact.constituents)
-		{
-			if (destSpecific && constituentID == destArtifact->id)
-			{
-				sha.artifWorn[artifactSlot] = VLC->arth->artifacts[assembleTo];
+		BOOST_FOREACH(ui32 constituentID, *artifact.constituents) {
+			if (destSpecific && constituentID == destArtifact->id) {
+				sha.artifWorn[artifactSlot] = assembleTo;
 				destConsumed = true;
 				continue;
 			}
 
 			bool found = false;
-			for (std::map<ui16, CArtifact*>::iterator it = sha.artifWorn.begin(); it != sha.artifWorn.end(); ++it)
-			{
-				if (it->second->id == constituentID)
-				{ // Found possible constituent to substitute.
-					if (destSpecific && !destConsumed && it->second->id == destArtifact->id)
-					{
+			for (std::map<ui16, ui32>::iterator it = sha.artifWorn.begin(); it != sha.artifWorn.end(); ++it) {
+				if (it->second == constituentID) { // Found possible constituent to substitute.
+					if (destSpecific && !destConsumed && it->second == destArtifact->id) {
 						// Find the specified destination for assembled artifact.
-						if (it->first == artifactSlot)
-						{
-							it->second = VLC->arth->artifacts[assembleTo];
+						if (it->first == artifactSlot) {
+							it->second = assembleTo;
 							destConsumed = true;
 
 							found = true;
 							break;
 						}
-					}
-					else
-					{
+					} else {
 						// Either put the assembled artifact in a fitting spot, or put a lock.
-						if (!destSpecific && !destConsumed && vstd::contains(artifact.possibleSlots, it->first))
-						{
-							it->second = VLC->arth->artifacts[assembleTo];
+						if (!destSpecific && !destConsumed && vstd::contains(artifact.possibleSlots, it->first)) {
+							it->second = assembleTo;
 							destConsumed = true;
-						}
-						else
-						{
-							it->second = VLC->arth->artifacts[145];
+						} else {
+							it->second = 145;
 						}
 
 						found = true;
@@ -3361,27 +3299,19 @@ bool CGameHandler::assembleArtifacts (si32 heroID, ui16 artifactSlot, bool assem
 				return false;
 			}
 		}
-	}
-	else
-	{
+	} else {
 		// Perform disassembly.
 		bool destConsumed = false; // Determines which constituent that will be counted for together with the artifact.
-		BOOST_FOREACH(ui32 constituentID, *destArtifact->constituents)
-		{
+		BOOST_FOREACH(ui32 constituentID, *destArtifact->constituents) {
 			const CArtifact &constituent = *VLC->arth->artifacts[constituentID];
 
-			if (!destConsumed && vstd::contains(constituent.possibleSlots, artifactSlot))
-			{
-				sha.artifWorn[artifactSlot] = VLC->arth->artifacts[constituentID];
+			if (!destConsumed && vstd::contains(constituent.possibleSlots, artifactSlot)) {
+				sha.artifWorn[artifactSlot] = constituentID;
 				destConsumed = true;
-			}
-			else
-			{
-				BOOST_REVERSE_FOREACH(ui16 slotID, constituent.possibleSlots)
-				{
-					if (vstd::contains(sha.artifWorn, slotID) && sha.artifWorn[slotID]->id == 145)
-					{
-						sha.artifWorn[slotID]->id = constituentID;
+			} else {
+				BOOST_REVERSE_FOREACH(ui16 slotID, constituent.possibleSlots) {
+					if (vstd::contains(sha.artifWorn, slotID) && sha.artifWorn[slotID] == 145) {
+						sha.artifWorn[slotID] = constituentID;
 						break;
 					}
 				}
@@ -4115,9 +4045,9 @@ void CGameHandler::playerMessage( ui8 player, const std::string &message )
 		sha.hid = hero->id;
 		sha.artifacts = hero->artifacts;
 		sha.artifWorn = hero->artifWorn;
-		VLC->arth->equipArtifact(sha.artifWorn, 13, VLC->arth->artifacts[4]);
-		VLC->arth->equipArtifact(sha.artifWorn, 14, VLC->arth->artifacts[5]);
-		VLC->arth->equipArtifact(sha.artifWorn, 15, VLC->arth->artifacts[6]);
+		VLC->arth->equipArtifact(sha.artifWorn, 13, 4);
+		VLC->arth->equipArtifact(sha.artifWorn, 14, 5);
+		VLC->arth->equipArtifact(sha.artifWorn, 15, 6);
 		sendAndApply(&sha);
 	}
 	else if(message == "vcminahar") //1000000 movement points
@@ -4174,10 +4104,10 @@ void CGameHandler::playerMessage( ui8 player, const std::string &message )
 		sha.hid = hero->id;
 		sha.artifacts = hero->artifacts;
 		sha.artifWorn = hero->artifWorn;
-		sha.artifacts.push_back(VLC->arth->artifacts[2]); //grail
+		sha.artifacts.push_back(2); //grail
 		for (int g=7; g<=140; ++g)
 		{
-			sha.artifacts.push_back(VLC->arth->artifacts[g]);
+			sha.artifacts.push_back(g);
 		}
 		sendAndApply(&sha);
 	}
@@ -5298,13 +5228,13 @@ bool CGameHandler::sacrificeCreatures(const IMarket *market, const CGHeroInstanc
 	return true;
 }
 
-bool CGameHandler::sacrificeArtifact(const IMarket * m, const CGHeroInstance * hero, CArtifact* art)
+bool CGameHandler::sacrificeArtifact(const IMarket * m, const CGHeroInstance * hero, ui32 artID)
 {
-	if(!removeArtifact(art, hero->id))
+	if(!removeArtifact(artID, hero->id))
 		COMPLAIN_RET("Cannot find artifact to sacrifice!");
 
 	int dmp, expToGive;
-	m->getOffer(art->id, 0, dmp, expToGive, ARTIFACT_EXP);
+	m->getOffer(artID, 0, dmp, expToGive, ARTIFACT_EXP);
 	changePrimSkill(hero->id, 4, expToGive);
 	return true;
 }

+ 2 - 3
server/CGameHandler.h

@@ -143,9 +143,8 @@ public:
 	void vistiCastleObjects (const CGTownInstance *t, const CGHeroInstance *h);
 	void stopHeroVisitCastle(int obj, int heroID);
 	void giveHeroArtifact(int artid, int hid, int position); //pos==-1 - first free slot in backpack; pos==-2 - default if available or backpack
-	void giveNewArtifact(int hid, int position);
 	void moveArtifact(int hid, int oldPosition, int destPos);
-	bool removeArtifact(CArtifact* art, int hid);
+	bool removeArtifact(int artid, int hid);
 	void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank = false, boost::function<void(BattleResult*)> cb = 0, const CGTownInstance *town = NULL); //use hero=NULL for no hero
 	void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false); //if any of armies is hero, hero will be used
 	void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false); //if any of armies is hero, hero will be used, visitable tile of second obj is place of battle//void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb); //for hero<=>neutral army
@@ -223,7 +222,7 @@ public:
 	void run(bool resume, const StartInfo *si = NULL);
 	void newTurn();
 	void handleAfterAttackCasting( const BattleAttack & bat );
-	bool sacrificeArtifact(const IMarket * m, const CGHeroInstance * hero, CArtifact* art);
+	bool sacrificeArtifact(const IMarket * m, const CGHeroInstance * hero, ui32 artID);
 	friend class CVCMIServer;
 	friend class CScriptCallback;
 };

+ 1 - 1
server/NetPacksServer.cpp

@@ -164,7 +164,7 @@ bool TradeOnMarketplace::applyGh( CGameHandler *gh )
 	case CREATURE_EXP:
 		return gh->sacrificeCreatures(m, hero, r1, val);
 	case ARTIFACT_EXP:
-		return gh->sacrificeArtifact(m, hero, hero->getArtAtPos(r1));
+		return gh->sacrificeArtifact(m, hero, r1);
 	default:
 		COMPLAIN_AND_RETURN("Unknown exchange mode!");
 	}