|
@@ -96,16 +96,15 @@ SpellID CScrollArtifactInstance::getScrollSpellID() const
|
|
|
void CGrowingArtifactInstance::growingUp()
|
|
|
{
|
|
|
auto artInst = static_cast<CArtifactInstance*>(this);
|
|
|
+ const auto artType = artInst->getType();
|
|
|
|
|
|
- if(artInst->getType()->isGrowing())
|
|
|
+ if(artType->isGrowing())
|
|
|
{
|
|
|
- auto growingBonus = std::make_shared<Bonus>();
|
|
|
- growingBonus->type = BonusType::ARTIFACT_GROWING;
|
|
|
- growingBonus->val = 1;
|
|
|
- growingBonus->duration = BonusDuration::PERMANENT;
|
|
|
- artInst->accumulateBonus(growingBonus);
|
|
|
+ const auto growingBonus = artInst->getBonusesOfType(BonusType::ARTIFACT_GROWING);
|
|
|
+ assert(!growingBonus.empty());
|
|
|
+ growingBonus->front()->val++;
|
|
|
|
|
|
- for(const auto & bonus : artInst->getType()->getBonusesPerLevel())
|
|
|
+ for(const auto & bonus : artType->getBonusesPerLevel())
|
|
|
{
|
|
|
// Every n levels
|
|
|
if(artInst->valOfBonuses(BonusType::ARTIFACT_GROWING) % bonus.first == 0)
|
|
@@ -113,7 +112,7 @@ void CGrowingArtifactInstance::growingUp()
|
|
|
artInst->accumulateBonus(std::make_shared<Bonus>(bonus.second));
|
|
|
}
|
|
|
}
|
|
|
- for(const auto & bonus : artInst->getType()->getThresholdBonuses())
|
|
|
+ for(const auto & bonus : artType->getThresholdBonuses())
|
|
|
{
|
|
|
// At n level
|
|
|
if(artInst->valOfBonuses(BonusType::ARTIFACT_GROWING) == bonus.first)
|
|
@@ -121,6 +120,41 @@ void CGrowingArtifactInstance::growingUp()
|
|
|
artInst->addNewBonus(std::make_shared<Bonus>(bonus.second));
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ if(artType->isCharged())
|
|
|
+ artInst->onChargesChanged();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void CChargedArtifactInstance::onChargesChanged()
|
|
|
+{
|
|
|
+ auto artInst = static_cast<CArtifactInstance*>(this);
|
|
|
+ const auto artType = artInst->getType();
|
|
|
+
|
|
|
+ const auto bonusSelector = artType->getDischargeCondition() == DischargeArtifactCondition::SPELLCAST ?
|
|
|
+ Selector::type()(BonusType::SPELL) : Selector::all;
|
|
|
+
|
|
|
+ auto instBonuses = artInst->getAllBonuses(bonusSelector, nullptr);
|
|
|
+
|
|
|
+ if(artInst->getCharges() == 0)
|
|
|
+ {
|
|
|
+ for(const auto & bonus : *instBonuses)
|
|
|
+ if(bonus->type != BonusType::ARTIFACT_GROWING && bonus->type != BonusType::ARTIFACT_CHARGE)
|
|
|
+ artInst->removeBonus(bonus);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ for(const auto & refBonus : *artType->getAllBonuses(bonusSelector, nullptr))
|
|
|
+ {
|
|
|
+ if(const auto bonusFound = std::find_if(instBonuses->begin(), instBonuses->end(),
|
|
|
+ [refBonus](const auto & instBonus)
|
|
|
+ {
|
|
|
+ return refBonus->type == instBonus->type;
|
|
|
+ }); bonusFound == instBonuses->end())
|
|
|
+ {
|
|
|
+ artInst->accumulateBonus(refBonus);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -128,12 +162,13 @@ void CChargedArtifactInstance::discharge(const uint16_t charges)
|
|
|
{
|
|
|
auto artInst = static_cast<CArtifactInstance*>(this);
|
|
|
|
|
|
- if(const auto chargeBonuses = artInst->getAllBonuses(Selector::type()(BonusType::ARTIFACT_CHARGE), nullptr))
|
|
|
+ if(const auto chargedBonus = artInst->getBonusesOfType(BonusType::ARTIFACT_CHARGE); !chargedBonus->empty())
|
|
|
{
|
|
|
- if(chargeBonuses->front()->val > charges)
|
|
|
- chargeBonuses->front()->val -= charges;
|
|
|
+ if(chargedBonus->front()->val > charges)
|
|
|
+ chargedBonus->front()->val -= charges;
|
|
|
else
|
|
|
- chargeBonuses->front()->val = 0;
|
|
|
+ chargedBonus->front()->val = 0;
|
|
|
+ onChargesChanged();
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -143,11 +178,10 @@ void CChargedArtifactInstance::addCharges(const uint16_t charges)
|
|
|
|
|
|
if(artInst->getType()->isCharged())
|
|
|
{
|
|
|
- auto bonus = std::make_shared<Bonus>();
|
|
|
- bonus->type = BonusType::ARTIFACT_CHARGE;
|
|
|
- bonus->val = charges;
|
|
|
- bonus->duration = BonusDuration::PERMANENT;
|
|
|
- artInst->accumulateBonus(bonus);
|
|
|
+ const auto chargedBonus = artInst->getBonusesOfType(BonusType::ARTIFACT_CHARGE);
|
|
|
+ assert(!chargedBonus.empty());
|
|
|
+ chargedBonus->front()->val += charges;
|
|
|
+ onChargesChanged();
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -158,11 +192,32 @@ uint16_t CChargedArtifactInstance::getCharges() const
|
|
|
return artInst->valOfBonuses(BonusType::ARTIFACT_CHARGE);
|
|
|
}
|
|
|
|
|
|
+void CArtifactInstance::init()
|
|
|
+{
|
|
|
+ const auto art = artTypeID.toArtifact();
|
|
|
+ assert(art);
|
|
|
+
|
|
|
+ if(art->isCharged())
|
|
|
+ {
|
|
|
+ // Charged artifacts contain all bonuses inside instance bonus node
|
|
|
+ if(art->getDischargeCondition() == DischargeArtifactCondition::SPELLCAST)
|
|
|
+ {
|
|
|
+ for(const auto & bonus : *art->getAllBonuses(Selector::all, nullptr))
|
|
|
+ if(bonus->type != BonusType::SPELL)
|
|
|
+ accumulateBonus(bonus);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ attachToSource(*art);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
CArtifactInstance::CArtifactInstance(IGameInfoCallback *cb, const CArtifact * art)
|
|
|
:CArtifactInstance(cb)
|
|
|
{
|
|
|
- setType(art);
|
|
|
- addCharges(getType()->getDefaultStartCharges());
|
|
|
+ artTypeID = art->getId();
|
|
|
+ init();
|
|
|
}
|
|
|
|
|
|
CArtifactInstance::CArtifactInstance(IGameInfoCallback *cb)
|
|
@@ -171,12 +226,6 @@ CArtifactInstance::CArtifactInstance(IGameInfoCallback *cb)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
-void CArtifactInstance::setType(const CArtifact * art)
|
|
|
-{
|
|
|
- artTypeID = art->getId();
|
|
|
- attachToSource(*art);
|
|
|
-}
|
|
|
-
|
|
|
std::string CArtifactInstance::nodeName() const
|
|
|
{
|
|
|
return "Artifact instance of " + (getType() ? getType()->getJsonKey() : std::string("uninitialized")) + " type";
|