Pārlūkot izejas kodu

"You have captured enemy artifact" window. All arts from commander & stacks will also be looted.

DjWarmonger 13 gadi atpakaļ
vecāks
revīzija
bd2a0c2a2b
3 mainītis faili ar 83 papildinājumiem un 31 dzēšanām
  1. 13 4
      lib/NetPacks.h
  2. 69 27
      server/CGameHandler.cpp
  3. 1 0
      server/CGameHandler.h

+ 13 - 4
lib/NetPacks.h

@@ -843,11 +843,21 @@ struct RebalanceStacks : CGarrisonOperationPack  //526
 };
 
 typedef si32 TArtPos;
-
+typedef boost::variant<ConstTransitivePtr<CGHeroInstance>, ConstTransitivePtr<CStackInstance> > TArtHolder;
+
+//struct GetArtifactSet : boost::static_visitor<>
+//{
+//  void operator()(const ConstTransitivePtr<CGHeroInstance> &h) const {}
+//  void operator()(const ConstTransitivePtr<CStackInstance> &s) const {}
+//};
+//struct GetArtifactSetPtr : boost::static_visitor<>
+//{
+//  ConstTransitivePtr<CGHeroInstance> operator()(const ConstTransitivePtr<CGHeroInstance> &h) const { return h;}
+//  ConstTransitivePtr<CStackInstance> operator()(const ConstTransitivePtr<CStackInstance> &s) const { return s;}
+//};
 struct ArtifactLocation
 {
-	typedef boost::variant<ConstTransitivePtr<CGHeroInstance>, ConstTransitivePtr<CStackInstance> > TArtHolder;
-	//, ConstTransitivePtr<CCommanderInstance> ?
+
 
 	TArtHolder artHolder;
 	TArtPos slot;
@@ -860,7 +870,6 @@ struct ArtifactLocation
 	template <typename T>
 	ArtifactLocation(const T *ArtHolder, TArtPos Slot)
 	{
-
 		artHolder = const_cast<T*>(ArtHolder); //we are allowed here to const cast -> change will go through one of our packages... do not abuse!
 		slot = Slot;
 	}

+ 69 - 27
server/CGameHandler.cpp

@@ -384,60 +384,95 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
 
 	ConstTransitivePtr <CGHeroInstance> winnerHero = battleResult.data->winner != 0 ? hero2 : hero1;
 	ConstTransitivePtr <CGHeroInstance> loserHero = battleResult.data->winner != 0 ? hero1 : hero2;
+	std::vector<ui32> arts; //display them in window
 
-	//TODO: check if hero surrended / fled
 	//TODO: display loot in window
 	if (result < BattleResult::SURRENDER && winnerHero)
 	{
 		if (loserHero)
 		{
-			auto artifactsWorn = loserHero->artifactsWorn;
+			auto artifactsWorn = loserHero->artifactsWorn; //TODO: wrap it into a function, somehow (boost::variant -_-)
 			BOOST_FOREACH (auto artSlot, artifactsWorn)
 			{
-				MoveArtifact ma; //TODO: put into a function?
+				MoveArtifact ma;
 				ma.src = ArtifactLocation (loserHero, artSlot.first);
 				const CArtifactInstance * art =  ma.src.getArt();
 				if (art && !art->artType->isBig()) // don't move war machines or locked arts (spellbook)
 				{
+					arts.push_back (art->artType->id);
 					ma.dst = ArtifactLocation (winnerHero, art->firstAvailableSlot(winnerHero));
 					sendAndApply(&ma);
 				}
 			}
 			while (!loserHero->artifactsInBackpack.empty())
 			{
-				//we assume that no big artifatcs cna be found
+				//we assume that no big artifacts can be found
 				MoveArtifact ma;
 				ma.src = ArtifactLocation (loserHero, GameConstants::BACKPACK_START); //backpack automatically shifts arts to beginning
 				const CArtifactInstance * art =  ma.src.getArt();
+				arts.push_back (art->artType->id);
 				ma.dst = ArtifactLocation (winnerHero, art->firstAvailableSlot(winnerHero));
 				sendAndApply(&ma);
 			}
-
-			//if (loserHero->commander) //TODO: what if commanders belong to no hero?
-			//{
-			//	BOOST_FOREACH (auto art, loserHero->commander->artifactsWorn)
-			//	{
-			//		MoveArtifact ma; //FIXME: boost::variant vs pointer casting is bad solution
-			//		ma.src = ArtifactLocation (loserHero->commander.get(), art.first);
-			//		ma.dst = ArtifactLocation (winnerHero, art.second.artifact->firstAvailableSlot(winnerHero));
-			//		sendAndApply(&ma);
-			//	}
-			//}
-		}
-		//BOOST_FOREACH (auto armySlot, gs->curB->belligerents[loser]->stacks)
-		//{
-		//	MoveArtifact ma;
-		//	ma.src = ArtifactLocation (armySlot.second, (ArtifactPosition::CREATURE_SLOT));
-		//	{
-		//		if (CArtifactInstance * art = ma.src.getArt())
-		//			ma.dst = ArtifactLocation (winnerHero, art->firstAvailableSlot(winnerHero));
-		//		sendAndApply(&ma);
-		//	}
-		//}
+			if (loserHero->commander) //TODO: what if commanders belong to no hero?
+			{
+				artifactsWorn = loserHero->commander->artifactsWorn;
+				BOOST_FOREACH (auto artSlot, artifactsWorn)
+				{
+					MoveArtifact ma;
+					ma.src = ArtifactLocation (loserHero->commander.get(), artSlot.first);
+					const CArtifactInstance * art =  ma.src.getArt();
+					if (art && !art->artType->isBig())
+					{
+						arts.push_back (art->artType->id);
+						ma.dst = ArtifactLocation (winnerHero, art->firstAvailableSlot(winnerHero));
+						sendAndApply(&ma);
+					}
+				}
+			}
+		}
+		BOOST_FOREACH (auto armySlot, gs->curB->belligerents[!battleResult.data->winner]->stacks)
+		{
+			auto artifactsWorn = armySlot.second->artifactsWorn;
+			BOOST_FOREACH (auto artSlot, artifactsWorn)
+			{
+				MoveArtifact ma;
+				ma.src = ArtifactLocation (armySlot.second, artSlot.first);
+				const CArtifactInstance * art =  ma.src.getArt();
+				if (art && !art->artType->isBig())
+				{
+					arts.push_back (art->artType->id);
+					ma.dst = ArtifactLocation (winnerHero, art->firstAvailableSlot(winnerHero));
+					sendAndApply(&ma);
+				}
+			}
+		}
 	}
 
 	sendAndApply(battleResult.data); //after this point casualties objects are destroyed
 
