浏览代码

Practically finished combined artifacts changes, many other fixes.

Michał W. Urbańczyk 14 年之前
父节点
当前提交
a75a37008f

+ 2 - 2
client/CHeroWindow.cpp

@@ -72,7 +72,7 @@ CHeroWindow::CHeroWindow(const CGHeroInstance *hero)
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 	garr = NULL;
 	garr = NULL;
 	curHero = hero;
 	curHero = hero;
-	player = hero->tempOwner;
+	player = LOCPLINT->playerID;//hero->tempOwner;
 
 
 	background = new CPicture("HeroScr4.BMP");
 	background = new CPicture("HeroScr4.BMP");
 	background->colorizeAndConvert(player);
 	background->colorizeAndConvert(player);
@@ -162,7 +162,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded /*= fals
 	}
 	}
 
 
 	assert(hero == curHero);
 	assert(hero == curHero);
-	assert(hero->tempOwner == LOCPLINT->playerID || hero->tempOwner == NEUTRAL_PLAYER); //for now we won't show hero windows for non-our heroes
+	//assert(hero->tempOwner == LOCPLINT->playerID || hero->tempOwner == NEUTRAL_PLAYER); //for now we won't show hero windows for non-our heroes
 
 
 	specArea->text = CGI->generaltexth->hTxts[hero->subID].longBonus;
 	specArea->text = CGI->generaltexth->hTxts[hero->subID].longBonus;
 
 

+ 1 - 0
client/Client.cpp

@@ -428,6 +428,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
 	{
 	{
 		playerint[255] =  CAIHandler::getNewAI(cb,conf.cc.defaultAI);
 		playerint[255] =  CAIHandler::getNewAI(cb,conf.cc.defaultAI);
 		playerint[255]->init(new CCallback(gs,255,this));
 		playerint[255]->init(new CCallback(gs,255,this));
+		battleints[255] = playerint[255];
 	}
 	}
 
 
 	serv->addStdVecItems(const_cast<CGameInfo*>(CGI)->state);
 	serv->addStdVecItems(const_cast<CGameInfo*>(CGI)->state);

+ 50 - 27
client/GUIClasses.cpp

@@ -2630,7 +2630,7 @@ void CTradeWindow::CTradeableItem::showAll(SDL_Surface * to)
 
 
 void CTradeWindow::CTradeableItem::clickLeft(tribool down, bool previousState)
 void CTradeWindow::CTradeableItem::clickLeft(tribool down, bool previousState)
 {
 {
-	CTradeWindow *mw = static_cast<CTradeWindow *>(parent);
+	CTradeWindow *mw = dynamic_cast<CTradeWindow *>(parent);
 	assert(mw);
 	assert(mw);
 	if(down)
 	if(down)
 	{
 	{
@@ -2638,23 +2638,21 @@ void CTradeWindow::CTradeableItem::clickLeft(tribool down, bool previousState)
 		if(type == ARTIFACT_PLACEHOLDER)
 		if(type == ARTIFACT_PLACEHOLDER)
 		{
 		{
 			CAltarWindow *aw = static_cast<CAltarWindow *>(mw);
 			CAltarWindow *aw = static_cast<CAltarWindow *>(mw);
-			const CArtifactInstance *movedArt = aw->arts->commonInfo->src.art;
-			if(movedArt)
+			if(const CArtifactInstance *movedArt = aw->arts->commonInfo->src.art)
 			{
 			{
 				aw->moveFromSlotToAltar(aw->arts->commonInfo->src.slotID, this, movedArt);
 				aw->moveFromSlotToAltar(aw->arts->commonInfo->src.slotID, this, movedArt);
 			}
 			}
 			else if(const CArtifactInstance *art = getArtInstance())
 			else if(const CArtifactInstance *art = getArtInstance())
 			{
 			{
-				movedArt = art;
 				aw->arts->commonInfo->src.AOH = aw->arts;
 				aw->arts->commonInfo->src.AOH = aw->arts;
-				aw->arts->commonInfo->src.art = movedArt;
+				aw->arts->commonInfo->src.art = art;
 				aw->arts->commonInfo->src.slotID = aw->hero->getArtPos(art);
 				aw->arts->commonInfo->src.slotID = aw->hero->getArtPos(art);
-				aw->arts->markPossibleSlots(movedArt);
+				aw->arts->markPossibleSlots(art);
 
 
 				//aw->arts->commonInfo->dst.AOH = aw->arts;
 				//aw->arts->commonInfo->dst.AOH = aw->arts;
-				CCS->curh->dragAndDropCursor(graphics->artDefs->ourImages[movedArt->artType->id].bitmap);
+				CCS->curh->dragAndDropCursor(graphics->artDefs->ourImages[art->artType->id].bitmap);
 
 
-				aw->arts->artifactsOnAltar.erase(movedArt);
+				aw->arts->artifactsOnAltar.erase(art);
 				id = -1;
 				id = -1;
 				subtitle = "";
 				subtitle = "";
 				aw->deal->block(!aw->arts->artifactsOnAltar.size());
 				aw->deal->block(!aw->arts->artifactsOnAltar.size());
@@ -2788,25 +2786,25 @@ const CArtifactInstance * CTradeWindow::CTradeableItem::getArtInstance() const
 	}
 	}
 }
 }
 
 
-const CArtifact * CTradeWindow::CTradeableItem::getArt() const
-{
-	return NULL;
-}
-
-void CTradeWindow::CTradeableItem::setArtInstance(const CArtifactInstance *art) const
-{
-
-}
-
-void CTradeWindow::CTradeableItem::setArt(const CArtifact *artT) const
-{
-
-}
+// const CArtifact * CTradeWindow::CTradeableItem::getArt() const
+// {
+// 	return NULL;
+// }
+// 
+// void CTradeWindow::CTradeableItem::setArtInstance(const CArtifactInstance *art) const
+// {
+// 
+// }
+// 
+// void CTradeWindow::CTradeableItem::setArt(const CArtifact *artT) const
+// {
+// 
+// }
 
 
 CTradeWindow::CTradeWindow(const IMarket *Market, const CGHeroInstance *Hero, EMarketMode Mode)
 CTradeWindow::CTradeWindow(const IMarket *Market, const CGHeroInstance *Hero, EMarketMode Mode)
 	: market(Market), hero(Hero),  arts(NULL), hLeft(NULL), hRight(NULL), readyToTrade(false)
 	: market(Market), hero(Hero),  arts(NULL), hLeft(NULL), hRight(NULL), readyToTrade(false)
 {
 {
-	type = BLOCK_ADV_HOTKEYS;
+	type |= BLOCK_ADV_HOTKEYS;
 	mode = Mode;
 	mode = Mode;
 	initTypes();
 	initTypes();
 }
 }
@@ -3537,6 +3535,7 @@ CAltarWindow::CAltarWindow(const IMarket *Market, const CGHeroInstance *Hero /*=
 			arts->recActions = 255;
 			arts->recActions = 255;
 			arts->allowedAssembling = false;
 			arts->allowedAssembling = false;
 			addChild(arts);
 			addChild(arts);
+			artSets.push_back(arts);
 		}
 		}
 
 
 		initItems(false);
 		initItems(false);
@@ -3873,6 +3872,7 @@ bool CAltarWindow::putOnAltar(CTradeableItem* altarSlot, const CArtifactInstance
 	arts->artifactsOnAltar.insert(art);
 	arts->artifactsOnAltar.insert(art);
 	altarSlot->id = artID;
 	altarSlot->id = artID;
 	altarSlot->subtitle = boost::lexical_cast<std::string>(val);
 	altarSlot->subtitle = boost::lexical_cast<std::string>(val);
+	altarSlot->hlp = art;
 
 
 	deal->block(false);
 	deal->block(false);
 	return true;
 	return true;
@@ -3880,14 +3880,23 @@ bool CAltarWindow::putOnAltar(CTradeableItem* altarSlot, const CArtifactInstance
 
 
 void CAltarWindow::moveFromSlotToAltar(int slotID, CTradeableItem* altarSlot, const CArtifactInstance *art)
 void CAltarWindow::moveFromSlotToAltar(int slotID, CTradeableItem* altarSlot, const CArtifactInstance *art)
 {
 {
+	int freeBackpackSlot = hero->artifactsInBackpack.size() + Arts::BACKPACK_START;
 	if(arts->commonInfo->src.art)
 	if(arts->commonInfo->src.art)
 	{
 	{
-		arts->commonInfo->dst.slotID = 65500;
+		arts->commonInfo->dst.slotID = freeBackpackSlot;
 		arts->commonInfo->dst.AOH = arts;
 		arts->commonInfo->dst.AOH = arts;
 	}
 	}
 
 
 	if(putOnAltar(altarSlot, art))
 	if(putOnAltar(altarSlot, art))
-		LOCPLINT->cb->swapArtifacts(hero, slotID, hero, 65500);
+	{
+		if(slotID < Arts::BACKPACK_START)
+			LOCPLINT->cb->swapArtifacts(hero, slotID, hero, freeBackpackSlot);
+		else
+		{
+			arts->commonInfo->src.clear();
+			arts->commonInfo->dst.clear();
+		}
+	}
 }
 }
 
 
 CSystemOptionsWindow::CSystemOptionsWindow(const SDL_Rect &pos, CPlayerInterface * owner)
 CSystemOptionsWindow::CSystemOptionsWindow(const SDL_Rect &pos, CPlayerInterface * owner)
@@ -4536,6 +4545,11 @@ CRClickPopupInt::~CRClickPopupInt()
 	CCS->curh->show();
 	CCS->curh->show();
 }
 }
 
 
+void CRClickPopupInt::showAll(SDL_Surface * to)
+{
+	inner->showAll(to);
+}
+
 CArtPlace::CArtPlace(const CArtifactInstance* Art)
 CArtPlace::CArtPlace(const CArtifactInstance* Art)
 	: marked(false), ourArt(Art), picked(false), locked(false)
 	: marked(false), ourArt(Art), picked(false), locked(false)
 {
 {
@@ -4704,7 +4718,7 @@ void CArtPlace::select ()
 		return;
 		return;
 
 
 	picked = true;
 	picked = true;
-	//int backpackCorrection = -(slotID - 19 < ourOwner->backpackPos);
+	//int backpackCorrection = -(slotID - Arts::BACKPACK_START < ourOwner->backpackPos);
 
 
 	CCS->curh->dragAndDropCursor(graphics->artDefs->ourImages[ourArt->artType->id].bitmap);
 	CCS->curh->dragAndDropCursor(graphics->artDefs->ourImages[ourArt->artType->id].bitmap);
 	ourOwner->commonInfo->src.setTo(this, false);
 	ourOwner->commonInfo->src.setTo(this, false);
@@ -5297,9 +5311,18 @@ void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const Artifact
 		tlog1 << "Unexpected artifact movement...\n";
 		tlog1 << "Unexpected artifact movement...\n";
 	}
 	}
 
 
+ 	int shift = 0;
+// 	if(dst.slot >= Arts::BACKPACK_START && dst.slot - Arts::BACKPACK_START < backpackPos)
+// 		shift++;
+// 
+ 	if(src.slot < Arts::BACKPACK_START  &&  dst.slot - Arts::BACKPACK_START < backpackPos)
+		shift++;
+	if(dst.slot < Arts::BACKPACK_START  &&  src.slot - Arts::BACKPACK_START < backpackPos)
+ 		shift--;
+
 	if( src.hero == curHero && src.slot >= Arts::BACKPACK_START
 	if( src.hero == curHero && src.slot >= Arts::BACKPACK_START
 	 || dst.hero == curHero && dst.slot >= Arts::BACKPACK_START)
 	 || dst.hero == curHero && dst.slot >= Arts::BACKPACK_START)
-		scrollBackpack(0); //update backpack slots
+		scrollBackpack(shift); //update backpack slots
 }
 }
 
 
 CArtPlace * CArtifactsOfHero::getArtPlace(int slot)
 CArtPlace * CArtifactsOfHero::getArtPlace(int slot)

+ 15 - 15
client/GUIClasses.h

@@ -130,6 +130,7 @@ public:
 	bool delInner;
 	bool delInner;
 
 
 	void show(SDL_Surface * to);
 	void show(SDL_Surface * to);
+	void showAll(SDL_Surface * to);
 	CRClickPopupInt(IShowActivable *our, bool deleteInt); //c-tor
 	CRClickPopupInt(IShowActivable *our, bool deleteInt); //c-tor
 	virtual ~CRClickPopupInt(); //d-tor
 	virtual ~CRClickPopupInt(); //d-tor
 };
 };
@@ -580,7 +581,16 @@ public:
 	void showAll(SDL_Surface * to);
 	void showAll(SDL_Surface * to);
 };
 };
 
 
-class CTradeWindow : public CIntObject //base for markets and altar of sacrifice
+class CWindowWithArtifacts : public virtual CIntObject
+{
+public:
+	std::vector<CArtifactsOfHero *> artSets;
+
+	CWindowWithArtifacts();
+	~CWindowWithArtifacts();
+};
+
+class CTradeWindow : public CWindowWithArtifacts //base for markets and altar of sacrifice
 {
 {
 public:
 public:
 	enum EType
 	enum EType
@@ -596,12 +606,11 @@ public:
 		bool left;
 		bool left;
 		std::string subtitle; //empty if default
 		std::string subtitle; //empty if default
 
 
-		void *hlp; //holds ptr to artifact instance id type artifact 
-
+		const CArtifactInstance *hlp; //holds ptr to artifact instance id type artifact 
 		const CArtifactInstance *getArtInstance() const;
 		const CArtifactInstance *getArtInstance() const;
-		const CArtifact *getArt() const;
-		void setArtInstance(const CArtifactInstance *art) const;
-		void setArt(const CArtifact *artT) const;
+// 		const CArtifact *getArt() const;
+// 		void setArtInstance(const CArtifactInstance *art) const;
+// 		void setArt(const CArtifact *artT) const;
 
 
 		CFunctionList<void()> callback;
 		CFunctionList<void()> callback;
 		bool downSelection;
 		bool downSelection;
@@ -909,15 +918,6 @@ public:
 	void show(SDL_Surface * to);
 	void show(SDL_Surface * to);
 };
 };
 
 
-class CWindowWithArtifacts : public virtual CIntObject
-{
-public:
-	std::vector<CArtifactsOfHero *> artSets;
-
-	CWindowWithArtifacts();
-	~CWindowWithArtifacts();
-};
-
 class CArtPlace: public LRClickableAreaWTextComp
 class CArtPlace: public LRClickableAreaWTextComp
 {
 {
 public:
 public:

+ 204 - 182
lib/CArtHandler.cpp

@@ -51,73 +51,73 @@ bool CArtifact::isBig () const
 {
 {
 	return VLC->arth->isBigArtifact(id);
 	return VLC->arth->isBigArtifact(id);
 }
 }
+// 
+// bool CArtifact::isModable () const
+// {
+// 	return (bool)dynamic_cast<const IModableArt *>(this);
+// }
 
 
-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, const CArtifact*> &artifWorn, ui16 slotID) const
-{
-	if (!vstd::contains(possibleSlots, slotID))
-		return false;
-
-	// Can't put an artifact in a locked slot.
-	std::map<ui16, const CArtifact*>::const_iterator it = artifWorn.find(slotID);
-	if (it != artifWorn.end() && it->second->id == 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, const CArtifact*> tempArtifWorn = artifWorn;
-		const ui16 ringSlots[] = {6, 7};
-		const ui16 miscSlots[] = {9, 10, 11, 12, 18};
-		int rings = 0;
-		int misc = 0;
-
-		VLC->arth->unequipArtifact(tempArtifWorn, slotID);
-
-		BOOST_FOREACH(ui32 constituentID, *constituents) 
-		{
-			const CArtifact& constituent = *VLC->arth->artifacts[constituentID];
-			const int slot = constituent.possibleSlots[0];
-
-			if (slot == 6 || slot == 7)
-				rings++;
-			else if ((slot >= 9 && slot <= 12) || slot == 18)
-				misc++;
-			else if (tempArtifWorn.find(slot) != tempArtifWorn.end())
-				return false;
-		}
-
-		// Ensure enough ring slots are free
-		for (int i = 0; i < sizeof(ringSlots)/sizeof(*ringSlots); i++) 
-		{
-			if (tempArtifWorn.find(ringSlots[i]) == tempArtifWorn.end() || ringSlots[i] == slotID)
-				rings--;
-		}
-		if (rings > 0)
-			return false;
-
-		// Ensure enough misc slots are free.
-		for (int i = 0; i < sizeof(miscSlots)/sizeof(*miscSlots); i++) 
-		{
-			if (tempArtifWorn.find(miscSlots[i]) == tempArtifWorn.end() || miscSlots[i] == slotID)
-				misc--;
-		}
-		if (misc > 0)
-			return false;
-	}
-
-	return true;
-}
+// /**
+//  * 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, const CArtifact*> &artifWorn, ui16 slotID) const
+// {
+// 	if (!vstd::contains(possibleSlots, slotID))
+// 		return false;
+// 
+// 	// Can't put an artifact in a locked slot.
+// 	std::map<ui16, const CArtifact*>::const_iterator it = artifWorn.find(slotID);
+// 	if (it != artifWorn.end() && it->second->id == 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, const CArtifact*> tempArtifWorn = artifWorn;
+// 		const ui16 ringSlots[] = {6, 7};
+// 		const ui16 miscSlots[] = {9, 10, 11, 12, 18};
+// 		int rings = 0;
+// 		int misc = 0;
+// 
+// 		VLC->arth->unequipArtifact(tempArtifWorn, slotID);
+// 
+// 		BOOST_FOREACH(ui32 constituentID, *constituents) 
+// 		{
+// 			const CArtifact& constituent = *VLC->arth->artifacts[constituentID];
+// 			const int slot = constituent.possibleSlots[0];
+// 
+// 			if (slot == 6 || slot == 7)
+// 				rings++;
+// 			else if ((slot >= 9 && slot <= 12) || slot == 18)
+// 				misc++;
+// 			else if (tempArtifWorn.find(slot) != tempArtifWorn.end())
+// 				return false;
+// 		}
+// 
+// 		// Ensure enough ring slots are free
+// 		for (int i = 0; i < sizeof(ringSlots)/sizeof(*ringSlots); i++) 
+// 		{
+// 			if (tempArtifWorn.find(ringSlots[i]) == tempArtifWorn.end() || ringSlots[i] == slotID)
+// 				rings--;
+// 		}
+// 		if (rings > 0)
+// 			return false;
+// 
+// 		// Ensure enough misc slots are free.
+// 		for (int i = 0; i < sizeof(miscSlots)/sizeof(*miscSlots); i++) 
+// 		{
+// 			if (tempArtifWorn.find(miscSlots[i]) == tempArtifWorn.end() || miscSlots[i] == slotID)
+// 				misc--;
+// 		}
+// 		if (misc > 0)
+// 			return false;
+// 	}
+// 
+// 	return true;
+// }
 
 
 // bool CArtifact::canBeAssembledTo (const std::map<ui16, const CArtifact*> &artifWorn, ui32 artifactID) const
 // bool CArtifact::canBeAssembledTo (const std::map<ui16, const CArtifact*> &artifWorn, ui32 artifactID) const
 // {
 // {
@@ -189,11 +189,11 @@ std::string CArtifact::nodeName() const
 // 	}
 // 	}
 // }
 // }
 
 
-void CScroll::Init()
-{
-// 	addNewBonus (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);
-}
+// void CScroll::Init()
+// {
+// // 	addNewBonus (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()
 CArtHandler::CArtHandler()
 {
 {
@@ -202,7 +202,7 @@ CArtHandler::CArtHandler()
 	// War machines are the default big artifacts.
 	// War machines are the default big artifacts.
 	for (ui32 i = 3; i <= 6; i++)
 	for (ui32 i = 3; i <= 6; i++)
 		bigArtifacts.insert(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);
+	//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()
 CArtHandler::~CArtHandler()
@@ -231,24 +231,24 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
 	std::map<ui32,ui8>::iterator itr;
 	std::map<ui32,ui8>::iterator itr;
 	for (int i=0; i<ARTIFACTS_QUANTITY; i++)
 	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();
+// 		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 &nart = *art;
 		CArtifact &nart = *art;
 		nart.id=i;
 		nart.id=i;
@@ -754,95 +754,95 @@ void CArtHandler::clear()
 
 
 }
 }
 
 
-/**
- * Locally equips an artifact to a hero's worn slots. Unequips an already present artifact.
- * Does not test if the operation is legal.
- * @param artifWorn A hero's set of worn artifacts.
- * @param bonuses Optional list of bonuses to update.
- */
-void CArtHandler::equipArtifact( std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID, const CArtifact* art ) const
-{
-	unequipArtifact(artifWorn, slotID);
-
-	if (art) //false when artifact is NULL -> slot set to empty
-	{
-		const CArtifact &artifact = *art;
-
-		// Add artifact.
-		artifWorn[slotID] = art;
-
-		// 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) 
-			{
-				const CArtifact &constituent = *artifacts[constituentID];
-
-				if (!destConsumed && vstd::contains(constituent.possibleSlots, slotID)) 
-				{
-					destConsumed = true;
-				} 
-				else 
-				{
-					BOOST_FOREACH(ui16 slot, constituent.possibleSlots) 
-					{
-						if (!vstd::contains(artifWorn, slot)) 
-						{
-							artifWorn[slot] = VLC->arth->artifacts[145]; //lock
-							break;
-						}
-					}
-				}
-			}
-		}
-	}
-}
-
-/**
- * Locally unequips an artifact from a hero's worn slots.
- * Does not test if the operation is legal.
- * @param artifWorn A hero's set of worn artifacts.
- * @param bonuses Optional list of bonuses to update.
- */
-void CArtHandler::unequipArtifact(std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID) const
-{
-	if (!vstd::contains(artifWorn, slotID))
-		return;
-
-	const CArtifact &artifact = *artifWorn[slotID];
-
-	// Remove artifact, if it's not already removed.
-	artifWorn.erase(slotID);
-
-	// Remove locks, in reverse order of being added.
-	if (artifact.constituents != NULL) 
-	{
-		bool destConsumed = false;
-
-		BOOST_FOREACH(ui32 constituentID, *artifact.constituents) 
-		{
-			const CArtifact &constituent = *artifacts[constituentID];
-
-			if (!destConsumed && vstd::contains(constituent.possibleSlots, slotID)) 
-			{
-				destConsumed = true;
-			} 
-			else 
-			{
-				BOOST_REVERSE_FOREACH(ui16 slot, constituent.possibleSlots) 
-				{
-					if (vstd::contains(artifWorn, slot) && artifWorn[slot]->id == 145) 
-					{
-						artifWorn.erase(slot);
-						break;
-					}
-				}
-			}
-		}
-	}
-}
+// /**
+//  * Locally equips an artifact to a hero's worn slots. Unequips an already present artifact.
+//  * Does not test if the operation is legal.
+//  * @param artifWorn A hero's set of worn artifacts.
+//  * @param bonuses Optional list of bonuses to update.
+//  */
+// void CArtHandler::equipArtifact( std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID, const CArtifact* art ) const
+// {
+// 	unequipArtifact(artifWorn, slotID);
+// 
+// 	if (art) //false when artifact is NULL -> slot set to empty
+// 	{
+// 		const CArtifact &artifact = *art;
+// 
+// 		// Add artifact.
+// 		artifWorn[slotID] = art;
+// 
+// 		// 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) 
+// 			{
+// 				const CArtifact &constituent = *artifacts[constituentID];
+// 
+// 				if (!destConsumed && vstd::contains(constituent.possibleSlots, slotID)) 
+// 				{
+// 					destConsumed = true;
+// 				} 
+// 				else 
+// 				{
+// 					BOOST_FOREACH(ui16 slot, constituent.possibleSlots) 
+// 					{
+// 						if (!vstd::contains(artifWorn, slot)) 
+// 						{
+// 							artifWorn[slot] = VLC->arth->artifacts[145]; //lock
+// 							break;
+// 						}
+// 					}
+// 				}
+// 			}
+// 		}
+// 	}
+// }
+// 
+// /**
+//  * Locally unequips an artifact from a hero's worn slots.
+//  * Does not test if the operation is legal.
+//  * @param artifWorn A hero's set of worn artifacts.
+//  * @param bonuses Optional list of bonuses to update.
+//  */
+// void CArtHandler::unequipArtifact(std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID) const
+// {
+// 	if (!vstd::contains(artifWorn, slotID))
+// 		return;
+// 
+// 	const CArtifact &artifact = *artifWorn[slotID];
+// 
+// 	// Remove artifact, if it's not already removed.
+// 	artifWorn.erase(slotID);
+// 
+// 	// Remove locks, in reverse order of being added.
+// 	if (artifact.constituents != NULL) 
+// 	{
+// 		bool destConsumed = false;
+// 
+// 		BOOST_FOREACH(ui32 constituentID, *artifact.constituents) 
+// 		{
+// 			const CArtifact &constituent = *artifacts[constituentID];
+// 
+// 			if (!destConsumed && vstd::contains(constituent.possibleSlots, slotID)) 
+// 			{
+// 				destConsumed = true;
+// 			} 
+// 			else 
+// 			{
+// 				BOOST_REVERSE_FOREACH(ui16 slot, constituent.possibleSlots) 
+// 				{
+// 					if (vstd::contains(artifWorn, slot) && artifWorn[slot]->id == 145) 
+// 					{
+// 						artifWorn.erase(slot);
+// 						break;
+// 					}
+// 				}
+// 			}
+// 		}
+// 	}
+// }
 
 
 void CArtHandler::clearHlpLists()
 void CArtHandler::clearHlpLists()
 {
 {
@@ -1023,8 +1023,30 @@ CArtifactInstance * CArtifactInstance::createNewArtifactInstance(int aid)
 
 
 bool CCombinedArtifactInstance::canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved /*= false*/) const
 bool CCombinedArtifactInstance::canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved /*= false*/) const
 {
 {
-	return CArtifactInstance::canBePutAt(al, assumeDestRemoved);
-	//TODO look for place for constituents
+	bool canMainArtifactBePlaced = CArtifactInstance::canBePutAt(al, assumeDestRemoved);
+	if(!canMainArtifactBePlaced)
+		return false; //no is no...
+	if(al.slot >= Arts::BACKPACK_START)
+		return true; //we can always remove combined art to the backapck
+
+
+	assert(artType->constituents);
+	std::vector<ConstituentInfo> constituentsToBePlaced = constituentsInfo; //we'll remove constituents from that list, as we find a suitable slot for them
+	
+	//we iterate over all active slots and check if constituents fits them
+	for (int i = 0; i < Arts::BACKPACK_START; i++)
+	{
+		for(std::vector<ConstituentInfo>::iterator art = constituentsToBePlaced.begin(); art != constituentsToBePlaced.end(); art++)
+		{
+			if(art->art->canBePutAt(ArtifactLocation(al.hero, i), i == al.slot)) // i == al.slot because we can remove already worn artifact only from that slot  that is our main destination
+			{
+				constituentsToBePlaced.erase(art);
+				break;
+			}
+		}
+	}
+
+	return constituentsToBePlaced.empty();
 }
 }
 
 
 bool CCombinedArtifactInstance::canBeDisassembled() const
 bool CCombinedArtifactInstance::canBeDisassembled() const
