diff --git a/CCallback.cpp b/CCallback.cpp index 5d5e00073..4768aaae8 100644 --- a/CCallback.cpp +++ b/CCallback.cpp @@ -168,14 +168,10 @@ bool CCallback::swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation * @param assembleTo If assemble is true, this represents the artifact ID of the combination * artifact to assemble to. Otherwise it's not used. */ -bool CCallback::assembleArtifacts (const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo) +void CCallback::assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo) { - if (player != hero->tempOwner) - return false; - AssembleArtifacts aa(hero->id, artifactSlot, assemble, assembleTo); sendRequest(&aa); - return true; } void CCallback::bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap) diff --git a/CCallback.h b/CCallback.h index 3657e3581..8fb7970f9 100644 --- a/CCallback.h +++ b/CCallback.h @@ -89,7 +89,7 @@ public: virtual int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2, int val)=0;//split creatures from the first stack //virtual bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)=0; //swaps artifacts between two given heroes virtual bool swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2)=0; - virtual bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo)=0; + virtual void assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo)=0; virtual void eraseArtifactByClient(const ArtifactLocation & al)=0; virtual bool dismissCreature(const CArmedInstance *obj, SlotID stackPos)=0; virtual void endTurn()=0; @@ -170,7 +170,7 @@ public: int bulkMergeStacks(ObjectInstanceID armyId, SlotID srcSlot) override; bool dismissHero(const CGHeroInstance * hero) override; bool swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2) override; - bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo) override; + void assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo) override; void bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap) override; void eraseArtifactByClient(const ArtifactLocation & al) override; bool buildBuilding(const CGTownInstance *town, BuildingID buildingID) override; diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index e277b9b30..ab28d7b8b 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -1288,7 +1288,7 @@ void CPlayerInterface::showGarrisonDialog( const CArmedInstance *up, const CGHer * into a combinational one on an artifact screen. Does not require the combination of * artifacts to be legal. */ -void CPlayerInterface::showArtifactAssemblyDialog(const Artifact * artifact, const Artifact * assembledArtifact, CFunctionList onYes) +void CPlayerInterface::showArtifactAssemblyDialog(const Artifact * artifact, const Artifact * assembledArtifact, CFunctionList onYes) { std::string text = artifact->getDescriptionTranslated(); text += "\n\n"; diff --git a/client/CPlayerInterface.h b/client/CPlayerInterface.h index a5e408ce4..5d91ef9e4 100644 --- a/client/CPlayerInterface.h +++ b/client/CPlayerInterface.h @@ -185,7 +185,7 @@ public: // public interface for use by client via LOCPLINT access void showShipyardDialog(const IShipyard *obj) override; //obj may be town or shipyard; void showHeroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2); - void showArtifactAssemblyDialog(const Artifact * artifact, const Artifact * assembledArtifact, CFunctionList onYes); + void showArtifactAssemblyDialog(const Artifact * artifact, const Artifact * assembledArtifact, CFunctionList onYes); void waitWhileDialog(bool unlockPim = true); void waitForAllDialogs(bool unlockPim = true); void openTownWindow(const CGTownInstance * town); //shows townscreen diff --git a/client/widgets/CArtifactHolder.cpp b/client/widgets/CArtifactHolder.cpp index d27a2975f..b53237c9a 100644 --- a/client/widgets/CArtifactHolder.cpp +++ b/client/widgets/CArtifactHolder.cpp @@ -260,17 +260,28 @@ bool ArtifactUtilsClient::askToAssemble(const CGHeroInstance * hero, const Artif assert(hero); const auto art = hero->getArt(slot); assert(art); + + if(hero->tempOwner != LOCPLINT->playerID) + return false; + auto assemblyPossibilities = ArtifactUtils::assemblyPossibilities(hero, art->getTypeId(), ArtifactUtils::isSlotEquipment(slot)); - - for(const auto combinedArt : assemblyPossibilities) + if(!assemblyPossibilities.empty()) { - LOCPLINT->showArtifactAssemblyDialog( - art->artType, - combinedArt, - std::bind(&CCallback::assembleArtifacts, LOCPLINT->cb.get(), hero, slot, true, combinedArt->getId())); + auto askThread = new boost::thread([hero, art, slot, assemblyPossibilities]() -> void + { + for(const auto combinedArt : assemblyPossibilities) + { + bool assembleConfirmed = false; + CFunctionList onYesHandlers([&assembleConfirmed]() -> void {assembleConfirmed = true; }); + onYesHandlers += std::bind(&CCallback::assembleArtifacts, LOCPLINT->cb.get(), hero, slot, true, combinedArt->getId()); - if(assemblyPossibilities.size() > 2) - logGlobal->warn("More than one possibility of assembling on %s... taking only first", art->artType->getNameTranslated()); + LOCPLINT->showArtifactAssemblyDialog(art->artType, combinedArt, onYesHandlers); + LOCPLINT->waitWhileDialog(false); + if(assembleConfirmed) + break; + } + }); + askThread->detach(); return true; } return false; @@ -282,6 +293,9 @@ bool ArtifactUtilsClient::askToDisassemble(const CGHeroInstance * hero, const Ar const auto art = hero->getArt(slot); assert(art); + if(hero->tempOwner != LOCPLINT->playerID) + return false; + if(art->isCombined()) { if(ArtifactUtils::isSlotBackpack(slot) && !ArtifactUtils::isBackpackFreeSlots(hero, art->artType->getConstituents().size() - 1))