Selaa lähdekoodia

BulkEraseArtifacts network pack

SoundSSGood 1 vuosi sitten
vanhempi
sitoutus
e15ea4fc75

+ 1 - 1
client/ClientNetPackVisitors.h

@@ -47,7 +47,7 @@ public:
 	void visitBulkRebalanceStacks(BulkRebalanceStacks & pack) override;
 	void visitBulkSmartRebalanceStacks(BulkSmartRebalanceStacks & pack) override;
 	void visitPutArtifact(PutArtifact & pack) override;
-	void visitEraseArtifact(EraseArtifact & pack) override;
+	void visitEraseArtifact(BulkEraseArtifacts & pack) override;
 	void visitBulkMoveArtifacts(BulkMoveArtifacts & pack) override;
 	void visitAssembledArtifact(AssembledArtifact & pack) override;
 	void visitDisassembledArtifact(DisassembledArtifact & pack) override;

+ 3 - 2
client/NetPacksClient.cpp

@@ -290,9 +290,10 @@ void ApplyClientNetPackVisitor::visitPutArtifact(PutArtifact & pack)
 		callInterfaceIfPresent(cl, cl.getOwner(pack.al.artHolder), &IGameEventsReceiver::askToAssembleArtifact, pack.al);
 }
 
-void ApplyClientNetPackVisitor::visitEraseArtifact(EraseArtifact & pack)
+void ApplyClientNetPackVisitor::visitEraseArtifact(BulkEraseArtifacts & pack)
 {
-	callInterfaceIfPresent(cl, cl.getOwner(pack.al.artHolder), &IGameEventsReceiver::artifactRemoved, pack.al);
+	for(const auto & slotErase : pack.posPack)
+		callInterfaceIfPresent(cl, cl.getOwner(pack.artHolder), &IGameEventsReceiver::artifactRemoved, ArtifactLocation(pack.artHolder, slotErase));
 }
 
 void ApplyClientNetPackVisitor::visitBulkMoveArtifacts(BulkMoveArtifacts & pack)

+ 1 - 1
lib/IGameCallback.h

@@ -120,7 +120,7 @@ public:
 
 	virtual bool giveHeroNewArtifact(const CGHeroInstance * h, const CArtifact * artType, ArtifactPosition pos) = 0;
 	virtual bool putArtifact(const ArtifactLocation & al, const CArtifactInstance * art, std::optional<bool> askAssemble = std::nullopt) = 0;
-	virtual void removeArtifact(const ArtifactLocation &al) = 0;
+	virtual void removeArtifact(const ArtifactLocation& al) = 0;
 	virtual bool moveArtifact(const PlayerColor & player, const ArtifactLocation & al1, const ArtifactLocation & al2) = 0;
 
 	virtual void heroVisitCastle(const CGTownInstance * obj, const CGHeroInstance * hero)=0;

+ 1 - 1
lib/networkPacks/NetPackVisitor.h

@@ -78,7 +78,7 @@ public:
 	virtual void visitBulkRebalanceStacks(BulkRebalanceStacks & pack) {}
 	virtual void visitBulkSmartRebalanceStacks(BulkSmartRebalanceStacks & pack) {}
 	virtual void visitPutArtifact(PutArtifact & pack) {}
-	virtual void visitEraseArtifact(EraseArtifact & pack) {}
+	virtual void visitEraseArtifact(BulkEraseArtifacts & pack) {}
 	virtual void visitBulkMoveArtifacts(BulkMoveArtifacts & pack) {}
 	virtual void visitAssembledArtifact(AssembledArtifact & pack) {}
 	virtual void visitDisassembledArtifact(DisassembledArtifact & pack) {}

+ 38 - 28
lib/networkPacks/NetPacksLib.cpp

@@ -336,7 +336,7 @@ void PutArtifact::visitTyped(ICPackVisitor & visitor)
 	visitor.visitPutArtifact(*this);
 }
 
-void EraseArtifact::visitTyped(ICPackVisitor & visitor)
+void BulkEraseArtifacts::visitTyped(ICPackVisitor & visitor)
 {
 	visitor.visitEraseArtifact(*this);
 }