@@ -1058,7 +1080,7 @@ void CCombinedArtifactInstance::addAsConstituent(CArtifactInstance *art, int slo
 	assert(vstd::contains(*artType->constituents, art->artType->id));
 	assert(vstd::contains(*artType->constituents, art->artType->id));
 	assert(art->parents.size() == 1  &&  art->parents.front() == art->artType);
 	assert(art->parents.size() == 1  &&  art->parents.front() == art->artType);
 	constituentsInfo.push_back(ConstituentInfo(art, slot));
 	constituentsInfo.push_back(ConstituentInfo(art, slot));
-	art->attachTo(this);
+	attachTo(art);
 }
 }
 
 
 void CCombinedArtifactInstance::putAt(CGHeroInstance *h, ui16 slot)
 void CCombinedArtifactInstance::putAt(CGHeroInstance *h, ui16 slot)

+ 62 - 62
lib/CArtHandler.h

@@ -30,11 +30,11 @@ public:
 	const std::string &Name() const; //getter
 	const std::string &Name() const; //getter
 	const std::string &Description() const; //getter
 	const std::string &Description() const; //getter
 	bool isBig () const;
 	bool isBig () const;
-	bool isModable () const;
-	bool fitsAt (const std::map<ui16, const CArtifact*> &artifWorn, ui16 slot) const;
+	//bool isModable () const;
+	//bool fitsAt (const std::map<ui16, const CArtifact*> &artifWorn, ui16 slot) const;
 	//bool canBeAssembledTo (const std::map<ui16, const CArtifact*> &artifWorn, ui32 artifactID) const;
 	//bool canBeAssembledTo (const std::map<ui16, const CArtifact*> &artifWorn, ui32 artifactID) const;
