Browse Source

Merge pull request #4892 from SoundSSGood/artifact-related-fixes

Artifact related fixes
Ivan Savenko 11 months ago
parent
commit
7be44278d7

+ 1 - 0
client/ArtifactsUIController.cpp

@@ -26,6 +26,7 @@
 ArtifactsUIController::ArtifactsUIController()
 ArtifactsUIController::ArtifactsUIController()
 {
 {
 	numOfMovedArts = 0;
 	numOfMovedArts = 0;
+	numOfArtsAskAssembleSession = 0;
 }
 }
 
 
 bool ArtifactsUIController::askToAssemble(const ArtifactLocation & al, const bool onlyEquipped, const bool checkIgnored)
 bool ArtifactsUIController::askToAssemble(const ArtifactLocation & al, const bool onlyEquipped, const bool checkIgnored)

+ 21 - 21
client/widgets/CArtifactsOfHeroBase.cpp

@@ -103,38 +103,38 @@ void CArtifactsOfHeroBase::setShowPopupArtPlacesCallback(const CArtPlace::ClickF
 
 
 void CArtifactsOfHeroBase::clickPressedArtPlace(CComponentHolder & artPlace, const Point & cursorPosition)
 void CArtifactsOfHeroBase::clickPressedArtPlace(CComponentHolder & artPlace, const Point & cursorPosition)
 {
 {
-	auto ownedPlace = getArtPlace(cursorPosition);
-	assert(ownedPlace != nullptr);
-
-	if(ownedPlace->isLocked())
-		return;
+	if(auto ownedPlace = getArtPlace(cursorPosition))
+	{
+		if(ownedPlace->isLocked())
+			return;
 
 
-	if(clickPressedCallback)
-		clickPressedCallback(*ownedPlace, cursorPosition);
+		if(clickPressedCallback)
+			clickPressedCallback(*ownedPlace, cursorPosition);
+	}
 }
 }
 
 
 void CArtifactsOfHeroBase::showPopupArtPlace(CComponentHolder & artPlace, const Point & cursorPosition)
 void CArtifactsOfHeroBase::showPopupArtPlace(CComponentHolder & artPlace, const Point & cursorPosition)
 {
 {
-	auto ownedPlace = getArtPlace(cursorPosition);
-	assert(ownedPlace != nullptr);
-
-	if(ownedPlace->isLocked())
-		return;
+	if(auto ownedPlace = getArtPlace(cursorPosition))
+	{
+		if(ownedPlace->isLocked())
+			return;
 
 
-	if(showPopupCallback)
-		showPopupCallback(*ownedPlace, cursorPosition);
+		if(showPopupCallback)
+			showPopupCallback(*ownedPlace, cursorPosition);
+	}
 }
 }
 
 
 void CArtifactsOfHeroBase::gestureArtPlace(CComponentHolder & artPlace, const Point & cursorPosition)
 void CArtifactsOfHeroBase::gestureArtPlace(CComponentHolder & artPlace, const Point & cursorPosition)
 {
 {
-	auto ownedPlace = getArtPlace(cursorPosition);
-	assert(ownedPlace != nullptr);
-
-	if(ownedPlace->isLocked())
-		return;
+	if(auto ownedPlace = getArtPlace(cursorPosition))
+	{
+		if(ownedPlace->isLocked())
+			return;
 
 
-	if(gestureCallback)
-		gestureCallback(*ownedPlace, cursorPosition);
+		if(gestureCallback)
+			gestureCallback(*ownedPlace, cursorPosition);
+	}
 }
 }
 
 
 void CArtifactsOfHeroBase::setHero(const CGHeroInstance * hero)
 void CArtifactsOfHeroBase::setHero(const CGHeroInstance * hero)

+ 16 - 16
client/widgets/CArtifactsOfHeroMarket.cpp

@@ -24,24 +24,24 @@ CArtifactsOfHeroMarket::CArtifactsOfHeroMarket(const Point & position, const int
 
 
 void CArtifactsOfHeroMarket::clickPressedArtPlace(CComponentHolder & artPlace, const Point & cursorPosition)
 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())
-		{
-			unmarkSlots();
-			artPlace.selectSlot(true);
-			onSelectArtCallback(ownedPlace.get());
-		}
-		else
+		if(ownedPlace->isLocked())
+			return;
+
+		if(const auto art = getArt(ownedPlace->slot))
 		{
 		{
-			if(onClickNotTradableCallback)
-				onClickNotTradableCallback();
+			if(onSelectArtCallback && art->getType()->isTradable())
+			{
+				unmarkSlots();
+				artPlace.selectSlot(true);
+				onSelectArtCallback(ownedPlace.get());
+			}
+			else
+			{
+				if(onClickNotTradableCallback)
+					onClickNotTradableCallback();
+			}
 		}
 		}
 	}
 	}
 }
 }

