diff --git a/client/ArtifactsUIController.cpp b/client/ArtifactsUIController.cpp index 064b22244..7f018c208 100644 --- a/client/ArtifactsUIController.cpp +++ b/client/ArtifactsUIController.cpp @@ -26,6 +26,7 @@ ArtifactsUIController::ArtifactsUIController() { numOfMovedArts = 0; + numOfArtsAskAssembleSession = 0; } bool ArtifactsUIController::askToAssemble(const ArtifactLocation & al, const bool onlyEquipped, const bool checkIgnored) diff --git a/client/widgets/CArtifactsOfHeroBase.cpp b/client/widgets/CArtifactsOfHeroBase.cpp index 22666df42..7113f114b 100644 --- a/client/widgets/CArtifactsOfHeroBase.cpp +++ b/client/widgets/CArtifactsOfHeroBase.cpp @@ -103,38 +103,38 @@ void CArtifactsOfHeroBase::setShowPopupArtPlacesCallback(const CArtPlace::ClickF void CArtifactsOfHeroBase::clickPressedArtPlace(CComponentHolder & artPlace, const Point & cursorPosition) { - auto ownedPlace = getArtPlace(cursorPosition); - assert(ownedPlace != nullptr); + if(auto ownedPlace = getArtPlace(cursorPosition)) + { + if(ownedPlace->isLocked()) + return; - if(ownedPlace->isLocked()) - return; - - if(clickPressedCallback) - clickPressedCallback(*ownedPlace, cursorPosition); + if(clickPressedCallback) + clickPressedCallback(*ownedPlace, cursorPosition); + } } void CArtifactsOfHeroBase::showPopupArtPlace(CComponentHolder & artPlace, const Point & cursorPosition) { - auto ownedPlace = getArtPlace(cursorPosition); - assert(ownedPlace != nullptr); + if(auto ownedPlace = getArtPlace(cursorPosition)) + { + if(ownedPlace->isLocked()) + return; - if(ownedPlace->isLocked()) - return; - - if(showPopupCallback) - showPopupCallback(*ownedPlace, cursorPosition); + if(showPopupCallback) + showPopupCallback(*ownedPlace, cursorPosition); + } } void CArtifactsOfHeroBase::gestureArtPlace(CComponentHolder & artPlace, const Point & cursorPosition) { - auto ownedPlace = getArtPlace(cursorPosition); - assert(ownedPlace != nullptr); + if(auto ownedPlace = getArtPlace(cursorPosition)) + { + if(ownedPlace->isLocked()) + return; - if(ownedPlace->isLocked()) - return; - - if(gestureCallback) - gestureCallback(*ownedPlace, cursorPosition); + if(gestureCallback) + gestureCallback(*ownedPlace, cursorPosition); + } } void CArtifactsOfHeroBase::setHero(const CGHeroInstance * hero) diff --git a/client/widgets/CArtifactsOfHeroMarket.cpp b/client/widgets/CArtifactsOfHeroMarket.cpp index 0e94fd34c..fac271b46 100644 --- a/client/widgets/CArtifactsOfHeroMarket.cpp +++ b/client/widgets/CArtifactsOfHeroMarket.cpp @@ -24,24 +24,24 @@ CArtifactsOfHeroMarket::CArtifactsOfHeroMarket(const Point & position, const int void CArtifactsOfHeroMarket::clickPressedArtPlace(CComponentHolder & artPlace, const Point & cursorPosition) { - auto ownedPlace = getArtPlace(cursorPosition); - assert(ownedPlace != nullptr); - - if(ownedPlace->isLocked()) - return; - - if(const auto art = getArt(ownedPlace->slot)) + if(auto ownedPlace = getArtPlace(cursorPosition)) { - if(onSelectArtCallback && art->getType()->isTradable()) + if(ownedPlace->isLocked()) + return; + + if(const auto art = getArt(ownedPlace->slot)) { - unmarkSlots(); - artPlace.selectSlot(true); - onSelectArtCallback(ownedPlace.get()); - } - else - { - if(onClickNotTradableCallback) - onClickNotTradableCallback(); + if(onSelectArtCallback && art->getType()->isTradable()) + { + unmarkSlots(); + artPlace.selectSlot(true); + onSelectArtCallback(ownedPlace.get()); + } + else + { + if(onClickNotTradableCallback) + onClickNotTradableCallback(); + } } } } diff --git a/lib/ArtifactUtils.cpp b/lib/ArtifactUtils.cpp index bfdb48468..3f6964c2d 100644 --- a/lib/ArtifactUtils.cpp +++ b/lib/ArtifactUtils.cpp @@ -236,7 +236,7 @@ DLL_LINKAGE CArtifactInstance * ArtifactUtils::createArtifact(const ArtifactID & assert(art); auto * artInst = new CArtifactInstance(art); - if(art->isCombined()) + if(art->isCombined() && !art->isFused()) { for(const auto & part : art->getConstituents()) artInst->addPart(createArtInst(part), ArtifactPosition::PRE_FIRST); diff --git a/lib/CArtHandler.cpp b/lib/CArtHandler.cpp index c566e8420..0232109c5 100644 --- a/lib/CArtHandler.cpp +++ b/lib/CArtHandler.cpp @@ -192,7 +192,6 @@ bool CArtifact::isTradable() const switch(id.toEnum()) { case ArtifactID::SPELLBOOK: - case ArtifactID::GRAIL: return false; default: return !isBig(); diff --git a/lib/networkPacks/NetPacksLib.cpp b/lib/networkPacks/NetPacksLib.cpp index 5317855ed..30e88a3f5 100644 --- a/lib/networkPacks/NetPacksLib.cpp +++ b/lib/networkPacks/NetPacksLib.cpp @@ -1802,61 +1802,59 @@ void BulkMoveArtifacts::applyGs(CGameState *gs) void AssembledArtifact::applyGs(CGameState *gs) { - auto hero = gs->getHero(al.artHolder); - assert(hero); - const auto transformedArt = hero->getArt(al.slot); + auto artSet = gs->getArtSet(al.artHolder); + assert(artSet); + const auto transformedArt = artSet->getArt(al.slot); assert(transformedArt); const auto builtArt = artId.toArtifact(); - assert(vstd::contains_if(ArtifactUtils::assemblyPossibilities(hero, transformedArt->getTypeId()), [=](const CArtifact * art)->bool + assert(vstd::contains_if(ArtifactUtils::assemblyPossibilities(artSet, transformedArt->getTypeId()), [=](const CArtifact * art)->bool { return art->getId() == builtArt->getId(); })); - const auto transformedArtSlot = hero->getArtPos(transformedArt); auto * combinedArt = new CArtifactInstance(builtArt); gs->map->addNewArtifactInstance(combinedArt); // Find slots for all involved artifacts - std::vector slotsInvolved; - CArtifactFittingSet artSet(*hero); - for(const auto constituent : builtArt->getConstituents()) + std::set> slotsInvolved = { al.slot }; + CArtifactFittingSet fittingSet(*artSet); + auto parts = builtArt->getConstituents(); + parts.erase(std::find(parts.begin(), parts.end(), transformedArt->getType())); + for(const auto constituent : parts) { - const auto slot = artSet.getArtPos(constituent->getId(), false, false); - artSet.lockSlot(slot); + const auto slot = fittingSet.getArtPos(constituent->getId(), false, false); + fittingSet.lockSlot(slot); assert(slot != ArtifactPosition::PRE_FIRST); - slotsInvolved.emplace_back(slot); + slotsInvolved.insert(slot); } - std::sort(slotsInvolved.begin(), slotsInvolved.end(), std::greater<>()); // Find a slot for combined artifact - al.slot = transformedArtSlot; - for(const auto & slot : slotsInvolved) + if(ArtifactUtils::isSlotEquipment(al.slot) && ArtifactUtils::isSlotBackpack(*slotsInvolved.begin())) { - if(ArtifactUtils::isSlotEquipment(transformedArtSlot)) - { - + al.slot = ArtifactPosition::BACKPACK_START; + } + else if(ArtifactUtils::isSlotBackpack(al.slot)) + { + for(const auto & slot : slotsInvolved) if(ArtifactUtils::isSlotBackpack(slot)) + al.slot = slot; + } + else + { + for(const auto & slot : slotsInvolved) + if(!vstd::contains(builtArt->getPossibleSlots().at(artSet->bearerType()), al.slot) + && vstd::contains(builtArt->getPossibleSlots().at(artSet->bearerType()), slot)) { - al.slot = ArtifactPosition::BACKPACK_START; + al.slot = slot; break; } - - if(!vstd::contains(combinedArt->getType()->getPossibleSlots().at(hero->bearerType()), al.slot) - && vstd::contains(combinedArt->getType()->getPossibleSlots().at(hero->bearerType()), slot)) - al.slot = slot; - } - else - { - if(ArtifactUtils::isSlotBackpack(slot)) - al.slot = std::min(al.slot, slot); - } } // Delete parts from hero for(const auto & slot : slotsInvolved) { - const auto constituentInstance = hero->getArt(slot); - gs->map->removeArtifactInstance(*hero, slot); + const auto constituentInstance = artSet->getArt(slot); + gs->map->removeArtifactInstance(*artSet, slot); if(!combinedArt->getType()->isFused()) { @@ -1868,7 +1866,7 @@ void AssembledArtifact::applyGs(CGameState *gs) } // Put new combined artifacts - gs->map->putArtifactInstance(*hero, combinedArt, al.slot); + gs->map->putArtifactInstance(*artSet, combinedArt, al.slot); } void DisassembledArtifact::applyGs(CGameState *gs) diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index d7bacfc10..cf68a18ea 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -2629,7 +2629,7 @@ bool CGameHandler::moveArtifact(const PlayerColor & player, const ArtifactLocati giveHeroNewArtifact(hero, ArtifactID::SPELLBOOK, ArtifactPosition::SPELLBOOK); ma.artsPack0.push_back(BulkMoveArtifacts::LinkedSlots(src.slot, dstSlot)); - if(src.artHolder != dst.artHolder) + if(src.artHolder != dst.artHolder && !isDstSlotBackpack) ma.artsPack0.back().askAssemble = true; sendAndApply(ma); return true;