-	void addBonusesTo (BonusList *otherBonuses) const;
-	void removeBonusesFrom (BonusList *otherBonuses) const;
+// 	void addBonusesTo (BonusList *otherBonuses) const;
+// 	void removeBonusesFrom (BonusList *otherBonuses) const;
 	virtual void SetProperty (int mod){};
 	virtual void SetProperty (int mod){};
 	virtual void Init(){};
 	virtual void Init(){};
 	int getArtClassSerial() const; //0 - treasure, 1 - minor, 2 - major, 3 - relic, 4 - spell scroll, 5 - other
 	int getArtClassSerial() const; //0 - treasure, 1 - minor, 2 - major, 3 - relic, 4 - spell scroll, 5 - other
@@ -136,61 +136,61 @@ public:
 	}
 	}
 };
 };
 
 
-class DLL_EXPORT IModableArt : public CArtifact //artifact which can have different properties, such as scroll or banner
-{ //used only for dynamic cast :P
-public:
-	si32 ID; //used for smart serialization
-
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & static_cast<CArtifact&>(*this);
-		h & ID;
-	}
-};
-
-class DLL_EXPORT CScroll : public IModableArt // Spell Scroll
-{
-public:
-	CScroll(){spellid=0;};
-	CScroll(spelltype sid){spellid = sid;};
-	spelltype spellid;
-	void Init();
-	void SetProperty (int mod){spellid = mod;};
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & static_cast<IModableArt&>(*this);
-		h & spellid;
-	}
-};
-
-class DLL_EXPORT CCustomizableArt : public IModableArt // Warlord's Banner with multiple options
-{
-public:
-	ui8 mode;
-	CCustomizableArt(){mode=0;};
-	void Init(){};
-	void SetProperty (int mod){};
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & static_cast<IModableArt&>(*this);
-		h & mode;
-	}
-};
-
-class DLL_EXPORT CCommanderArt : 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 & level;
-	}
-};
+// class DLL_EXPORT IModableArt : public CArtifact //artifact which can have different properties, such as scroll or banner
+// { //used only for dynamic cast :P
+// public:
+// 	si32 ID; //used for smart serialization
+// 
+// 	template <typename Handler> void serialize(Handler &h, const int version)
+// 	{
+// 		h & static_cast<CArtifact&>(*this);
+// 		h & ID;
+// 	}
+// };
+// 
+// class DLL_EXPORT CScroll : public IModableArt // Spell Scroll
+// {
+// public:
+// 	CScroll(){spellid=0;};
+// 	CScroll(spelltype sid){spellid = sid;};
+// 	spelltype spellid;
+// 	void Init();
+// 	void SetProperty (int mod){spellid = mod;};
+// 	template <typename Handler> void serialize(Handler &h, const int version)
+// 	{
+// 		h & static_cast<IModableArt&>(*this);
+// 		h & spellid;
+// 	}
+// };
+// 
+// class DLL_EXPORT CCustomizableArt : public IModableArt // Warlord's Banner with multiple options
+// {
+// public:
+// 	ui8 mode;
+// 	CCustomizableArt(){mode=0;};
+// 	void Init(){};
+// 	void SetProperty (int mod){};
+// 	template <typename Handler> void serialize(Handler &h, const int version)
+// 	{
+// 		h & static_cast<IModableArt&>(*this);
+// 		h & mode;
+// 	}
+// };
+// 
+// class DLL_EXPORT CCommanderArt : 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 & level;
+// 	}
+// };
 
 
 class DLL_EXPORT CArtHandler //handles artifacts
 class DLL_EXPORT CArtHandler //handles artifacts
 {
 {
@@ -200,7 +200,7 @@ public:
 	std::vector< ConstTransitivePtr<CArtifact> > artifacts;
 	std::vector< ConstTransitivePtr<CArtifact> > artifacts;
 	std::vector<CArtifact *> allowedArtifacts;
 	std::vector<CArtifact *> allowedArtifacts;
 	std::set<ui32> bigArtifacts; // Artifacts that cannot be moved to backpack, e.g. war machines.
 	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
+	//std::map<ui32, ui8> modableArtifacts; //1-scroll, 2-banner, 3-commander art with progressive bonus
 
 
 	void loadArtifacts(bool onlyTxt);
 	void loadArtifacts(bool onlyTxt);
 	void sortArts();
 	void sortArts();
@@ -213,8 +213,8 @@ public:
 	void getAllowed(std::vector<ConstTransitivePtr<CArtifact> > &out, int flags);
 	void getAllowed(std::vector<ConstTransitivePtr<CArtifact> > &out, int flags);
 	void erasePickedArt (si32 id);
 	void erasePickedArt (si32 id);
 	bool isBigArtifact (ui32 artID) const {return bigArtifacts.find(artID) != bigArtifacts.end();}
 	bool isBigArtifact (ui32 artID) const {return bigArtifacts.find(artID) != bigArtifacts.end();}
-	void equipArtifact (std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID, const CArtifact* art) const;
-	void unequipArtifact (std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID) const;
+// 	void equipArtifact (std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID, const CArtifact* art) const;
+// 	void unequipArtifact (std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID) const;
 	void initAllowedArtifactsList(const std::vector<ui8> &allowed); //allowed[art_id] -> 0 if not allowed, 1 if allowed
 	void initAllowedArtifactsList(const std::vector<ui8> &allowed); //allowed[art_id] -> 0 if not allowed, 1 if allowed
 	static int convertMachineID(int id, bool creToArt);
 	static int convertMachineID(int id, bool creToArt);
 	CArtHandler();
 	CArtHandler();

+ 23 - 7
lib/CCreatureSet.cpp

@@ -306,19 +306,18 @@ CCreatureSet::~CCreatureSet()
 	clear();
 	clear();
 }
 }
 
 