@@ -1611,9 +1611,10 @@ void RebalanceStacks::applyGs(CGameState *gs)
 					//else - artifact can be lost :/
 					else
 					{
-						EraseArtifact ea;
-						ea.al = ArtifactLocation(dstHero->id, ArtifactPosition::CREATURE_SLOT);
-						ea.al.creature = dst.slot;
+						BulkEraseArtifacts ea;
+						ea.artHolder = dstHero->id;
+						ea.posPack.emplace_back(ArtifactPosition::CREATURE_SLOT);
+						ea.creature = dst.slot;
 						ea.applyGs(gs);
 						logNetwork->warn("Cannot move artifact! No free slots");
 					}
@@ -1701,37 +1702,46 @@ void PutArtifact::applyGs(CGameState *gs)
 	art->putAt(*hero, al.slot);
 }
 
-void EraseArtifact::applyGs(CGameState *gs)
+void BulkEraseArtifacts::applyGs(CGameState *gs)
 {
-	const auto artSet = gs->getArtSet(al.artHolder);
+	const auto artSet = gs->getArtSet(artHolder);
 	assert(artSet);
-	const auto slot = artSet->getSlot(al.slot);
-	if(slot->locked)
-	{
-		logGlobal->debug("Erasing locked artifact: %s", slot->artifact->artType->getNameTranslated());
-		DisassembledArtifact dis;
-		dis.al.artHolder = al.artHolder;
-		
-		for(auto & slotInfo : artSet->artifactsWorn)
+
+	std::sort(posPack.begin(), posPack.end(), [](const ArtifactPosition & slot0, const ArtifactPosition & slot1) -> bool
+		{
+			return slot0.num > slot1.num;
+		});
+
+	for(const auto & slot : posPack)
+	{
+		const auto slotInfo = artSet->getSlot(slot);
+		if(slotInfo->locked)
 		{
-			auto art = slotInfo.second.artifact;
-			if(art->isCombined() && art->isPart(slot->artifact))
+			logGlobal->debug("Erasing locked artifact: %s", slotInfo->artifact->artType->getNameTranslated());
+			DisassembledArtifact dis;
+			dis.al.artHolder = artHolder;
+
+			for(auto & slotInfoWorn : artSet->artifactsWorn)
 			{
-				dis.al.slot = artSet->getArtPos(art);
-				break;
+				auto art = slotInfoWorn.second.artifact;
+				if(art->isCombined() && art->isPart(slotInfo->getArt()))
+				{
+					dis.al.slot = artSet->getArtPos(art);
+					break;
+				}
 			}
+			assert((dis.al.slot != ArtifactPosition::PRE_FIRST) && "Failed to determine the assembly this locked artifact belongs to");
+			logGlobal->debug("Found the corresponding assembly: %s", artSet->getArt(dis.al.slot)->artType->getNameTranslated());
+			dis.applyGs(gs);
 		}
-		assert((dis.al.slot != ArtifactPosition::PRE_FIRST) && "Failed to determine the assembly this locked artifact belongs to");
-		logGlobal->debug("Found the corresponding assembly: %s", artSet->getArt(dis.al.slot)->artType->getNameTranslated());
-		dis.applyGs(gs);
-	}
-	else
-	{
-		logGlobal->debug("Erasing artifact %s", slot->artifact->artType->getNameTranslated());
+		else
+		{
+			logGlobal->debug("Erasing artifact %s", slotInfo->artifact->artType->getNameTranslated());
+		}
+		auto art = artSet->getArt(slot);
+		assert(art);
+		art->removeFrom(*artSet, slot);
 	}
-	auto art = artSet->getArt(al.slot);
-	assert(art);
-	art->removeFrom(*artSet, al.slot);
 }
 
 void BulkMoveArtifacts::applyGs(CGameState *gs)

+ 7 - 3
lib/networkPacks/PacksForClient.h

@@ -998,16 +998,20 @@ struct DLL_LINKAGE NewArtifact : public CArtifactOperationPack
 	}
 };
 
