Browse Source

End of battle BulkMoveArtifacts

SoundSSGood 1 year ago
parent
commit
5dbe88d9a4

+ 2 - 2
client/NetPacksClient.cpp

@@ -306,8 +306,8 @@ void ApplyClientNetPackVisitor::visitMoveArtifact(MoveArtifact & pack)
 	};
 	};
 
 
 	moveArtifact(pack.interfaceOwner);
 	moveArtifact(pack.interfaceOwner);
-	if(pack.interfaceOwner != cl.getOwner(pack.dst.artHolder))
-		moveArtifact(cl.getOwner(pack.dst.artHolder));
+	//if(pack.interfaceOwner != cl.getOwner(pack.dst.artHolder))
+	//	moveArtifact(cl.getOwner(pack.dst.artHolder));
 
 
 	cl.invalidatePaths(); // hero might have equipped/unequipped Angel Wings
 	cl.invalidatePaths(); // hero might have equipped/unequipped Angel Wings
 }
 }

+ 3 - 3
lib/CArtHandler.cpp

@@ -1079,8 +1079,8 @@ void CArtifactSet::serializeJsonSlot(JsonSerializeFormat & handler, const Artifa
 	}
 	}
 }
 }
 
 
-CArtifactFittingSet::CArtifactFittingSet(ArtBearer::ArtBearer Bearer):
-	Bearer(Bearer)
+CArtifactFittingSet::CArtifactFittingSet(ArtBearer::ArtBearer bearer)
+	: bearer(bearer)
 {
 {
 }
 }
 
 
@@ -1094,7 +1094,7 @@ CArtifactFittingSet::CArtifactFittingSet(const CArtifactSet & artSet)
 
 
 ArtBearer::ArtBearer CArtifactFittingSet::bearerType() const
 ArtBearer::ArtBearer CArtifactFittingSet::bearerType() const
 {
 {
-	return this->Bearer;
+	return this->bearer;
 }
 }
 
 
 VCMI_LIB_NAMESPACE_END
 VCMI_LIB_NAMESPACE_END

+ 1 - 1
lib/CArtHandler.h

@@ -255,7 +255,7 @@ public:
 	ArtBearer::ArtBearer bearerType() const override;
 	ArtBearer::ArtBearer bearerType() const override;
 
 
 protected:
 protected:
-	ArtBearer::ArtBearer Bearer;
+	ArtBearer::ArtBearer bearer;
 };
 };
 
 
 VCMI_LIB_NAMESPACE_END
 VCMI_LIB_NAMESPACE_END

+ 6 - 0
lib/networkPacks/ArtifactLocation.h

@@ -37,6 +37,12 @@ struct ArtifactLocation
 		, creature(creatureSlot)
 		, creature(creatureSlot)
 	{
 	{
 	}
 	}
