Browse Source

ArtInfoWindow on client. Client side

SoundSSGood 8 months ago
parent
commit
f0a9c95075

+ 17 - 2
client/ArtifactsUIController.cpp

@@ -60,10 +60,9 @@ bool ArtifactsUIController::askToAssemble(const CGHeroInstance * hero, const Art
 	{
 		auto askThread = new std::thread([this, hero, art, slot, assemblyPossibilities, checkIgnored]() -> void
 			{
-				std::scoped_lock askLock(askAssembleArtifactMutex);
+				std::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 				for(const auto combinedArt : assemblyPossibilities)
 				{
-					std::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 					if(checkIgnored)
 					{
 						if(vstd::contains(ignoredArtifacts, combinedArt->getId()))
@@ -168,3 +167,19 @@ void ArtifactsUIController::artifactDisassembled()
 	for(const auto & artWin : ENGINE->windows().findWindows<CWindowWithArtifacts>())
 		artWin->update();
 }
+
+std::vector<Component> ArtifactsUIController::getMovedComponents(const CArtifactSet & artSet, const std::vector<MoveArtifactInfo> & movedPack) const
+{
+	std::vector<Component> components;
+	for(const auto & artMoveInfo : movedPack)
+	{
+		const auto art = artSet.getArt(artMoveInfo.dstPos);
+		assert(art);
+
+		if(art->isScroll())
+			components.emplace_back(ComponentType::SPELL_SCROLL, art->getScrollSpellID());
+		else
+			components.emplace_back(ComponentType::ARTIFACT, art->getTypeId());
+	}
+	return components;
+}

+ 3 - 3
client/ArtifactsUIController.h

@@ -14,7 +14,9 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
+class CArtifactSet;
 class CGHeroInstance;
+struct Component;
 
 VCMI_LIB_NAMESPACE_END
 
@@ -24,8 +26,6 @@ class ArtifactsUIController
 	size_t numOfArtsAskAssembleSession;
 	std::set<ArtifactID> ignoredArtifacts;
 
-	std::mutex askAssembleArtifactMutex;
-
 public:
 	ArtifactsUIController();
 	bool askToAssemble(const ArtifactLocation & al, const bool onlyEquipped = false, const bool checkIgnored = false);
@@ -38,5 +38,5 @@ public:
 	void bulkArtMovementStart(size_t totalNumOfArts, size_t possibleAssemblyNumOfArts);
 	void artifactAssembled();
 	void artifactDisassembled();
+	std::vector<Component> getMovedComponents(const CArtifactSet & artSet, const std::vector<MoveArtifactInfo> & movedPack) const;
 };
- 

+ 1 - 0
client/CPlayerInterface.cpp

@@ -1072,6 +1072,7 @@ void CPlayerInterface::showInfoDialogAndWait(std::vector<Component> & components
 
 void CPlayerInterface::showYesNoDialog(const std::string &text, CFunctionList<void()> onYes, CFunctionList<void()> onNo, const std::vector<std::shared_ptr<CComponent>> & components)
 {
+	waitWhileDialog();
 	movementController->requestMovementAbort();
 	GAME->interface()->showingDialog->setBusy();
 	CInfoWindow::showYesNoDialog(text, components, onYes, onNo, playerID);

+ 17 - 1
client/NetPacksClient.cpp

@@ -291,7 +291,7 @@ void ApplyClientNetPackVisitor::visitEraseArtifact(BulkEraseArtifacts & pack)
 void ApplyClientNetPackVisitor::visitBulkMoveArtifacts(BulkMoveArtifacts & pack)
 {
 	const auto dstOwner = cl.getOwner(pack.dstArtHolder);
-	const auto applyMove = [this, &pack, dstOwner](std::vector<BulkMoveArtifacts::LinkedSlots> & artsPack)
+	const auto applyMove = [this, &pack, dstOwner](const std::vector<MoveArtifactInfo> & artsPack)
 	{
 		for(const auto & slotToMove : artsPack)
 		{
@@ -851,6 +851,22 @@ void ApplyClientNetPackVisitor::visitStacksInjured(StacksInjured & pack)
 
 void ApplyClientNetPackVisitor::visitBattleResultsApplied(BattleResultsApplied & pack)
 {
+	InfoWindow win;
+	win.player = pack.victor;
+	win.text.appendLocalString(EMetaText::GENERAL_TXT, 30);
+	const auto artSet = GAME->interface()->cb->getArtSet(ArtifactLocation(pack.artifacts.front().dstArtHolder));
+	assert(artSet);
+	for(const auto & artPack : pack.artifacts)
+	{
+		auto packComponents = GAME->interface()->artifactController->getMovedComponents(*artSet, artPack.artsPack0);
+		win.components.insert(win.components.end(), std::make_move_iterator(packComponents.begin()), std::make_move_iterator(packComponents.end()));
+	}
+	if(!win.components.empty())
+		visitInfoWindow(win);
+
+	for(auto & artPack : pack.artifacts)
+		visitBulkMoveArtifacts(artPack);
+
 	callInterfaceIfPresent(cl, pack.victor, &IGameEventsReceiver::battleResultsApplied);
 	callInterfaceIfPresent(cl, pack.loser, &IGameEventsReceiver::battleResultsApplied);
 	callInterfaceIfPresent(cl, PlayerColor::SPECTATOR, &IGameEventsReceiver::battleResultsApplied);

+ 28 - 0
lib/networkPacks/ArtifactLocation.h

@@ -10,6 +10,7 @@
 #pragma once
 
 #include "../constants/EntityIdentifiers.h"
+#include <optional>
 
 VCMI_LIB_NAMESPACE_BEGIN
 
@@ -52,4 +53,31 @@ struct ArtifactLocation
 	}
 };
 
+struct MoveArtifactInfo
+{
+	ArtifactPosition srcPos;
+	ArtifactPosition dstPos;
+	bool askAssemble;
+
+	MoveArtifactInfo()
+		: srcPos(ArtifactPosition::PRE_FIRST)
+		, dstPos(ArtifactPosition::PRE_FIRST)
+		, askAssemble(false)
+	{
+	}
+	MoveArtifactInfo(const ArtifactPosition & srcPos, const ArtifactPosition & dstPos, bool askAssemble = false)
+		: srcPos(srcPos)
+		, dstPos(dstPos)
+		, askAssemble(askAssemble)
+	{
+	}
+
+	template <typename Handler> void serialize(Handler & h)
+	{
+		h & srcPos;
+		h & dstPos;
+		h & askAssemble;
+	}
+};
+
 VCMI_LIB_NAMESPACE_END

+ 2 - 2
lib/networkPacks/NetPacksLib.cpp

@@ -1766,7 +1766,7 @@ void BulkEraseArtifacts::applyGs(CGameState *gs)
 
 void BulkMoveArtifacts::applyGs(CGameState *gs)
 {
-	const auto bulkArtsRemove = [gs](std::vector<LinkedSlots> & artsPack, CArtifactSet & artSet)
+	const auto bulkArtsRemove = [gs](std::vector<MoveArtifactInfo> & artsPack, CArtifactSet & artSet)
 	{
 		std::vector<ArtifactPosition> packToRemove;
 		for(const auto & slotsPair : artsPack)
@@ -1780,7 +1780,7 @@ void BulkMoveArtifacts::applyGs(CGameState *gs)
 			gs->getMap().removeArtifactInstance(artSet, slot);
 	};
 
-	const auto bulkArtsPut = [gs](std::vector<LinkedSlots> & artsPack, CArtifactSet & initArtSet, CArtifactSet & dstArtSet)
+	const auto bulkArtsPut = [gs](std::vector<MoveArtifactInfo> & artsPack, CArtifactSet & initArtSet, CArtifactSet & dstArtSet)
 	{
 		for(const auto & slotsPair : artsPack)
 		{

+ 2 - 23
lib/networkPacks/PacksForClient.h

@@ -1049,27 +1049,6 @@ struct DLL_LINKAGE BulkEraseArtifacts : CArtifactOperationPack
 
 struct DLL_LINKAGE BulkMoveArtifacts : CArtifactOperationPack
 {
-	struct LinkedSlots
-	{
-		ArtifactPosition srcPos;
-		ArtifactPosition dstPos;
-		bool askAssemble;
-
-		LinkedSlots() = default;
-		LinkedSlots(const ArtifactPosition & srcPos, const ArtifactPosition & dstPos, bool askAssemble = false)
-			: srcPos(srcPos)
-			, dstPos(dstPos)
-			, askAssemble(askAssemble)
-		{
-		}
-		template <typename Handler> void serialize(Handler & h)
-		{
-			h & srcPos;
-			h & dstPos;
-			h & askAssemble;
-		}
-	};
-
 	PlayerColor interfaceOwner;
 	ObjectInstanceID srcArtHolder;
 	ObjectInstanceID dstArtHolder;
@@ -1095,8 +1074,8 @@ struct DLL_LINKAGE BulkMoveArtifacts : CArtifactOperationPack
 
 	void applyGs(CGameState * gs) override;
 
-	std::vector<LinkedSlots> artsPack0;
-	std::vector<LinkedSlots> artsPack1;
+	std::vector<MoveArtifactInfo> artsPack0;
+	std::vector<MoveArtifactInfo> artsPack1;
 
 	void visitTyped(ICPackVisitor & visitor) override;
 

+ 10 - 14
server/CGameHandler.cpp

@@ -2643,14 +2643,14 @@ bool CGameHandler::moveArtifact(const PlayerColor & player, const ArtifactLocati
 	{
 		// Previous artifact must be swapped
 		COMPLAIN_RET_FALSE_IF(!dstArtifact->canBePutAt(srcArtSet, src.slot, true), "Cannot swap artifacts!");
-		ma.artsPack1.push_back(BulkMoveArtifacts::LinkedSlots(dstSlot, src.slot));
+		ma.artsPack1.emplace_back(dstSlot, src.slot);
 	}
 
 	auto hero = getHero(dst.artHolder);
 	if(ArtifactUtils::checkSpellbookIsNeeded(hero, srcArtifact->getTypeId(), dstSlot))
 		giveHeroNewArtifact(hero, ArtifactID::SPELLBOOK, ArtifactPosition::SPELLBOOK);
 
-	ma.artsPack0.push_back(BulkMoveArtifacts::LinkedSlots(src.slot, dstSlot));
+	ma.artsPack0.emplace_back(src.slot, dstSlot);
 	if(src.artHolder != dst.artHolder && !isDstSlotBackpack)
 		ma.artsPack0.back().askAssemble = true;
 	sendAndApply(ma);
@@ -2676,14 +2676,14 @@ bool CGameHandler::bulkMoveArtifacts(const PlayerColor & player, ObjectInstanceI
 	CArtifactFittingSet artFittingSet(pdstSet->bearerType());
 
 	auto moveArtifact = [this, &artFittingSet, dstId](const CArtifactInstance * artifact,
-		ArtifactPosition srcSlot, std::vector<BulkMoveArtifacts::LinkedSlots> & slots) -> void
+		ArtifactPosition srcSlot, std::vector<MoveArtifactInfo> & slots) -> void
 	{
 		assert(artifact);
 		auto dstSlot = ArtifactUtils::getArtAnyPosition(&artFittingSet, artifact->getTypeId());
 		if(dstSlot != ArtifactPosition::PRE_FIRST)
 		{
 			artFittingSet.putArtifact(dstSlot, static_cast<ConstTransitivePtr<CArtifactInstance>>(artifact));
-			slots.push_back(BulkMoveArtifacts::LinkedSlots(srcSlot, dstSlot));
+			slots.emplace_back(srcSlot, dstSlot);
 
 			// TODO Shouldn't be here. Possibly in callback after equipping the artifact
 			if(auto dstHero = getHero(dstId))
@@ -2696,7 +2696,7 @@ bool CGameHandler::bulkMoveArtifacts(const PlayerColor & player, ObjectInstanceI
 
 	if(swap)
 	{
-		auto moveArtsWorn = [moveArtifact](const CArtifactSet * srcArtSet, std::vector<BulkMoveArtifacts::LinkedSlots> & slots)
+		auto moveArtsWorn = [moveArtifact](const CArtifactSet * srcArtSet, std::vector<MoveArtifactInfo> & slots)
 		{
 			for(auto & artifact : srcArtSet->artifactsWorn)
 			{
@@ -2705,12 +2705,12 @@ bool CGameHandler::bulkMoveArtifacts(const PlayerColor & player, ObjectInstanceI
 			}
 		};
 		auto moveArtsInBackpack = [](const CArtifactSet * artSet,
-			std::vector<BulkMoveArtifacts::LinkedSlots> & slots) -> void
+			std::vector<MoveArtifactInfo> & slots) -> void
 		{
 			for(auto & slotInfo : artSet->artifactsInBackpack)
 			{
 				auto slot = artSet->getArtPos(slotInfo.artifact);
-				slots.push_back(BulkMoveArtifacts::LinkedSlots(slot, slot));
+				slots.emplace_back(slot, slot);
 			}
 		};
 		if(equipped)
@@ -2766,7 +2766,7 @@ bool CGameHandler::manageBackpackArtifacts(const PlayerColor & player, const Obj
 	BulkMoveArtifacts bma(player, heroID, heroID, false);
 	const auto makeSortBackpackRequest = [artSet, &bma](const std::function<int32_t(const ArtSlotInfo&)> & getSortId)
 	{
-		std::map<int32_t, std::vector<BulkMoveArtifacts::LinkedSlots>> packsSorted;
+		std::map<int32_t, std::vector<MoveArtifactInfo>> packsSorted;
 		ArtifactPosition backpackSlot = ArtifactPosition::BACKPACK_START;
 		for(const auto & backpackSlotInfo : artSet->artifactsInBackpack)
 			packsSorted.try_emplace(getSortId(backpackSlotInfo)).first->second.emplace_back(backpackSlot++, ArtifactPosition::PRE_FIRST);
@@ -2888,11 +2888,7 @@ bool CGameHandler::switchArtifactsCostume(const PlayerColor & player, const Obje
 		{
 			if(const auto slot = artFittingSet.getArtPos(artPos.second, false, false); slot != ArtifactPosition::PRE_FIRST)
 			{
-				bma.artsPack0.emplace_back(BulkMoveArtifacts::LinkedSlots
-					{
-						artSet->getArtPos(artFittingSet.getArt(slot)),
-						artPos.first
-					});
+				bma.artsPack0.emplace_back(artSet->getArtPos(artFittingSet.getArt(slot)), artPos.first);
 				artFittingSet.removeArtifact(slot);
 				if(ArtifactUtils::isSlotBackpack(slot))
 					estimateBackpackSize--;
@@ -2903,7 +2899,7 @@ bool CGameHandler::switchArtifactsCostume(const PlayerColor & player, const Obje
 		for(const auto & slot : ArtifactUtils::commonWornSlots())
 			if(artFittingSet.getArt(slot))
 			{
-				bma.artsPack0.emplace_back(BulkMoveArtifacts::LinkedSlots{slot, ArtifactPosition::BACKPACK_START});
+				bma.artsPack0.emplace_back(slot, ArtifactPosition::BACKPACK_START);
 				estimateBackpackSize++;
 			}
 		

+ 1 - 1
server/battles/BattleResultProcessor.cpp

@@ -392,7 +392,7 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle)
 			const auto dstSlot = ArtifactUtils::getArtAnyPosition(&artFittingSet, art->getTypeId());
 			if(dstSlot != ArtifactPosition::PRE_FIRST)
 			{
-				pack.artsPack0.emplace_back(BulkMoveArtifacts::LinkedSlots(srcSlot, dstSlot));
+				pack.artsPack0.emplace_back(MoveArtifactInfo(srcSlot, dstSlot));
 				if(ArtifactUtils::isSlotEquipment(dstSlot))
 					pack.artsPack0.back().askAssemble = true;
 				artFittingSet.putArtifact(dstSlot, const_cast<CArtifactInstance*>(art));

+ 1 - 1
server/battles/BattleResultProcessor.h

@@ -47,7 +47,7 @@ struct FinishingBattleHelper
 
 	inline bool isDraw() const {return winnerSide == BattleSide::NONE;}
 
-	ObjectInstanceID winnerId, loserId;
+	ObjectInstanceID winnerId = ObjectInstanceID::NONE, loserId = ObjectInstanceID::NONE;
 	PlayerColor victor, loser;
 	BattleSide winnerSide;
 	std::vector<BulkMoveArtifacts> artifacts;

+ 1 - 1
test/mock/mock_IGameCallback.h

@@ -68,7 +68,7 @@ public:
 	void tryJoiningArmy(const CArmedInstance *src, const CArmedInstance *dst, bool removeObjWhenFinished, bool allowMerging) override {} //merges army from src do dst or opens a garrison window
 	bool moveStack(const StackLocation &src, const StackLocation &dst, TQuantity count) override {return false;}
 
-	void removeAfterVisit(const CGObjectInstance *object) override {} //object will be destroyed when interaction is over. Do not call when interaction is not ongoing!
+	void removeAfterVisit(const ObjectInstanceID & id) override {} //object will be destroyed when interaction is over. Do not call when interaction is not ongoing!
 
 	bool giveHeroNewArtifact(const CGHeroInstance * h, const ArtifactID & artId, const ArtifactPosition & pos) override {return false;}
 	bool giveHeroNewScroll(const CGHeroInstance * h, const SpellID & spellId, const ArtifactPosition & pos) override {return false;}