| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 | /* * CArtifactInstance.cpp, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * * License: GNU General Public License v2.0 or later * Full text of license available in license.txt file, in main folder * */ #include "StdInc.h"#include "CArtifactInstance.h"#include "CArtifact.h"#include "CArtifactSet.h"#include "../../callback/IGameInfoCallback.h"#include "../../gameState/CGameState.h"VCMI_LIB_NAMESPACE_BEGINCCombinedArtifactInstance::PartInfo::PartInfo(const CArtifactInstance * artifact, ArtifactPosition slot)	: artifactPtr(artifact)	, artifactID(artifact->getId())	, slot(slot){}const CArtifactInstance * CCombinedArtifactInstance::PartInfo::getArtifact() const{	assert(artifactPtr != nullptr || !artifactID.hasValue());	return artifactPtr;}ArtifactInstanceID CCombinedArtifactInstance::PartInfo::getArtifactID() const{	return artifactID;}void CCombinedArtifactInstance::addPart(const CArtifactInstance * art, const ArtifactPosition & slot){	auto artInst = static_cast<CArtifactInstance*>(this);	assert(vstd::contains_if(artInst->getType()->getConstituents(),		[=](const CArtifact * partType)		{			return partType->getId() == art->getTypeId();		}));	assert(art->getParentNodes().size() == 1  &&  art->getParentNodes().front() == art->getType());	partsInfo.emplace_back(art, slot);	artInst->attachToSource(*art);}bool CCombinedArtifactInstance::isPart(const CArtifactInstance * supposedPart) const{	if(supposedPart == this)		return true;	for(const PartInfo & constituent : partsInfo)	{		if(constituent.getArtifactID() == supposedPart->getId())			return true;	}	return false;}bool CCombinedArtifactInstance::hasParts() const{	return !partsInfo.empty();}const std::vector<CCombinedArtifactInstance::PartInfo> & CCombinedArtifactInstance::getPartsInfo() const{	return partsInfo;}void CCombinedArtifactInstance::addPlacementMap(const CArtifactSet::ArtPlacementMap & placementMap){	if(!placementMap.empty())		for(auto & part : partsInfo)		{			if(placementMap.find(part.getArtifact()) != placementMap.end())				part.slot = placementMap.at(part.getArtifact());		}}SpellID CScrollArtifactInstance::getScrollSpellID() const{	auto artInst = static_cast<const CArtifactInstance*>(this);	const auto bonus = artInst->getFirstBonus(Selector::type()(BonusType::SPELL));	if(!bonus)		return SpellID::NONE;	return bonus->subtype.as<SpellID>();}void CGrowingArtifactInstance::growingUp(){	auto artInst = static_cast<CArtifactInstance*>(this);	const auto artType = artInst->getType();		if(artType->isGrowing())	{		const auto growingBonus = artInst->getBonusesOfType(BonusType::ARTIFACT_GROWING);		assert(!growingBonus->empty());		growingBonus->front()->val++;		for(const auto & bonus : artType->getBonusesPerLevel())		{			// Every n levels			if(artInst->valOfBonuses(BonusType::ARTIFACT_GROWING) % bonus.first == 0)			{				artInst->accumulateBonus(std::make_shared<Bonus>(*bonus.second));			}		}		for(const auto & bonus : artType->getThresholdBonuses())		{			// At n level			if(artInst->valOfBonuses(BonusType::ARTIFACT_GROWING) == bonus.first)			{				artInst->addNewBonus(std::make_shared<Bonus>(*bonus.second));			}		}	}}void CChargedArtifactInstance::discharge(const uint16_t charges){	auto artInst = static_cast<CArtifactInstance*>(this);	if(const auto chargedBonus = artInst->getBonusesOfType(BonusType::ARTIFACT_CHARGE); !chargedBonus->empty())	{		if(chargedBonus->front()->val > charges)			chargedBonus->front()->val -= charges;		else			chargedBonus->front()->val = 0;	}}void CChargedArtifactInstance::addCharges(const uint16_t charges){	auto artInst = static_cast<CArtifactInstance*>(this);	if(artInst->getType()->isCharged())	{		const auto chargedBonus = artInst->getBonusesOfType(BonusType::ARTIFACT_CHARGE);		assert(!chargedBonus->empty());		chargedBonus->front()->val += charges;	}}uint16_t CChargedArtifactInstance::getCharges() const{	auto artInst = static_cast<const CArtifactInstance*>(this);	return artInst->valOfBonuses(BonusType::ARTIFACT_CHARGE);}void CArtifactInstance::init(){	const auto art = artTypeID.toArtifact();	assert(art);	attachToSource(*art);}CArtifactInstance::CArtifactInstance(IGameInfoCallback *cb, const CArtifact * art)	:CArtifactInstance(cb){	artTypeID = art->getId();	init();}CArtifactInstance::CArtifactInstance(IGameInfoCallback *cb)	: CBonusSystemNode(BonusNodeType::ARTIFACT_INSTANCE)	, CCombinedArtifactInstance(cb){}std::string CArtifactInstance::nodeName() const{	return "Artifact instance of " + (getType() ? getType()->getJsonKey() : std::string("uninitialized")) + " type";}ArtifactID CArtifactInstance::getTypeId() const{	return artTypeID;}const CArtifact * CArtifactInstance::getType() const{	return artTypeID.hasValue() ? artTypeID.toArtifact() : nullptr;}ArtifactInstanceID CArtifactInstance::getId() const{	return id;}void CArtifactInstance::setId(ArtifactInstanceID id){	this->id = id;}bool CArtifactInstance::canBePutAt(const CArtifactSet * artSet, ArtifactPosition slot, bool assumeDestRemoved) const{	return getType()->canBePutAt(artSet, slot, assumeDestRemoved);}bool CArtifactInstance::isCombined() const{	return getType()->isCombined();}bool CArtifactInstance::isScroll() const{	return getType()->isScroll();}void CArtifactInstance::attachToBonusSystem(CGameState & gs){	for(PartInfo & part : partsInfo)	{		part = PartInfo(gs.getArtInstance(part.getArtifactID()), part.slot);		attachToSource(*gs.getArtInstance(part.getArtifactID()));	}}void CArtifactInstance::saveCompatibilityFixArtifactID(std::shared_ptr<CArtifactInstance> self){	self->cb->gameState().saveCompatibilityLastAllocatedArtifactID = ArtifactInstanceID(self->cb->gameState().saveCompatibilityLastAllocatedArtifactID.getNum()+1);	self->id = self->cb->gameState().saveCompatibilityLastAllocatedArtifactID;	self->cb->gameState().saveCompatibilityUnregisteredArtifacts.push_back(self);}VCMI_LIB_NAMESPACE_END
 |