+	ArtifactLocation(const ObjectInstanceID id, const std::optional<SlotID> creatureSlot, const ArtifactPosition & slot)
+		: artHolder(id)
+		, slot(slot)
+		, creature(creatureSlot)
+	{
+	}
 
 
 	template <typename Handler> void serialize(Handler & h)
 	template <typename Handler> void serialize(Handler & h)
 	{
 	{

+ 1 - 1
server/CGameHandler.cpp

@@ -2891,7 +2891,7 @@ bool CGameHandler::bulkMoveArtifacts(const PlayerColor & player, ObjectInstanceI
 
 
 bool CGameHandler::scrollBackpackArtifacts(const PlayerColor & player, const ObjectInstanceID heroID, bool left)
 bool CGameHandler::scrollBackpackArtifacts(const PlayerColor & player, const ObjectInstanceID heroID, bool left)
 {
 {
-	auto artSet = getArtSet(heroID);
+	const auto artSet = getArtSet(heroID);
 	COMPLAIN_RET_FALSE_IF(artSet == nullptr, "scrollBackpackArtifacts: wrong hero's ID");
 	COMPLAIN_RET_FALSE_IF(artSet == nullptr, "scrollBackpackArtifacts: wrong hero's ID");
 
 
 	BulkMoveArtifacts bma(player, heroID, heroID, false);
 	BulkMoveArtifacts bma(player, heroID, heroID, false);

+ 41 - 60
server/battles/BattleResultProcessor.cpp

@@ -342,80 +342,61 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle)
 
 
 	if(result == EBattleResult::NORMAL && !finishingBattle->isDraw() && finishingBattle->winnerHero)
 	if(result == EBattleResult::NORMAL && !finishingBattle->isDraw() && finishingBattle->winnerHero)
 	{
 	{
-		auto sendMoveArtifact = [&](const CArtifactInstance *art, MoveArtifact *ma)
+		BulkMoveArtifacts bma(finishingBattle->winnerHero->getOwner(), finishingBattle->loserHero->id, finishingBattle->winnerHero->id, false);
+		bma.askAssemble = true;
+		CArtifactFittingSet artFittingSet(*finishingBattle->winnerHero);
+
+		const auto addArtifactToTransfer = [&](const ArtifactPosition & srcSlot, const CArtifactInstance * art)
 		{
 		{
-			const auto slot = ArtifactUtils::getArtAnyPosition(finishingBattle->winnerHero, art->getTypeId());
-			if(slot != ArtifactPosition::PRE_FIRST)
+			const auto dstSlot = ArtifactUtils::getArtAnyPosition(&artFittingSet, art->getTypeId());
+			if(dstSlot != ArtifactPosition::PRE_FIRST)
 			{
 			{
-				arts.push_back(art);
-				ma->dst = ArtifactLocation(finishingBattle->winnerHero->id, slot);
-				if(ArtifactUtils::isSlotBackpack(slot))
-					ma->askAssemble = false;
-				gameHandler->sendAndApply(ma);
+				bma.artsPack0.emplace_back(BulkMoveArtifacts::LinkedSlots(srcSlot, dstSlot));
+				arts.emplace_back(art);
+				artFittingSet.putArtifact(dstSlot, const_cast<CArtifactInstance*>(art));
 			}
 			}
 		};
 		};
+		const auto sendArtifacts = [&bma, this]()
+		{
+			if(!bma.artsPack0.empty())
+				gameHandler->sendAndApply(&bma);
+		};
 
 
-		if (finishingBattle->loserHero)
+		if(finishingBattle->loserHero)
 		{
 		{
-			//TODO: wrap it into a function, somehow (std::variant -_-)
-			auto artifactsWorn = finishingBattle->loserHero->artifactsWorn;
-			for (auto artSlot : artifactsWorn)
+			for(const auto & artSlot : finishingBattle->loserHero->artifactsWorn)
 			{
 			{
-				MoveArtifact ma;
-				ma.src = ArtifactLocation(finishingBattle->loserHero->id, artSlot.first);
-				const CArtifactInstance * art = finishingBattle->loserHero->getArt(artSlot.first);
-				if (art && !art->artType->isBig() &&
-					art->artType->getId() != ArtifactID::SPELLBOOK)
-						// don't move war machines or locked arts (spellbook)
-				{
-					sendMoveArtifact(art, &ma);
-				}
+				if(ArtifactUtils::isArtRemovable(artSlot))
+					addArtifactToTransfer(artSlot.first, artSlot.second.getArt());
 			}
 			}
-			for(int slotNumber = finishingBattle->loserHero->artifactsInBackpack.size() - 1; slotNumber >= 0; slotNumber--)
+			for(const auto & artSlot : finishingBattle->loserHero->artifactsInBackpack)
 			{
 			{
-				//we assume that no big artifacts can be found
-				MoveArtifact ma;
-				ma.src = ArtifactLocation(finishingBattle->loserHero->id,
-					ArtifactPosition(ArtifactPosition::BACKPACK_START + slotNumber)); //backpack automatically shifts arts to beginning
-				const CArtifactInstance * art = finishingBattle->loserHero->getArt(ArtifactPosition::BACKPACK_START + slotNumber);
-				if (art->artType->getId() != ArtifactID::GRAIL) //grail may not be won
-				{
-					sendMoveArtifact(art, &ma);
-				}
+				const auto art = artSlot.getArt();
+				if(art->getTypeId() != ArtifactID::GRAIL)
+					addArtifactToTransfer(finishingBattle->loserHero->getArtPos(art), art);
 			}
 			}
-			if (finishingBattle->loserHero->commander) //TODO: what if commanders belong to no hero?
+			sendArtifacts();
+
+			bma.askAssemble = false;
+			bma.artsPack0.clear();
+			if(finishingBattle->loserHero->commander)
 			{
 			{
-				artifactsWorn = finishingBattle->loserHero->commander->artifactsWorn;
-				for (auto artSlot : artifactsWorn)
-				{
-					MoveArtifact ma;
-					ma.src = ArtifactLocation(finishingBattle->loserHero->id, artSlot.first);
-					ma.src.creature = finishingBattle->loserHero->findStack(finishingBattle->loserHero->commander);
-					const auto art = finishingBattle->loserHero->commander->getArt(artSlot.first);
-					if (art && !art->artType->isBig())
-					{
-						sendMoveArtifact(art, &ma);
-					}
-				}
+				bma.srcCreature = finishingBattle->loserHero->findStack(finishingBattle->loserHero->commander);
+				for(const auto & artSlot : finishingBattle->loserHero->commander->artifactsWorn)
+					addArtifactToTransfer(artSlot.first, artSlot.second.getArt());
+				sendArtifacts();
 			}
 			}
 		}
 		}
-
-		auto loser = battle.otherSide(battleResult->winner);
-
-		for (auto armySlot : battle.battleGetArmyObject(loser)->stacks)
+		auto armyObj = battle.battleGetArmyObject(battle.otherSide(battleResult->winner));
+		bma.srcArtHolder = armyObj->id;
+		for(const auto & armySlot : armyObj->stacks)
 		{
 		{
-			auto artifactsWorn = armySlot.second->artifactsWorn;
-			for(const auto & artSlot : artifactsWorn)
-			{
-				MoveArtifact ma;
-				ma.src = ArtifactLocation(finishingBattle->loserHero->id, artSlot.first);
-				ma.src.creature = finishingBattle->loserHero->findStack(finishingBattle->loserHero->commander);
-				const auto art = finishingBattle->loserHero->commander->getArt(artSlot.first);
-				if (art && !art->artType->isBig())
-				{
-					sendMoveArtifact(art, &ma);
-				}
-			}
+			bma.artsPack0.clear();
+			bma.interfaceOwner = finishingBattle->winnerHero->getOwner();
+			bma.srcCreature = armySlot.first;
+			for(const auto & artSlot : armySlot.second->artifactsWorn)
+				addArtifactToTransfer(artSlot.first, armySlot.second->getArt(artSlot.first));
+			sendArtifacts();
 		}
 		}
 	}
 	}