瀏覽代碼

endBattleConfirm

SoundSSGood 1 年之前
父節點
當前提交
f87762bc96
共有 2 個文件被更改,包括 105 次插入96 次删除
  1. 1 1
      client/widgets/CArtPlace.cpp
  2. 104 95
      server/battles/BattleResultProcessor.cpp

+ 1 - 1
client/widgets/CArtPlace.cpp

@@ -263,12 +263,12 @@ bool ArtifactUtilsClient::askToAssemble(const CGHeroInstance * hero, const Artif
 				boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
 				for(const auto combinedArt : assemblyPossibilities)
 				{
+					LOCPLINT->waitWhileDialog();
 					bool assembleConfirmed = false;
 					CFunctionList<void()> onYesHandlers([&assembleConfirmed]() -> void {assembleConfirmed = true; });
 					onYesHandlers += std::bind(&CCallback::assembleArtifacts, LOCPLINT->cb.get(), hero, slot, true, combinedArt->getId());
 
 					LOCPLINT->showArtifactAssemblyDialog(art->artType, combinedArt, onYesHandlers);
-					LOCPLINT->waitWhileDialog();
 					if(assembleConfirmed)
 						break;
 				}

+ 104 - 95
server/battles/BattleResultProcessor.cpp

@@ -323,165 +323,174 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle)
 	CasualtiesAfterBattle cab1(battle, BattleSide::ATTACKER);
 	CasualtiesAfterBattle cab2(battle, BattleSide::DEFENDER);
 
-	ChangeSpells cs; //for Eagle Eye
+	cab1.updateArmy(gameHandler);
+	cab2.updateArmy(gameHandler); //take casualties after battle is deleted
+
+	if(battleResult->winner == BattleSide::DEFENDER
+	   && finishingBattle->winnerHero
+	   && finishingBattle->winnerHero->visitedTown
+	   && !finishingBattle->winnerHero->inTownGarrison
+	   && finishingBattle->winnerHero->visitedTown->garrisonHero == finishingBattle->winnerHero)
+	{
+		gameHandler->swapGarrisonOnSiege(finishingBattle->winnerHero->visitedTown->id); //return defending visitor from garrison to its rightful place
+	}
+	//give exp
+	if(!finishingBattle->isDraw() && battleResult->exp[finishingBattle->winnerSide] && finishingBattle->winnerHero)
+		gameHandler->giveExperience(finishingBattle->winnerHero, battleResult->exp[finishingBattle->winnerSide]);
 
+	// Eagle Eye handling
 	if(!finishingBattle->isDraw() && finishingBattle->winnerHero)
 	{
-		if (int eagleEyeLevel = finishingBattle->winnerHero->valOfBonuses(BonusType::LEARN_BATTLE_SPELL_LEVEL_LIMIT))
+		ChangeSpells spells;
+
+		if(auto eagleEyeLevel = finishingBattle->winnerHero->valOfBonuses(BonusType::LEARN_BATTLE_SPELL_LEVEL_LIMIT))
 		{
-			double eagleEyeChance = finishingBattle->winnerHero->valOfBonuses(BonusType::LEARN_BATTLE_SPELL_CHANCE);
+			auto eagleEyeChance = finishingBattle->winnerHero->valOfBonuses(BonusType::LEARN_BATTLE_SPELL_CHANCE);
 			for(auto & spellId : battle.getBattle()->getUsedSpells(battle.otherSide(battleResult->winner)))
 			{
 				auto spell = spellId.toEntity(VLC->spells());
-				if(spell && spell->getLevel() <= eagleEyeLevel && !finishingBattle->winnerHero->spellbookContainsSpell(spell->getId()) && gameHandler->getRandomGenerator().nextInt(99) < eagleEyeChance)
-					cs.spells.insert(spell->getId());
+				if(spell
+					&& spell->getLevel() <= eagleEyeLevel
+					&& !finishingBattle->winnerHero->spellbookContainsSpell(spell->getId())
+					&& gameHandler->getRandomGenerator().nextInt(99) < eagleEyeChance)
+				{
+					spells.spells.insert(spell->getId());
+				}
 			}
 		}
-	}
-	std::vector<const CArtifactInstance *> arts; //display them in window
 
