瀏覽代碼

ManageBackpackArtifacts

SoundSSGood 1 年之前
父節點
當前提交
b1f52eec41

+ 8 - 0
CCallback.cpp

@@ -180,6 +180,14 @@ void CCallback::bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dst
 	sendRequest(&bma);
 	sendRequest(&bma);
 }
 }
 
 
+void CCallback::scrollBackpackArtifacts(ObjectInstanceID hero, bool left)
+{
+	ManageBackpackArtifacts mba(hero, ManageBackpackArtifacts::ManageCmd::SCROLL_RIGHT);
+	if(left)
+		mba.cmd = ManageBackpackArtifacts::ManageCmd::SCROLL_LEFT;
+	sendRequest(&mba);
+}
+
 void CCallback::eraseArtifactByClient(const ArtifactLocation & al)
 void CCallback::eraseArtifactByClient(const ArtifactLocation & al)
 {
 {
 	EraseArtifactByClient ea(al);
 	EraseArtifactByClient ea(al);

+ 2 - 0
CCallback.h

@@ -90,6 +90,7 @@ public:
 	virtual int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2, int val)=0;//split creatures from the first stack
 	virtual int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2, int val)=0;//split creatures from the first stack
 	//virtual bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)=0; //swaps artifacts between two given heroes
 	//virtual bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)=0; //swaps artifacts between two given heroes
 	virtual bool swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2)=0;
 	virtual bool swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2)=0;
+	virtual void scrollBackpackArtifacts(ObjectInstanceID hero, bool left) = 0;
 	virtual void assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo)=0;
 	virtual void assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo)=0;
 	virtual void eraseArtifactByClient(const ArtifactLocation & al)=0;
 	virtual void eraseArtifactByClient(const ArtifactLocation & al)=0;
 	virtual bool dismissCreature(const CArmedInstance *obj, SlotID stackPos)=0;
 	virtual bool dismissCreature(const CArmedInstance *obj, SlotID stackPos)=0;
@@ -174,6 +175,7 @@ public:
 	bool swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2) override;
 	bool swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2) override;
 	void assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo) override;
 	void assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo) override;
 	void bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap, bool equipped = true, bool backpack = true) override;
 	void bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap, bool equipped = true, bool backpack = true) override;
+	void scrollBackpackArtifacts(ObjectInstanceID hero, bool left) override;
 	void eraseArtifactByClient(const ArtifactLocation & al) override;
 	void eraseArtifactByClient(const ArtifactLocation & al) override;
 	bool buildBuilding(const CGTownInstance *town, BuildingID buildingID) override;
 	bool buildBuilding(const CGTownInstance *town, BuildingID buildingID) override;
 	void recruitCreatures(const CGDwelling * obj, const CArmedInstance * dst, CreatureID ID, ui32 amount, si32 level=-1) override;
 	void recruitCreatures(const CGDwelling * obj, const CArmedInstance * dst, CreatureID ID, ui32 amount, si32 level=-1) override;

+ 1 - 1
client/NetPacksClient.cpp

@@ -290,7 +290,7 @@ void ApplyClientNetPackVisitor::visitMoveArtifact(MoveArtifact & pack)
 			callInterfaceIfPresent(cl, player, &IGameEventsReceiver::askToAssembleArtifact, pack.dst);
 			callInterfaceIfPresent(cl, player, &IGameEventsReceiver::askToAssembleArtifact, pack.dst);
 	};
 	};
 
 
-	moveArtifact(cl.getOwner(pack.src.artHolder));
+	moveArtifact(LOCPLINT->playerID);
 	if(cl.getOwner(pack.src.artHolder) != cl.getOwner(pack.dst.artHolder))
 	if(cl.getOwner(pack.src.artHolder) != cl.getOwner(pack.dst.artHolder))
 		moveArtifact(cl.getOwner(pack.dst.artHolder));
 		moveArtifact(cl.getOwner(pack.dst.artHolder));
 
 

+ 1 - 1
client/widgets/CArtifactsOfHeroBackpack.h