-void CCreatureSet::setToArmy(CCreatureSet &src)
+void CCreatureSet::setToArmy(CSimpleArmy &src)
 {
 {
 	clear();
 	clear();
 	while(src)
 	while(src)
 	{
 	{
-		TSlots::iterator i = src.stacks.begin();
+		TSimpleSlots::iterator i = src.army.begin();
 
 
-		assert(i->second->type);
-		assert(i->second->valid(false));
-		assert(i->second->armyObj == NULL);
+		assert(i->second.type);
+		assert(i->second.count);
 
 
-		putStack(i->first, i->second);
-		src.stacks.erase(i);
+		putStack(i->first, new CStackInstance(i->second.type, i->second.count));
+		src.army.erase(i);
 	}
 	}
 }
 }
 
 
@@ -523,4 +522,21 @@ DLL_EXPORT std::ostream & operator<<(std::ostream & str, const CStackInstance &
 		str << sth.idRand;
 		str << sth.idRand;
 
 
 	return str;
 	return str;
+}
+
+void CSimpleArmy::clear()
+{
+	army.clear();
+}
+
+CSimpleArmy::operator bool() const
+{
+	return army.size();
+}
+
+bool CSimpleArmy::setCreature(TSlot slot, TCreature cre, TQuantity count)
+{
+	assert(!vstd::contains(army, slot));
+	army[slot] = CStackBasicDescriptor(cre, count);
+	return true;
 }
 }