+	if (arts.size()) //display loot
+	{
+		InfoWindow iw;
+		iw.player = winnerHero->tempOwner;
+
+		iw.text.addTxt (MetaString::GENERAL_TXT, 30); //You have captured enemy artifact
+
+		BOOST_FOREACH (auto id, arts) //TODO; separate function to display loot for various ojects?
+		{
+			iw.components.push_back (Component (Component::ARTIFACT, id, 0, 0));
+			if(iw.components.size() >= 14)
+			{
+				sendAndApply(&iw);
+				iw.components.clear();
+				iw.text.addTxt (MetaString::GENERAL_TXT, 30); //repeat
+			}
+		}
+		if (iw.components.size())
+		{
+			sendAndApply(&iw);
+		}
+	}
 	//Eagle Eye secondary skill handling
 	if(cs.spells.size())
 	{
@@ -547,7 +582,6 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
 		sendAndApply(&sah);
 	}
 }
-
 void CGameHandler::afterBattleCallback() //object interaction after leveling up is done
 {
 	if(battleEndCallback && *battleEndCallback)
@@ -2752,6 +2786,14 @@ bool CGameHandler::sellArtifact(const IMarket *m, const CGHeroInstance *h, int a
 	return true;
 }
 
+//void CGameHandler::lootArtifacts (TArtHolder source, TArtHolder dest, std::vector<ui32> &arts)
+//{
+//	//const CGHeroInstance * h1 = dynamic_cast<CGHeroInstance *> source;
+//	//auto s = boost::apply_visitor(GetArtifactSetPtr(), source);
+//	{
+//	}
+//}
+
 bool CGameHandler::buySecSkill( const IMarket *m, const CGHeroInstance *h, int skill)
 {
 	if (!h)

+ 1 - 0
server/CGameHandler.h

@@ -210,6 +210,7 @@ public:
 	bool buyArtifact( ui32 hid, si32 aid ); //for blacksmith and mage guild only -> buying for gold in common buildings
 	bool buyArtifact( const IMarket *m, const CGHeroInstance *h, int rid, int aid); //for artifact merchant and black market -> buying for any resource in special building / advobject
 	bool sellArtifact( const IMarket *m, const CGHeroInstance *h, int aid, int rid); //for artifact merchant selling
+	//void lootArtifacts (TArtHolder source, TArtHolder dest, std::vector<ui32> &arts); //after battle - move al arts to winer
 	bool buySecSkill( const IMarket *m, const CGHeroInstance *h, int skill);
 	bool garrisonSwap(si32 tid);
 	bool upgradeCreature( ui32 objid, ui8 pos, ui32 upgID );