@@ -24,7 +24,7 @@ class CArtifactsOfHeroBackpack : public CArtifactsOfHeroBase
 public:
 public:
 	CArtifactsOfHeroBackpack(size_t slotsColumnsMax, size_t slotsRowsMax);
 	CArtifactsOfHeroBackpack(size_t slotsColumnsMax, size_t slotsRowsMax);
 	CArtifactsOfHeroBackpack();
 	CArtifactsOfHeroBackpack();
-	void scrollBackpack(int offset) override;
+	void scrollBackpack(int offset);
 	void updateBackpackSlots() override;
 	void updateBackpackSlots() override;
 	size_t getActiveSlotRowsNum();
 	size_t getActiveSlotRowsNum();
 	size_t getSlotsNum();
 	size_t getSlotsNum();

+ 10 - 26
client/widgets/CArtifactsOfHeroBase.cpp

@@ -87,9 +87,9 @@ void CArtifactsOfHeroBase::init(
 		artPlace->setShowPopupCallback(showPopupCallback);
 		artPlace->setShowPopupCallback(showPopupCallback);
 	}
 	}
 	leftBackpackRoll = std::make_shared<CButton>(Point(379, 364), AnimationPath::builtin("hsbtns3.def"), CButton::tooltip(),
 	leftBackpackRoll = std::make_shared<CButton>(Point(379, 364), AnimationPath::builtin("hsbtns3.def"), CButton::tooltip(),
-		[scrollCallback](){scrollCallback(-1);}, EShortcut::MOVE_LEFT);
+		[scrollCallback](){scrollCallback(true);}, EShortcut::MOVE_LEFT);
 	rightBackpackRoll = std::make_shared<CButton>(Point(632, 364), AnimationPath::builtin("hsbtns5.def"), CButton::tooltip(),
 	rightBackpackRoll = std::make_shared<CButton>(Point(632, 364), AnimationPath::builtin("hsbtns5.def"), CButton::tooltip(),
-		[scrollCallback](){scrollCallback(+1);}, EShortcut::MOVE_RIGHT);
+		[scrollCallback](){scrollCallback(false);}, EShortcut::MOVE_RIGHT);
 	leftBackpackRoll->block(true);
 	leftBackpackRoll->block(true);
 	rightBackpackRoll->block(true);
 	rightBackpackRoll->block(true);
 
 
@@ -130,30 +130,9 @@ const CGHeroInstance * CArtifactsOfHeroBase::getHero() const
 	return curHero;
 	return curHero;
 }
 }
 
 
-void CArtifactsOfHeroBase::scrollBackpack(int offset)
+void CArtifactsOfHeroBase::scrollBackpack(bool left)
 {
 {
-	const ArtifactLocation beginLoc = ArtifactLocation(curHero->id, ArtifactPosition::BACKPACK_START);
-	const ArtifactLocation endLoc = ArtifactLocation(curHero->id, ArtifactPosition(ArtifactPosition::BACKPACK_START + curHero->artifactsInBackpack.size() - 1));
-	// To right by default
-	ArtifactLocation const * srcLoc = &beginLoc;
-	ArtifactLocation const * dstLoc = &endLoc;
-	if(offset < 0)
-	{
-		// To left
-		srcLoc = &endLoc;
-		dstLoc = &beginLoc;
-		offset = -offset;
-	}
-
-	for(auto step = 0; step < offset; step++)
-		LOCPLINT->cb->swapArtifacts(*srcLoc, *dstLoc);
-
-	ArtifactPosition slot = ArtifactPosition::BACKPACK_START;
-	for(auto artPlace : backpack)
-	{
-		setSlotData(artPlace, slot);
-		slot = slot + 1;
-	}
+	LOCPLINT->cb->scrollBackpackArtifacts(curHero->id, left);
 }
 }
 
 
 void CArtifactsOfHeroBase::markPossibleSlots(const CArtifactInstance * art, bool assumeDestRemoved)
 void CArtifactsOfHeroBase::markPossibleSlots(const CArtifactInstance * art, bool assumeDestRemoved)