+ 25 - 4
lib/CCreatureSet.h

@@ -64,10 +64,31 @@ public:
 DLL_EXPORT std::ostream & operator<<(std::ostream & str, const CStackInstance & sth);
 DLL_EXPORT std::ostream & operator<<(std::ostream & str, const CStackInstance & sth);
 
 
 typedef std::map<TSlot, CStackInstance*> TSlots;
 typedef std::map<TSlot, CStackInstance*> TSlots;
+typedef std::map<TSlot, CStackBasicDescriptor> TSimpleSlots;
 
 
+class IArmyDescriptor
+{
+public:
+	virtual void clear() = 0;
+	virtual bool setCreature(TSlot slot, TCreature cre, TQuantity count) = 0;
+};
+
+//simplified version of CCreatureSet
+class DLL_EXPORT CSimpleArmy : public IArmyDescriptor
+{
+public:
+	TSimpleSlots army;
+	void clear() OVERRIDE;
+	bool setCreature(TSlot slot, TCreature cre, TQuantity count) OVERRIDE;
+	operator bool() const;
 
 
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & army;
+	}
+};
 
 
-class DLL_EXPORT CCreatureSet //seven combined creatures
+class DLL_EXPORT CCreatureSet : public IArmyDescriptor //seven combined creatures
 {
 {
 	CCreatureSet(const CCreatureSet&);;
 	CCreatureSet(const CCreatureSet&);;
 	CCreatureSet &operator=(const CCreatureSet&);
 	CCreatureSet &operator=(const CCreatureSet&);
@@ -84,7 +105,7 @@ public:
 
 
 	void addToSlot(TSlot slot, TCreature cre, TQuantity count, bool allowMerging = true); //Adds stack to slot. Slot must be empty or with same type creature
 	void addToSlot(TSlot slot, TCreature cre, TQuantity count, bool allowMerging = true); //Adds stack to slot. Slot must be empty or with same type creature
 	void addToSlot(TSlot slot, CStackInstance *stack, bool allowMerging = true); //Adds stack to slot. Slot must be empty or with same type creature
 	void addToSlot(TSlot slot, CStackInstance *stack, bool allowMerging = true); //Adds stack to slot. Slot must be empty or with same type creature
-	void clear();
+	void clear() OVERRIDE;
 	void setFormation(bool tight);
 	void setFormation(bool tight);
 	CArmedInstance *castToArmyObj();
 	CArmedInstance *castToArmyObj();
 
 
@@ -98,8 +119,8 @@ public:
 
 
 	//derivative 
 	//derivative 
 	void changeStackCount(TSlot slot, TQuantity toAdd); //stack must exist!
 	void changeStackCount(TSlot slot, TQuantity toAdd); //stack must exist!
-	bool setCreature (TSlot slot, TCreature type, TQuantity quantity); //replaces creature in stack; slots 0 to 6, if quantity=0 erases stack
-	void setToArmy(CCreatureSet &src); //erases all our army and moves stacks from src to us; src MUST NOT be an armed object! WARNING: use it wisely. Or better do not use at all.
+	bool setCreature (TSlot slot, TCreature type, TQuantity quantity) OVERRIDE; //replaces creature in stack; slots 0 to 6, if quantity=0 erases stack
+	void setToArmy(CSimpleArmy &src); //erases all our army and moves stacks from src to us; src MUST NOT be an armed object! WARNING: use it wisely. Or better do not use at all.
 	
 	
 	const CStackInstance& getStack(TSlot slot) const; 
 	const CStackInstance& getStack(TSlot slot) const; 
 	const CCreature* getCreature(TSlot slot) const; //workaround of map issue;
 	const CCreature* getCreature(TSlot slot) const; //workaround of map issue;

+ 2 - 2
lib/CObjectHandler.cpp

@@ -836,7 +836,7 @@ void CGHeroInstance::initHero()
 		mana = manaLimit();
 		mana = manaLimit();
 }
 }
 
 
