浏览代码

Merge pull request #4028 from SoundSSGood/artifacts-parts-calc

Parts calculation for combined artifacts
Ivan Savenko 1 年之前
父节点
当前提交
985adbe07b

+ 25 - 15
client/widgets/CArtPlace.cpp

@@ -140,11 +140,6 @@ void CCommanderArtPlace::showPopupWindow(const Point & cursorPosition)
 		CArtPlace::showPopupWindow(cursorPosition);
 }
 
-CHeroArtPlace::CHeroArtPlace(Point position, const CArtifactInstance * art)
-	: CArtPlace(position, art)
-{
-}
-
 void CArtPlace::lockSlot(bool on)
 {
 	if(locked == on)
@@ -219,20 +214,35 @@ void CArtPlace::setGestureCallback(const ClickFunctor & callback)
 	gestureCallback = callback;
 }
 
-void CHeroArtPlace::addCombinedArtInfo(const std::map<const CArtifact*, int> & arts)
+void CArtPlace::addCombinedArtInfo(const std::map<const ArtifactID, std::vector<ArtifactID>> & arts)
 {
-	for(const auto & combinedArt : arts)
+	for(const auto & availableArts : arts)
 	{
-		std::string artList;
-		text += "\n\n";
-		text += "{" + combinedArt.first->getNameTranslated() + "}";
-		if(arts.size() == 1)
+		const auto combinedArt = availableArts.first.toArtifact();
+		MetaString info;
+		info.appendEOL();
+		info.appendEOL();
+		info.appendRawString("{");
+		info.appendName(combinedArt->getId());
+		info.appendRawString("}");
+		info.appendRawString(" (%d/%d)");
+		info.replaceNumber(availableArts.second.size());
+		info.replaceNumber(combinedArt->getConstituents().size());
+		for(const auto part : combinedArt->getConstituents())
 		{
-			for(const auto part : combinedArt.first->getConstituents())
-				artList += "\n" + part->getNameTranslated();
+			info.appendEOL();
+			if(vstd::contains(availableArts.second, part->getId()))
+			{
+				info.appendName(part->getId());
+			}
+			else
+			{
+				info.appendRawString("{#A9A9A9|");
+				info.appendName(part->getId());
+				info.appendRawString("}");
+			}
 		}
-		text += " (" + boost::str(boost::format("%d") % combinedArt.second) + " / " +
-			boost::str(boost::format("%d") % combinedArt.first->getConstituents().size()) + ")" + artList;
+		text += info.toString();
 	}
 }
 

+ 1 - 7
client/widgets/CArtPlace.h

@@ -31,6 +31,7 @@ public:
 	void clickPressed(const Point & cursorPosition) override;
 	void showPopupWindow(const Point & cursorPosition) override;
 	void gesture(bool on, const Point & initialPosition, const Point & finalPosition) override;
+	void addCombinedArtInfo(const std::map<const ArtifactID, std::vector<ArtifactID>> & arts);
 
 private:
 	const CArtifactInstance * ourArt;
@@ -59,13 +60,6 @@ public:
 	void showPopupWindow(const Point & cursorPosition) override;
 };
 