@@ -203,7 +182,12 @@ void CArtifactsOfHeroBase::updateWornSlots()
 
 
 void CArtifactsOfHeroBase::updateBackpackSlots()
 void CArtifactsOfHeroBase::updateBackpackSlots()
 {
 {
-	scrollBackpack(0);
+	ArtifactPosition slot = ArtifactPosition::BACKPACK_START;
+	for(auto & artPlace : backpack)
+	{
+		setSlotData(artPlace, slot);
+		slot = slot + 1;
+	}
 	auto scrollingPossible = static_cast<int>(curHero->artifactsInBackpack.size()) > backpack.size();
 	auto scrollingPossible = static_cast<int>(curHero->artifactsInBackpack.size()) > backpack.size();
 	// Blocking scrolling if there is not enough artifacts to scroll
 	// Blocking scrolling if there is not enough artifacts to scroll
 	if(leftBackpackRoll)
 	if(leftBackpackRoll)

+ 1 - 1
client/widgets/CArtifactsOfHeroBase.h

@@ -36,7 +36,7 @@ public:
 	virtual void gestureArtPlace(CArtPlace & artPlace, const Point & cursorPosition);
 	virtual void gestureArtPlace(CArtPlace & artPlace, const Point & cursorPosition);
 	virtual void setHero(const CGHeroInstance * hero);
 	virtual void setHero(const CGHeroInstance * hero);
 	virtual const CGHeroInstance * getHero() const;
 	virtual const CGHeroInstance * getHero() const;
-	virtual void scrollBackpack(int offset);
+	virtual void scrollBackpack(bool left);
 	virtual void markPossibleSlots(const CArtifactInstance * art, bool assumeDestRemoved = true);
 	virtual void markPossibleSlots(const CArtifactInstance * art, bool assumeDestRemoved = true);
 	virtual void unmarkSlots();
 	virtual void unmarkSlots();
 	virtual ArtPlacePtr getArtPlace(const ArtifactPosition & slot);
 	virtual ArtPlacePtr getArtPlace(const ArtifactPosition & slot);

+ 2 - 2
client/widgets/CArtifactsOfHeroMarket.cpp

@@ -26,9 +26,9 @@ CArtifactsOfHeroMarket::CArtifactsOfHeroMarket(const Point & position)
 		artPlace->setSelectionWidth(2);
 		artPlace->setSelectionWidth(2);
 };
 };
 
 
-void CArtifactsOfHeroMarket::scrollBackpack(int offset)
+void CArtifactsOfHeroMarket::scrollBackpack(bool left)
 {
 {
-	CArtifactsOfHeroBase::scrollBackpack(offset);
+	CArtifactsOfHeroBase::scrollBackpack(left);
 
 
 	// We may have highlight on one of backpack artifacts
 	// We may have highlight on one of backpack artifacts
 	if(selectArtCallback)
 	if(selectArtCallback)

+ 1 - 1
client/widgets/CArtifactsOfHeroMarket.h

@@ -17,5 +17,5 @@ public:
 	std::function<void(CArtPlace*)> selectArtCallback;
 	std::function<void(CArtPlace*)> selectArtCallback;
 
 
 	CArtifactsOfHeroMarket(const Point & position);
 	CArtifactsOfHeroMarket(const Point & position);
-	void scrollBackpack(int offset) override;
+	void scrollBackpack(bool left) override;
 };
 };

+ 5 - 1
client/widgets/CWindowWithArtifacts.cpp