-void CGHeroInstance::initArmy(CCreatureSet *dst /*= NULL*/)
+void CGHeroInstance::initArmy(IArmyDescriptor *dst /*= NULL*/)
 {
 {
 	if(!dst)
 	if(!dst)
 		dst = this;
 		dst = this;
@@ -883,7 +883,7 @@ void CGHeroInstance::initArmy(CCreatureSet *dst /*= NULL*/)
 				tlog3 << "Hero " << name << " already has artifact at " << slot << ", ommiting giving " << aid << std::endl;
 				tlog3 << "Hero " << name << " already has artifact at " << slot << ", ommiting giving " << aid << std::endl;
 		}
 		}
 		else
 		else
-			dst->putStack(stackNo-warMachinesGiven, new CStackInstance(creID, count));
+			dst->setCreature(stackNo-warMachinesGiven, creID, count);
 	}
 	}
 }
 }
 void CGHeroInstance::initHeroDefInfo()
 void CGHeroInstance::initHeroDefInfo()

+ 1 - 1
lib/CObjectHandler.h

@@ -418,7 +418,7 @@ public:
 	void putArtifact(ui16 pos, CArtifactInstance *art);
 	void putArtifact(ui16 pos, CArtifactInstance *art);
 	void putInBackpack(CArtifactInstance *art);
 	void putInBackpack(CArtifactInstance *art);
 	void initExp();
 	void initExp();
