Ver código fonte

Fixing several issues with artifacts in hero window described in note http://bugs.vcmi.eu/view.php?id=761#c1828 . Also resolving #741.

Michał W. Urbańczyk 14 anos atrás
pai
commit
4592ddb74e
3 arquivos alterados com 55 adições e 4 exclusões
  1. 20 4
      client/GUIClasses.cpp
  2. 32 0
      lib/CArtHandler.cpp
  3. 3 0
      lib/CArtHandler.h

+ 20 - 4
client/GUIClasses.cpp

@@ -4779,6 +4779,15 @@ void CArtPlace::select ()
 		return;
 
 	picked = true;
+	if(ourArt->canBeDisassembled() && slotID < Arts::BACKPACK_START) //worn combined artifact -> locks have to disappear
+	{
+		for(int i = 0; i < Arts::BACKPACK_START; i++)
+		{
+			CArtPlace *ap = ourOwner->getArtPlace(i);
+			ap->picked = ourArt->isPart(ap->ourArt);
+		}
+	}
+
 	//int backpackCorrection = -(slotID - Arts::BACKPACK_START < ourOwner->backpackPos);
 
 	CCS->curh->dragAndDropCursor(graphics->artDefs->ourImages[ourArt->artType->id].bitmap);
@@ -4798,6 +4807,12 @@ void CArtPlace::select ()
 void CArtPlace::deselect ()
 {
 	picked = false;
+	if(ourArt && ourArt->canBeDisassembled()) //combined art returned to its slot -> restore locks
+	{
+		for(int i = 0; i < Arts::BACKPACK_START; i++)
+			ourOwner->getArtPlace(i)->picked = false;
+	}
+
 	CCS->curh->dragAndDropCursor(NULL);
 	ourOwner->unmarkSlots();
 	ourOwner->commonInfo->src.clear();
@@ -5427,7 +5442,6 @@ void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const Artifact
 		assert(commonInfo->dst == dst  ||  dst.slot == dst.hero->artifactsInBackpack.size() + Arts::BACKPACK_START);
 		commonInfo->reset();
 		unmarkSlots();
-		updateParentWindow();
 	}
 	else if(commonInfo->dst == src) //the dest artifact was moved -> we are picking it
 	{
@@ -5456,7 +5470,6 @@ void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const Artifact
 			assert(commonInfo->src.AOH);
 			CCS->curh->dragAndDropCursor(graphics->artDefs->ourImages[dst.getArt()->artType->id].bitmap);
 			markPossibleSlots(dst.getArt());
-			updateParentWindow();
 		}
 	}
 	else if(src.slot >= Arts::BACKPACK_START && 
@@ -5466,13 +5479,16 @@ void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const Artifact
 		//int fixedSlot = src.hero->getArtPos(commonInfo->src.art);
 		commonInfo->src.slotID--;
 		assert(commonInfo->src.valid());
-		updateParentWindow();
 	}
 	else
 	{
-		tlog1 << "Unexpected artifact movement...\n";
+		//when moving one artifact onto another it leads to two art movements: dst->backapck; src->dst
+		// however after first movement we pick the art from backpack and the second movement coming when
+		// we have a different artifact may look surprising... but it's valid.
+		//tlog1 << "Unexpected artifact movement...\n";
 	}
 
+	updateParentWindow();
  	int shift = 0;
 // 	if(dst.slot >= Arts::BACKPACK_START && dst.slot - Arts::BACKPACK_START < backpackPos)
 // 		shift++;

+ 32 - 0
lib/CArtHandler.cpp

@@ -1045,6 +1045,11 @@ int CArtifactInstance::getGivenSpellID() const
 	return b->subtype;
 }
 
+bool CArtifactInstance::isPart(const CArtifactInstance *supposedPart) const
+{
+	return supposedPart == this;
+}
+
 bool CCombinedArtifactInstance::canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved /*= false*/) const
 {
 	bool canMainArtifactBePlaced = CArtifactInstance::canBePutAt(al, assumeDestRemoved);
@@ -1056,6 +1061,14 @@ bool CCombinedArtifactInstance::canBePutAt(const ArtifactLocation &al, bool assu
 
 	assert(artType->constituents);
 	std::vector<ConstituentInfo> constituentsToBePlaced = constituentsInfo; //we'll remove constituents from that list, as we find a suitable slot for them
+
+	//it may be that we picked a combined artifact in hero screen (though technically it's still there) to move it
+	//so we remove from the list all constituents that are already present on dst hero in the form of locks
+	BOOST_FOREACH(const ConstituentInfo &constituent, constituentsInfo)
+	{
+		if(constituent.art == al.hero->getArt(constituent.slot, false)) //no need to worry about locked constituent
+			constituentsToBePlaced -= constituent;
+	}
 	
 	//we iterate over all active slots and check if constituents fits them
 	for (int i = 0; i < Arts::BACKPACK_START; i++)
@@ -1191,12 +1204,31 @@ void CCombinedArtifactInstance::deserializationFix()
 		attachTo(ci.art);
 }
 
+bool CCombinedArtifactInstance::isPart(const CArtifactInstance *supposedPart) const
+{
+	bool me = CArtifactInstance::isPart(supposedPart);
+	if(me)
+		return true;
+
+	//check for constituents
+	BOOST_FOREACH(const ConstituentInfo &constituent, constituentsInfo)
+		if(constituent.art == supposedPart)
+			return true;
+
+	return false;
+}
+
 CCombinedArtifactInstance::ConstituentInfo::ConstituentInfo(CArtifactInstance *Art /*= NULL*/, ui16 Slot /*= -1*/)
 {
 	art = Art;
 	slot = Slot;
 }
 
+bool CCombinedArtifactInstance::ConstituentInfo::operator==(const ConstituentInfo &rhs) const
+{
+	return art == rhs.art && slot == rhs.slot;
+}
+
 const CArtifactInstance* CArtifactSet::getArt(ui16 pos, bool excludeLocked /*= true*/) const
 {
 	if(const ArtSlotInfo *si = getSlot(pos))

+ 3 - 0
lib/CArtHandler.h

@@ -79,6 +79,7 @@ public:
 	virtual bool canBeDisassembled() const;
 	virtual void putAt(CGHeroInstance *h, ui16 slot);
 	virtual void removeFrom(CGHeroInstance *h, ui16 slot);
+	virtual bool isPart(const CArtifactInstance *supposedPart) const; //checks if this a part of this artifact: artifact instance is a part of itself, additionally truth is returned for consituents of combined arts
 
 	std::vector<const CArtifact *> assemblyPossibilities(const CGHeroInstance *h) const;
 	void move(ArtifactLocation &src, ArtifactLocation &dst);
@@ -108,6 +109,7 @@ public:
 			h & art & slot;
 		}
 
+		bool operator==(const ConstituentInfo &rhs) const;
 		ConstituentInfo(CArtifactInstance *art = NULL, ui16 slot = -1);
 	};
 
@@ -117,6 +119,7 @@ public:
 	bool canBeDisassembled() const OVERRIDE;
 	void putAt(CGHeroInstance *h, ui16 slot) OVERRIDE;
 	void removeFrom(CGHeroInstance *h, ui16 slot) OVERRIDE;
+	bool isPart(const CArtifactInstance *supposedPart) const OVERRIDE;
 
 	void createConstituents();
 	void addAsConstituent(CArtifactInstance *art, int slot);