@@ -145,7 +145,11 @@ void CWindowWithArtifacts::clickPressedArtPlaceHero(CArtifactsOfHeroBase & artsI
 					if(artSetPtr->getHero()->getOwner() == LOCPLINT->playerID)
 					if(artSetPtr->getHero()->getOwner() == LOCPLINT->playerID)
 					{
 					{
 						if(checkSpecialArts(*art, hero, std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroAltar>> ? true : false))
 						if(checkSpecialArts(*art, hero, std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroAltar>> ? true : false))
-							LOCPLINT->cb->swapArtifacts(ArtifactLocation(artSetPtr->getHero()->id, artPlace.slot), ArtifactLocation(artSetPtr->getHero()->id, ArtifactPosition::TRANSITION_POS));
+						{
+							assert(artSetPtr->getHero()->getSlotByInstance(art));
+							LOCPLINT->cb->swapArtifacts(ArtifactLocation(artSetPtr->getHero()->id, artSetPtr->getHero()->getSlotByInstance(art)),
+								ArtifactLocation(artSetPtr->getHero()->id, ArtifactPosition::TRANSITION_POS));
+						}
 					}
 					}
 					else
 					else
 					{
 					{

+ 1 - 0
lib/networkPacks/NetPackVisitor.h

@@ -131,6 +131,7 @@ public:
 	virtual void visitGarrisonHeroSwap(GarrisonHeroSwap & pack) {}
 	virtual void visitGarrisonHeroSwap(GarrisonHeroSwap & pack) {}
 	virtual void visitExchangeArtifacts(ExchangeArtifacts & pack) {}
 	virtual void visitExchangeArtifacts(ExchangeArtifacts & pack) {}
 	virtual void visitBulkExchangeArtifacts(BulkExchangeArtifacts & pack) {}
 	virtual void visitBulkExchangeArtifacts(BulkExchangeArtifacts & pack) {}
+	virtual void visitManageBackpackArtifacts(ManageBackpackArtifacts & pack) {}
 	virtual void visitAssembleArtifacts(AssembleArtifacts & pack) {}
 	virtual void visitAssembleArtifacts(AssembleArtifacts & pack) {}
 	virtual void visitEraseArtifactByClient(EraseArtifactByClient & pack) {}
 	virtual void visitEraseArtifactByClient(EraseArtifactByClient & pack) {}
 	virtual void visitBuyArtifact(BuyArtifact & pack) {}
 	virtual void visitBuyArtifact(BuyArtifact & pack) {}

+ 5 - 0
lib/networkPacks/NetPacksLib.cpp

@@ -608,6 +608,11 @@ void BulkExchangeArtifacts::visitTyped(ICPackVisitor & visitor)
 	visitor.visitBulkExchangeArtifacts(*this);
 	visitor.visitBulkExchangeArtifacts(*this);
 }
 }
 
 
+void ManageBackpackArtifacts::visitTyped(ICPackVisitor & visitor)
+{
+	visitor.visitManageBackpackArtifacts(*this);
+}
+
 void AssembleArtifacts::visitTyped(ICPackVisitor & visitor)
 void AssembleArtifacts::visitTyped(ICPackVisitor & visitor)
 {
 {
 	visitor.visitAssembleArtifacts(*this);
 	visitor.visitAssembleArtifacts(*this);

+ 27 - 0
lib/networkPacks/PacksForServer.h

@@ -401,6 +401,33 @@ struct DLL_LINKAGE BulkExchangeArtifacts : public CPackForServer
 	}
 	}
 };
 };
 
 