-class CHeroArtPlace: public CArtPlace
-{
-public:
-	CHeroArtPlace(Point position, const CArtifactInstance * art = nullptr);
-	void addCombinedArtInfo(const std::map<const CArtifact*, int> & arts);
-};
-
 namespace ArtifactUtilsClient
 {
 	bool askToAssemble(const CGHeroInstance * hero, const ArtifactPosition & slot);

+ 1 - 1
client/widgets/CArtifactsOfHeroBackpack.cpp

@@ -82,7 +82,7 @@ void CArtifactsOfHeroBackpack::initAOHbackpack(size_t slots, bool slider)
 		const auto pos = Point(slotSizeWithMargin * (artPlaceIdx % slotsColumnsMax),
 			slotSizeWithMargin * (artPlaceIdx / slotsColumnsMax));
 		backpackSlotsBackgrounds.emplace_back(std::make_shared<CPicture>(ImagePath::builtin("heroWindow/artifactSlotEmpty"), pos));
-		artPlace = std::make_shared<CHeroArtPlace>(pos);
+		artPlace = std::make_shared<CArtPlace>(pos);
 		artPlace->setArtifact(nullptr);
 		artPlace->setClickPressedCallback(std::bind(&CArtifactsOfHeroBase::clickPrassedArtPlace, this, _1, _2));
 		artPlace->setShowPopupCallback(std::bind(&CArtifactsOfHeroBase::showPopupArtPlace, this, _1, _2));

+ 13 - 13
client/widgets/CArtifactsOfHeroBase.cpp

@@ -57,12 +57,12 @@ void CArtifactsOfHeroBase::init(
 	pos += position;
 	for(int g = 0; g < ArtifactPosition::BACKPACK_START; g++)
 	{
-		artWorn[ArtifactPosition(g)] = std::make_shared<CHeroArtPlace>(slotPos[g]);
+		artWorn[ArtifactPosition(g)] = std::make_shared<CArtPlace>(slotPos[g]);
 	}
 	backpack.clear();
 	for(int s = 0; s < 5; s++)
 	{
-		auto artPlace = std::make_shared<CHeroArtPlace>(Point(403 + 46 * s, 365));
+		auto artPlace = std::make_shared<CArtPlace>(Point(403 + 46 * s, 365));
 		backpack.push_back(artPlace);
 	}
 	for(auto artPlace : artWorn)
@@ -224,21 +224,21 @@ void CArtifactsOfHeroBase::setSlotData(ArtPlacePtr artPlace, const ArtifactPosit
 	{
 		artPlace->lockSlot(slotInfo->locked);
 		artPlace->setArtifact(slotInfo->artifact);
-		if(!slotInfo->artifact->isCombined())
+		if(slotInfo->locked || slotInfo->artifact->isCombined())
+			return;
+
+		// If the artifact is part of at least one combined artifact, add additional information
+		std::map<const ArtifactID, std::vector<ArtifactID>> arts;
+		for(const auto combinedArt : slotInfo->artifact->artType->getPartOf())
 		{
-			// If the artifact is part of at least one combined artifact, add additional information
-			std::map<const CArtifact*, int> arts;
-			for(const auto combinedArt : slotInfo->artifact->artType->getPartOf())
+			arts.try_emplace(combinedArt->getId(), std::vector<ArtifactID>{});
+			for(const auto part : combinedArt->getConstituents())
 			{
-				arts.insert(std::pair(combinedArt, 0));
-				for(const auto part : combinedArt->getConstituents())
-				{
-					if(curHero->hasArt(part->getId(), false))
-						arts.at(combinedArt)++;
-				}
+				if(curHero->hasArt(part->getId(), false, false, false))
+					arts.at(combinedArt->getId()).emplace_back(part->getId());
 			}
-			artPlace->addCombinedArtInfo(arts);
 		}
+		artPlace->addCombinedArtInfo(arts);
 	}
 	else
 	{

+ 2 - 2
client/widgets/CArtifactsOfHeroBase.h

@@ -16,7 +16,7 @@ class CButton;
 class CArtifactsOfHeroBase : virtual public CIntObject
 {
 protected:
-	using ArtPlacePtr = std::shared_ptr<CHeroArtPlace>;
+	using ArtPlacePtr = std::shared_ptr<CArtPlace>;
 	using BpackScrollFunctor = std::function<void(int)>;
 
 public:
@@ -62,7 +62,7 @@ protected:
 		Point(381,295) //18
 	};
 
-	virtual void init(const CHeroArtPlace::ClickFunctor & lClickCallback, const CHeroArtPlace::ClickFunctor & showPopupCallback,
+	virtual void init(const CArtPlace::ClickFunctor & lClickCallback, const CArtPlace::ClickFunctor & showPopupCallback,
 		const Point & position, const BpackScrollFunctor & scrollCallback);
 	// Assigns an artifacts to an artifact place depending on it's new slot ID
 	virtual void setSlotData(ArtPlacePtr artPlace, const ArtifactPosition & slot);

+ 4 - 4
client/windows/CKingdomInterface.cpp

@@ -866,7 +866,7 @@ class ArtSlotsTab : public CIntObject
 {
 public:
 	std::shared_ptr<CAnimImage> background;
-	std::vector<std::shared_ptr<CHeroArtPlace>> arts;
+	std::vector<std::shared_ptr<CArtPlace>> arts;
 
 	ArtSlotsTab()
 	{
@@ -874,7 +874,7 @@ public:
 		background = std::make_shared<CAnimImage>(AnimationPath::builtin("OVSLOT"), 4);
 		pos = background->pos;
 		for(int i=0; i<9; i++)
-			arts.push_back(std::make_shared<CHeroArtPlace>(Point(269+i*48, 66)));
+			arts.push_back(std::make_shared<CArtPlace>(Point(269+i*48, 66)));
 	}
 };
 
@@ -882,7 +882,7 @@ class BackpackTab : public CIntObject
 {
 public:
 	std::shared_ptr<CAnimImage> background;
-	std::vector<std::shared_ptr<CHeroArtPlace>> arts;
+	std::vector<std::shared_ptr<CArtPlace>> arts;
 	std::shared_ptr<CButton> btnLeft;
 	std::shared_ptr<CButton> btnRight;
 
@@ -894,7 +894,7 @@ public:
 		btnLeft = std::make_shared<CButton>(Point(269, 66), AnimationPath::builtin("HSBTNS3"), CButton::tooltip(), 0);
 		btnRight = std::make_shared<CButton>(Point(675, 66), AnimationPath::builtin("HSBTNS5"), CButton::tooltip(), 0);
 		for(int i=0; i<8; i++)
-			arts.push_back(std::make_shared<CHeroArtPlace>(Point(294+i*48, 66)));
+			arts.push_back(std::make_shared<CArtPlace>(Point(294+i*48, 66)));
 	}
 };
 

+ 11 - 0
lib/MetaString.cpp

@@ -64,6 +64,11 @@ void MetaString::appendNumber(int64_t value)
 	numbers.push_back(value);
 }
 
+void MetaString::appendEOL()
+{
+	message.push_back(EMessage::APPEND_EOL);
+}
+
 void MetaString::replaceLocalString(EMetaText type, ui32 serial)
 {
 	message.push_back(EMessage::REPLACE_LOCAL_STRING);
@@ -155,6 +160,9 @@ DLL_LINKAGE std::string MetaString::toString() const
 			case EMessage::APPEND_NUMBER:
 				dst += std::to_string(numbers.at(nums++));
 				break;
+			case EMessage::APPEND_EOL:
+				dst += '\n';
+				break;
 			case EMessage::REPLACE_RAW_STRING:
 				boost::replace_first(dst, "%s", exactStrings.at(exSt++));
 				break;
@@ -220,6 +228,9 @@ DLL_LINKAGE std::string MetaString::buildList() const
 			case EMessage::APPEND_NUMBER:
 				lista += std::to_string(numbers.at(nums++));
 				break;
+			case EMessage::APPEND_EOL:
+				lista += '\n';
+				break;
 			case EMessage::REPLACE_RAW_STRING:
 				lista.replace(lista.find("%s"), 2, exactStrings.at(exSt++));
 				break;

+ 3 - 1
lib/MetaString.h

@@ -48,7 +48,8 @@ private:
 		REPLACE_LOCAL_STRING,
 		REPLACE_TEXTID_STRING,
 		REPLACE_NUMBER,
-		REPLACE_POSITIVE_NUMBER
+		REPLACE_POSITIVE_NUMBER,
+                APPEND_EOL
 	};
 
 	std::vector<EMessage> message;
@@ -81,6 +82,7 @@ public:
 	void appendName(const CreatureID & id, TQuantity count);
 	void appendNameSingular(const CreatureID & id);
 	void appendNamePlural(const CreatureID & id);
+	void appendEOL();
 
 	/// Replaces first '%s' placeholder in string with specified local string
 	void replaceLocalString(EMetaText type, ui32 serial);