mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	CArtifactSet cleanup
This commit is contained in:
		| @@ -743,7 +743,7 @@ void BattleWindow::bSpellf() | |||||||
| 			const auto artID = blockingBonus->sid.as<ArtifactID>(); | 			const auto artID = blockingBonus->sid.as<ArtifactID>(); | ||||||
| 			//If we have artifact, put name of our hero. Otherwise assume it's the enemy. | 			//If we have artifact, put name of our hero. Otherwise assume it's the enemy. | ||||||
| 			//TODO check who *really* is source of bonus | 			//TODO check who *really* is source of bonus | ||||||
| 			std::string heroName = myHero->hasArt(artID) ? myHero->getNameTranslated() : owner.enemyHero().name; | 			std::string heroName = myHero->hasArt(artID, true) ? myHero->getNameTranslated() : owner.enemyHero().name; | ||||||
|  |  | ||||||
| 			//%s wields the %s, an ancient artifact which creates a p dead to all magic. | 			//%s wields the %s, an ancient artifact which creates a p dead to all magic. | ||||||
| 			LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[683]) | 			LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[683]) | ||||||
|   | |||||||
| @@ -271,7 +271,7 @@ void CArtifactsOfHeroBase::setSlotData(ArtPlacePtr artPlace, const ArtifactPosit | |||||||
| 			arts.try_emplace(combinedArt->getId(), std::vector<ArtifactID>{}); | 			arts.try_emplace(combinedArt->getId(), std::vector<ArtifactID>{}); | ||||||
| 			for(const auto part : combinedArt->getConstituents()) | 			for(const auto part : combinedArt->getConstituents()) | ||||||
| 			{ | 			{ | ||||||
| 				if(curHero->hasArt(part->getId(), false, false, false)) | 				if(curHero->hasArt(part->getId(), false, false)) | ||||||
| 					arts.at(combinedArt->getId()).emplace_back(part->getId()); | 					arts.at(combinedArt->getId()).emplace_back(part->getId()); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -209,7 +209,7 @@ DLL_LINKAGE std::vector<const CArtifact*> ArtifactUtils::assemblyPossibilities( | |||||||
|  |  | ||||||
| 		for(const auto constituent : artifact->getConstituents()) //check if all constituents are available | 		for(const auto constituent : artifact->getConstituents()) //check if all constituents are available | ||||||
| 		{ | 		{ | ||||||
| 			if(!artSet->hasArt(constituent->getId(), onlyEquiped, false, false)) | 			if(!artSet->hasArt(constituent->getId(), onlyEquiped, false)) | ||||||
| 			{ | 			{ | ||||||
| 				possible = false; | 				possible = false; | ||||||
| 				break; | 				break; | ||||||
|   | |||||||
| @@ -220,7 +220,7 @@ bool CArtifact::canBePutAt(const CArtifactSet * artSet, ArtifactPosition slot, b | |||||||
| 				auto possibleSlot = ArtifactUtils::getArtAnyPosition(&fittingSet, art->getId()); | 				auto possibleSlot = ArtifactUtils::getArtAnyPosition(&fittingSet, art->getId()); | ||||||
| 				if(ArtifactUtils::isSlotEquipment(possibleSlot)) | 				if(ArtifactUtils::isSlotEquipment(possibleSlot)) | ||||||
| 				{ | 				{ | ||||||
| 					fittingSet.setNewArtSlot(possibleSlot, nullptr, true); | 					fittingSet.lockSlot(possibleSlot); | ||||||
| 				} | 				} | ||||||
| 				else | 				else | ||||||
| 				{ | 				{ | ||||||
| @@ -691,9 +691,7 @@ void CArtHandler::afterLoadFinalization() | |||||||
| 	CBonusSystemNode::treeHasChanged(); | 	CBonusSystemNode::treeHasChanged(); | ||||||
| } | } | ||||||
|  |  | ||||||
| CArtifactSet::~CArtifactSet() = default; | CArtifactInstance * CArtifactSet::getArt(const ArtifactPosition & pos, bool excludeLocked) const | ||||||
|  |  | ||||||
| const CArtifactInstance * CArtifactSet::getArt(const ArtifactPosition & pos, bool excludeLocked) const |  | ||||||
| { | { | ||||||
| 	if(const ArtSlotInfo * si = getSlot(pos)) | 	if(const ArtSlotInfo * si = getSlot(pos)) | ||||||
| 	{ | 	{ | ||||||
| @@ -704,56 +702,34 @@ const CArtifactInstance * CArtifactSet::getArt(const ArtifactPosition & pos, boo | |||||||
| 	return nullptr; | 	return nullptr; | ||||||
| } | } | ||||||
|  |  | ||||||
| CArtifactInstance * CArtifactSet::getArt(const ArtifactPosition & pos, bool excludeLocked) |  | ||||||
| { |  | ||||||
| 	return const_cast<CArtifactInstance*>((const_cast<const CArtifactSet*>(this))->getArt(pos, excludeLocked)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| ArtifactPosition CArtifactSet::getArtPos(const ArtifactID & aid, bool onlyWorn, bool allowLocked) const | ArtifactPosition CArtifactSet::getArtPos(const ArtifactID & aid, bool onlyWorn, bool allowLocked) const | ||||||
| { | { | ||||||
| 	const auto result = getAllArtPositions(aid, onlyWorn, allowLocked, false); | 	for(const auto & [slot, slotInfo] : artifactsWorn) | ||||||
| 	return result.empty() ? ArtifactPosition{ArtifactPosition::PRE_FIRST} : result[0]; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| std::vector<ArtifactPosition> CArtifactSet::getAllArtPositions(const ArtifactID & aid, bool onlyWorn, bool allowLocked, bool getAll) const |  | ||||||
| { |  | ||||||
| 	std::vector<ArtifactPosition> result; |  | ||||||
| 	for(const auto & slotInfo : artifactsWorn) |  | ||||||
| 		if(slotInfo.second.artifact->getTypeId() == aid && (allowLocked || !slotInfo.second.locked)) |  | ||||||
| 			result.push_back(slotInfo.first); |  | ||||||
|  |  | ||||||
| 	if(onlyWorn) |  | ||||||
| 		return result; |  | ||||||
| 	if(!getAll && !result.empty()) |  | ||||||
| 		return result; |  | ||||||
|  |  | ||||||
| 	auto backpackPositions = getBackpackArtPositions(aid); |  | ||||||
| 	result.insert(result.end(), backpackPositions.begin(), backpackPositions.end()); |  | ||||||
| 	return result; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| std::vector<ArtifactPosition> CArtifactSet::getBackpackArtPositions(const ArtifactID & aid) const |  | ||||||
| { |  | ||||||
| 	std::vector<ArtifactPosition> result; |  | ||||||
|  |  | ||||||
| 	si32 backpackPosition = ArtifactPosition::BACKPACK_START; |  | ||||||
| 	for(const auto & artInfo : artifactsInBackpack) |  | ||||||
| 	{ | 	{ | ||||||
| 		const auto * art = artInfo.getArt(); | 		if(slotInfo.artifact->getTypeId() == aid && (allowLocked || !slotInfo.locked)) | ||||||
| 		if(art && art->artType->getId() == aid) | 			return slot; | ||||||
| 			result.emplace_back(backpackPosition); |  | ||||||
| 		backpackPosition++; |  | ||||||
| 	} | 	} | ||||||
| 	return result; | 	if(!onlyWorn) | ||||||
|  | 	{ | ||||||
|  | 		size_t backpackPositionIdx = ArtifactPosition::BACKPACK_START; | ||||||
|  | 		for(const auto & artInfo : artifactsInBackpack) | ||||||
|  | 		{ | ||||||
|  | 			const auto art = artInfo.getArt(); | ||||||
|  | 			if(art && art->artType->getId() == aid) | ||||||
|  | 				return ArtifactPosition(backpackPositionIdx); | ||||||
|  | 			backpackPositionIdx++; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return ArtifactPosition::PRE_FIRST; | ||||||
| } | } | ||||||
|  |  | ||||||
| const CArtifactInstance * CArtifactSet::getArtByInstanceId(const ArtifactInstanceID & artInstId) const | const CArtifactInstance * CArtifactSet::getArtByInstanceId(const ArtifactInstanceID & artInstId) const | ||||||
| { | { | ||||||
| 	for(auto i : artifactsWorn) | 	for(const auto & i : artifactsWorn) | ||||||
| 		if(i.second.artifact->getId() == artInstId) | 		if(i.second.artifact->getId() == artInstId) | ||||||
| 			return i.second.artifact; | 			return i.second.artifact; | ||||||
|  |  | ||||||
| 	for(auto i : artifactsInBackpack) | 	for(const auto & i : artifactsInBackpack) | ||||||
| 		if(i.artifact->getId() == artInstId) | 		if(i.artifact->getId() == artInstId) | ||||||
| 			return i.artifact; | 			return i.artifact; | ||||||
|  |  | ||||||
| @@ -779,29 +755,16 @@ ArtifactPosition CArtifactSet::getArtPos(const CArtifactInstance * artInst) cons | |||||||
| 	return ArtifactPosition::PRE_FIRST; | 	return ArtifactPosition::PRE_FIRST; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool CArtifactSet::hasArt(const ArtifactID & aid, bool onlyWorn, bool searchBackpackAssemblies, bool allowLocked) const | bool CArtifactSet::hasArt(const ArtifactID & aid, bool onlyWorn, bool searchCombinedParts) const | ||||||
| { | { | ||||||
| 	return getArtPosCount(aid, onlyWorn, searchBackpackAssemblies, allowLocked) > 0; | 	if(searchCombinedParts && getCombinedArtWithPart(aid)) | ||||||
|  | 		return true; | ||||||
|  | 	if(getArtPos(aid, onlyWorn, searchCombinedParts) != ArtifactPosition::PRE_FIRST) | ||||||
|  | 		return true; | ||||||
|  | 	return false; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool CArtifactSet::hasArtBackpack(const ArtifactID & aid) const | CArtifactSet::ArtPlacementMap CArtifactSet::putArtifact(const ArtifactPosition & slot, CArtifactInstance * art) | ||||||
| { |  | ||||||
| 	return !getBackpackArtPositions(aid).empty(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| unsigned CArtifactSet::getArtPosCount(const ArtifactID & aid, bool onlyWorn, bool searchBackpackAssemblies, bool allowLocked) const |  | ||||||
| { |  | ||||||
| 	const auto allPositions = getAllArtPositions(aid, onlyWorn, allowLocked, true); |  | ||||||
| 	if(!allPositions.empty()) |  | ||||||
| 		return allPositions.size(); |  | ||||||
|  |  | ||||||
| 	if(searchBackpackAssemblies && getHiddenArt(aid)) |  | ||||||
| 		return 1; |  | ||||||
|  |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| CArtifactSet::ArtPlacementMap CArtifactSet::putArtifact(ArtifactPosition slot, CArtifactInstance * art) |  | ||||||
| { | { | ||||||
| 	ArtPlacementMap resArtPlacement; | 	ArtPlacementMap resArtPlacement; | ||||||
|  |  | ||||||
| @@ -827,19 +790,38 @@ CArtifactSet::ArtPlacementMap CArtifactSet::putArtifact(ArtifactPosition slot, C | |||||||
|  |  | ||||||
| 				assert(ArtifactUtils::isSlotEquipment(partSlot)); | 				assert(ArtifactUtils::isSlotEquipment(partSlot)); | ||||||
| 				setNewArtSlot(partSlot, part.art, true); | 				setNewArtSlot(partSlot, part.art, true); | ||||||
| 				resArtPlacement.emplace(std::make_pair(part.art, partSlot)); | 				resArtPlacement.emplace(part.art, partSlot); | ||||||
| 			} | 			} | ||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
| 				resArtPlacement.emplace(std::make_pair(part.art, part.slot)); | 				resArtPlacement.emplace(part.art, part.slot); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return resArtPlacement; | 	return resArtPlacement; | ||||||
| } | } | ||||||
|  |  | ||||||
| void CArtifactSet::removeArtifact(ArtifactPosition slot) | void CArtifactSet::removeArtifact(const ArtifactPosition & slot) | ||||||
| { | { | ||||||
|  | 	const auto eraseArtSlot = [this](const ArtifactPosition & slotForErase) | ||||||
|  | 	{ | ||||||
|  | 		if(slotForErase == ArtifactPosition::TRANSITION_POS) | ||||||
|  | 		{ | ||||||
|  | 			artifactsTransitionPos.artifact = nullptr; | ||||||
|  | 		} | ||||||
|  | 		else if(ArtifactUtils::isSlotBackpack(slotForErase)) | ||||||
|  | 		{ | ||||||
|  | 			auto backpackSlot = ArtifactPosition(slotForErase - ArtifactPosition::BACKPACK_START); | ||||||
|  |  | ||||||
|  | 			assert(artifactsInBackpack.begin() + backpackSlot < artifactsInBackpack.end()); | ||||||
|  | 			artifactsInBackpack.erase(artifactsInBackpack.begin() + backpackSlot); | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			artifactsWorn.erase(slotForErase); | ||||||
|  | 		} | ||||||
|  | 	}; | ||||||
|  |  | ||||||
| 	if(const auto art = getArt(slot, false)) | 	if(const auto art = getArt(slot, false)) | ||||||
| 	{ | 	{ | ||||||
| 		if(art->isCombined()) | 		if(art->isCombined()) | ||||||
| @@ -858,7 +840,7 @@ void CArtifactSet::removeArtifact(ArtifactPosition slot) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| std::pair<const CArtifactInstance *, const CArtifactInstance *> CArtifactSet::searchForConstituent(const ArtifactID & aid) const | const CArtifactInstance * CArtifactSet::getCombinedArtWithPart(const ArtifactID & partId) const | ||||||
| { | { | ||||||
| 	for(const auto & slot : artifactsInBackpack) | 	for(const auto & slot : artifactsInBackpack) | ||||||
| 	{ | 	{ | ||||||
| @@ -867,24 +849,12 @@ std::pair<const CArtifactInstance *, const CArtifactInstance *> CArtifactSet::se | |||||||
| 		{ | 		{ | ||||||
| 			for(auto & ci : art->getPartsInfo()) | 			for(auto & ci : art->getPartsInfo()) | ||||||
| 			{ | 			{ | ||||||
| 				if(ci.art->getTypeId() == aid) | 				if(ci.art->getTypeId() == partId) | ||||||
| 				{ | 					return art; | ||||||
| 					return {art, ci.art}; |  | ||||||
| 				} |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return {nullptr, nullptr}; | 	return nullptr; | ||||||
| } |  | ||||||
|  |  | ||||||
| const CArtifactInstance * CArtifactSet::getHiddenArt(const ArtifactID & aid) const |  | ||||||
| { |  | ||||||
| 	return searchForConstituent(aid).second; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const CArtifactInstance * CArtifactSet::getAssemblyByConstituent(const ArtifactID & aid) const |  | ||||||
| { |  | ||||||
| 	return searchForConstituent(aid).first; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| const ArtSlotInfo * CArtifactSet::getSlot(const ArtifactPosition & pos) const | const ArtSlotInfo * CArtifactSet::getSlot(const ArtifactPosition & pos) const | ||||||
| @@ -905,6 +875,11 @@ const ArtSlotInfo * CArtifactSet::getSlot(const ArtifactPosition & pos) const | |||||||
| 	return nullptr; | 	return nullptr; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void CArtifactSet::lockSlot(const ArtifactPosition & pos) | ||||||
|  | { | ||||||
|  | 	setNewArtSlot(pos, nullptr, true); | ||||||
|  | } | ||||||
|  |  | ||||||
| bool CArtifactSet::isPositionFree(const ArtifactPosition & pos, bool onlyLockCheck) const | bool CArtifactSet::isPositionFree(const ArtifactPosition & pos, bool onlyLockCheck) const | ||||||
| { | { | ||||||
| 	if(bearerType() == ArtBearer::ALTAR) | 	if(bearerType() == ArtBearer::ALTAR) | ||||||
| @@ -916,7 +891,7 @@ bool CArtifactSet::isPositionFree(const ArtifactPosition & pos, bool onlyLockChe | |||||||
| 	return true; //no slot means not used | 	return true; //no slot means not used | ||||||
| } | } | ||||||
|  |  | ||||||
| void CArtifactSet::setNewArtSlot(const ArtifactPosition & slot, ConstTransitivePtr<CArtifactInstance> art, bool locked) | void CArtifactSet::setNewArtSlot(const ArtifactPosition & slot, CArtifactInstance * art, bool locked) | ||||||
| { | { | ||||||
| 	assert(!vstd::contains(artifactsWorn, slot)); | 	assert(!vstd::contains(artifactsWorn, slot)); | ||||||
|  |  | ||||||
| @@ -932,31 +907,12 @@ void CArtifactSet::setNewArtSlot(const ArtifactPosition & slot, ConstTransitiveP | |||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		auto position = artifactsInBackpack.begin() + slot - ArtifactPosition::BACKPACK_START; | 		auto position = artifactsInBackpack.begin() + slot - ArtifactPosition::BACKPACK_START; | ||||||
| 		slotInfo = &(*artifactsInBackpack.emplace(position, ArtSlotInfo())); | 		slotInfo = &(*artifactsInBackpack.emplace(position)); | ||||||
| 	} | 	} | ||||||
| 	slotInfo->artifact = art; | 	slotInfo->artifact = art; | ||||||
| 	slotInfo->locked = locked; | 	slotInfo->locked = locked; | ||||||
| } | } | ||||||
|  |  | ||||||
| void CArtifactSet::eraseArtSlot(const ArtifactPosition & slot) |  | ||||||
| { |  | ||||||
| 	if(slot == ArtifactPosition::TRANSITION_POS) |  | ||||||
| 	{ |  | ||||||
| 		artifactsTransitionPos.artifact = nullptr; |  | ||||||
| 	} |  | ||||||
| 	else if(ArtifactUtils::isSlotBackpack(slot)) |  | ||||||
| 	{ |  | ||||||
| 		auto backpackSlot = ArtifactPosition(slot - ArtifactPosition::BACKPACK_START); |  | ||||||
|  |  | ||||||
| 		assert(artifactsInBackpack.begin() + backpackSlot < artifactsInBackpack.end()); |  | ||||||
| 		artifactsInBackpack.erase(artifactsInBackpack.begin() + backpackSlot); |  | ||||||
| 	} |  | ||||||
| 	else |  | ||||||
| 	{ |  | ||||||
| 		artifactsWorn.erase(slot); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void CArtifactSet::artDeserializationFix(CBonusSystemNode *node) | void CArtifactSet::artDeserializationFix(CBonusSystemNode *node) | ||||||
| { | { | ||||||
| 	for(auto & elem : artifactsWorn) | 	for(auto & elem : artifactsWorn) | ||||||
|   | |||||||
| @@ -175,10 +175,10 @@ private: | |||||||
|  |  | ||||||
| struct DLL_LINKAGE ArtSlotInfo | struct DLL_LINKAGE ArtSlotInfo | ||||||
| { | { | ||||||
| 	ConstTransitivePtr<CArtifactInstance> artifact; | 	CArtifactInstance * artifact; | ||||||
| 	ui8 locked; //if locked, then artifact points to the combined artifact | 	bool locked; //if locked, then artifact points to the combined artifact | ||||||
|  |  | ||||||
| 	ArtSlotInfo() : locked(false) {} | 	ArtSlotInfo() : artifact(nullptr), locked(false) {} | ||||||
| 	const CArtifactInstance * getArt() const; | 	const CArtifactInstance * getArt() const; | ||||||
|  |  | ||||||
| 	template <typename Handler> void serialize(Handler & h) | 	template <typename Handler> void serialize(Handler & h) | ||||||
| @@ -197,32 +197,20 @@ public: | |||||||
| 	std::map<ArtifactPosition, ArtSlotInfo> artifactsWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5 | 	std::map<ArtifactPosition, ArtSlotInfo> artifactsWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5 | ||||||
| 	ArtSlotInfo artifactsTransitionPos; // Used as transition position for dragAndDrop artifact exchange | 	ArtSlotInfo artifactsTransitionPos; // Used as transition position for dragAndDrop artifact exchange | ||||||
|  |  | ||||||
| 	void setNewArtSlot(const ArtifactPosition & slot, ConstTransitivePtr<CArtifactInstance> art, bool locked); |  | ||||||
| 	void eraseArtSlot(const ArtifactPosition & slot); |  | ||||||
|  |  | ||||||
| 	const ArtSlotInfo * getSlot(const ArtifactPosition & pos) const; | 	const ArtSlotInfo * getSlot(const ArtifactPosition & pos) const; | ||||||
| 	const CArtifactInstance * getArt(const ArtifactPosition & pos, bool excludeLocked = true) const; //nullptr - no artifact | 	void lockSlot(const ArtifactPosition & pos); | ||||||
| 	CArtifactInstance * getArt(const ArtifactPosition & pos, bool excludeLocked = true); //nullptr - no artifact | 	CArtifactInstance * getArt(const ArtifactPosition & pos, bool excludeLocked = true) const; | ||||||
| 	/// Looks for equipped artifact with given ID and returns its slot ID or -1 if none | 	/// Looks for first artifact with given ID | ||||||
| 	/// (if more than one such artifact lower ID is returned) |  | ||||||
| 	ArtifactPosition getArtPos(const ArtifactID & aid, bool onlyWorn = true, bool allowLocked = true) const; | 	ArtifactPosition getArtPos(const ArtifactID & aid, bool onlyWorn = true, bool allowLocked = true) const; | ||||||
| 	ArtifactPosition getArtPos(const CArtifactInstance * art) const; | 	ArtifactPosition getArtPos(const CArtifactInstance * art) const; | ||||||
| 	std::vector<ArtifactPosition> getAllArtPositions(const ArtifactID & aid, bool onlyWorn, bool allowLocked, bool getAll) const; |  | ||||||
| 	std::vector<ArtifactPosition> getBackpackArtPositions(const ArtifactID & aid) const; |  | ||||||
| 	const CArtifactInstance * getArtByInstanceId(const ArtifactInstanceID & artInstId) const; | 	const CArtifactInstance * getArtByInstanceId(const ArtifactInstanceID & artInstId) const; | ||||||
| 	/// Search for constituents of assemblies in backpack which do not have an ArtifactPosition | 	bool hasArt(const ArtifactID & aid, bool onlyWorn = false, bool searchCombinedParts = false) const; | ||||||
| 	const CArtifactInstance * getHiddenArt(const ArtifactID & aid) const; |  | ||||||
| 	const CArtifactInstance * getAssemblyByConstituent(const ArtifactID & aid) const; |  | ||||||
| 	/// Checks if hero possess artifact of given id (either in backack or worn) |  | ||||||
| 	bool hasArt(const ArtifactID & aid, bool onlyWorn = false, bool searchBackpackAssemblies = false, bool allowLocked = true) const; |  | ||||||
| 	bool hasArtBackpack(const ArtifactID & aid) const; |  | ||||||
| 	bool isPositionFree(const ArtifactPosition & pos, bool onlyLockCheck = false) const; | 	bool isPositionFree(const ArtifactPosition & pos, bool onlyLockCheck = false) const; | ||||||
| 	unsigned getArtPosCount(const ArtifactID & aid, bool onlyWorn = true, bool searchBackpackAssemblies = true, bool allowLocked = true) const; |  | ||||||
|  |  | ||||||
| 	virtual ArtBearer::ArtBearer bearerType() const = 0; | 	virtual ArtBearer::ArtBearer bearerType() const = 0; | ||||||
| 	virtual ArtPlacementMap putArtifact(ArtifactPosition slot, CArtifactInstance * art); | 	virtual ArtPlacementMap putArtifact(const ArtifactPosition & slot, CArtifactInstance * art); | ||||||
| 	virtual void removeArtifact(ArtifactPosition slot); | 	virtual void removeArtifact(const ArtifactPosition & slot); | ||||||
| 	virtual ~CArtifactSet(); | 	virtual ~CArtifactSet() = default; | ||||||
|  |  | ||||||
| 	template <typename Handler> void serialize(Handler &h) | 	template <typename Handler> void serialize(Handler &h) | ||||||
| 	{ | 	{ | ||||||
| @@ -233,10 +221,11 @@ public: | |||||||
| 	void artDeserializationFix(CBonusSystemNode *node); | 	void artDeserializationFix(CBonusSystemNode *node); | ||||||
|  |  | ||||||
| 	void serializeJsonArtifacts(JsonSerializeFormat & handler, const std::string & fieldName); | 	void serializeJsonArtifacts(JsonSerializeFormat & handler, const std::string & fieldName); | ||||||
| protected: | 	const CArtifactInstance * getCombinedArtWithPart(const ArtifactID & partId) const; | ||||||
| 	std::pair<const CArtifactInstance *, const CArtifactInstance *> searchForConstituent(const ArtifactID & aid) const; |  | ||||||
|  |  | ||||||
| private: | private: | ||||||
|  | 	void setNewArtSlot(const ArtifactPosition & slot, CArtifactInstance * art, bool locked); | ||||||
|  |  | ||||||
| 	void serializeJsonHero(JsonSerializeFormat & handler); | 	void serializeJsonHero(JsonSerializeFormat & handler); | ||||||
| 	void serializeJsonCreature(JsonSerializeFormat & handler); | 	void serializeJsonCreature(JsonSerializeFormat & handler); | ||||||
| 	void serializeJsonCommander(JsonSerializeFormat & handler); | 	void serializeJsonCommander(JsonSerializeFormat & handler); | ||||||
|   | |||||||
| @@ -863,7 +863,7 @@ ArtBearer::ArtBearer CStackInstance::bearerType() const | |||||||
| 	return ArtBearer::CREATURE; | 	return ArtBearer::CREATURE; | ||||||
| } | } | ||||||
|  |  | ||||||
| CStackInstance::ArtPlacementMap CStackInstance::putArtifact(ArtifactPosition pos, CArtifactInstance * art) | CStackInstance::ArtPlacementMap CStackInstance::putArtifact(const ArtifactPosition & pos, CArtifactInstance * art) | ||||||
| { | { | ||||||
| 	assert(!getArt(pos)); | 	assert(!getArt(pos)); | ||||||
| 	assert(art->canBePutAt(this, pos)); | 	assert(art->canBePutAt(this, pos)); | ||||||
| @@ -872,7 +872,7 @@ CStackInstance::ArtPlacementMap CStackInstance::putArtifact(ArtifactPosition pos | |||||||
| 	return CArtifactSet::putArtifact(pos, art); | 	return CArtifactSet::putArtifact(pos, art); | ||||||
| } | } | ||||||
|  |  | ||||||
| void CStackInstance::removeArtifact(ArtifactPosition pos) | void CStackInstance::removeArtifact(const ArtifactPosition & pos) | ||||||
| { | { | ||||||
| 	assert(getArt(pos)); | 	assert(getArt(pos)); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -126,8 +126,8 @@ public: | |||||||
| 	void setArmyObj(const CArmedInstance *ArmyObj); | 	void setArmyObj(const CArmedInstance *ArmyObj); | ||||||
| 	virtual void giveStackExp(TExpType exp); | 	virtual void giveStackExp(TExpType exp); | ||||||
| 	bool valid(bool allowUnrandomized) const; | 	bool valid(bool allowUnrandomized) const; | ||||||
| 	ArtPlacementMap putArtifact(ArtifactPosition pos, CArtifactInstance * art) override;//from CArtifactSet | 	ArtPlacementMap putArtifact(const ArtifactPosition & pos, CArtifactInstance * art) override;//from CArtifactSet | ||||||
| 	void removeArtifact(ArtifactPosition pos) override; | 	void removeArtifact(const ArtifactPosition & pos) override; | ||||||
| 	ArtBearer::ArtBearer bearerType() const override; //from CArtifactSet | 	ArtBearer::ArtBearer bearerType() const override; //from CArtifactSet | ||||||
| 	std::string nodeName() const override; //from CBonusSystemnode | 	std::string nodeName() const override; //from CBonusSystemnode | ||||||
| 	void deserializationFix(); | 	void deserializationFix(); | ||||||
|   | |||||||
| @@ -1156,7 +1156,7 @@ std::string CGHeroInstance::getBiographyTextID() const | |||||||
| 	return ""; //for random hero | 	return ""; //for random hero | ||||||
| } | } | ||||||
|  |  | ||||||
| CGHeroInstance::ArtPlacementMap CGHeroInstance::putArtifact(ArtifactPosition pos, CArtifactInstance * art) | CGHeroInstance::ArtPlacementMap CGHeroInstance::putArtifact(const ArtifactPosition & pos, CArtifactInstance * art) | ||||||
| { | { | ||||||
| 	assert(art->canBePutAt(this, pos)); | 	assert(art->canBePutAt(this, pos)); | ||||||
|  |  | ||||||
| @@ -1165,7 +1165,7 @@ CGHeroInstance::ArtPlacementMap CGHeroInstance::putArtifact(ArtifactPosition pos | |||||||
| 	return CArtifactSet::putArtifact(pos, art); | 	return CArtifactSet::putArtifact(pos, art); | ||||||
| } | } | ||||||
|  |  | ||||||
| void CGHeroInstance::removeArtifact(ArtifactPosition pos) | void CGHeroInstance::removeArtifact(const ArtifactPosition & pos) | ||||||
| { | { | ||||||
| 	auto art = getArt(pos); | 	auto art = getArt(pos); | ||||||
| 	assert(art); | 	assert(art); | ||||||
| @@ -1201,7 +1201,7 @@ void CGHeroInstance::removeSpellbook() | |||||||
|  |  | ||||||
| 	if(hasSpellbook()) | 	if(hasSpellbook()) | ||||||
| 	{ | 	{ | ||||||
| 		//VLC->arth->removeArtifactFrom(*this, ArtifactPosition::SPELLBOOK); | 		cb->removeArtifact(ArtifactLocation(this->id, ArtifactPosition::SPELLBOOK)); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -241,8 +241,8 @@ public: | |||||||
| 	void initHero(vstd::RNG & rand); | 	void initHero(vstd::RNG & rand); | ||||||
| 	void initHero(vstd::RNG & rand, const HeroTypeID & SUBID); | 	void initHero(vstd::RNG & rand, const HeroTypeID & SUBID); | ||||||
|  |  | ||||||
| 	ArtPlacementMap putArtifact(ArtifactPosition pos, CArtifactInstance * art) override; | 	ArtPlacementMap putArtifact(const ArtifactPosition & pos, CArtifactInstance * art) override; | ||||||
| 	void removeArtifact(ArtifactPosition pos) override; | 	void removeArtifact(const ArtifactPosition & pos) override; | ||||||
| 	void initExp(vstd::RNG & rand); | 	void initExp(vstd::RNG & rand); | ||||||
| 	void initArmy(vstd::RNG & rand, IArmyDescriptor *dst = nullptr); | 	void initArmy(vstd::RNG & rand, IArmyDescriptor *dst = nullptr); | ||||||
| 	void pushPrimSkill(PrimarySkill which, int val); | 	void pushPrimSkill(PrimarySkill which, int val); | ||||||
|   | |||||||
| @@ -152,7 +152,7 @@ void CQuest::completeQuest(IGameCallback * cb, const CGHeroInstance *h) const | |||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			const auto * assembly = h->getAssemblyByConstituent(elem); | 			const auto * assembly = h->getCombinedArtWithPart(elem); | ||||||
| 			assert(assembly); | 			assert(assembly); | ||||||
| 			auto parts = assembly->getPartsInfo(); | 			auto parts = assembly->getPartsInfo(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -917,7 +917,7 @@ void CMapLoaderH3M::loadArtifactsOfHero(CGHeroInstance * hero) | |||||||
|  |  | ||||||
| 		hero->artifactsInBackpack.clear(); | 		hero->artifactsInBackpack.clear(); | ||||||
| 		while(!hero->artifactsWorn.empty()) | 		while(!hero->artifactsWorn.empty()) | ||||||
| 			hero->eraseArtSlot(hero->artifactsWorn.begin()->first); | 			hero->removeArtifact(hero->artifactsWorn.begin()->first); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for(int i = 0; i < features.artifactSlotsCount; i++) | 	for(int i = 0; i < features.artifactSlotsCount; i++) | ||||||
|   | |||||||
| @@ -966,7 +966,7 @@ struct DLL_LINKAGE PutArtifact : CArtifactOperationPack | |||||||
| { | { | ||||||
| 	PutArtifact() = default; | 	PutArtifact() = default; | ||||||
| 	explicit PutArtifact(const ArtifactInstanceID & id, const ArtifactLocation & dst, bool askAssemble = true) | 	explicit PutArtifact(const ArtifactInstanceID & id, const ArtifactLocation & dst, bool askAssemble = true) | ||||||
| 		: id(id), al(dst), askAssemble(askAssemble) | 		: al(dst), askAssemble(askAssemble), id(id) | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -143,10 +143,28 @@ bool Rewardable::Limiter::heroAllowed(const CGHeroInstance * hero) const | |||||||
| 		for(const auto & elem : artifactsRequirements) | 		for(const auto & elem : artifactsRequirements) | ||||||
| 		{ | 		{ | ||||||
| 			// check required amount of artifacts | 			// check required amount of artifacts | ||||||
| 			if(hero->getArtPosCount(elem.first, false, true, true) < elem.second) | 			size_t artCnt = 0; | ||||||
|  | 			for(const auto & [slot, slotInfo] : hero->artifactsWorn) | ||||||
|  | 				if(slotInfo.artifact->getTypeId() == elem.first) | ||||||
|  | 					artCnt++; | ||||||
|  |  | ||||||
|  | 			for(auto & slotInfo : hero->artifactsInBackpack) | ||||||
|  | 				if(slotInfo.artifact->getTypeId() == elem.first) | ||||||
|  | 				{ | ||||||
|  | 					artCnt++; | ||||||
|  | 				} | ||||||
|  | 				else if(slotInfo.artifact->isCombined()) | ||||||
|  | 				{ | ||||||
|  | 					for(const auto & partInfo : slotInfo.artifact->getPartsInfo()) | ||||||
|  | 						if(partInfo.art->getTypeId() == elem.first) | ||||||
|  | 							artCnt++; | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 			if(artCnt < elem.second) | ||||||
| 				return false; | 				return false; | ||||||
| 			if(!hero->hasArt(elem.first)) | 			// Check if art has no own slot. (As part of combined in backpack) | ||||||
| 				reqSlots += hero->getAssemblyByConstituent(elem.first)->getPartsInfo().size() - 2; | 			if(hero->getArtPos(elem.first, false) == ArtifactPosition::PRE_FIRST) | ||||||
|  | 				reqSlots += hero->getCombinedArtWithPart(elem.first)->getPartsInfo().size() - 2; | ||||||
| 		} | 		} | ||||||
| 		if(!ArtifactUtils::isBackpackFreeSlots(hero, reqSlots)) | 		if(!ArtifactUtils::isBackpackFreeSlots(hero, reqSlots)) | ||||||
| 			return false; | 			return false; | ||||||
|   | |||||||
| @@ -2718,15 +2718,15 @@ bool CGameHandler::switchArtifactsCostume(const PlayerColor & player, const Obje | |||||||
| 		// Second, find the necessary artifacts for the costume | 		// Second, find the necessary artifacts for the costume | ||||||
| 		for(const auto & artPos : costumeArtMap) | 		for(const auto & artPos : costumeArtMap) | ||||||
| 		{ | 		{ | ||||||
| 			if(const auto availableArts = artFittingSet.getAllArtPositions(artPos.second, false, false, false); !availableArts.empty()) | 			if(const auto slot = artFittingSet.getArtPos(artPos.second, false, false); slot != ArtifactPosition::PRE_FIRST) | ||||||
| 			{ | 			{ | ||||||
| 				bma.artsPack0.emplace_back(BulkMoveArtifacts::LinkedSlots | 				bma.artsPack0.emplace_back(BulkMoveArtifacts::LinkedSlots | ||||||
| 					{ | 					{ | ||||||
| 						artSet->getArtPos(artFittingSet.getArt(availableArts.front())), | 						artSet->getArtPos(artFittingSet.getArt(slot)), | ||||||
| 						artPos.first | 						artPos.first | ||||||
| 					}); | 					}); | ||||||
| 				artFittingSet.removeArtifact(availableArts.front()); | 				artFittingSet.removeArtifact(slot); | ||||||
| 				if(ArtifactUtils::isSlotBackpack(availableArts.front())) | 				if(ArtifactUtils::isSlotBackpack(slot)) | ||||||
| 					estimateBackpackSize--; | 					estimateBackpackSize--; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user