+struct DLL_LINKAGE ManageBackpackArtifacts : public CPackForServer
+{
+	enum class ManageCmd
+	{
+		SCROLL_LEFT, SCROLL_RIGHT, SORT_BY_SLOT, SORT_BY_CLASS, SORT_BY_COST
+	};
+	
+	ManageBackpackArtifacts() = default;
+	ManageBackpackArtifacts(const ObjectInstanceID & artHolder, const ManageCmd & cmd)
+		: artHolder(artHolder)
+		, cmd(cmd)
+	{
+	}
+
+	ObjectInstanceID artHolder;
+	ManageCmd cmd;
+
+	void visitTyped(ICPackVisitor & visitor) override;
+
+	template <typename Handler> void serialize(Handler & h)
+	{
+		h & static_cast<CPackForServer&>(*this);
+		h & artHolder;
+		h & cmd;
+	}
+};
+
 struct DLL_LINKAGE AssembleArtifacts : public CPackForServer
 struct DLL_LINKAGE AssembleArtifacts : public CPackForServer
 {
 {
 	AssembleArtifacts() = default;
 	AssembleArtifacts() = default;

+ 1 - 0
lib/registerTypes/RegisterTypesServerPacks.h

@@ -49,6 +49,7 @@ void registerTypesServerPacks(Serializer &s)
 	s.template registerType<CPackForServer, BulkSmartSplitStack>();
 	s.template registerType<CPackForServer, BulkSmartSplitStack>();
 	s.template registerType<CPackForServer, BulkMoveArmy>();
 	s.template registerType<CPackForServer, BulkMoveArmy>();
 	s.template registerType<CPackForServer, BulkExchangeArtifacts>();
 	s.template registerType<CPackForServer, BulkExchangeArtifacts>();
+	s.template registerType < CPackForServer, ManageBackpackArtifacts>();
 	s.template registerType<CPackForServer, EraseArtifactByClient>();
 	s.template registerType<CPackForServer, EraseArtifactByClient>();
 	s.template registerType<CPackForServer, GamePause>();
 	s.template registerType<CPackForServer, GamePause>();
 }
 }

+ 19 - 0
server/CGameHandler.cpp

@@ -2857,6 +2857,25 @@ bool CGameHandler::bulkMoveArtifacts(ObjectInstanceID srcId, ObjectInstanceID ds
 	return true;
 	return true;
 }
 }
 
 