-	void initArmy(CCreatureSet *dst = NULL);
+	void initArmy(IArmyDescriptor *dst = NULL);
 	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 - 0
lib/HeroBonus.h

@@ -438,6 +438,8 @@ public:
 	template <typename Handler> void serialize(Handler &h, const int version)
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 	{
 		h & bonuses & nodeType;
 		h & bonuses & nodeType;
+		h & exportedBonuses;
+		//h & parents & children;
 	}
 	}
 
 
 	enum ENodeTypes
 	enum ENodeTypes

+ 2 - 4
lib/NetPacks.h

@@ -368,19 +368,17 @@ struct SetAvailableHeroes : public CPackForClient //113
 	{
 	{
 		type = 113;
 		type = 113;
 		for (int i = 0; i < AVAILABLE_HEROES_PER_PLAYER; i++)
 		for (int i = 0; i < AVAILABLE_HEROES_PER_PLAYER; i++)
-			army[i] = NULL;
+			army[i].clear();
 	}
 	}
 	~SetAvailableHeroes()
 	~SetAvailableHeroes()
 	{
 	{
-		for (int i = 0; i < AVAILABLE_HEROES_PER_PLAYER; i++)
-			delete army[i];
 	}
 	}
 	void applyCl(CClient *cl);
 	void applyCl(CClient *cl);
 	DLL_EXPORT void applyGs(CGameState *gs);
 	DLL_EXPORT void applyGs(CGameState *gs);
 
 
 	ui8 player;
 	ui8 player;
 	si32 hid[AVAILABLE_HEROES_PER_PLAYER]; //-1 if no hero
 	si32 hid[AVAILABLE_HEROES_PER_PLAYER]; //-1 if no hero
-	CCreatureSet *army[AVAILABLE_HEROES_PER_PLAYER];
+	CSimpleArmy army[AVAILABLE_HEROES_PER_PLAYER];
 	template <typename Handler> void serialize(Handler &h, const int version)
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 	{
 		h & player & hid & army;
 		h & player & hid & army;

+ 6 - 3
lib/NetPacksLib.cpp

@@ -180,7 +180,7 @@ DLL_EXPORT void SetAvailableHeroes::applyGs( CGameState *gs )
 	{
 	{
 		CGHeroInstance *h = (hid[i]>=0 ?  (CGHeroInstance*)gs->hpool.heroesPool[hid[i]] : NULL);
 		CGHeroInstance *h = (hid[i]>=0 ?  (CGHeroInstance*)gs->hpool.heroesPool[hid[i]] : NULL);
 		if(h && army[i])
 		if(h && army[i])
-			h->setToArmy(*army[i]);
+			h->setToArmy(army[i]);
 		p->availableHeroes.push_back(h);
 		p->availableHeroes.push_back(h);
 	}
 	}
 }
 }
@@ -729,6 +729,7 @@ DLL_EXPORT void AssembledArtifact::applyGs( CGameState *gs )
 	assert(vstd::contains(transformedArt->assemblyPossibilities(al.hero), builtArt));
 	assert(vstd::contains(transformedArt->assemblyPossibilities(al.hero), builtArt));
 
 
 	CCombinedArtifactInstance *combinedArt = new CCombinedArtifactInstance(builtArt);
 	CCombinedArtifactInstance *combinedArt = new CCombinedArtifactInstance(builtArt);
+	gs->map->addNewArtifactInstance(combinedArt);
 	//retreive all constituents
 	//retreive all constituents
 	BOOST_FOREACH(si32 constituentID, *builtArt->constituents)
 	BOOST_FOREACH(si32 constituentID, *builtArt->constituents)
 	{
 	{
@@ -739,6 +740,8 @@ DLL_EXPORT void AssembledArtifact::applyGs( CGameState *gs )
 		//move constituent from hero to be part of new, combined artifact
 		//move constituent from hero to be part of new, combined artifact
 		constituentInstance->removeFrom(h, pos);
 		constituentInstance->removeFrom(h, pos);
 		combinedArt->addAsConstituent(constituentInstance, pos);
 		combinedArt->addAsConstituent(constituentInstance, pos);
+		if(!vstd::contains(combinedArt->artType->possibleSlots, al.slot) && vstd::contains(combinedArt->artType->possibleSlots, pos))
+			al.slot = pos;
 	}
 	}
 
 
 	//put new combined artifacts
 	//put new combined artifacts
