Переглянути джерело

ArtifactUtils and CArtifactFittingSet class

SoundSSGood 3 роки тому
батько
коміт
363e461c3e
3 змінених файлів з 160 додано та 0 видалено
  1. 63 0
      lib/CArtHandler.cpp
  2. 22 0
      lib/CArtHandler.h
  3. 75 0
      lib/NetPacks.h

+ 63 - 0
lib/CArtHandler.cpp

@@ -1457,4 +1457,67 @@ void CArtifactSet::serializeJsonSlot(JsonSerializeFormat & handler, const Artifa
 	}
 }
 
+CArtifactFittingSet::CArtifactFittingSet(ArtBearer::ArtBearer Bearer)
+{
+	this->Bearer = Bearer;
+}
+
+void CArtifactFittingSet::setNewArtSlot(ArtifactPosition slot, CArtifactInstance * art, bool locked)
+{
+	ArtSlotInfo & asi = retrieveNewArtSlot(slot);
+	asi.artifact = art;
+	asi.locked = locked;
+}
+
+void CArtifactFittingSet::putArtifact(ArtifactPosition pos, CArtifactInstance * art)
+{
+	if (art->canBeDisassembled() && (pos < ArtifactPosition::AFTER_LAST))
+	{
+		for (auto part : dynamic_cast<CCombinedArtifactInstance*>(art)->constituentsInfo)
+		{
+			// For the ArtFittingSet is no needed to do figureMainConstituent, just lock slots
+			this->setNewArtSlot(part.art->firstAvailableSlot(this), part.art, true);
+		}
+	}
+	else
+	{
+		this->setNewArtSlot(pos, art, false);
+	}
+}
+
+ArtBearer::ArtBearer CArtifactFittingSet::bearerType() const
+{
+	return this->Bearer;
+}
+
+DLL_LINKAGE ArtifactPosition ArtifactUtils::getArtifactDstPosition(const CArtifactInstance * artifact,
+	const CArtifactSet * target, ArtBearer::ArtBearer barer)
+{
+	for (auto slot : artifact->artType->possibleSlots.at(barer))
+	{
+		auto existingArtifact = target->getArt(slot);
+		auto existingArtInfo = target->getSlot(slot);
+
+		if (!existingArtifact
+			&& (!existingArtInfo || !existingArtInfo->locked)
+			&& artifact->canBePutAt(target, slot))
+		{
+			return slot;
+		}
+	}
+	return ArtifactPosition(GameConstants::BACKPACK_START);
+}
+
+DLL_LINKAGE std::vector<ArtifactPosition> ArtifactUtils::unmovablePositions()
+{
+	return { ArtifactPosition::SPELLBOOK, ArtifactPosition::MACH4 };
+}
+
+DLL_LINKAGE bool ArtifactUtils::isArtRemovable(const std::pair<ArtifactPosition, ArtSlotInfo> & slot)
+{
+	return slot.second.artifact
+		&& !slot.second.locked
+	    && !vstd::contains(unmovablePositions(), slot.first);
+}
+
 VCMI_LIB_NAMESPACE_END

+ 22 - 0
lib/CArtHandler.h

@@ -363,4 +363,26 @@ private:
 	void serializeJsonSlot(JsonSerializeFormat & handler, const ArtifactPosition & slot, CMap * map);//normal slots
 };
 
+// Used to try on artifacts before the claimed changes have been applied
+class DLL_LINKAGE CArtifactFittingSet : public CArtifactSet
+{
+public:
+	CArtifactFittingSet(ArtBearer::ArtBearer Bearer);
+	void setNewArtSlot(ArtifactPosition slot, CArtifactInstance * art, bool locked);
+	void putArtifact(ArtifactPosition pos, CArtifactInstance * art) override;
+	ArtBearer::ArtBearer bearerType() const override;
+
+protected:
+	ArtBearer::ArtBearer Bearer;
+};
+
+namespace ArtifactUtils
+{
+	// Calculates where an artifact gets placed when it gets transferred from one hero to another.
+	DLL_LINKAGE ArtifactPosition getArtifactDstPosition(const CArtifactInstance * artifact, const CArtifactSet * target,
+		ArtBearer::ArtBearer barer);
+	DLL_LINKAGE std::vector<ArtifactPosition> unmovablePositions(); // TODO: Make this constexpr when the toolset is upgraded
+	DLL_LINKAGE bool isArtRemovable(const std::pair<ArtifactPosition, ArtSlotInfo> & slot);
+}
+
 VCMI_LIB_NAMESPACE_END

+ 75 - 0
lib/NetPacks.h

@@ -1006,6 +1006,60 @@ struct MoveArtifact : CArtifactOperationPack
 	}
 };
 
+struct BulkMoveArtifacts : CArtifactOperationPack
+{
+	struct HeroArtsToMove
+	{
+		struct LinkedSlots
+		{
+			ArtifactPosition srcPos;
+			ArtifactPosition dstPos;
+
+			LinkedSlots() {}
+			LinkedSlots(ArtifactPosition srcPos, ArtifactPosition dstPos)
+				: srcPos(srcPos), dstPos(dstPos) {}
+
+			template <typename Handler> void serialize(Handler & h, const int version)
+			{
+				h & srcPos;
+				h & dstPos;
+			}
+		};
+
+		TArtHolder srcArtHolder;
+		TArtHolder dstArtHolder;
+		std::vector<LinkedSlots> slots;
+
+		CArtifactSet * getSrcHolderArtSet();
+		CArtifactSet * getDstHolderArtSet();
+		template <typename Handler> void serialize(Handler & h, const int version)
+		{
+			h & srcArtHolder;
+			h & dstArtHolder;
+			h & slots;
+		}
+	};
+
+	BulkMoveArtifacts() {}
+	BulkMoveArtifacts(TArtHolder srcArtHolder, TArtHolder dstArtHolder)
+	{
+		artsPack0.srcArtHolder = srcArtHolder;
+		artsPack0.dstArtHolder = dstArtHolder;
+	}
+
+	void applyCl(CClient * cl);
+	DLL_LINKAGE void applyGs(CGameState * gs);
+
+	HeroArtsToMove artsPack0;
+	// If the artsPack1 is present then make swap
+	boost::optional<HeroArtsToMove> artsPack1;
+	template <typename Handler> void serialize(Handler & h, const int version)
+	{
+		h & artsPack0;
+		h & artsPack1;
+	}
+};
+
 struct AssembledArtifact : CArtifactOperationPack
 {
 	ArtifactLocation al; //where assembly will be put
@@ -2197,6 +2251,27 @@ struct ExchangeArtifacts : public CPackForServer
 	}
 };
 
+struct BulkExchangeArtifacts : public CPackForServer
+{
+	ObjectInstanceID srcHero;
+	ObjectInstanceID dstHero;
+	bool swap;
+
+	BulkExchangeArtifacts() = default;
+	BulkExchangeArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap)
+		: srcHero(srcHero), dstHero(dstHero), swap(swap)
+	{}
+
+	bool applyGh(CGameHandler * gh);
+	template <typename Handler> void serialize(Handler & h, const int version)
+	{
+		h & static_cast<CPackForServer&>(*this);
+		h & srcHero;
+		h & dstHero;
+		h & swap;
+	}
+};
+
 struct AssembleArtifacts : public CPackForServer
 {
 	AssembleArtifacts():assemble(false){};