mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	artifacts swap optimization
This commit is contained in:
		| @@ -301,7 +301,7 @@ void ApplyClientNetPackVisitor::visitBulkMoveArtifacts(BulkMoveArtifacts & pack) | ||||
| 		{ | ||||
| 			auto srcLoc = ArtifactLocation(pack.srcArtHolder, slotToMove.srcPos); | ||||
| 			auto dstLoc = ArtifactLocation(pack.dstArtHolder, slotToMove.dstPos); | ||||
| 			MoveArtifact ma(&srcLoc, &dstLoc, false); | ||||
| 			MoveArtifact ma(&srcLoc, &dstLoc, pack.askAssemble); | ||||
| 			visitMoveArtifact(ma); | ||||
| 		} | ||||
| 	}; | ||||
|   | ||||
| @@ -31,6 +31,12 @@ struct ArtifactLocation | ||||
| 		, creature(std::nullopt) | ||||
| 	{ | ||||
| 	} | ||||
| 	ArtifactLocation(const ObjectInstanceID id, const std::optional<SlotID> creatureSlot) | ||||
| 		: artHolder(id) | ||||
| 		, slot(ArtifactPosition::PRE_FIRST) | ||||
| 		, creature(creatureSlot) | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler & h, const int version) | ||||
| 	{ | ||||
|   | ||||
| @@ -1837,13 +1837,13 @@ void BulkMoveArtifacts::applyGs(CGameState * gs) | ||||
| 			switch(operation) | ||||
| 			{ | ||||
| 			case EBulkArtsOp::BULK_MOVE: | ||||
| 				art->move(artSet, srcPos, *gs->getHero(dstArtHolder), slot.dstPos); | ||||
| 				art->move(artSet, srcPos, *gs->getArtSet(ArtifactLocation(dstArtHolder, dstCreature)), slot.dstPos); | ||||
| 				break; | ||||
| 			case EBulkArtsOp::BULK_REMOVE: | ||||
| 				art->removeFrom(artSet, srcPos); | ||||
| 				break; | ||||
| 			case EBulkArtsOp::BULK_PUT: | ||||
| 				art->putAt(*gs->getHero(srcArtHolder), slot.dstPos); | ||||
| 				art->putAt(*gs->getArtSet(ArtifactLocation(srcArtHolder, srcCreature)), slot.dstPos); | ||||
| 				break; | ||||
| 			default: | ||||
| 				break; | ||||
| @@ -1856,11 +1856,11 @@ void BulkMoveArtifacts::applyGs(CGameState * gs) | ||||
| 		} | ||||
| 	}; | ||||
| 	 | ||||
| 	auto * leftSet = gs->getArtSet(ArtifactLocation(srcArtHolder)); | ||||
| 	auto * leftSet = gs->getArtSet(ArtifactLocation(srcArtHolder, srcCreature)); | ||||
| 	if(swap) | ||||
| 	{ | ||||
| 		// Swap | ||||
| 		auto * rightSet = gs->getArtSet(ArtifactLocation(dstArtHolder)); | ||||
| 		auto * rightSet = gs->getArtSet(ArtifactLocation(dstArtHolder, dstCreature)); | ||||
| 		CArtifactFittingSet artFittingSet(leftSet->bearerType()); | ||||
|  | ||||
| 		artFittingSet.artifactsWorn = rightSet->artifactsWorn; | ||||
|   | ||||
| @@ -1064,17 +1064,25 @@ struct DLL_LINKAGE BulkMoveArtifacts : CArtifactOperationPack | ||||
|  | ||||
| 	ObjectInstanceID srcArtHolder; | ||||
| 	ObjectInstanceID dstArtHolder; | ||||
| 	std::optional<SlotID> srcCreature; | ||||
| 	std::optional<SlotID> dstCreature; | ||||
|  | ||||
| 	BulkMoveArtifacts() | ||||
| 		: srcArtHolder(ObjectInstanceID::NONE) | ||||
| 		, dstArtHolder(ObjectInstanceID::NONE) | ||||
| 		, swap(false) | ||||
| 		, askAssemble(false) | ||||
| 		, srcCreature(std::nullopt) | ||||
| 		, dstCreature(std::nullopt) | ||||
| 	{ | ||||
| 	} | ||||
| 	BulkMoveArtifacts(const ObjectInstanceID srcArtHolder, const ObjectInstanceID dstArtHolder, bool swap) | ||||
| 		: srcArtHolder(std::move(srcArtHolder)) | ||||
| 		, dstArtHolder(std::move(dstArtHolder)) | ||||
| 		, swap(swap) | ||||
| 		, askAssemble(false) | ||||
| 		, srcCreature(std::nullopt) | ||||
| 		, dstCreature(std::nullopt) | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| @@ -1083,6 +1091,7 @@ struct DLL_LINKAGE BulkMoveArtifacts : CArtifactOperationPack | ||||
| 	std::vector<LinkedSlots> artsPack0; | ||||
| 	std::vector<LinkedSlots> artsPack1; | ||||
| 	bool swap; | ||||
| 	bool askAssemble; | ||||
|  | ||||
| 	void visitTyped(ICPackVisitor & visitor) override; | ||||
|  | ||||
| @@ -1092,7 +1101,10 @@ struct DLL_LINKAGE BulkMoveArtifacts : CArtifactOperationPack | ||||
| 		h & artsPack1; | ||||
| 		h & srcArtHolder; | ||||
| 		h & dstArtHolder; | ||||
| 		h & srcCreature; | ||||
| 		h & dstCreature; | ||||
| 		h & swap; | ||||
| 		h & askAssemble; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -2667,19 +2667,18 @@ bool CGameHandler::garrisonSwap(ObjectInstanceID tid) | ||||
| // Function moves artifact from src to dst. If dst is not a backpack and is already occupied, old dst art goes to backpack and is replaced. | ||||
| bool CGameHandler::moveArtifact(const ArtifactLocation & src, const ArtifactLocation & dst) | ||||
| { | ||||
| 	ArtifactLocation srcLoc = src, dstLoc = dst; | ||||
| 	const auto srcArtSet = getArtSet(srcLoc); | ||||
| 	const auto dstArtSet = getArtSet(dstLoc); | ||||
| 	const auto srcArtSet = getArtSet(src); | ||||
| 	const auto dstArtSet = getArtSet(dst); | ||||
| 	assert(srcArtSet); | ||||
| 	assert(dstArtSet); | ||||
|  | ||||
| 	// Make sure exchange is even possible between the two heroes. | ||||
| 	if(!isAllowedExchange(srcLoc.artHolder, dstLoc.artHolder)) | ||||
| 	if(!isAllowedExchange(src.artHolder, dst.artHolder)) | ||||
| 		COMPLAIN_RET("That heroes cannot make any exchange!"); | ||||
|  | ||||
| 	const auto srcArtifact = srcArtSet->getArt(srcLoc.slot); | ||||
| 	const auto dstArtifact = dstArtSet->getArt(dstLoc.slot); | ||||
| 	const bool isDstSlotBackpack = dstArtSet->bearerType() == ArtBearer::HERO ? ArtifactUtils::isSlotBackpack(dstLoc.slot) : false; | ||||
| 	const auto srcArtifact = srcArtSet->getArt(src.slot); | ||||
| 	const auto dstArtifact = dstArtSet->getArt(dst.slot); | ||||
| 	const bool isDstSlotBackpack = dstArtSet->bearerType() == ArtBearer::HERO ? ArtifactUtils::isSlotBackpack(dst.slot) : false; | ||||
|  | ||||
| 	if(srcArtifact == nullptr) | ||||
| 		COMPLAIN_RET("No artifact to move!"); | ||||
| @@ -2688,55 +2687,54 @@ bool CGameHandler::moveArtifact(const ArtifactLocation & src, const ArtifactLoca | ||||
|  | ||||
| 	// Check if src/dest slots are appropriate for the artifacts exchanged. | ||||
| 	// Moving to the backpack is always allowed. | ||||
| 	if((!srcArtifact || !isDstSlotBackpack) && srcArtifact && !srcArtifact->canBePutAt(dstArtSet, dstLoc.slot, true)) | ||||
| 	if((!srcArtifact || !isDstSlotBackpack) && srcArtifact && !srcArtifact->canBePutAt(dstArtSet, dst.slot, true)) | ||||
| 		COMPLAIN_RET("Cannot move artifact!"); | ||||
|  | ||||
| 	auto srcSlotInfo = srcArtSet->getSlot(srcLoc.slot); | ||||
| 	auto dstSlotInfo = dstArtSet->getSlot(dstLoc.slot); | ||||
| 	auto srcSlotInfo = srcArtSet->getSlot(src.slot); | ||||
| 	auto dstSlotInfo = dstArtSet->getSlot(dst.slot); | ||||
|  | ||||
| 	if((srcSlotInfo && srcSlotInfo->locked) || (dstSlotInfo && dstSlotInfo->locked)) | ||||
| 		COMPLAIN_RET("Cannot move artifact locks."); | ||||
|  | ||||
| 	if(isDstSlotBackpack && srcArtifact->artType->isBig()) | ||||
| 		COMPLAIN_RET("Cannot put big artifacts in backpack!"); | ||||
| 	if(srcLoc.slot == ArtifactPosition::MACH4 || dstLoc.slot == ArtifactPosition::MACH4) | ||||
| 	if(src.slot == ArtifactPosition::MACH4 || dst.slot == ArtifactPosition::MACH4) | ||||
| 		COMPLAIN_RET("Cannot move catapult!"); | ||||
| 	if(isDstSlotBackpack && !ArtifactUtils::isBackpackFreeSlots(dstArtSet)) | ||||
| 		COMPLAIN_RET("Backpack is full!"); | ||||
|  | ||||
| 	if(isDstSlotBackpack) | ||||
| 	auto dstSlot = std::min(dst.slot, ArtifactPosition(ArtifactPosition::BACKPACK_START + dstArtSet->artifactsInBackpack.size())); | ||||
|  | ||||
| 	if(src.slot == dstSlot && src.artHolder == dst.artHolder) | ||||
| 		COMPLAIN_RET("Won't move artifact: Dest same as source!"); | ||||
| 	 | ||||
| 	BulkMoveArtifacts ma(src.artHolder, dst.artHolder, false); | ||||
| 	ma.srcCreature = src.creature; | ||||
| 	ma.dstCreature = dst.creature; | ||||
| 	 | ||||
| 	// Check if dst slot is occupied | ||||
| 	if(!isDstSlotBackpack && dstArtifact) | ||||
| 	{ | ||||
| 		if(!ArtifactUtils::isBackpackFreeSlots(dstArtSet)) | ||||
| 			COMPLAIN_RET("Backpack is full!"); | ||||
| 		vstd::amin(dstLoc.slot, ArtifactPosition::BACKPACK_START + dstArtSet->artifactsInBackpack.size()); | ||||
| 		// Previous artifact must be removed | ||||
| 		ma.artsPack1.push_back(BulkMoveArtifacts::LinkedSlots(dstSlot, src.slot)); | ||||
| 		ma.swap = true; | ||||
| 	} | ||||
|  | ||||
| 	if(!(srcLoc.slot == ArtifactPosition::TRANSITION_POS && dstLoc.slot == ArtifactPosition::TRANSITION_POS)) | ||||
| 	try | ||||
| 	{ | ||||
| 		if(srcLoc.slot == dstLoc.slot && srcLoc.artHolder == dstLoc.artHolder) | ||||
| 			COMPLAIN_RET("Won't move artifact: Dest same as source!"); | ||||
|  | ||||
| 		// Check if dst slot is occupied | ||||
| 		if(!isDstSlotBackpack && dstArtifact) | ||||
| 		{ | ||||
| 			// Previous artifact must be removed first | ||||
| 			moveArtifact(dstLoc, ArtifactLocation(dstLoc.artHolder, ArtifactPosition::TRANSITION_POS)); | ||||
| 		} | ||||
|  | ||||
| 		try | ||||
| 		{ | ||||
| 			auto hero = getHero(dst.artHolder); | ||||
| 			if(ArtifactUtils::checkSpellbookIsNeeded(hero, srcArtifact->artType->getId(), dstLoc.slot)) | ||||
| 				giveHeroNewArtifact(hero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK); | ||||
| 		} | ||||
| 		catch(const std::bad_variant_access &) | ||||
| 		{ | ||||
| 			// object other than hero received an art - ignore | ||||
| 		} | ||||
|  | ||||
| 		MoveArtifact ma(&srcLoc, &dstLoc); | ||||
| 		if(srcLoc.artHolder == dstLoc.artHolder) | ||||
| 			ma.askAssemble = false; | ||||
| 		sendAndApply(&ma); | ||||
| 		auto hero = getHero(dst.artHolder); | ||||
| 		if(ArtifactUtils::checkSpellbookIsNeeded(hero, srcArtifact->artType->getId(), dstSlot)) | ||||
| 			giveHeroNewArtifact(hero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK); | ||||
| 	} | ||||
| 	catch(const std::bad_variant_access &) | ||||
| 	{ | ||||
| 		// object other than hero received an art - ignore | ||||
| 	} | ||||
|  | ||||
| 	ma.artsPack0.push_back(BulkMoveArtifacts::LinkedSlots(src.slot, dstSlot)); | ||||
| 	if(src.artHolder != dst.artHolder) | ||||
| 		ma.askAssemble = true; | ||||
| 	sendAndApply(&ma); | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user