@@ -755,11 +758,11 @@ DLL_EXPORT void DisassembledArtifact::applyGs( CGameState *gs )
 	disassembled->removeFrom(h, al.slot);
 	disassembled->removeFrom(h, al.slot);
 	BOOST_FOREACH(CCombinedArtifactInstance::ConstituentInfo &ci, constituents)
 	BOOST_FOREACH(CCombinedArtifactInstance::ConstituentInfo &ci, constituents)
 	{
 	{
-		ci.art->detachFrom(disassembled);
+		disassembled->detachFrom(ci.art);
 		ci.art->putAt(h, ci.slot >= 0 ? ci.slot : al.slot); //-1 is slot of main constituent -> it'll replace combined artifact in its pos
 		ci.art->putAt(h, ci.slot >= 0 ? ci.slot : al.slot); //-1 is slot of main constituent -> it'll replace combined artifact in its pos
 	}
 	}
 
 
-	delNull(disassembled);
+	gs->map->eraseArtifactInstance(disassembled);
 }
 }
 
 
 DLL_EXPORT void SetAvailableArtifacts::applyGs( CGameState *gs )
 DLL_EXPORT void SetAvailableArtifacts::applyGs( CGameState *gs )

+ 11 - 0
lib/RegisterTypes.cpp

@@ -80,6 +80,17 @@ void registerTypes1(Serializer &s)
 	s.template registerType<CreatureFactionLimiter>();
 	s.template registerType<CreatureFactionLimiter>();
 	s.template registerType<CreatureAlignmentLimiter>();
 	s.template registerType<CreatureAlignmentLimiter>();
 
 
+	s.template registerType<CBonusSystemNode>();
+	s.template registerType<CArtifact>();
+	s.template registerType<CCreature>();
+	s.template registerType<CStackInstance>();
+	s.template registerType<PlayerState>();
+	s.template registerType<TeamState>();
+	s.template registerType<CGameState>();
+	s.template registerType<CGHeroInstance::HeroSpecial>();
+	s.template registerType<CArmedInstance>();
+	s.template registerType<CStack>();
+	s.template registerType<BattleInfo>();
 	s.template registerType<CArtifactInstance>();
 	s.template registerType<CArtifactInstance>();
 	s.template registerType<CCombinedArtifactInstance>();
 	s.template registerType<CCombinedArtifactInstance>();
 }
 }

+ 6 - 0
lib/map.cpp

@@ -2097,6 +2097,12 @@ CArtifactInstance * Mapa::createArt(int aid)
 	return a;
 	return a;
 }
 }
 
 
+void Mapa::eraseArtifactInstance(CArtifactInstance *art)
+{
+	assert(artInstances[art->id] == art);
+	artInstances[art->id].dellNull();
+}
+
 LossCondition::LossCondition()
 LossCondition::LossCondition()
 {
 {
 	obj = NULL;
 	obj = NULL;

+ 2 - 1
lib/map.h

@@ -307,9 +307,10 @@ struct DLL_EXPORT Mapa : public CMapHeader
 	int loadSeerHut( const unsigned char * bufor, int i, CGObjectInstance *& nobj);
 	int loadSeerHut( const unsigned char * bufor, int i, CGObjectInstance *& nobj);
 
 
 	CArtifactInstance *createArt(int aid);
 	CArtifactInstance *createArt(int aid);
+	void addNewArtifactInstance(CArtifactInstance *art);
+	void eraseArtifactInstance(CArtifactInstance *art);
 
 
 	void checkForObjectives();
 	void checkForObjectives();
-	void addNewArtifactInstance(CArtifactInstance *art);
 	void addBlockVisTiles(CGObjectInstance * obj);
 	void addBlockVisTiles(CGObjectInstance * obj);
 	void removeBlockVisTiles(CGObjectInstance * obj, bool total=false);
 	void removeBlockVisTiles(CGObjectInstance * obj, bool total=false);
 	Mapa(std::string filename); //creates map structure from .h3m file
 	Mapa(std::string filename); //creates map structure from .h3m file

+ 5 - 5
server/CGameHandler.cpp

@@ -430,8 +430,8 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
 		sah.hid[0] = loserHero->subID;
 		sah.hid[0] = loserHero->subID;
 		if(result == 1) //retreat
 		if(result == 1) //retreat
 		{
 		{
-			sah.army[0] = new CCreatureSet();
-			sah.army[0]->addToSlot(0, VLC->creh->nameToID[loserHero->type->refTypeStack[0]],1);
+			sah.army[0].clear();
+			sah.army[0].setCreature(0, VLC->creh->nameToID[loserHero->type->refTypeStack[0]],1);
 		}
 		}
 
 
 		if(const CGHeroInstance *another =  getPlayerState(loser)->availableHeroes[1])
 		if(const CGHeroInstance *another =  getPlayerState(loser)->availableHeroes[1])
@@ -799,7 +799,7 @@ void CGameHandler::newTurn()
 				if(CGHeroInstance *h = gs->hpool.pickHeroFor(j == 0, i->first, getNativeTown(i->first), pool, banned)) //first hero - native if possible, second hero -> any other class
 				if(CGHeroInstance *h = gs->hpool.pickHeroFor(j == 0, i->first, getNativeTown(i->first), pool, banned)) //first hero - native if possible, second hero -> any other class
 				{
 				{
 					sah.hid[j] = h->subID;
 					sah.hid[j] = h->subID;
-					h->initArmy(sah.army[j] = new CCreatureSet());
+					h->initArmy(&sah.army[j]);
 					banned = h->type->heroClass;
 					banned = h->type->heroClass;
 				}
 				}
 				else
 				else
@@ -2994,8 +2994,8 @@ bool CGameHandler::hireHero(const CGObjectInstance *obj, ui8 hid, ui8 player)
 	if(newHero)
 	if(newHero)
 	{
 	{
 		sah.hid[hid] = newHero->subID;
 		sah.hid[hid] = newHero->subID;
-		sah.army[hid] = new CCreatureSet();
-		sah.army[hid]->addToSlot(0, VLC->creh->nameToID[newHero->type->refTypeStack[0]],1);
+		sah.army[hid].clear();
+		sah.army[hid].setCreature(0, VLC->creh->nameToID[newHero->type->refTypeStack[0]],1);
 	}
 	}
 	else
 	else
 		sah.hid[hid] = -1;
 		sah.hid[hid] = -1;