-struct DLL_LINKAGE EraseArtifact : CArtifactOperationPack
+struct DLL_LINKAGE BulkEraseArtifacts : CArtifactOperationPack
 {
-	ArtifactLocation al;
+	ObjectInstanceID artHolder;
+	std::vector<ArtifactPosition> posPack;
+	std::optional<SlotID> creature;
 
 	void applyGs(CGameState * gs) override;
 	void visitTyped(ICPackVisitor & visitor) override;
 
 	template <typename Handler> void serialize(Handler & h)
 	{
-		h & al;
+		h & artHolder;
+		h & posPack;
+		h & creature;
 	}
 };
 

+ 1 - 1
lib/serializer/RegisterTypes.h

@@ -223,7 +223,7 @@ void registerTypes(Serializer &s)
 	s.template registerType<InsertNewStack>(166);
 	s.template registerType<RebalanceStacks>(167);
 	s.template registerType<PutArtifact>(169);
-	s.template registerType<EraseArtifact>(170);
+	s.template registerType<BulkEraseArtifacts>(170);
 	s.template registerType<AssembledArtifact>(171);
 	s.template registerType<DisassembledArtifact>(172);
 	s.template registerType<BulkMoveArtifacts>(173);

+ 13 - 5
server/CGameHandler.cpp

@@ -1189,10 +1189,16 @@ void CGameHandler::stopHeroVisitCastle(const CGTownInstance * obj, const CGHeroI
 	sendAndApply(&vc);
 }
 
-void CGameHandler::removeArtifact(const ArtifactLocation &al)
+void CGameHandler::removeArtifact(const ArtifactLocation & al)
 {
-	EraseArtifact ea;
-	ea.al = al;
+	removeArtifact(al.artHolder, {al.slot});
+}
+
+void CGameHandler::removeArtifact(const ObjectInstanceID & srcId, const std::vector<ArtifactPosition> & slotsPack)
+{
+	BulkEraseArtifacts ea;
+	ea.artHolder = srcId;
+	ea.posPack.insert(ea.posPack.end(), slotsPack.begin(), slotsPack.end());
 	sendAndApply(&ea);
 }
 
@@ -3491,8 +3497,10 @@ bool CGameHandler::sacrificeArtifact(const IMarket * market, const CGHeroInstanc
 	const auto artSet = market->getArtifactsStorage();
 
 	int expSum = 0;
-	auto finish = [this, &hero, &expSum]()
+	std::vector<ArtifactPosition> artPack;
+	auto finish = [this, &hero, &expSum, &artPack, market]()
 	{
+		removeArtifact(market->getObjInstanceID(), artPack);
 		giveExperience(hero, hero->calculateXp(expSum));
 	};
 
@@ -3506,7 +3514,7 @@ bool CGameHandler::sacrificeArtifact(const IMarket * market, const CGHeroInstanc
 				int expToGive;
 				market->getOffer(art->getTypeId(), 0, dmp, expToGive, EMarketMode::ARTIFACT_EXP);
 				expSum += expToGive;
-				removeArtifact(ArtifactLocation(market->getObjInstanceID(), artSet->getArtPos(art)));
+				artPack.push_back(artSet->getArtPos(art));
 			}
 			else
 			{

+ 1 - 0
server/CGameHandler.h

@@ -136,6 +136,7 @@ public:
 	bool giveHeroNewArtifact(const CGHeroInstance * h, const CArtifact * artType, ArtifactPosition pos = ArtifactPosition::FIRST_AVAILABLE) override;
 	bool putArtifact(const ArtifactLocation & al, const CArtifactInstance * art, std::optional<bool> askAssemble) override;
 	void removeArtifact(const ArtifactLocation &al) override;
+	void removeArtifact(const ObjectInstanceID & srcId, const std::vector<ArtifactPosition> & slotsPack);
 	bool moveArtifact(const PlayerColor & player, const ArtifactLocation & src, const ArtifactLocation & dst) override;
 	bool bulkMoveArtifacts(const PlayerColor & player, ObjectInstanceID srcId, ObjectInstanceID dstId, bool swap, bool equipped, bool backpack);
 	bool scrollBackpackArtifacts(const PlayerColor & player, const ObjectInstanceID heroID, bool left);