+		if(!spells.spells.empty())
+		{
+			spells.learn = 1;
+			spells.hid = finishingBattle->winnerHero->id;
+
+			InfoWindow iw;
+			iw.player = finishingBattle->winnerHero->tempOwner;
+			iw.text.appendLocalString(EMetaText::GENERAL_TXT, 221); //Through eagle-eyed observation, %s is able to learn %s
+			iw.text.replaceRawString(finishingBattle->winnerHero->getNameTranslated());
+
+			std::ostringstream names;
+			for(int i = 0; i < spells.spells.size(); i++)
+			{
+				names << "%s";
+				if(i < spells.spells.size() - 2)
+					names << ", ";
+				else if(i < spells.spells.size() - 1)
+					names << "%s";
+			}
+			names << ".";
+
+			iw.text.replaceRawString(names.str());
+
+			auto it = spells.spells.begin();
+			for(int i = 0; i < spells.spells.size(); i++, it++)
+			{
+				iw.text.replaceName(*it);
+				if(i == spells.spells.size() - 2) //we just added pre-last name
+					iw.text.replaceLocalString(EMetaText::GENERAL_TXT, 141); // " and "
+				iw.components.emplace_back(ComponentType::SPELL, *it);
+			}
+			gameHandler->sendAndApply(&iw);
+			gameHandler->sendAndApply(&spells);
+		}
+	}
+	// Artifacts handling
 	if(result == EBattleResult::NORMAL && !finishingBattle->isDraw() && finishingBattle->winnerHero)
 	{
-		BulkMoveArtifacts bma(finishingBattle->winnerHero->getOwner(), finishingBattle->loserHero->id, finishingBattle->winnerHero->id, false);
-		bma.askAssemble = true;
+		std::vector<const CArtifactInstance*> arts; // display them in window
 		CArtifactFittingSet artFittingSet(*finishingBattle->winnerHero);
 
-		const auto addArtifactToTransfer = [&](const ArtifactPosition & srcSlot, const CArtifactInstance * art)
+		const auto addArtifactToTransfer = [&artFittingSet, &arts](BulkMoveArtifacts & pack, const ArtifactPosition & srcSlot, const CArtifactInstance * art)
 		{
 			assert(art);
 			const auto dstSlot = ArtifactUtils::getArtAnyPosition(&artFittingSet, art->getTypeId());
 			if(dstSlot != ArtifactPosition::PRE_FIRST)
 			{
-				bma.artsPack0.emplace_back(BulkMoveArtifacts::LinkedSlots(srcSlot, dstSlot));
+				pack.artsPack0.emplace_back(BulkMoveArtifacts::LinkedSlots(srcSlot, dstSlot));
 				arts.emplace_back(art);
 				artFittingSet.putArtifact(dstSlot, const_cast<CArtifactInstance*>(art));
 			}
 		};
-		const auto sendArtifacts = [&bma, this]()
+		const auto sendArtifacts = [this](BulkMoveArtifacts & bma)
 		{
 			if(!bma.artsPack0.empty())
 				gameHandler->sendAndApply(&bma);
 		};
 
+		BulkMoveArtifacts packHero(finishingBattle->winnerHero->getOwner(), ObjectInstanceID::NONE, finishingBattle->winnerHero->id, false);
 		if(finishingBattle->loserHero)
 		{
+			packHero.srcArtHolder = finishingBattle->loserHero->id;
+			packHero.askAssemble = true;
 			for(const auto & artSlot : finishingBattle->loserHero->artifactsWorn)
 			{
 				if(ArtifactUtils::isArtRemovable(artSlot))
-					addArtifactToTransfer(artSlot.first, artSlot.second.getArt());
+					addArtifactToTransfer(packHero, artSlot.first, artSlot.second.getArt());
 			}
 			for(const auto & artSlot : finishingBattle->loserHero->artifactsInBackpack)
 			{
 				if(const auto art = artSlot.getArt(); art->getTypeId() != ArtifactID::GRAIL)
-					addArtifactToTransfer(finishingBattle->loserHero->getArtPos(art), art);
+					addArtifactToTransfer(packHero, finishingBattle->loserHero->getArtPos(art), art);
 			}
-			sendArtifacts();
 
-			bma.askAssemble = false;
-			bma.artsPack0.clear();
 			if(finishingBattle->loserHero->commander)
 			{
-				bma.srcCreature = finishingBattle->loserHero->findStack(finishingBattle->loserHero->commander);
+				BulkMoveArtifacts packCommander(finishingBattle->winnerHero->getOwner(), finishingBattle->loserHero->id, finishingBattle->winnerHero->id, false);
+				packCommander.srcCreature = finishingBattle->loserHero->findStack(finishingBattle->loserHero->commander);
 				for(const auto & artSlot : finishingBattle->loserHero->commander->artifactsWorn)
-					addArtifactToTransfer(artSlot.first, artSlot.second.getArt());
-				sendArtifacts();
+					addArtifactToTransfer(packCommander, artSlot.first, artSlot.second.getArt());
+				sendArtifacts(packCommander);
 			}
 		}
 		auto armyObj = battle.battleGetArmyObject(battle.otherSide(battleResult->winner));
-		bma.srcArtHolder = armyObj->id;
 		for(const auto & armySlot : armyObj->stacks)
 		{
-			bma.artsPack0.clear();
-			bma.interfaceOwner = finishingBattle->winnerHero->getOwner();
-			bma.srcCreature = armySlot.first;
+			BulkMoveArtifacts packsArmy(finishingBattle->winnerHero->getOwner(), finishingBattle->loserHero->id, finishingBattle->winnerHero->id, false);
+			packsArmy.srcArtHolder = armyObj->id;
+			packsArmy.srcCreature = armySlot.first;
 			for(const auto & artSlot : armySlot.second->artifactsWorn)
-				addArtifactToTransfer(artSlot.first, armySlot.second->getArt(artSlot.first));
-			sendArtifacts();
+				addArtifactToTransfer(packsArmy, artSlot.first, armySlot.second->getArt(artSlot.first));
+			sendArtifacts(packsArmy);
 		}
-	}
-	// Display loot
-	if(!arts.empty())
-	{
-		InfoWindow iw;
-		iw.player = finishingBattle->winnerHero->tempOwner;
-		iw.text.appendLocalString(EMetaText::GENERAL_TXT, 30); //You have captured enemy artifact
-
-		for(auto art : arts) //TODO; separate function to display loot for various objects?
+		// Display loot
+		if(!arts.empty())
 		{
-			if(art->isScroll())
-				iw.components.emplace_back(ComponentType::SPELL_SCROLL, art->getScrollSpellID());
-			else
-				iw.components.emplace_back(ComponentType::ARTIFACT, art->getTypeId());
+			InfoWindow iw;
+			iw.player = finishingBattle->winnerHero->tempOwner;
+			iw.text.appendLocalString(EMetaText::GENERAL_TXT, 30); //You have captured enemy artifact
 
-			if(iw.components.size() >= GameConstants::INFO_WINDOW_ARTIFACTS_MAX_ITEMS)
+			for(auto art : arts) //TODO; separate function to display loot for various objects?
 			{
-				gameHandler->sendAndApply(&iw);
-				iw.components.clear();
-			}
-		}
-		gameHandler->sendAndApply(&iw);
-	}
-	//Eagle Eye secondary skill handling
-	if (!cs.spells.empty())
-	{
-		cs.learn = 1;
-		cs.hid = finishingBattle->winnerHero->id;
-
-		InfoWindow iw;
-		iw.player = finishingBattle->winnerHero->tempOwner;
-		iw.text.appendLocalString(EMetaText::GENERAL_TXT, 221); //Through eagle-eyed observation, %s is able to learn %s
-		iw.text.replaceRawString(finishingBattle->winnerHero->getNameTranslated());
-
-		std::ostringstream names;
-		for (int i = 0; i < cs.spells.size(); i++)
-		{
-			names << "%s";
-			if (i < cs.spells.size() - 2)
-				names << ", ";
-			else if (i < cs.spells.size() - 1)
-				names << "%s";
-		}
-		names << ".";
-
-		iw.text.replaceRawString(names.str());
+				if(art->isScroll())
+					iw.components.emplace_back(ComponentType::SPELL_SCROLL, art->getScrollSpellID());
+				else
+					iw.components.emplace_back(ComponentType::ARTIFACT, art->getTypeId());
 
-		auto it = cs.spells.begin();
-		for (int i = 0; i < cs.spells.size(); i++, it++)
-		{
-			iw.text.replaceName(*it);
-			if (i == cs.spells.size() - 2) //we just added pre-last name
-				iw.text.replaceLocalString(EMetaText::GENERAL_TXT, 141); // " and "
-			iw.components.emplace_back(ComponentType::SPELL, *it);
+				if(iw.components.size() >= GameConstants::INFO_WINDOW_ARTIFACTS_MAX_ITEMS)
+				{
+					gameHandler->sendAndApply(&iw);
+					iw.components.clear();
+				}
+			}
+			gameHandler->sendAndApply(&iw);
 		}