+bool CGameHandler::scrollBackpackArtifacts(const ObjectInstanceID heroID, bool left)
+{
+	auto artSet = getArtSet(heroID);
+	COMPLAIN_RET_FALSE_IF(artSet == nullptr, "scrollBackpackArtifacts: wrong hero's ID");
+
+	BulkMoveArtifacts bma(heroID, heroID, false);
+
+	const auto backpackEnd = ArtifactPosition(ArtifactPosition::BACKPACK_START + artSet->artifactsInBackpack.size() - 1);
+	if(backpackEnd > ArtifactPosition::BACKPACK_START)
+	{
+		if(left)
+			bma.artsPack0.push_back(BulkMoveArtifacts::LinkedSlots(backpackEnd, ArtifactPosition::BACKPACK_START));
+		else
+			bma.artsPack0.push_back(BulkMoveArtifacts::LinkedSlots(ArtifactPosition::BACKPACK_START, backpackEnd));
+		sendAndApply(&bma);
+	}
+	return true;
+}
+
 /**
 /**
  * Assembles or disassembles a combination artifact.
  * Assembles or disassembles a combination artifact.
  * @param heroID ID of hero holding the artifact(s).
  * @param heroID ID of hero holding the artifact(s).

+ 1 - 0
server/CGameHandler.h

@@ -130,6 +130,7 @@ public:
 	void removeArtifact(const ArtifactLocation &al) override;
 	void removeArtifact(const ArtifactLocation &al) override;
 	bool moveArtifact(const ArtifactLocation & src, const ArtifactLocation & dst) override;
 	bool moveArtifact(const ArtifactLocation & src, const ArtifactLocation & dst) override;
 	bool bulkMoveArtifacts(ObjectInstanceID srcId, ObjectInstanceID dstId, bool swap, bool equipped, bool backpack);
 	bool bulkMoveArtifacts(ObjectInstanceID srcId, ObjectInstanceID dstId, bool swap, bool equipped, bool backpack);
+	bool scrollBackpackArtifacts(const ObjectInstanceID heroID, bool left);
 	bool eraseArtifactByClient(const ArtifactLocation & al);
 	bool eraseArtifactByClient(const ArtifactLocation & al);
 	void synchronizeArtifactHandlerLists();
 	void synchronizeArtifactHandlerLists();
 
 

+ 21 - 0
server/NetPacksServer.cpp

@@ -148,6 +148,27 @@ void ApplyGhNetPackVisitor::visitBulkExchangeArtifacts(BulkExchangeArtifacts & p
 	result = gh.bulkMoveArtifacts(pack.srcHero, pack.dstHero, pack.swap, pack.equipped, pack.backpack);
 	result = gh.bulkMoveArtifacts(pack.srcHero, pack.dstHero, pack.swap, pack.equipped, pack.backpack);
 }
 }
 
 
+void ApplyGhNetPackVisitor::visitManageBackpackArtifacts(ManageBackpackArtifacts & pack)
+{
+	if(gh.getPlayerRelations(pack.player, gh.getOwner(pack.artHolder)) != PlayerRelations::ENEMIES)
+	{
+		if(pack.cmd == ManageBackpackArtifacts::ManageCmd::SCROLL_LEFT)
+			result = gh.scrollBackpackArtifacts(pack.artHolder, true);
+		else if(pack.cmd == ManageBackpackArtifacts::ManageCmd::SCROLL_RIGHT)
+			result = gh.scrollBackpackArtifacts(pack.artHolder, false);
+		else
+		{
+			gh.throwIfWrongOwner(&pack, pack.artHolder);
+			if(pack.cmd == ManageBackpackArtifacts::ManageCmd::SORT_BY_CLASS)
+				result = true;
+			else if(pack.cmd == ManageBackpackArtifacts::ManageCmd::SORT_BY_COST)
+				result = true;
+			else if(pack.cmd == ManageBackpackArtifacts::ManageCmd::SORT_BY_SLOT)
+				result = true;
+		}
+	}
+}
+
 void ApplyGhNetPackVisitor::visitAssembleArtifacts(AssembleArtifacts & pack)
 void ApplyGhNetPackVisitor::visitAssembleArtifacts(AssembleArtifacts & pack)
 {
 {
 	gh.throwIfWrongOwner(&pack, pack.heroID);
 	gh.throwIfWrongOwner(&pack, pack.heroID);

+ 1 - 0
server/ServerNetPackVisitors.h

@@ -46,6 +46,7 @@ public:
 	void visitGarrisonHeroSwap(GarrisonHeroSwap & pack) override;
 	void visitGarrisonHeroSwap(GarrisonHeroSwap & pack) override;
 	void visitExchangeArtifacts(ExchangeArtifacts & pack) override;
 	void visitExchangeArtifacts(ExchangeArtifacts & pack) override;
 	void visitBulkExchangeArtifacts(BulkExchangeArtifacts & pack) override;
 	void visitBulkExchangeArtifacts(BulkExchangeArtifacts & pack) override;
+	void visitManageBackpackArtifacts(ManageBackpackArtifacts & pack) override;
 	void visitAssembleArtifacts(AssembleArtifacts & pack) override;
 	void visitAssembleArtifacts(AssembleArtifacts & pack) override;
 	void visitEraseArtifactByClient(EraseArtifactByClient & pack) override;
 	void visitEraseArtifactByClient(EraseArtifactByClient & pack) override;
 	void visitBuyArtifact(BuyArtifact & pack) override;
 	void visitBuyArtifact(BuyArtifact & pack) override;

+ 3 - 0
server/queries/MapQueries.cpp

@@ -128,6 +128,9 @@ bool CGarrisonDialogQuery::blocksPack(const CPack * pack) const
 	if(auto arts = dynamic_ptr_cast<BulkExchangeArtifacts>(pack))
 	if(auto arts = dynamic_ptr_cast<BulkExchangeArtifacts>(pack))
 		return !vstd::contains(ourIds, arts->srcHero) || !vstd::contains(ourIds, arts->dstHero);
 		return !vstd::contains(ourIds, arts->srcHero) || !vstd::contains(ourIds, arts->dstHero);
 
 
+	if(auto arts = dynamic_ptr_cast<ManageBackpackArtifacts>(pack))
+		return !vstd::contains(ourIds, arts->artHolder);
+
 	if(auto art = dynamic_ptr_cast<EraseArtifactByClient>(pack))
 	if(auto art = dynamic_ptr_cast<EraseArtifactByClient>(pack))
 	{
 	{
 		if(auto id = art->al.artHolder)
 		if(auto id = art->al.artHolder)