+ 1 - 1
lib/ArtifactUtils.cpp

@@ -236,7 +236,7 @@ DLL_LINKAGE CArtifactInstance * ArtifactUtils::createArtifact(const ArtifactID &
 		assert(art);
 		assert(art);
 
 
 		auto * artInst = new CArtifactInstance(art);
 		auto * artInst = new CArtifactInstance(art);
-		if(art->isCombined())
+		if(art->isCombined() && !art->isFused())
 		{
 		{
 			for(const auto & part : art->getConstituents())
 			for(const auto & part : art->getConstituents())
 				artInst->addPart(createArtInst(part), ArtifactPosition::PRE_FIRST);
 				artInst->addPart(createArtInst(part), ArtifactPosition::PRE_FIRST);

+ 0 - 1
lib/CArtHandler.cpp

@@ -192,7 +192,6 @@ bool CArtifact::isTradable() const
 	switch(id.toEnum())
 	switch(id.toEnum())
 	{
 	{
 	case ArtifactID::SPELLBOOK:
 	case ArtifactID::SPELLBOOK:
-	case ArtifactID::GRAIL:
 		return false;
 		return false;
 	default:
 	default:
 		return !isBig();
 		return !isBig();

+ 30 - 32
lib/networkPacks/NetPacksLib.cpp

@@ -1802,61 +1802,59 @@ void BulkMoveArtifacts::applyGs(CGameState *gs)
 
 
 void AssembledArtifact::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);
 	assert(transformedArt);
 	const auto builtArt = artId.toArtifact();
 	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();
 			return art->getId() == builtArt->getId();
 		}));
 		}));
 
 
-	const auto transformedArtSlot = hero->getArtPos(transformedArt);
 	auto * combinedArt = new CArtifactInstance(builtArt);
 	auto * combinedArt = new CArtifactInstance(builtArt);
 	gs->map->addNewArtifactInstance(combinedArt);
 	gs->map->addNewArtifactInstance(combinedArt);
 
 
 	// Find slots for all involved artifacts
 	// Find slots for all involved artifacts
-	std::vector<ArtifactPosition> slotsInvolved;
-	CArtifactFittingSet artSet(*hero);
-	for(const auto constituent : builtArt->getConstituents())
-	{
-		const auto slot = artSet.getArtPos(constituent->getId(), false, false);
-		artSet.lockSlot(slot);
+	std::set<ArtifactPosition, std::greater<>> 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 = fittingSet.getArtPos(constituent->getId(), false, false);
+		fittingSet.lockSlot(slot);
 		assert(slot != ArtifactPosition::PRE_FIRST);
 		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
 	// 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))
 			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;
 				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
 	// Delete parts from hero
 	for(const auto & slot : slotsInvolved)
 	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())
 		if(!combinedArt->getType()->isFused())
 		{
 		{
@@ -1868,7 +1866,7 @@ void AssembledArtifact::applyGs(CGameState *gs)
 	}
 	}
 
 
 	// Put new combined artifacts
 	// Put new combined artifacts
-	gs->map->putArtifactInstance(*hero, combinedArt, al.slot);
+	gs->map->putArtifactInstance(*artSet, combinedArt, al.slot);
 }
 }
 
 
 void DisassembledArtifact::applyGs(CGameState *gs)
 void DisassembledArtifact::applyGs(CGameState *gs)

+ 1 - 1
server/CGameHandler.cpp

@@ -2629,7 +2629,7 @@ bool CGameHandler::moveArtifact(const PlayerColor & player, const ArtifactLocati
 		giveHeroNewArtifact(hero, ArtifactID::SPELLBOOK, ArtifactPosition::SPELLBOOK);
 		giveHeroNewArtifact(hero, ArtifactID::SPELLBOOK, ArtifactPosition::SPELLBOOK);
 
 
 	ma.artsPack0.push_back(BulkMoveArtifacts::LinkedSlots(src.slot, dstSlot));
 	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;
 		ma.artsPack0.back().askAssemble = true;
 	sendAndApply(ma);
 	sendAndApply(ma);
 	return true;
 	return true;