-		gameHandler->sendAndApply(&iw);
-		gameHandler->sendAndApply(&cs);
+		if(!packHero.artsPack0.empty())
+			sendArtifacts(packHero);
 	}
-	cab1.updateArmy(gameHandler);
-	cab2.updateArmy(gameHandler); //take casualties after battle is deleted
 
-	if(finishingBattle->loserHero) //remove beaten hero
+	// Remove beaten hero
+	if(finishingBattle->loserHero)
 	{
 		RemoveObject ro(finishingBattle->loserHero->id, finishingBattle->victor);
 		gameHandler->sendAndApply(&ro);
 	}
-	if(finishingBattle->isDraw() && finishingBattle->winnerHero) //for draw case both heroes should be removed
+	// For draw case both heroes should be removed
+	if(finishingBattle->isDraw() && finishingBattle->winnerHero)
 	{
 		RemoveObject ro(finishingBattle->winnerHero->id, finishingBattle->loser);
 		gameHandler->sendAndApply(&ro);
 	}
 
-	if(battleResult->winner == BattleSide::DEFENDER
-	   && finishingBattle->winnerHero
-	   && finishingBattle->winnerHero->visitedTown
-	   && !finishingBattle->winnerHero->inTownGarrison
-	   && finishingBattle->winnerHero->visitedTown->garrisonHero == finishingBattle->winnerHero)
-	{
-		gameHandler->swapGarrisonOnSiege(finishingBattle->winnerHero->visitedTown->id); //return defending visitor from garrison to its rightful place
-	}
-	//give exp
-	if(!finishingBattle->isDraw() && battleResult->exp[finishingBattle->winnerSide] && finishingBattle->winnerHero)
-		gameHandler->giveExperience(finishingBattle->winnerHero, battleResult->exp[finishingBattle->winnerSide]);
-
 	BattleResultAccepted raccepted;
 	raccepted.battleID = battle.getBattle()->getBattleID();
 	raccepted.heroResult[0].army = const_cast<CArmedInstance*>(battle.battleGetArmyObject(BattleSide::ATTACKER));
@@ -490,7 +499,7 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle)
 	raccepted.heroResult[1].hero = const_cast<CGHeroInstance*>(battle.battleGetFightingHero(BattleSide::DEFENDER));
 	raccepted.heroResult[0].exp = battleResult->exp[0];
 	raccepted.heroResult[1].exp = battleResult->exp[1];
-	raccepted.winnerSide = finishingBattle->winnerSide; 
+	raccepted.winnerSide = finishingBattle->winnerSide;
 	gameHandler->sendAndApply(&raccepted);
 
 	gameHandler->queries->popIfTop(battleQuery);