diff --git a/lib/CArtHandler.cpp b/lib/CArtHandler.cpp index ee57823f9..1d0f9cca4 100644 --- a/lib/CArtHandler.cpp +++ b/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(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 ArtifactUtils::unmovablePositions() +{ + return { ArtifactPosition::SPELLBOOK, ArtifactPosition::MACH4 }; +} + +DLL_LINKAGE bool ArtifactUtils::isArtRemovable(const std::pair & slot) +{ + return slot.second.artifact + && !slot.second.locked + && !vstd::contains(unmovablePositions(), slot.first); +} + VCMI_LIB_NAMESPACE_END diff --git a/lib/CArtHandler.h b/lib/CArtHandler.h index a933b70a3..d30bd81f8 100644 --- a/lib/CArtHandler.h +++ b/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 unmovablePositions(); // TODO: Make this constexpr when the toolset is upgraded + DLL_LINKAGE bool isArtRemovable(const std::pair & slot); +} + VCMI_LIB_NAMESPACE_END diff --git a/lib/NetPacks.h b/lib/NetPacks.h index 171ebdace..e1abab1da 100644 --- a/lib/NetPacks.h +++ b/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 void serialize(Handler & h, const int version) + { + h & srcPos; + h & dstPos; + } + }; + + TArtHolder srcArtHolder; + TArtHolder dstArtHolder; + std::vector slots; + + CArtifactSet * getSrcHolderArtSet(); + CArtifactSet * getDstHolderArtSet(); + template 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 artsPack1; + template 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 void serialize(Handler & h, const int version) + { + h & static_cast(*this); + h & srcHero; + h & dstHero; + h & swap; + } +}; + struct AssembleArtifacts : public CPackForServer { AssembleArtifacts():assemble(false){};