mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	ArtifactLocation now use ID for artHolder identification part2
This commit is contained in:
		| @@ -996,21 +996,21 @@ void AIGateway::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance | ||||
| 				for(auto p : h->artifactsWorn) | ||||
| 				{ | ||||
| 					if(p.second.artifact) | ||||
| 						allArtifacts.push_back(ArtifactLocation(h, p.first)); | ||||
| 						allArtifacts.push_back(ArtifactLocation(h->id, p.first)); | ||||
| 				} | ||||
| 			} | ||||
| 			for(auto slot : h->artifactsInBackpack) | ||||
| 				allArtifacts.push_back(ArtifactLocation(h, h->getArtPos(slot.artifact))); | ||||
| 				allArtifacts.push_back(ArtifactLocation(h->id, h->getArtPos(slot.artifact))); | ||||
|  | ||||
| 			if(otherh) | ||||
| 			{ | ||||
| 				for(auto p : otherh->artifactsWorn) | ||||
| 				{ | ||||
| 					if(p.second.artifact) | ||||
| 						allArtifacts.push_back(ArtifactLocation(otherh, p.first)); | ||||
| 						allArtifacts.push_back(ArtifactLocation(otherh->id, p.first)); | ||||
| 				} | ||||
| 				for(auto slot : otherh->artifactsInBackpack) | ||||
| 					allArtifacts.push_back(ArtifactLocation(otherh, otherh->getArtPos(slot.artifact))); | ||||
| 					allArtifacts.push_back(ArtifactLocation(otherh->id, otherh->getArtPos(slot.artifact))); | ||||
| 			} | ||||
| 			//we give stuff to one hero or another, depending on giveStuffToFirstHero | ||||
|  | ||||
| @@ -1022,13 +1022,13 @@ void AIGateway::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance | ||||
|  | ||||
| 			for(auto location : allArtifacts) | ||||
| 			{ | ||||
| 				if(location.relatedObj() == target && ArtifactUtils::isSlotEquipment(location.slot)) | ||||
| 				if(location.artHolder == target->id && ArtifactUtils::isSlotEquipment(location.slot)) | ||||
| 					continue; //don't reequip artifact we already wear | ||||
|  | ||||
| 				if(location.slot == ArtifactPosition::MACH4) // don't attempt to move catapult | ||||
| 					continue; | ||||
|  | ||||
| 				auto s = location.getSlot(); | ||||
| 				auto s = cb->getHero(location.artHolder)->getSlot(location.slot); | ||||
| 				if(!s || s->locked) //we can't move locks | ||||
| 					continue; | ||||
| 				auto artifact = s->artifact; | ||||
| @@ -1039,9 +1039,9 @@ void AIGateway::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance | ||||
| 				bool emptySlotFound = false; | ||||
| 				for(auto slot : artifact->artType->getPossibleSlots().at(target->bearerType())) | ||||
| 				{ | ||||
| 					ArtifactLocation destLocation(target, slot); | ||||
| 					if(target->isPositionFree(slot) && artifact->canBePutAt(destLocation, true)) //combined artifacts are not always allowed to move | ||||
| 					if(target->isPositionFree(slot) && artifact->canBePutAt(target, slot, true)) //combined artifacts are not always allowed to move | ||||
| 					{ | ||||
| 						ArtifactLocation destLocation(target->id, slot); | ||||
| 						cb->swapArtifacts(location, destLocation); //just put into empty slot | ||||
| 						emptySlotFound = true; | ||||
| 						changeMade = true; | ||||
| @@ -1055,11 +1055,11 @@ void AIGateway::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance | ||||
| 						auto otherSlot = target->getSlot(slot); | ||||
| 						if(otherSlot && otherSlot->artifact) //we need to exchange artifact for better one | ||||
| 						{ | ||||
| 							ArtifactLocation destLocation(target, slot); | ||||
| 							//if that artifact is better than what we have, pick it | ||||
| 							if(compareArtifacts(artifact, otherSlot->artifact) && artifact->canBePutAt(destLocation, true)) //combined artifacts are not always allowed to move | ||||
| 							if(compareArtifacts(artifact, otherSlot->artifact) && artifact->canBePutAt(target, slot, true)) //combined artifacts are not always allowed to move | ||||
| 							{ | ||||
| 								cb->swapArtifacts(location, ArtifactLocation(target, target->getArtPos(otherSlot->artifact))); | ||||
| 								ArtifactLocation destLocation(target->id, slot); | ||||
| 								cb->swapArtifacts(location, ArtifactLocation(target->id, target->getArtPos(otherSlot->artifact))); | ||||
| 								changeMade = true; | ||||
| 								break; | ||||
| 							} | ||||
|   | ||||
| @@ -1167,21 +1167,21 @@ void VCAI::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance * ot | ||||
| 				for(auto p : h->artifactsWorn) | ||||
| 				{ | ||||
| 					if(p.second.artifact) | ||||
| 						allArtifacts.push_back(ArtifactLocation(h, p.first)); | ||||
| 						allArtifacts.push_back(ArtifactLocation(h->id, p.first)); | ||||
| 				} | ||||
| 			} | ||||
| 			for(auto slot : h->artifactsInBackpack) | ||||
| 				allArtifacts.push_back(ArtifactLocation(h, h->getArtPos(slot.artifact))); | ||||
| 				allArtifacts.push_back(ArtifactLocation(h->id, h->getArtPos(slot.artifact))); | ||||
|  | ||||
| 			if(otherh) | ||||
| 			{ | ||||
| 				for(auto p : otherh->artifactsWorn) | ||||
| 				{ | ||||
| 					if(p.second.artifact) | ||||
| 						allArtifacts.push_back(ArtifactLocation(otherh, p.first)); | ||||
| 						allArtifacts.push_back(ArtifactLocation(otherh->id, p.first)); | ||||
| 				} | ||||
| 				for(auto slot : otherh->artifactsInBackpack) | ||||
| 					allArtifacts.push_back(ArtifactLocation(otherh, otherh->getArtPos(slot.artifact))); | ||||
| 					allArtifacts.push_back(ArtifactLocation(otherh->id, otherh->getArtPos(slot.artifact))); | ||||
| 			} | ||||
| 			//we give stuff to one hero or another, depending on giveStuffToFirstHero | ||||
|  | ||||
| @@ -1196,10 +1196,10 @@ void VCAI::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance * ot | ||||
| 				if(location.slot == ArtifactPosition::MACH4 || location.slot == ArtifactPosition::SPELLBOOK) | ||||
| 					continue; // don't attempt to move catapult and spellbook | ||||
|  | ||||
| 				if(location.relatedObj() == target && ArtifactUtils::isSlotEquipment(location.slot)) | ||||
| 				if(location.artHolder == target->id && ArtifactUtils::isSlotEquipment(location.slot)) | ||||
| 					continue; //don't reequip artifact we already wear | ||||
|  | ||||
| 				auto s = location.getSlot(); | ||||
| 				auto s = cb->getHero(location.artHolder)->getSlot(location.slot); | ||||
| 				if(!s || s->locked) //we can't move locks | ||||
| 					continue; | ||||
| 				auto artifact = s->artifact; | ||||
| @@ -1210,9 +1210,9 @@ void VCAI::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance * ot | ||||
| 				bool emptySlotFound = false; | ||||
| 				for(auto slot : artifact->artType->getPossibleSlots().at(target->bearerType())) | ||||
| 				{ | ||||
| 					ArtifactLocation destLocation(target, slot); | ||||
| 					if(target->isPositionFree(slot) && artifact->canBePutAt(destLocation, true)) //combined artifacts are not always allowed to move | ||||
| 					if(target->isPositionFree(slot) && artifact->canBePutAt(target, slot, true)) //combined artifacts are not always allowed to move | ||||
| 					{ | ||||
| 						ArtifactLocation destLocation(target->id, slot); | ||||
| 						cb->swapArtifacts(location, destLocation); //just put into empty slot | ||||
| 						emptySlotFound = true; | ||||
| 						changeMade = true; | ||||
| @@ -1226,11 +1226,11 @@ void VCAI::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance * ot | ||||
| 						auto otherSlot = target->getSlot(slot); | ||||
| 						if(otherSlot && otherSlot->artifact) //we need to exchange artifact for better one | ||||
| 						{ | ||||
| 							ArtifactLocation destLocation(target, slot); | ||||
| 							//if that artifact is better than what we have, pick it | ||||
| 							if(compareArtifacts(artifact, otherSlot->artifact) && artifact->canBePutAt(destLocation, true)) //combined artifacts are not always allowed to move | ||||
| 							if(compareArtifacts(artifact, otherSlot->artifact) && artifact->canBePutAt(target, slot, true)) //combined artifacts are not always allowed to move | ||||
| 							{ | ||||
| 								cb->swapArtifacts(location, ArtifactLocation(target, target->getArtPos(otherSlot->artifact))); | ||||
| 								ArtifactLocation destLocation(target->id, slot); | ||||
| 								cb->swapArtifacts(location, ArtifactLocation(target->id, target->getArtPos(otherSlot->artifact))); | ||||
| 								changeMade = true; | ||||
| 								break; | ||||
| 							} | ||||
|   | ||||
| @@ -1753,8 +1753,7 @@ void CPlayerInterface::requestReturningToMainMenu(bool won) | ||||
|  | ||||
| void CPlayerInterface::askToAssembleArtifact(const ArtifactLocation &al) | ||||
| { | ||||
| 	auto hero = std::visit(HeroObjectRetriever(), al.artHolder); | ||||
| 	if(hero) | ||||
| 	if(auto hero = cb->getHero(al.artHolder)) | ||||
| 	{ | ||||
| 		auto art = hero->getArt(al.slot); | ||||
| 		if(art == nullptr) | ||||
| @@ -1770,15 +1769,13 @@ void CPlayerInterface::askToAssembleArtifact(const ArtifactLocation &al) | ||||
| void CPlayerInterface::artifactPut(const ArtifactLocation &al) | ||||
| { | ||||
| 	EVENT_HANDLER_CALLED_BY_CLIENT; | ||||
| 	auto hero = std::visit(HeroObjectRetriever(), al.artHolder); | ||||
| 	adventureInt->onHeroChanged(hero); | ||||
| 	adventureInt->onHeroChanged(cb->getHero(al.artHolder)); | ||||
| } | ||||
|  | ||||
| void CPlayerInterface::artifactRemoved(const ArtifactLocation &al) | ||||
| { | ||||
| 	EVENT_HANDLER_CALLED_BY_CLIENT; | ||||
| 	auto hero = std::visit(HeroObjectRetriever(), al.artHolder); | ||||
| 	adventureInt->onHeroChanged(hero); | ||||
| 	adventureInt->onHeroChanged(cb->getHero(al.artHolder)); | ||||
|  | ||||
| 	for(auto artWin : GH.windows().findWindows<CArtifactHolder>()) | ||||
| 		artWin->artifactRemoved(al); | ||||
| @@ -1789,8 +1786,7 @@ void CPlayerInterface::artifactRemoved(const ArtifactLocation &al) | ||||
| void CPlayerInterface::artifactMoved(const ArtifactLocation &src, const ArtifactLocation &dst) | ||||
| { | ||||
| 	EVENT_HANDLER_CALLED_BY_CLIENT; | ||||
| 	auto hero = std::visit(HeroObjectRetriever(), dst.artHolder); | ||||
| 	adventureInt->onHeroChanged(hero); | ||||
| 	adventureInt->onHeroChanged(cb->getHero(dst.artHolder)); | ||||
|  | ||||
| 	bool redraw = true; | ||||
| 	// If a bulk transfer has arrived, then redrawing only the last art movement. | ||||
| @@ -1815,8 +1811,7 @@ void CPlayerInterface::bulkArtMovementStart(size_t numOfArts) | ||||
| void CPlayerInterface::artifactAssembled(const ArtifactLocation &al) | ||||
| { | ||||
| 	EVENT_HANDLER_CALLED_BY_CLIENT; | ||||
| 	auto hero = std::visit(HeroObjectRetriever(), al.artHolder); | ||||
| 	adventureInt->onHeroChanged(hero); | ||||
| 	adventureInt->onHeroChanged(cb->getHero(al.artHolder)); | ||||
|  | ||||
| 	for(auto artWin : GH.windows().findWindows<CArtifactHolder>()) | ||||
| 		artWin->artifactAssembled(al); | ||||
| @@ -1825,8 +1820,7 @@ void CPlayerInterface::artifactAssembled(const ArtifactLocation &al) | ||||
| void CPlayerInterface::artifactDisassembled(const ArtifactLocation &al) | ||||
| { | ||||
| 	EVENT_HANDLER_CALLED_BY_CLIENT; | ||||
| 	auto hero = std::visit(HeroObjectRetriever(), al.artHolder); | ||||
| 	adventureInt->onHeroChanged(hero); | ||||
| 	adventureInt->onHeroChanged(cb->getHero(al.artHolder)); | ||||
|  | ||||
| 	for(auto artWin : GH.windows().findWindows<CArtifactHolder>()) | ||||
| 		artWin->artifactDisassembled(al); | ||||
|   | ||||
| @@ -267,14 +267,14 @@ void ApplyClientNetPackVisitor::visitBulkSmartRebalanceStacks(BulkSmartRebalance | ||||
|  | ||||
| void ApplyClientNetPackVisitor::visitPutArtifact(PutArtifact & pack) | ||||
| { | ||||
| 	callInterfaceIfPresent(cl, pack.al.owningPlayer(), &IGameEventsReceiver::artifactPut, pack.al); | ||||
| 	callInterfaceIfPresent(cl, cl.getOwner(pack.al.artHolder), &IGameEventsReceiver::artifactPut, pack.al); | ||||
| 	if(pack.askAssemble) | ||||
| 		callInterfaceIfPresent(cl, pack.al.owningPlayer(), &IGameEventsReceiver::askToAssembleArtifact, pack.al); | ||||
| 		callInterfaceIfPresent(cl, cl.getOwner(pack.al.artHolder), &IGameEventsReceiver::askToAssembleArtifact, pack.al); | ||||
| } | ||||
|  | ||||
| void ApplyClientNetPackVisitor::visitEraseArtifact(EraseArtifact & pack) | ||||
| { | ||||
| 	callInterfaceIfPresent(cl, pack.al.owningPlayer(), &IGameEventsReceiver::artifactRemoved, pack.al); | ||||
| 	callInterfaceIfPresent(cl, cl.getOwner(pack.al.artHolder), &IGameEventsReceiver::artifactRemoved, pack.al); | ||||
| } | ||||
|  | ||||
| void ApplyClientNetPackVisitor::visitMoveArtifact(MoveArtifact & pack) | ||||
| @@ -286,16 +286,16 @@ void ApplyClientNetPackVisitor::visitMoveArtifact(MoveArtifact & pack) | ||||
| 			callInterfaceIfPresent(cl, player, &IGameEventsReceiver::askToAssembleArtifact, pack.dst); | ||||
| 	}; | ||||
|  | ||||
| 	moveArtifact(pack.src.owningPlayer()); | ||||
| 	if(pack.src.owningPlayer() != pack.dst.owningPlayer()) | ||||
| 		moveArtifact(pack.dst.owningPlayer()); | ||||
| 	moveArtifact(cl.getOwner(pack.src.artHolder)); | ||||
| 	if(cl.getOwner(pack.src.artHolder) != cl.getOwner(pack.dst.artHolder)) | ||||
| 		moveArtifact(cl.getOwner(pack.dst.artHolder)); | ||||
|  | ||||
| 	cl.invalidatePaths(); // hero might have equipped/unequipped Angel Wings | ||||
| } | ||||
|  | ||||
| void ApplyClientNetPackVisitor::visitBulkMoveArtifacts(BulkMoveArtifacts & pack) | ||||
| { | ||||
| 	auto applyMove = [this, &pack](std::vector<BulkMoveArtifacts::LinkedSlots> & artsPack) -> void | ||||
| 	/*auto applyMove = [this, &pack](std::vector<BulkMoveArtifacts::LinkedSlots> & artsPack) -> void | ||||
| 	{ | ||||
| 		for(auto & slotToMove : artsPack) | ||||
| 		{ | ||||
| @@ -316,19 +316,19 @@ void ApplyClientNetPackVisitor::visitBulkMoveArtifacts(BulkMoveArtifacts & pack) | ||||
|  | ||||
| 	applyMove(pack.artsPack0); | ||||
| 	if(pack.swap) | ||||
| 		applyMove(pack.artsPack1); | ||||
| 		applyMove(pack.artsPack1);*/ | ||||
| } | ||||
|  | ||||
| void ApplyClientNetPackVisitor::visitAssembledArtifact(AssembledArtifact & pack) | ||||
| { | ||||
| 	callInterfaceIfPresent(cl, pack.al.owningPlayer(), &IGameEventsReceiver::artifactAssembled, pack.al); | ||||
| 	callInterfaceIfPresent(cl, cl.getOwner(pack.al.artHolder), &IGameEventsReceiver::artifactAssembled, pack.al); | ||||
|  | ||||
| 	cl.invalidatePaths(); // hero might have equipped/unequipped Angel Wings | ||||
| } | ||||
|  | ||||
| void ApplyClientNetPackVisitor::visitDisassembledArtifact(DisassembledArtifact & pack) | ||||
| { | ||||
| 	callInterfaceIfPresent(cl, pack.al.owningPlayer(), &IGameEventsReceiver::artifactDisassembled, pack.al); | ||||
| 	callInterfaceIfPresent(cl, cl.getOwner(pack.al.artHolder), &IGameEventsReceiver::artifactDisassembled, pack.al); | ||||
|  | ||||
| 	cl.invalidatePaths(); // hero might have equipped/unequipped Angel Wings | ||||
| } | ||||
|   | ||||
| @@ -121,10 +121,10 @@ void CCommanderArtPlace::returnArtToHeroCallback() | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		ArtifactLocation src(commanderOwner->commander.get(), artifactPos); | ||||
| 		ArtifactLocation dst(commanderOwner, freeSlot); | ||||
| 		ArtifactLocation src(commanderOwner->id, artifactPos); | ||||
| 		ArtifactLocation dst(commanderOwner->id, freeSlot); | ||||
|  | ||||
| 		if(ourArt->canBePutAt(dst, true)) | ||||
| 		if(ourArt->canBePutAt(commanderOwner, freeSlot, true)) | ||||
| 		{ | ||||
| 			LOCPLINT->cb->swapArtifacts(src, dst); | ||||
| 			setArtifact(nullptr); | ||||
|   | ||||
| @@ -72,7 +72,7 @@ void CArtifactsOfHeroAltar::pickUpArtifact(CHeroArtPlace & artPlace) | ||||
| 		if(ArtifactUtils::isSlotBackpack(pickedArtFromSlot)) | ||||
| 			pickedArtFromSlot = curHero->getSlotByInstance(art); | ||||
| 		assert(pickedArtFromSlot != ArtifactPosition::PRE_FIRST); | ||||
| 		LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero, pickedArtFromSlot), ArtifactLocation(curHero, ArtifactPosition::TRANSITION_POS)); | ||||
| 		LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero->id, pickedArtFromSlot), ArtifactLocation(curHero->id, ArtifactPosition::TRANSITION_POS)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -89,7 +89,7 @@ void CArtifactsOfHeroAltar::pickedArtMoveToAltar(const ArtifactPosition & slot) | ||||
| 	if(ArtifactUtils::isSlotBackpack(slot) || ArtifactUtils::isSlotEquipment(slot) || slot == ArtifactPosition::TRANSITION_POS) | ||||
| 	{ | ||||
| 		assert(curHero->getSlot(slot)->getArt()); | ||||
| 		LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero, slot), ArtifactLocation(curHero, pickedArtFromSlot)); | ||||
| 		LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero->id, slot), ArtifactLocation(curHero->id, pickedArtFromSlot)); | ||||
| 		pickedArtFromSlot = ArtifactPosition::PRE_FIRST; | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -80,8 +80,8 @@ void CArtifactsOfHeroBackpack::swapArtifacts(const ArtifactLocation & srcLoc, co | ||||
|  | ||||
| void CArtifactsOfHeroBackpack::pickUpArtifact(CHeroArtPlace & artPlace) | ||||
| { | ||||
| 	LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero, artPlace.slot), | ||||
| 		ArtifactLocation(curHero, ArtifactPosition::TRANSITION_POS)); | ||||
| 	LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero->id, artPlace.slot), | ||||
| 		ArtifactLocation(curHero->id, ArtifactPosition::TRANSITION_POS)); | ||||
| } | ||||
|  | ||||
| void CArtifactsOfHeroBackpack::scrollBackpack(int offset) | ||||
|   | ||||
| @@ -39,11 +39,11 @@ void CArtifactsOfHeroBase::putBackPickedArtifact() | ||||
| 		auto slot = ArtifactUtils::getArtAnyPosition(curHero, curHero->artifactsTransitionPos.begin()->artifact->getTypeId()); | ||||
| 		if(slot == ArtifactPosition::PRE_FIRST) | ||||
| 		{ | ||||
| 			LOCPLINT->cb->eraseArtifactByClient(ArtifactLocation(curHero, ArtifactPosition::TRANSITION_POS)); | ||||
| 			LOCPLINT->cb->eraseArtifactByClient(ArtifactLocation(curHero->id, ArtifactPosition::TRANSITION_POS)); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero, ArtifactPosition::TRANSITION_POS), ArtifactLocation(curHero, slot)); | ||||
| 			LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero->id, ArtifactPosition::TRANSITION_POS), ArtifactLocation(curHero->id, slot)); | ||||
| 		} | ||||
| 	} | ||||
| 	if(putBackPickedArtCallback) | ||||
| @@ -178,7 +178,7 @@ void CArtifactsOfHeroBase::scrollBackpackForArtSet(int offset, const CArtifactSe | ||||
| void CArtifactsOfHeroBase::markPossibleSlots(const CArtifactInstance * art, bool assumeDestRemoved) | ||||
| { | ||||
| 	for(auto artPlace : artWorn) | ||||
| 		artPlace.second->selectSlot(art->artType->canBePutAt(curHero, artPlace.second->slot, assumeDestRemoved)); | ||||
| 		artPlace.second->selectSlot(art->canBePutAt(curHero, artPlace.second->slot, assumeDestRemoved)); | ||||
| } | ||||
|  | ||||
| void CArtifactsOfHeroBase::unmarkSlots() | ||||
|   | ||||
| @@ -13,6 +13,7 @@ | ||||
| #include "Buttons.h" | ||||
|  | ||||
| #include "../CPlayerInterface.h" | ||||
| #include "../../lib/mapObjects/CGHeroInstance.h" | ||||
|  | ||||
| #include "../../CCallback.h" | ||||
| #include "../../lib/networkPacks/ArtifactLocation.h" | ||||
| @@ -56,7 +57,7 @@ void CArtifactsOfHeroKingdom::swapArtifacts(const ArtifactLocation & srcLoc, con | ||||
|  | ||||
| void CArtifactsOfHeroKingdom::pickUpArtifact(CHeroArtPlace & artPlace) | ||||
| { | ||||
| 	LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero, artPlace.slot), | ||||
| 		ArtifactLocation(curHero, ArtifactPosition::TRANSITION_POS)); | ||||
| 	LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero->id, artPlace.slot), | ||||
| 		ArtifactLocation(curHero->id, ArtifactPosition::TRANSITION_POS)); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -11,6 +11,7 @@ | ||||
| #include "CArtifactsOfHeroMain.h" | ||||
|  | ||||
| #include "../CPlayerInterface.h" | ||||
| #include "../../lib/mapObjects/CGHeroInstance.h" | ||||
|  | ||||
| #include "../../CCallback.h" | ||||
| #include "../../lib/networkPacks/ArtifactLocation.h" | ||||
| @@ -36,6 +37,6 @@ void CArtifactsOfHeroMain::swapArtifacts(const ArtifactLocation & srcLoc, const | ||||
|  | ||||
| void CArtifactsOfHeroMain::pickUpArtifact(CHeroArtPlace & artPlace) | ||||
| { | ||||
| 	LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero, artPlace.slot), | ||||
| 		ArtifactLocation(curHero, ArtifactPosition::TRANSITION_POS)); | ||||
| 	LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero->id, artPlace.slot), | ||||
| 		ArtifactLocation(curHero->id, ArtifactPosition::TRANSITION_POS)); | ||||
| } | ||||
|   | ||||
| @@ -196,7 +196,7 @@ bool CGarrisonSlot::highlightOrDropArtifact() | ||||
| 			artSelected = true; | ||||
| 			if (myStack) // try dropping the artifact only if the slot isn't empty | ||||
| 			{ | ||||
| 				ArtifactLocation src(srcHero, ArtifactPosition::TRANSITION_POS); | ||||
| 				/*ArtifactLocation src(srcHero, ArtifactPosition::TRANSITION_POS); | ||||
| 				ArtifactLocation dst(myStack, ArtifactPosition::CREATURE_SLOT); | ||||
| 				if(pickedArtInst->canBePutAt(dst, true)) | ||||
| 				{	//equip clicked stack | ||||
| @@ -208,7 +208,7 @@ bool CGarrisonSlot::highlightOrDropArtifact() | ||||
| 							ArtifactUtils::getArtBackpackPosition(srcHero, dst.getArt()->getTypeId()))); | ||||
| 					} | ||||
| 					LOCPLINT->cb->swapArtifacts(src, dst); | ||||
| 				} | ||||
| 				}*/ | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -122,8 +122,8 @@ void CWindowWithArtifacts::leftClickArtPlaceHero(CArtifactsOfHeroBase & artsInst | ||||
|  | ||||
| 				if(pickedArtInst) | ||||
| 				{ | ||||
| 					auto srcLoc = ArtifactLocation(heroPickedArt, ArtifactPosition::TRANSITION_POS); | ||||
| 					auto dstLoc = ArtifactLocation(hero, artPlace.slot); | ||||
| 					auto srcLoc = ArtifactLocation(heroPickedArt->id, ArtifactPosition::TRANSITION_POS); | ||||
| 					auto dstLoc = ArtifactLocation(hero->id, artPlace.slot); | ||||
|  | ||||
| 					if(ArtifactUtils::isSlotBackpack(artPlace.slot)) | ||||
| 					{ | ||||
| @@ -141,7 +141,7 @@ void CWindowWithArtifacts::leftClickArtPlaceHero(CArtifactsOfHeroBase & artsInst | ||||
| 						} | ||||
| 					} | ||||
| 					// Check if artifact transfer is possible | ||||
| 					else if(pickedArtInst->canBePutAt(dstLoc, true) && (!artPlace.getArt() || hero->tempOwner == LOCPLINT->playerID)) | ||||
| 					else if(pickedArtInst->canBePutAt(hero, artPlace.slot, true) && (!artPlace.getArt() || hero->tempOwner == LOCPLINT->playerID)) | ||||
| 					{ | ||||
| 						isTransferAllowed = true; | ||||
| 					} | ||||
| @@ -270,7 +270,7 @@ void CWindowWithArtifacts::artifactMoved(const ArtifactLocation & srcLoc, const | ||||
| 	// we have a different artifact may look surprising... but it's valid. | ||||
|  | ||||
| 	auto pickedArtInst = std::get<const CArtifactInstance*>(curState.value()); | ||||
| 	assert(!pickedArtInst || destLoc.isHolder(std::get<const CGHeroInstance*>(curState.value()))); | ||||
| 	assert(!pickedArtInst || destLoc.artHolder == std::get<const CGHeroInstance*>(curState.value())->id); | ||||
|  | ||||
| 	auto artifactMovedBody = [this, withRedraw, &destLoc, &pickedArtInst](auto artSetWeak) -> void | ||||
| 	{ | ||||
| @@ -316,7 +316,7 @@ void CWindowWithArtifacts::artifactMoved(const ArtifactLocation & srcLoc, const | ||||
| 			} | ||||
|  | ||||
| 			// Make sure the status bar is updated so it does not display old text | ||||
| 			if(destLoc.getHolderArtSet() == hero) | ||||
| 			if(destLoc.artHolder == hero->id) | ||||
| 			{ | ||||
| 				if(auto artPlace = artSetPtr->getArtPlace(destLoc.slot)) | ||||
| 					artPlace->hover(true); | ||||
|   | ||||
| @@ -974,7 +974,7 @@ void CStackWindow::removeStackArtifact(ArtifactPosition pos) | ||||
| 	const auto slot = ArtifactUtils::getArtBackpackPosition(info->owner, art->getTypeId()); | ||||
| 	if(slot != ArtifactPosition::PRE_FIRST) | ||||
| 	{ | ||||
| 		LOCPLINT->cb->swapArtifacts(ArtifactLocation(info->stackNode, pos), ArtifactLocation(info->owner, slot)); | ||||
| 		//LOCPLINT->cb->swapArtifacts(ArtifactLocation(info->stackNode, pos), ArtifactLocation(info->owner->id, slot)); | ||||
| 		stackArtifactButton.reset(); | ||||
| 		stackArtifactHelp.reset(); | ||||
| 		stackArtifactIcon.reset(); | ||||
| @@ -982,3 +982,4 @@ void CStackWindow::removeStackArtifact(ArtifactPosition pos) | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -336,10 +336,10 @@ void CHeroWindow::commanderWindow() | ||||
| 		const auto freeSlot = ArtifactUtils::getArtAnyPosition(curHero->commander, pickedArtInst->getTypeId()); | ||||
| 		if(vstd::contains(ArtifactUtils::commanderSlots(), freeSlot)) // We don't want to put it in commander's backpack! | ||||
| 		{ | ||||
| 			ArtifactLocation src(hero, ArtifactPosition::TRANSITION_POS); | ||||
| 			ArtifactLocation dst(curHero->commander.get(), freeSlot); | ||||
|  | ||||
| 			if(pickedArtInst->canBePutAt(dst, true)) | ||||
| 			ArtifactLocation src(hero->id, ArtifactPosition::TRANSITION_POS); | ||||
| 			ArtifactLocation dst(curHero->id, freeSlot); | ||||
| 			// TODO add ->commander.get() !!! | ||||
| 			/*if(pickedArtInst->canBePutAt(dst, true)) | ||||
| 			{	//equip clicked stack | ||||
| 				if(dst.getArt()) | ||||
| 				{ | ||||
| @@ -347,7 +347,7 @@ void CHeroWindow::commanderWindow() | ||||
| 						ArtifactUtils::getArtBackpackPosition(hero, pickedArtInst->getTypeId()))); | ||||
| 				} | ||||
| 				LOCPLINT->cb->swapArtifacts(src, dst); | ||||
| 			} | ||||
| 			}*/ | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
|   | ||||
| @@ -191,8 +191,8 @@ void CTradeWindow::CTradeableItem::clickPressed(const Point & cursorPosition) | ||||
| 				const auto hero = aw->arts->getHero(); | ||||
| 				const auto slot = hero->getSlotByInstance(art); | ||||
| 				assert(slot != ArtifactPosition::PRE_FIRST); | ||||
| 				LOCPLINT->cb->swapArtifacts(ArtifactLocation(hero, slot), | ||||
| 					ArtifactLocation(hero, ArtifactPosition::TRANSITION_POS)); | ||||
| 				LOCPLINT->cb->swapArtifacts(ArtifactLocation(hero->id, slot), | ||||
| 					ArtifactLocation(hero->id, ArtifactPosition::TRANSITION_POS)); | ||||
| 				aw->arts->pickedArtFromSlot = slot; | ||||
| 				aw->arts->artifactsOnAltar.erase(art); | ||||
| 				setID(-1); | ||||
|   | ||||
| @@ -155,9 +155,9 @@ void CArtifactInstance::setId(ArtifactInstanceID id) | ||||
| 	this->id = id; | ||||
| } | ||||
|  | ||||
| bool CArtifactInstance::canBePutAt(const ArtifactLocation & al, bool assumeDestRemoved) const | ||||
| bool CArtifactInstance::canBePutAt(const CArtifactSet * artSet, ArtifactPosition slot, bool assumeDestRemoved) const | ||||
| { | ||||
| 	return artType->canBePutAt(al.getHolderArtSet(), al.slot, assumeDestRemoved); | ||||
| 	return artType->canBePutAt(artSet, slot, assumeDestRemoved); | ||||
| } | ||||
|  | ||||
| bool CArtifactInstance::isCombined() const | ||||
| @@ -165,15 +165,15 @@ bool CArtifactInstance::isCombined() const | ||||
| 	return artType->isCombined(); | ||||
| } | ||||
|  | ||||
| void CArtifactInstance::putAt(const ArtifactLocation & al) | ||||
| void CArtifactInstance::putAt(CArtifactSet & set, const ArtifactPosition slot) | ||||
| { | ||||
| 	auto placementMap = al.getHolderArtSet()->putArtifact(al.slot, this); | ||||
| 	auto placementMap = set.putArtifact(slot, this); | ||||
| 	addPlacementMap(placementMap); | ||||
| } | ||||
|  | ||||
| void CArtifactInstance::removeFrom(const ArtifactLocation & al) | ||||
| void CArtifactInstance::removeFrom(CArtifactSet & set, const ArtifactPosition slot) | ||||
| { | ||||
| 	al.getHolderArtSet()->removeArtifact(al.slot); | ||||
| 	set.removeArtifact(slot); | ||||
| 	for(auto & part : partsInfo) | ||||
| 	{ | ||||
| 		if(part.slot != ArtifactPosition::PRE_FIRST) | ||||
| @@ -181,10 +181,10 @@ void CArtifactInstance::removeFrom(const ArtifactLocation & al) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CArtifactInstance::move(const ArtifactLocation & src, const ArtifactLocation & dst) | ||||
| void CArtifactInstance::move(CArtifactSet & srcSet, const ArtifactPosition srcSlot, CArtifactSet & dstSet, const ArtifactPosition dstSlot) | ||||
| { | ||||
| 	removeFrom(src); | ||||
| 	putAt(dst); | ||||
| 	removeFrom(srcSet, srcSlot); | ||||
| 	putAt(dstSet, dstSlot); | ||||
| } | ||||
|  | ||||
| void CArtifactInstance::deserializationFix() | ||||
|   | ||||
| @@ -84,11 +84,12 @@ public: | ||||
| 	ArtifactInstanceID getId() const; | ||||
| 	void setId(ArtifactInstanceID id); | ||||
|  | ||||
| 	bool canBePutAt(const ArtifactLocation & al, bool assumeDestRemoved = false) const; | ||||
| 	bool canBePutAt(const CArtifactSet * artSet, ArtifactPosition slot = ArtifactPosition::FIRST_AVAILABLE, | ||||
| 		bool assumeDestRemoved = false) const; | ||||
| 	bool isCombined() const; | ||||
| 	void putAt(const ArtifactLocation & al); | ||||
| 	void removeFrom(const ArtifactLocation & al); | ||||
| 	void move(const ArtifactLocation & src, const ArtifactLocation & dst); | ||||
| 	void putAt(CArtifactSet & set, const ArtifactPosition slot); | ||||
| 	void removeFrom(CArtifactSet & set, const ArtifactPosition slot); | ||||
| 	void move(CArtifactSet & srcSet, const ArtifactPosition srcSlot, CArtifactSet & dstSet, const ArtifactPosition dstSlot); | ||||
| 	 | ||||
| 	void deserializationFix(); | ||||
| 	template <typename Handler> void serialize(Handler & h, const int version) | ||||
|   | ||||
| @@ -870,7 +870,7 @@ ArtBearer::ArtBearer CStackInstance::bearerType() const | ||||
| CStackInstance::ArtPlacementMap CStackInstance::putArtifact(ArtifactPosition pos, CArtifactInstance * art) | ||||
| { | ||||
| 	assert(!getArt(pos)); | ||||
| 	assert(art->artType->canBePutAt(this, pos)); | ||||
| 	assert(art->canBePutAt(this, pos)); | ||||
|  | ||||
| 	attachTo(*art); | ||||
| 	return CArtifactSet::putArtifact(pos, art); | ||||
|   | ||||
| @@ -2103,7 +2103,7 @@ bool CGameState::giveHeroArtifact(CGHeroInstance * h, const ArtifactID & aid) | ||||
| 	 auto slot = ArtifactUtils::getArtAnyPosition(h, aid); | ||||
| 	 if(ArtifactUtils::isSlotEquipment(slot) || ArtifactUtils::isSlotBackpack(slot)) | ||||
| 	 { | ||||
| 		 ai->putAt(ArtifactLocation(h, slot)); | ||||
| 		 ai->putAt(*h, slot); | ||||
| 		 return true; | ||||
| 	 } | ||||
| 	 else | ||||
|   | ||||
| @@ -134,9 +134,9 @@ void CGameStateCampaign::trimCrossoverHeroesParameters(std::vector<CampaignHeroR | ||||
|  | ||||
| 				bool takeable = travelOptions.artifactsKeptByHero.count(art->artType->getId()); | ||||
|  | ||||
| 				ArtifactLocation al(hero, artifactPosition); | ||||
| 				if(!takeable  &&  !al.getSlot()->locked)  //don't try removing locked artifacts -> it crashes #1719 | ||||
| 					al.removeArtifact(); | ||||
| 				ArtifactLocation al(hero->id, artifactPosition); | ||||
| 				if(!takeable && !hero->getSlot(al.slot)->locked)  //don't try removing locked artifacts -> it crashes #1719 | ||||
| 					hero->getArt(al.slot)->removeFrom(*hero, al.slot); | ||||
| 			}; | ||||
|  | ||||
| 			// process on copy - removal of artifact will invalidate container | ||||
| @@ -300,7 +300,7 @@ void CGameStateCampaign::giveCampaignBonusToHero(CGHeroInstance * hero) | ||||
| 			CArtifactInstance * scroll = ArtifactUtils::createScroll(SpellID(curBonus->info2)); | ||||
| 			const auto slot = ArtifactUtils::getArtAnyPosition(hero, scroll->getTypeId()); | ||||
| 			if(ArtifactUtils::isSlotEquipment(slot) || ArtifactUtils::isSlotBackpack(slot)) | ||||
| 				scroll->putAt(ArtifactLocation(hero, slot)); | ||||
| 				scroll->putAt(*hero, slot); | ||||
| 			else | ||||
| 				logGlobal->error("Cannot give starting scroll - no free slots!"); | ||||
| 			break; | ||||
|   | ||||
| @@ -1087,7 +1087,7 @@ std::string CGHeroInstance::getBiographyTextID() const | ||||
|  | ||||
| CGHeroInstance::ArtPlacementMap CGHeroInstance::putArtifact(ArtifactPosition pos, CArtifactInstance * art) | ||||
| { | ||||
| 	assert(art->artType->canBePutAt(this, pos)); | ||||
| 	assert(art->canBePutAt(this, pos)); | ||||
|  | ||||
| 	if(ArtifactUtils::isSlotEquipment(pos)) | ||||
| 		attachTo(*art); | ||||
| @@ -1130,7 +1130,7 @@ void CGHeroInstance::removeSpellbook() | ||||
|  | ||||
| 	if(hasSpellbook()) | ||||
| 	{ | ||||
| 		ArtifactLocation(this, ArtifactPosition(ArtifactPosition::SPELLBOOK)).removeArtifact(); | ||||
| 		getArt(ArtifactPosition::SPELLBOOK)->removeFrom(*this, ArtifactPosition::SPELLBOOK); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -144,7 +144,7 @@ void CQuest::completeQuest(IGameCallback * cb, const CGHeroInstance *h) const | ||||
| 	{ | ||||
| 		if(h->hasArt(elem)) | ||||
| 		{ | ||||
| 			cb->removeArtifact(ArtifactLocation(h, h->getArtPos(elem, false))); | ||||
| 			cb->removeArtifact(ArtifactLocation(h->id, h->getArtPos(elem, false))); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| @@ -153,7 +153,7 @@ void CQuest::completeQuest(IGameCallback * cb, const CGHeroInstance *h) const | ||||
| 			auto parts = assembly->getPartsInfo(); | ||||
|  | ||||
| 			// Remove the assembly | ||||
| 			cb->removeArtifact(ArtifactLocation(h, h->getArtPos(assembly))); | ||||
| 			cb->removeArtifact(ArtifactLocation(h->id, h->getArtPos(assembly))); | ||||
|  | ||||
| 			// Disassemble this backpack artifact | ||||
| 			for(const auto & ci : parts) | ||||
|   | ||||
| @@ -944,10 +944,9 @@ bool CMapLoaderH3M::loadArtifactToSlot(CGHeroInstance * hero, int slot) | ||||
| 	// He has Shackles of War (normally - MISC slot artifact) in LEFT_HAND slot set in editor | ||||
| 	// Artifact seems to be missing in game, so skip artifacts that don't fit target slot | ||||
| 	auto * artifact = ArtifactUtils::createArtifact(map, artifactID); | ||||
| 	auto dstLoc = ArtifactLocation(hero, ArtifactPosition(slot)); | ||||
| 	if(artifact->canBePutAt(dstLoc)) | ||||
| 	if(artifact->canBePutAt(hero, ArtifactPosition(slot))) | ||||
| 	{ | ||||
| 		artifact->putAt(dstLoc); | ||||
| 		artifact->putAt(*hero, ArtifactPosition(slot)); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
|   | ||||
| @@ -1574,67 +1574,6 @@ struct GetBase | ||||
| 	} | ||||
| }; | ||||
|  | ||||
|  | ||||
| void ArtifactLocation::removeArtifact() | ||||
| { | ||||
| 	CArtifactInstance *a = getArt(); | ||||
| 	assert(a); | ||||
| 	a->removeFrom(*this); | ||||
| } | ||||
|  | ||||
| const CArmedInstance * ArtifactLocation::relatedObj() const | ||||
| { | ||||
| 	return std::visit(ObjectRetriever(), artHolder); | ||||
| } | ||||
|  | ||||
| PlayerColor ArtifactLocation::owningPlayer() const | ||||
| { | ||||
| 	const auto * obj = relatedObj(); | ||||
| 	return obj ? obj->tempOwner : PlayerColor::NEUTRAL; | ||||
| } | ||||
|  | ||||
| CArtifactSet *ArtifactLocation::getHolderArtSet() | ||||
| { | ||||
| 	return std::visit(GetBase<CArtifactSet>(), artHolder); | ||||
| } | ||||
|  | ||||
| CBonusSystemNode *ArtifactLocation::getHolderNode() | ||||
| { | ||||
| 	return std::visit(GetBase<CBonusSystemNode>(), artHolder); | ||||
| } | ||||
|  | ||||
| const CArtifactInstance *ArtifactLocation::getArt() const | ||||
| { | ||||
| 	const auto * s = getSlot(); | ||||
| 	if(s) | ||||
| 		return s->getArt(); | ||||
| 	else | ||||
| 		return nullptr; | ||||
| } | ||||
|  | ||||
| CArtifactSet * ArtifactLocation::getHolderArtSet() const | ||||
| { | ||||
| 	auto * t = const_cast<ArtifactLocation *>(this); | ||||
| 	return t->getHolderArtSet(); | ||||
| } | ||||
|  | ||||
| const CBonusSystemNode * ArtifactLocation::getHolderNode() const | ||||
| { | ||||
| 	auto * t = const_cast<ArtifactLocation *>(this); | ||||
| 	return t->getHolderNode(); | ||||
| } | ||||
|  | ||||
| CArtifactInstance *ArtifactLocation::getArt() | ||||
| { | ||||
| 	const ArtifactLocation *t = this; | ||||
| 	return const_cast<CArtifactInstance*>(t->getArt()); | ||||
| } | ||||
|  | ||||
| const ArtSlotInfo *ArtifactLocation::getSlot() const | ||||
| { | ||||
| 	return getHolderArtSet()->getSlot(slot); | ||||
| } | ||||
|  | ||||
| void ChangeStackCount::applyGs(CGameState * gs) | ||||
| { | ||||
| 	auto * srcObj = gs->getArmyInstance(army); | ||||
| @@ -1709,41 +1648,43 @@ void RebalanceStacks::applyGs(CGameState * gs) | ||||
|  | ||||
| 	if(srcCount == count) //moving whole stack | ||||
| 	{ | ||||
| 		[[maybe_unused]] const CCreature *c = dst.army->getCreature(dst.slot); | ||||
| 		const auto c = dst.army->getCreature(dst.slot); | ||||
|  | ||||
| 		if(c) //stack at dest -> merge | ||||
| 		{ | ||||
| 			assert(c == srcType); | ||||
| 			auto alHere = ArtifactLocation (src.getStack(), ArtifactPosition::CREATURE_SLOT); | ||||
| 			auto alDest = ArtifactLocation (dst.getStack(), ArtifactPosition::CREATURE_SLOT); | ||||
| 			auto * artHere = alHere.getArt(); | ||||
| 			auto * artDest = alDest.getArt(); | ||||
| 			if (artHere) | ||||
| 			 | ||||
| 			const auto srcHero = dynamic_cast<CGHeroInstance*>(src.army.get()); | ||||
| 			const auto dstHero = dynamic_cast<CGHeroInstance*>(dst.army.get()); | ||||
| 			auto srcLoc = ArtifactLocation(srcHero->id, ArtifactPosition::CREATURE_SLOT); | ||||
| 			auto dstLoc = ArtifactLocation(dstHero->id, ArtifactPosition::CREATURE_SLOT); | ||||
| 			// TODO set creature id !!! | ||||
| 			/*if (auto artHere = srcLoc.getArt()) | ||||
| 			{ | ||||
| 				if (alDest.getArt()) | ||||
| 				if (dstLoc.getArt()) | ||||
| 				{ | ||||
| 					auto * hero = dynamic_cast<CGHeroInstance *>(src.army.get()); | ||||
| 					auto dstSlot = ArtifactUtils::getArtBackpackPosition(hero, alDest.getArt()->getTypeId()); | ||||
| 					if(hero && dstSlot != ArtifactPosition::PRE_FIRST) | ||||
| 					 | ||||
| 					auto dstSlot = ArtifactUtils::getArtBackpackPosition(srcHero, dstLoc.getArt()->getTypeId()); | ||||
| 					if(srcHero && dstSlot != ArtifactPosition::PRE_FIRST) | ||||
| 					{ | ||||
| 						artDest->move (alDest, ArtifactLocation (hero, dstSlot)); | ||||
| 						dstLoc.getArt()->move (dstLoc, ArtifactLocation (srcHero, dstSlot)); | ||||
| 					} | ||||
| 					//else - artifact cna be lost :/ | ||||
| 					else | ||||
| 					{ | ||||
| 						EraseArtifact ea; | ||||
| 						ea.al = alDest; | ||||
| 						ea.al = dstLoc; | ||||
| 						ea.applyGs(gs); | ||||
| 						logNetwork->warn("Cannot move artifact! No free slots"); | ||||
| 					} | ||||
| 					artHere->move (alHere, alDest); | ||||
| 					artHere->move (srcLoc, dstLoc); | ||||
| 					//TODO: choose from dialog | ||||
| 				} | ||||
| 				else //just move to the other slot before stack gets erased | ||||
| 				{ | ||||
| 					artHere->move (alHere, alDest); | ||||
| 					artHere->move (srcLoc, dstLoc); | ||||
| 				} | ||||
| 			} | ||||
| 			}*/ | ||||
| 			if (stackExp) | ||||
| 			{ | ||||
| 				ui64 totalExp = srcCount * src.army->getStackExperience(src.slot) + dst.army->getStackCount(dst.slot) * dst.army->getStackExperience(dst.slot); | ||||
| @@ -1811,53 +1752,57 @@ void BulkSmartRebalanceStacks::applyGs(CGameState * gs) | ||||
|  | ||||
| void PutArtifact::applyGs(CGameState *gs) | ||||
| { | ||||
| 	assert(art->canBePutAt(al)); | ||||
| 	// Ensure that artifact has been correctly added via NewArtifact pack | ||||
| 	assert(vstd::contains(gs->map->artInstances, art)); | ||||
| 	assert(!art->getParentNodes().empty()); | ||||
| 	art->putAt(al); | ||||
| 	auto hero = gs->getHero(al.artHolder); | ||||
| 	assert(hero); | ||||
| 	assert(art->canBePutAt(hero, al.slot)); | ||||
| 	art->putAt(*hero, al.slot); | ||||
| } | ||||
|  | ||||
| void EraseArtifact::applyGs(CGameState *gs) | ||||
| { | ||||
| 	const auto * slot = al.getSlot(); | ||||
| 	const auto hero = gs->getHero(al.artHolder); | ||||
| 	assert(hero); | ||||
| 	const auto slot = hero->getSlot(al.slot); | ||||
| 	if(slot->locked) | ||||
| 	{ | ||||
| 		logGlobal->debug("Erasing locked artifact: %s", slot->artifact->artType->getNameTranslated()); | ||||
| 		DisassembledArtifact dis; | ||||
| 		dis.al.artHolder = al.artHolder; | ||||
| 		auto * aset = al.getHolderArtSet(); | ||||
| 		#ifndef NDEBUG | ||||
| 		bool found = false; | ||||
| 		#endif | ||||
| 		for(auto& p : aset->artifactsWorn) | ||||
| 		 | ||||
| 		for(auto & slotInfo : hero->artifactsWorn) | ||||
| 		{ | ||||
| 			auto art = p.second.artifact; | ||||
| 			auto art = slotInfo.second.artifact; | ||||
| 			if(art->isCombined() && art->isPart(slot->artifact)) | ||||
| 			{ | ||||
| 				dis.al.slot = aset->getArtPos(art); | ||||
| 				#ifndef NDEBUG | ||||
| 				found = true; | ||||
| 				#endif | ||||
| 				dis.al.slot = hero->getArtPos(art); | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		assert(found && "Failed to determine the assembly this locked artifact belongs to"); | ||||
| 		logGlobal->debug("Found the corresponding assembly: %s", dis.al.getSlot()->artifact->artType->getNameTranslated()); | ||||
| 		assert((dis.al.slot != ArtifactPosition::PRE_FIRST) && "Failed to determine the assembly this locked artifact belongs to"); | ||||
| 		logGlobal->debug("Found the corresponding assembly: %s", hero->getArt(dis.al.slot)->artType->getNameTranslated()); | ||||
| 		dis.applyGs(gs); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		logGlobal->debug("Erasing artifact %s", slot->artifact->artType->getNameTranslated()); | ||||
| 	} | ||||
| 	al.removeArtifact(); | ||||
| 	auto art = hero->getArt(al.slot); | ||||
| 	assert(art); | ||||
| 	art->removeFrom(*hero, al.slot); | ||||
| } | ||||
|  | ||||
| void MoveArtifact::applyGs(CGameState * gs) | ||||
| { | ||||
| 	CArtifactInstance * art = src.getArt(); | ||||
| 	auto srcHero = gs->getHero(src.artHolder); | ||||
| 	auto dstHero = gs->getHero(dst.artHolder); | ||||
| 	assert(srcHero); | ||||
| 	assert(dstHero); | ||||
| 	auto art = srcHero->getArt(src.slot); | ||||
| 	assert(!ArtifactUtils::isSlotEquipment(dst.slot) || !dst.getArt()); | ||||
| 	art->move(src, dst); | ||||
| 	art->move(*srcHero, src.slot, *dstHero, dst.slot); | ||||
| } | ||||
|  | ||||
| void BulkMoveArtifacts::applyGs(CGameState * gs) | ||||
| @@ -1887,7 +1832,7 @@ void BulkMoveArtifacts::applyGs(CGameState * gs) | ||||
| 			assert(slotInfo); | ||||
| 			auto * art = const_cast<CArtifactInstance *>(slotInfo->getArt()); | ||||
| 			assert(art); | ||||
| 			switch(operation) | ||||
| 			/*switch(operation) | ||||
| 			{ | ||||
| 			case EBulkArtsOp::BULK_MOVE: | ||||
| 				const_cast<CArtifactInstance*>(art)->move( | ||||
| @@ -1901,7 +1846,7 @@ void BulkMoveArtifacts::applyGs(CGameState * gs) | ||||
| 				break; | ||||
| 			default: | ||||
| 				break; | ||||
| 			} | ||||
| 			}*/ | ||||
|  | ||||
| 			if(srcPos >= ArtifactPosition::BACKPACK_START) | ||||
| 			{ | ||||
| @@ -1932,15 +1877,16 @@ void BulkMoveArtifacts::applyGs(CGameState * gs) | ||||
|  | ||||
| void AssembledArtifact::applyGs(CGameState *gs) | ||||
| { | ||||
| 	CArtifactSet * artSet = al.getHolderArtSet(); | ||||
| 	const CArtifactInstance * transformedArt = al.getArt(); | ||||
| 	auto hero = gs->getHero(al.artHolder); | ||||
| 	assert(hero); | ||||
| 	const auto transformedArt = hero->getArt(al.slot); | ||||
| 	assert(transformedArt); | ||||
| 	assert(vstd::contains_if(ArtifactUtils::assemblyPossibilities(artSet, transformedArt->getTypeId()), [=](const CArtifact * art)->bool | ||||
| 	assert(vstd::contains_if(ArtifactUtils::assemblyPossibilities(hero, transformedArt->getTypeId()), [=](const CArtifact * art)->bool | ||||
| 		{ | ||||
| 			return art->getId() == builtArt->getId(); | ||||
| 		})); | ||||
|  | ||||
| 	const auto transformedArtSlot = artSet->getSlotByInstance(transformedArt); | ||||
| 	const auto transformedArtSlot = hero->getSlotByInstance(transformedArt); | ||||
| 	auto * combinedArt = new CArtifactInstance(builtArt); | ||||
| 	gs->map->addNewArtifactInstance(combinedArt); | ||||
|  | ||||
| @@ -1952,7 +1898,7 @@ void AssembledArtifact::applyGs(CGameState *gs) | ||||
| 		if(transformedArt->getTypeId() == constituent->getId()) | ||||
| 			slot = transformedArtSlot; | ||||
| 		else | ||||
| 			slot = artSet->getArtPos(constituent->getId(), false, false); | ||||
| 			slot = hero->getArtPos(constituent->getId(), false, false); | ||||
|  | ||||
| 		assert(slot != ArtifactPosition::PRE_FIRST); | ||||
| 		slotsInvolved.emplace_back(slot); | ||||
| @@ -1972,8 +1918,8 @@ void AssembledArtifact::applyGs(CGameState *gs) | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			if(!vstd::contains(combinedArt->artType->getPossibleSlots().at(artSet->bearerType()), al.slot) | ||||
| 				&& vstd::contains(combinedArt->artType->getPossibleSlots().at(artSet->bearerType()), slot)) | ||||
| 			if(!vstd::contains(combinedArt->artType->getPossibleSlots().at(hero->bearerType()), al.slot) | ||||
| 				&& vstd::contains(combinedArt->artType->getPossibleSlots().at(hero->bearerType()), slot)) | ||||
| 				al.slot = slot; | ||||
| 		} | ||||
| 		else | ||||
| @@ -1986,8 +1932,8 @@ void AssembledArtifact::applyGs(CGameState *gs) | ||||
| 	// Delete parts from hero | ||||
| 	for(const auto slot : slotsInvolved) | ||||
| 	{ | ||||
| 		const auto constituentInstance = artSet->getArt(slot); | ||||
| 		constituentInstance->removeFrom(ArtifactLocation(al.artHolder, slot)); | ||||
| 		const auto constituentInstance = hero->getArt(slot); | ||||
| 		constituentInstance->removeFrom(*hero, slot); | ||||
|  | ||||
| 		if(ArtifactUtils::isSlotEquipment(al.slot) && slot != al.slot) | ||||
| 			combinedArt->addPart(constituentInstance, slot); | ||||
| @@ -1996,25 +1942,26 @@ void AssembledArtifact::applyGs(CGameState *gs) | ||||
| 	} | ||||
|  | ||||
| 	// Put new combined artifacts | ||||
| 	combinedArt->putAt(al); | ||||
| 	combinedArt->putAt(*hero, al.slot); | ||||
| } | ||||
|  | ||||
| void DisassembledArtifact::applyGs(CGameState *gs) | ||||
| { | ||||
| 	auto * disassembled = al.getArt(); | ||||
| 	assert(disassembled); | ||||
| 	auto hero = gs->getHero(al.artHolder); | ||||
| 	assert(hero); | ||||
| 	auto disassembledArt = hero->getArt(al.slot); | ||||
| 	assert(disassembledArt); | ||||
|  | ||||
| 	auto parts = disassembled->getPartsInfo(); | ||||
| 	disassembled->removeFrom(al); | ||||
| 	auto parts = disassembledArt->getPartsInfo(); | ||||
| 	disassembledArt->removeFrom(*hero, al.slot); | ||||
| 	for(auto & part : parts) | ||||
| 	{ | ||||
| 		ArtifactLocation partLoc = al; | ||||
| 		// ArtifactPosition::PRE_FIRST is value of main part slot -> it'll replace combined artifact in its pos | ||||
| 		partLoc.slot = (ArtifactUtils::isSlotEquipment(part.slot) ? part.slot : al.slot); | ||||
| 		disassembled->detachFrom(*part.art); | ||||
| 		part.art->putAt(partLoc); | ||||
| 		auto slot = (ArtifactUtils::isSlotEquipment(part.slot) ? part.slot : al.slot); | ||||
| 		disassembledArt->detachFrom(*part.art); | ||||
| 		part.art->putAt(*hero, slot); | ||||
| 	} | ||||
| 	gs->map->eraseArtifactInstance(disassembled); | ||||
| 	gs->map->eraseArtifactInstance(disassembledArt); | ||||
| } | ||||
|  | ||||
| void HeroVisit::applyGs(CGameState *gs) | ||||
|   | ||||
| @@ -2270,7 +2270,7 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID, | ||||
| 				if(!t->visitingHero || !t->visitingHero->hasArt(ArtifactID::GRAIL)) | ||||
| 					COMPLAIN_RET("Cannot build this without grail!") | ||||
| 				else | ||||
| 					removeArtifact(ArtifactLocation(t->visitingHero, t->visitingHero->getArtPos(ArtifactID::GRAIL, false))); | ||||
| 					removeArtifact(ArtifactLocation(t->visitingHero->id, t->visitingHero->getArtPos(ArtifactID::GRAIL, false))); | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| @@ -2664,74 +2664,71 @@ bool CGameHandler::garrisonSwap(ObjectInstanceID tid) | ||||
|  | ||||
| // With the amount of changes done to the function, it's more like transferArtifacts. | ||||
| // 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 &al1, const ArtifactLocation &al2) | ||||
| bool CGameHandler::moveArtifact(const ArtifactLocation & src, const ArtifactLocation & dst) | ||||
| { | ||||
| 	ArtifactLocation src = al1, dst = al2; | ||||
| 	const PlayerColor srcPlayer = src.owningPlayer(), dstPlayer = dst.owningPlayer(); | ||||
| 	const CArmedInstance *srcObj = src.relatedObj(), *dstObj = dst.relatedObj(); | ||||
| 	const auto srcHero = getHero(src.artHolder), dstHero = getHero(dst.artHolder); | ||||
| 	ArtifactLocation srcLoc = src, dstLoc = dst; | ||||
|  | ||||
| 	// Make sure exchange is even possible between the two heroes. | ||||
| 	if(!isAllowedExchange(srcObj->id, dstObj->id)) | ||||
| 	if(!isAllowedExchange(srcLoc.artHolder, dstLoc.artHolder)) | ||||
| 		COMPLAIN_RET("That heroes cannot make any exchange!"); | ||||
|  | ||||
| 	const CArtifactInstance *srcArtifact = src.getArt(); | ||||
| 	const CArtifactInstance *destArtifact = dst.getArt(); | ||||
| 	const bool isDstSlotBackpack = ArtifactUtils::isSlotBackpack(dst.slot); | ||||
| 	const auto srcArtifact = srcHero->getArt(srcLoc.slot); | ||||
| 	const auto dstArtifact = dstHero->getArt(dstLoc.slot); | ||||
| 	const bool isDstSlotBackpack = ArtifactUtils::isSlotBackpack(dstLoc.slot); | ||||
|  | ||||
| 	if(srcArtifact == nullptr) | ||||
| 		COMPLAIN_RET("No artifact to move!"); | ||||
| 	if(destArtifact && srcPlayer != dstPlayer && !isDstSlotBackpack) | ||||
| 	if(dstArtifact && srcHero->getOwner() != dstHero->getOwner() && !isDstSlotBackpack) | ||||
| 		COMPLAIN_RET("Can't touch artifact on hero of another player!"); | ||||
|  | ||||
| 	// Check if src/dest slots are appropriate for the artifacts exchanged. | ||||
| 	// Moving to the backpack is always allowed. | ||||
| 	if((!srcArtifact || !isDstSlotBackpack) | ||||
| 		&& srcArtifact && !srcArtifact->canBePutAt(dst, true)) | ||||
| 	if((!srcArtifact || !isDstSlotBackpack) && srcArtifact && !srcArtifact->canBePutAt(dstHero, dstLoc.slot, true)) | ||||
| 		COMPLAIN_RET("Cannot move artifact!"); | ||||
|  | ||||
| 	auto srcSlot = src.getSlot(); | ||||
| 	auto dstSlot = dst.getSlot(); | ||||
| 	auto srcSlotInfo = srcHero->getSlot(srcLoc.slot); | ||||
| 	auto dstSlotInfo = dstHero->getSlot(dstLoc.slot); | ||||
|  | ||||
| 	if((srcSlot && srcSlot->locked) || (dstSlot && dstSlot->locked)) | ||||
| 	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(src.slot == ArtifactPosition::MACH4 || dst.slot == ArtifactPosition::MACH4) | ||||
| 	if(srcLoc.slot == ArtifactPosition::MACH4 || dstLoc.slot == ArtifactPosition::MACH4) | ||||
| 		COMPLAIN_RET("Cannot move catapult!"); | ||||
|  | ||||
| 	if(isDstSlotBackpack) | ||||
| 	{ | ||||
| 		if(!ArtifactUtils::isBackpackFreeSlots(dst.getHolderArtSet())) | ||||
| 		if(!ArtifactUtils::isBackpackFreeSlots(dstHero)) | ||||
| 			COMPLAIN_RET("Backpack is full!"); | ||||
| 		vstd::amin(dst.slot, ArtifactPosition::BACKPACK_START + dst.getHolderArtSet()->artifactsInBackpack.size()); | ||||
| 		vstd::amin(dstLoc.slot, ArtifactPosition::BACKPACK_START + dstHero->artifactsInBackpack.size()); | ||||
| 	} | ||||
|  | ||||
| 	if(!(src.slot == ArtifactPosition::TRANSITION_POS && dst.slot == ArtifactPosition::TRANSITION_POS)) | ||||
| 	if(!(srcLoc.slot == ArtifactPosition::TRANSITION_POS && dstLoc.slot == ArtifactPosition::TRANSITION_POS)) | ||||
| 	{ | ||||
| 		if(src.slot == dst.slot && src.artHolder == dst.artHolder) | ||||
| 		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 && destArtifact) | ||||
| 		if(!isDstSlotBackpack && dstArtifact) | ||||
| 		{ | ||||
| 			// Previous artifact must be removed first | ||||
| 			moveArtifact(dst, ArtifactLocation(dst.artHolder, ArtifactPosition::TRANSITION_POS)); | ||||
| 			moveArtifact(dstLoc, ArtifactLocation(dstLoc.artHolder, ArtifactPosition::TRANSITION_POS)); | ||||
| 		} | ||||
|  | ||||
| 		try | ||||
| 		{ | ||||
| 			auto hero = std::get<ConstTransitivePtr<CGHeroInstance>>(dst.artHolder); | ||||
| 			if(ArtifactUtils::checkSpellbookIsNeeded(hero, srcArtifact->artType->getId(), dst.slot)) | ||||
| 				giveHeroNewArtifact(hero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK); | ||||
| 			if(ArtifactUtils::checkSpellbookIsNeeded(dstHero, srcArtifact->artType->getId(), dstLoc.slot)) | ||||
| 				giveHeroNewArtifact(dstHero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK); | ||||
| 		} | ||||
| 		catch(const std::bad_variant_access &) | ||||
| 		{ | ||||
| 			// object other than hero received an art - ignore | ||||
| 		} | ||||
|  | ||||
| 		MoveArtifact ma(&src, &dst); | ||||
| 		if(src.artHolder == dst.artHolder) | ||||
| 		MoveArtifact ma(&srcLoc, &dstLoc); | ||||
| 		if(srcLoc.artHolder == dstLoc.artHolder) | ||||
| 			ma.askAssemble = false; | ||||
| 		sendAndApply(&ma); | ||||
| 	} | ||||
| @@ -2854,7 +2851,7 @@ bool CGameHandler::assembleArtifacts(ObjectInstanceID heroID, ArtifactPosition a | ||||
| 	if(!destArtifact) | ||||
| 		COMPLAIN_RET("assembleArtifacts: there is no such artifact instance!"); | ||||
|  | ||||
| 	const auto dstLoc = ArtifactLocation(hero, artifactSlot); | ||||
| 	const auto dstLoc = ArtifactLocation(hero->id, artifactSlot); | ||||
| 	if(assemble) | ||||
| 	{ | ||||
| 		CArtifact * combinedArt = VLC->arth->objects[assembleTo]; | ||||
| @@ -2864,8 +2861,8 @@ bool CGameHandler::assembleArtifacts(ObjectInstanceID heroID, ArtifactPosition a | ||||
| 		{ | ||||
| 			COMPLAIN_RET("assembleArtifacts: It's impossible to assemble requested artifact!"); | ||||
| 		} | ||||
| 		if(!destArtifact->canBePutAt(dstLoc) | ||||
| 			&& !destArtifact->canBePutAt(ArtifactLocation(hero, ArtifactPosition::BACKPACK_START))) | ||||
| 		if(!destArtifact->canBePutAt(hero, artifactSlot) | ||||
| 			&& !destArtifact->canBePutAt(hero, ArtifactPosition::BACKPACK_START)) | ||||
| 		{ | ||||
| 			COMPLAIN_RET("assembleArtifacts: It's impossible to give the artholder requested artifact!"); | ||||
| 		} | ||||
| @@ -2897,15 +2894,15 @@ bool CGameHandler::assembleArtifacts(ObjectInstanceID heroID, ArtifactPosition a | ||||
|  | ||||
| bool CGameHandler::eraseArtifactByClient(const ArtifactLocation & al) | ||||
| { | ||||
| 	const auto * hero = getHero(al.relatedObj()->id); | ||||
| 	const auto * hero = getHero(al.artHolder); | ||||
| 	if(hero == nullptr) | ||||
| 		COMPLAIN_RET("eraseArtifactByClient: wrong hero's ID"); | ||||
|  | ||||
| 	const auto * art = al.getArt(); | ||||
| 	const auto * art = hero->getArt(al.slot); | ||||
| 	if(art == nullptr) | ||||
| 		COMPLAIN_RET("Cannot remove artifact!"); | ||||
|  | ||||
| 	if(al.getArt()->artType->canBePutAt(hero) || al.slot != ArtifactPosition::TRANSITION_POS) | ||||
| 	if(art->canBePutAt(hero) || al.slot != ArtifactPosition::TRANSITION_POS) | ||||
| 		COMPLAIN_RET("Illegal artifact removal request"); | ||||
|  | ||||
| 	removeArtifact(al); | ||||
| @@ -3012,7 +3009,7 @@ bool CGameHandler::sellArtifact(const IMarket *m, const CGHeroInstance *h, Artif | ||||
| 	int resVal = 0, dump = 1; | ||||
| 	m->getOffer(art->artType->getId(), rid, dump, resVal, EMarketMode::ARTIFACT_RESOURCE); | ||||
|  | ||||
| 	removeArtifact(ArtifactLocation(h, h->getArtPos(art))); | ||||
| 	removeArtifact(ArtifactLocation(h->id, h->getArtPos(art))); | ||||
| 	giveResource(h->tempOwner, rid, resVal); | ||||
| 	return true; | ||||
| } | ||||
| @@ -3750,8 +3747,8 @@ bool CGameHandler::sacrificeArtifact(const IMarket * m, const CGHeroInstance * h | ||||
|  | ||||
| 	for(int i = 0; i < slot.size(); ++i) | ||||
| 	{ | ||||
| 		ArtifactLocation al(hero, slot[i]); | ||||
| 		const CArtifactInstance * a = al.getArt(); | ||||
| 		ArtifactLocation al(hero->id, slot[i]); | ||||
| 		const CArtifactInstance * a = hero->getArt(al.slot); | ||||
|  | ||||
| 		if(!a) | ||||
| 		{ | ||||
| @@ -3963,7 +3960,7 @@ bool CGameHandler::swapStacks(const StackLocation & sl1, const StackLocation & s | ||||
| bool CGameHandler::giveHeroArtifact(const CGHeroInstance * h, const CArtifactInstance * a, ArtifactPosition pos) | ||||
| { | ||||
| 	assert(a->artType); | ||||
| 	ArtifactLocation al(h, ArtifactPosition::PRE_FIRST); | ||||
| 	ArtifactLocation al(h->id, ArtifactPosition::PRE_FIRST); | ||||
|  | ||||
| 	if(pos == ArtifactPosition::FIRST_AVAILABLE) | ||||
| 	{ | ||||
| @@ -3978,7 +3975,7 @@ bool CGameHandler::giveHeroArtifact(const CGHeroInstance * h, const CArtifactIns | ||||
| 		al.slot = pos; | ||||
| 	} | ||||
|  | ||||
| 	if(a->canBePutAt(al)) | ||||
| 	if(a->canBePutAt(h, al.slot)) | ||||
| 		putArtifact(al, a); | ||||
| 	else | ||||
| 		return false; | ||||
|   | ||||
| @@ -130,7 +130,7 @@ public: | ||||
| 	bool giveHeroArtifact(const CGHeroInstance * h, const CArtifactInstance * a, ArtifactPosition pos) override; | ||||
| 	void putArtifact(const ArtifactLocation &al, const CArtifactInstance *a) override; | ||||
| 	void removeArtifact(const ArtifactLocation &al) override; | ||||
| 	bool moveArtifact(const ArtifactLocation & al1, const ArtifactLocation & al2) override; | ||||
| 	bool moveArtifact(const ArtifactLocation & src, const ArtifactLocation & dst) override; | ||||
| 	bool bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap, bool equipped, bool backpack); | ||||
| 	bool eraseArtifactByClient(const ArtifactLocation & al); | ||||
| 	void synchronizeArtifactHandlerLists(); | ||||
|   | ||||
| @@ -134,7 +134,7 @@ void ApplyGhNetPackVisitor::visitGarrisonHeroSwap(GarrisonHeroSwap & pack) | ||||
|  | ||||
| void ApplyGhNetPackVisitor::visitExchangeArtifacts(ExchangeArtifacts & pack) | ||||
| { | ||||
| 	gh.throwIfWrongPlayer(&pack, pack.src.owningPlayer()); //second hero can be ally | ||||
| 	gh.throwIfWrongPlayer(&pack, gh.getOwner(pack.src.artHolder)); //second hero can be ally | ||||
| 	result = gh.moveArtifact(pack.src, pack.dst); | ||||
| } | ||||
|  | ||||
| @@ -154,7 +154,7 @@ void ApplyGhNetPackVisitor::visitAssembleArtifacts(AssembleArtifacts & pack) | ||||
|  | ||||
| void ApplyGhNetPackVisitor::visitEraseArtifactByClient(EraseArtifactByClient & pack) | ||||
| { | ||||
| 	gh.throwIfWrongPlayer(&pack, pack.al.owningPlayer()); | ||||
| 	gh.throwIfWrongPlayer(&pack, gh.getOwner(pack.al.artHolder)); | ||||
| 	result = gh.eraseArtifactByClient(pack.al); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -79,7 +79,7 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CBattleInfoCallback & battle, | ||||
| 				logGlobal->debug("War machine has been destroyed"); | ||||
| 				auto hero = dynamic_ptr_cast<CGHeroInstance> (army); | ||||
| 				if (hero) | ||||
| 					removedWarMachines.push_back (ArtifactLocation(hero, hero->getArtPos(warMachine, true))); | ||||
| 					removedWarMachines.push_back (ArtifactLocation(hero->id, hero->getArtPos(warMachine, true))); | ||||
| 				else | ||||
| 					logGlobal->error("War machine in army without hero"); | ||||
| 			} | ||||
| @@ -339,7 +339,7 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle) | ||||
| 			if(slot != ArtifactPosition::PRE_FIRST) | ||||
| 			{ | ||||
| 				arts.push_back(art); | ||||
| 				ma->dst = ArtifactLocation(finishingBattle->winnerHero, slot); | ||||
| 				ma->dst = ArtifactLocation(finishingBattle->winnerHero->id, slot); | ||||
| 				if(ArtifactUtils::isSlotBackpack(slot)) | ||||
| 					ma->askAssemble = false; | ||||
| 				gameHandler->sendAndApply(ma); | ||||
| @@ -353,8 +353,8 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle) | ||||
| 			for (auto artSlot : artifactsWorn) | ||||
| 			{ | ||||
| 				MoveArtifact ma; | ||||
| 				ma.src = ArtifactLocation(finishingBattle->loserHero, artSlot.first); | ||||
| 				const CArtifactInstance * art =  ma.src.getArt(); | ||||
| 				ma.src = ArtifactLocation(finishingBattle->loserHero->id, artSlot.first); | ||||
| 				const CArtifactInstance * art = finishingBattle->loserHero->getArt(artSlot.first); | ||||
| 				if (art && !art->artType->isBig() && | ||||
| 					art->artType->getId() != ArtifactID::SPELLBOOK) | ||||
| 						// don't move war machines or locked arts (spellbook) | ||||
| @@ -366,9 +366,9 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle) | ||||
| 			{ | ||||
| 				//we assume that no big artifacts can be found | ||||
| 				MoveArtifact ma; | ||||
| 				ma.src = ArtifactLocation(finishingBattle->loserHero, | ||||
| 				ma.src = ArtifactLocation(finishingBattle->loserHero->id, | ||||
| 					ArtifactPosition(ArtifactPosition::BACKPACK_START + slotNumber)); //backpack automatically shifts arts to beginning | ||||
| 				const CArtifactInstance * art =  ma.src.getArt(); | ||||
| 				const CArtifactInstance * art = finishingBattle->loserHero->getArt(ArtifactPosition::BACKPACK_START + slotNumber); | ||||
| 				if (art->artType->getId() != ArtifactID::GRAIL) //grail may not be won | ||||
| 				{ | ||||
| 					sendMoveArtifact(art, &ma); | ||||
| @@ -380,12 +380,13 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle) | ||||
| 				for (auto artSlot : artifactsWorn) | ||||
| 				{ | ||||
| 					MoveArtifact ma; | ||||
| 					ma.src = ArtifactLocation(finishingBattle->loserHero->commander.get(), artSlot.first); | ||||
| 					const CArtifactInstance * art =  ma.src.getArt(); | ||||
| 					ma.src = ArtifactLocation(finishingBattle->loserHero->id, artSlot.first); | ||||
| 					// TODO add ->commander.get() !!! | ||||
| 					/*const CArtifactInstance* art = ma.src.getArt(); | ||||
| 					if (art && !art->artType->isBig()) | ||||
| 					{ | ||||
| 						sendMoveArtifact(art, &ma); | ||||
| 					} | ||||
| 					}*/ | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| @@ -395,16 +396,17 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle) | ||||
| 		for (auto armySlot : battle.battleGetArmyObject(loser)->stacks) | ||||
| 		{ | ||||
| 			auto artifactsWorn = armySlot.second->artifactsWorn; | ||||
| 			for (auto artSlot : artifactsWorn) | ||||
| 			/*for (auto artSlot : artifactsWorn) | ||||
| 			{ | ||||
| 				MoveArtifact ma; | ||||
| 				ma.src = ArtifactLocation(armySlot.second, artSlot.first); | ||||
| 				const CArtifactInstance * art =  ma.src.getArt(); | ||||
| 				const CArtifactInstance* art = ma.src.getArt(); | ||||
| 				if (art && !art->artType->isBig()) | ||||
| 				{ | ||||
| 					sendMoveArtifact(art, &ma); | ||||
| 				} | ||||
| 			} | ||||
| 				// TODO add stack !!! | ||||
| 			}*/ | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -127,12 +127,12 @@ bool CGarrisonDialogQuery::blocksPack(const CPack * pack) const | ||||
|  | ||||
| 	if(auto arts = dynamic_ptr_cast<ExchangeArtifacts>(pack)) | ||||
| 	{ | ||||
| 		if(auto id1 = std::visit(GetEngagedHeroIds(), arts->src.artHolder)) | ||||
| 			if(!vstd::contains(ourIds, *id1)) | ||||
| 		if(auto id1 = arts->src.artHolder) | ||||
| 			if(!vstd::contains(ourIds, id1)) | ||||
| 				return true; | ||||
|  | ||||
| 		if(auto id2 = std::visit(GetEngagedHeroIds(), arts->dst.artHolder)) | ||||
| 			if(!vstd::contains(ourIds, *id2)) | ||||
| 		if(auto id2 = arts->dst.artHolder) | ||||
| 			if(!vstd::contains(ourIds, id2)) | ||||
| 				return true; | ||||
| 		return false; | ||||
| 	} | ||||
| @@ -144,8 +144,8 @@ bool CGarrisonDialogQuery::blocksPack(const CPack * pack) const | ||||
|  | ||||
| 	if(auto art = dynamic_ptr_cast<EraseArtifactByClient>(pack)) | ||||
| 	{ | ||||
| 		if (auto id = std::visit(GetEngagedHeroIds(), art->al.artHolder)) | ||||
| 			return !vstd::contains(ourIds, *id); | ||||
| 		if(auto id = art->al.artHolder) | ||||
| 			return !vstd::contains(ourIds, id); | ||||
| 	} | ||||
|  | ||||
| 	if(auto dismiss = dynamic_ptr_cast<AssembleArtifacts>(pack)) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user