瀏覽代碼

assemble in backpack initial

SoundSSGood 2 年之前
父節點
當前提交
2d078132bf
共有 5 個文件被更改,包括 70 次插入40 次删除
  1. 22 22
      client/widgets/CArtifactHolder.cpp
  2. 43 15
      lib/CArtHandler.cpp
  3. 3 1
      lib/CArtHandler.h
  4. 1 1
      lib/NetPacksLib.cpp
  5. 1 1
      server/CGameHandler.cpp

+ 22 - 22
client/widgets/CArtifactHolder.cpp

@@ -206,12 +206,17 @@ void CHeroArtPlace::clickLeft(tribool down, bool previousState)
 bool CHeroArtPlace::askToAssemble(const CArtifactInstance *art, ArtifactPosition slot,
                               const CGHeroInstance *hero)
 {
-	assert(art != nullptr);
-	assert(hero != nullptr);
-	std::vector<const CArtifact *> assemblyPossibilities = art->assemblyPossibilities(hero);
+	assert(art);
+	assert(hero);
+	bool assembleEqipped = true;
+	if(slot >= GameConstants::BACKPACK_START)
+	{
+		assembleEqipped = false;
+	}
+	auto assemblyPossibilities = art->assemblyPossibilities(hero, assembleEqipped);
 
 	// If the artifact can be assembled, display dialog.
-	for(const CArtifact *combination : assemblyPossibilities)
+	for(auto combination : assemblyPossibilities)
 	{
 		LOCPLINT->showArtifactAssemblyDialog(
 			art->artType,
@@ -229,27 +234,22 @@ void CHeroArtPlace::clickRight(tribool down, bool previousState)
 {
 	if(ourArt && down && !locked && text.size() && !picked)  //if there is no description or it's a lock, do nothing ;]
 	{
-		if(slotID < GameConstants::BACKPACK_START)
+		if(ourOwner->allowedAssembling)
 		{
-			if(ourOwner->allowedAssembling)
+			// If the artifact can be assembled, display dialog.
+			if(askToAssemble(ourArt, slotID, ourOwner->curHero))
 			{
-				std::vector<const CArtifact *> assemblyPossibilities = ourArt->assemblyPossibilities(ourOwner->curHero);
-
-				// If the artifact can be assembled, display dialog.
-				if(askToAssemble(ourArt, slotID, ourOwner->curHero))
-				{
-					return;
-				}
+				return;
+			}
 
-				// Otherwise if the artifact can be diasassembled, display dialog.
-				if(ourArt->canBeDisassembled())
-				{
-					LOCPLINT->showArtifactAssemblyDialog(
-						ourArt->artType,
-						nullptr,
-						std::bind(&CCallback::assembleArtifacts, LOCPLINT->cb.get(), ourOwner->curHero, slotID, false, ArtifactID()));
-					return;
-				}
+			// Otherwise if the artifact can be diasassembled, display dialog.
+			if(ourArt->canBeDisassembled())
+			{
+				LOCPLINT->showArtifactAssemblyDialog(
+					ourArt->artType,
+					nullptr,
+					std::bind(&CCallback::assembleArtifacts, LOCPLINT->cb.get(), ourOwner->curHero, slotID, false, ArtifactID()));
+				return;
 			}
 		}
 

+ 43 - 15
lib/CArtHandler.cpp

@@ -870,26 +870,36 @@ bool CArtifactInstance::canBeDisassembled() const
 	return bool(artType->constituents);
 }
 
-std::vector<const CArtifact *> CArtifactInstance::assemblyPossibilities(const CArtifactSet *h) const
+std::vector<const CArtifact *> CArtifactInstance::assemblyPossibilities(const CArtifactSet * h, bool equipped) const
 {
 	std::vector<const CArtifact *> ret;
 	if(artType->constituents) //combined artifact already: no combining of combined artifacts... for now.
 		return ret;
 
-	for(const CArtifact * artifact : artType->constituentOf)
+	for(auto artifact : artType->constituentOf)
 	{
 		assert(artifact->constituents);
 		bool possible = true;
 
-		for(const CArtifact * constituent : *artifact->constituents) //check if all constituents are available
+		for(auto constituent : *artifact->constituents) //check if all constituents are available
 		{
-			const bool noBackpack = false;
-			const bool notAlreadyAssembled = false;
-
-			if(!h->hasArt(constituent->id, true, noBackpack, notAlreadyAssembled)) //constituent must be equipped
+			if (equipped)
 			{
-				possible = false;
-				break;
+				// Search for equipped arts
+				if (!h->hasArt(constituent->id, true, false, false))
+				{
+					possible = false;
+					break;
+				}
+			}
+			else
+			{
+				// Search in backpack
+				if(!h->hasArtBackpack(constituent->id))
+				{
+					possible = false;
+					break;
+				}
 			}
 		}
 
@@ -1198,19 +1208,32 @@ ArtifactPosition CArtifactSet::getArtPos(int aid, bool onlyWorn, bool allowLocke
 std::vector<ArtifactPosition> CArtifactSet::getAllArtPositions(int aid, bool onlyWorn, bool allowLocked, bool getAll) const
 {
 	std::vector<ArtifactPosition> result;
-	for(auto i = artifactsWorn.cbegin(); i != artifactsWorn.cend(); i++)
-		if(i->second.artifact->artType->id == aid && (allowLocked || !i->second.locked))
-			result.push_back(i->first);
+	for(auto & slotInfo : artifactsWorn)
+		if(slotInfo.second.artifact->artType->id == aid && (allowLocked || !slotInfo.second.locked))
+			result.push_back(slotInfo.first);
 
 	if(onlyWorn)
 		return result;
 	if(!getAll && !result.empty())
 		return result;
 
-	for(int i = 0; i < artifactsInBackpack.size(); i++)
-		if(artifactsInBackpack[i].artifact->artType->id == aid)
-			result.push_back(ArtifactPosition(GameConstants::BACKPACK_START + i));
+	auto backpackPositions = getBackpackArtPositions(aid);
+	result.insert(result.end(), backpackPositions.begin(), backpackPositions.end());
+	return result;
+}
+
+std::vector<ArtifactPosition> CArtifactSet::getBackpackArtPositions(int aid) const
+{
+	std::vector<ArtifactPosition> result;
 
+	si32 backpackPosition = GameConstants::BACKPACK_START;
+	for(auto & artInfo : artifactsInBackpack)
+	{
+		auto art = artInfo.getArt();
+		if (art && art->artType->id == aid)
+			result.push_back(ArtifactPosition(backpackPosition));
+		backpackPosition++;
+	}
 	return result;
 }
 
@@ -1249,6 +1272,11 @@ bool CArtifactSet::hasArt(
 	return getArtPosCount(aid, onlyWorn, searchBackpackAssemblies, allowLocked) > 0;
 }
 
+bool CArtifactSet::hasArtBackpack(ui32 aid) const
+{
+	return getBackpackArtPositions(aid).size() > 0;
+}
+
 unsigned CArtifactSet::getArtPosCount(int aid, bool onlyWorn, bool searchBackpackAssemblies, bool allowLocked) const
 {
 	const auto allPositions = getAllArtPositions(aid, onlyWorn, allowLocked, true);

+ 3 - 1
lib/CArtHandler.h

@@ -163,7 +163,7 @@ public:
 	/// of itself, additionally truth is returned for constituents of combined arts
 	virtual bool isPart(const CArtifactInstance *supposedPart) const;
 
-	std::vector<const CArtifact *> assemblyPossibilities(const CArtifactSet *h) const;
+	std::vector<const CArtifact *> assemblyPossibilities(const CArtifactSet * h, bool equipped) const;
 	void move(ArtifactLocation src, ArtifactLocation dst);
 
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -330,12 +330,14 @@ public:
 	ArtifactPosition getArtPos(int aid, bool onlyWorn = true, bool allowLocked = true) const;
 	ArtifactPosition getArtPos(const CArtifactInstance *art) const;
 	std::vector<ArtifactPosition> getAllArtPositions(int aid, bool onlyWorn, bool allowLocked, bool getAll) const;
+	std::vector<ArtifactPosition> getBackpackArtPositions(int aid) const;
 	const CArtifactInstance *getArtByInstanceId(ArtifactInstanceID artInstId) const;
 	/// Search for constituents of assemblies in backpack which do not have an ArtifactPosition
 	const CArtifactInstance *getHiddenArt(int aid) const;
 	const CCombinedArtifactInstance *getAssemblyByConstituent(int aid) const;
 	/// Checks if hero possess artifact of given id (either in backack or worn)
 	bool hasArt(ui32 aid, bool onlyWorn = false, bool searchBackpackAssemblies = false, bool allowLocked = true) const;
+	bool hasArtBackpack(ui32 aid) const;
 	bool isPositionFree(ArtifactPosition pos, bool onlyLockCheck = false) const;
 	unsigned getArtPosCount(int aid, bool onlyWorn = true, bool searchBackpackAssemblies = true, bool allowLocked = true) const;
 

+ 1 - 1
lib/NetPacksLib.cpp

@@ -1170,7 +1170,7 @@ DLL_LINKAGE void AssembledArtifact::applyGs(CGameState *gs)
 	CArtifactSet *artSet = al.getHolderArtSet();
 	const CArtifactInstance *transformedArt = al.getArt();
 	assert(transformedArt);
-	assert(vstd::contains(transformedArt->assemblyPossibilities(artSet), builtArt));
+	assert(vstd::contains(transformedArt->assemblyPossibilities(artSet, true), builtArt));
 	UNUSED(transformedArt);
 
 	auto combinedArt = new CCombinedArtifactInstance(builtArt);

+ 1 - 1
server/CGameHandler.cpp

@@ -4036,7 +4036,7 @@ bool CGameHandler::assembleArtifacts (ObjectInstanceID heroID, ArtifactPosition
 		CArtifact *combinedArt = VLC->arth->objects[assembleTo];
 		if (!combinedArt->constituents)
 			COMPLAIN_RET("assembleArtifacts: Artifact being attempted to assemble is not a combined artifacts!");
-		if (!vstd::contains(destArtifact->assemblyPossibilities(hero), combinedArt))
+		if (!vstd::contains(destArtifact->assemblyPossibilities(hero, true), combinedArt))
 			COMPLAIN_RET("assembleArtifacts: It's impossible to assemble requested artifact!");
 		
 		if(ArtifactUtils::checkSpellbookIsNeeded(hero, assembleTo, artifactSlot))