mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
Attempt to make constant bonus system nodes (CCreature / CArtifact)
fully constant
This commit is contained in:
@@ -121,7 +121,7 @@ CArtifactInstance::CArtifactInstance()
|
||||
void CArtifactInstance::setType(const CArtifact * art)
|
||||
{
|
||||
artType = art;
|
||||
attachTo(const_cast<CArtifact&>(*art));
|
||||
attachToSource(*art);
|
||||
}
|
||||
|
||||
std::string CArtifactInstance::nodeName() const
|
||||
|
@@ -758,7 +758,7 @@ void CStackInstance::setType(const CCreature *c)
|
||||
{
|
||||
if(type)
|
||||
{
|
||||
detachFrom(const_cast<CCreature&>(*type));
|
||||
detachFromSource(*type);
|
||||
if (type->isMyUpgrade(c) && VLC->settings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE))
|
||||
experience = static_cast<TExpType>(experience * VLC->creh->expAfterUpgrade / 100.0);
|
||||
}
|
||||
@@ -766,7 +766,7 @@ void CStackInstance::setType(const CCreature *c)
|
||||
CStackBasicDescriptor::setType(c);
|
||||
|
||||
if(type)
|
||||
attachTo(const_cast<CCreature&>(*type));
|
||||
attachToSource(*type);
|
||||
}
|
||||
std::string CStackInstance::bonusToString(const std::shared_ptr<Bonus>& bonus, bool description) const
|
||||
{
|
||||
|
@@ -72,7 +72,7 @@ void CStack::localInit(BattleInfo * battleInfo)
|
||||
CArmedInstance * army = battle->battleGetArmyObject(side);
|
||||
assert(army);
|
||||
attachTo(*army);
|
||||
attachTo(const_cast<CCreature&>(*type));
|
||||
attachToSource(*type);
|
||||
}
|
||||
nativeTerrain = getNativeTerrain(); //save nativeTerrain in the variable on the battle start to avoid dead lock
|
||||
CUnitState::localInit(this); //it causes execution of the CStack::isOnNativeTerrain where nativeTerrain will be considered
|
||||
|
@@ -25,10 +25,18 @@ std::shared_ptr<Bonus> CBonusSystemNode::getBonusLocalFirst(const CSelector & se
|
||||
auto ret = bonuses.getFirst(selector);
|
||||
if(ret)
|
||||
return ret;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TNodes lparents;
|
||||
std::shared_ptr<const Bonus> CBonusSystemNode::getBonusLocalFirst(const CSelector & selector) const
|
||||
{
|
||||
auto ret = bonuses.getFirst(selector);
|
||||
if(ret)
|
||||
return ret;
|
||||
|
||||
TCNodes lparents;
|
||||
getParents(lparents);
|
||||
for(CBonusSystemNode *pname : lparents)
|
||||
for(const CBonusSystemNode *pname : lparents)
|
||||
{
|
||||
ret = pname->getBonusLocalFirst(selector);
|
||||
if (ret)
|
||||
@@ -38,28 +46,15 @@ std::shared_ptr<Bonus> CBonusSystemNode::getBonusLocalFirst(const CSelector & se
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<const Bonus> CBonusSystemNode::getBonusLocalFirst(const CSelector & selector) const
|
||||
{
|
||||
return (const_cast<CBonusSystemNode*>(this))->getBonusLocalFirst(selector);
|
||||
}
|
||||
|
||||
void CBonusSystemNode::getParents(TCNodes & out) const /*retrieves list of parent nodes (nodes to inherit bonuses from) */
|
||||
{
|
||||
for(const auto * elem : parents)
|
||||
for(const auto * elem : parentsToInherit)
|
||||
out.insert(elem);
|
||||
}
|
||||
|
||||
void CBonusSystemNode::getParents(TNodes &out)
|
||||
{
|
||||
for (auto * elem : parents)
|
||||
{
|
||||
out.insert(elem);
|
||||
}
|
||||
}
|
||||
|
||||
void CBonusSystemNode::getAllParents(TCNodes & out) const //retrieves list of parent nodes (nodes to inherit bonuses from)
|
||||
{
|
||||
for(auto * parent : parents)
|
||||
for(auto * parent : parentsToInherit)
|
||||
{
|
||||
out.insert(parent);
|
||||
parent->getAllParents(out);
|
||||
@@ -239,14 +234,14 @@ CBonusSystemNode::~CBonusSystemNode()
|
||||
|
||||
void CBonusSystemNode::attachTo(CBonusSystemNode & parent)
|
||||
{
|
||||
assert(!vstd::contains(parents, &parent));
|
||||
parents.push_back(&parent);
|
||||
assert(!vstd::contains(parentsToPropagate, &parent));
|
||||
parentsToPropagate.push_back(&parent);
|
||||
|
||||
attachToSource(parent);
|
||||
|
||||
if(!isHypothetic())
|
||||
{
|
||||
if(parent.actsAsBonusSourceOnly())
|
||||
parent.newRedDescendant(*this);
|
||||
else
|
||||
if(!parent.actsAsBonusSourceOnly())
|
||||
newRedDescendant(parent);
|
||||
|
||||
parent.newChildAttached(*this);
|
||||
@@ -255,21 +250,35 @@ void CBonusSystemNode::attachTo(CBonusSystemNode & parent)
|
||||
CBonusSystemNode::treeHasChanged();
|
||||
}
|
||||
|
||||
void CBonusSystemNode::detachFrom(CBonusSystemNode & parent)
|
||||
void CBonusSystemNode::attachToSource(const CBonusSystemNode & parent)
|
||||
{
|
||||
assert(vstd::contains(parents, &parent));
|
||||
assert(!vstd::contains(parentsToInherit, &parent));
|
||||
parentsToInherit.push_back(&parent);
|
||||
|
||||
if(!isHypothetic())
|
||||
{
|
||||
if(parent.actsAsBonusSourceOnly())
|
||||
parent.removedRedDescendant(*this);
|
||||
else
|
||||
parent.newRedDescendant(*this);
|
||||
}
|
||||
|
||||
CBonusSystemNode::treeHasChanged();
|
||||
}
|
||||
|
||||
void CBonusSystemNode::detachFrom(CBonusSystemNode & parent)
|
||||
{
|
||||
assert(vstd::contains(parentsToPropagate, &parent));
|
||||
|
||||
if(!isHypothetic())
|
||||
{
|
||||
if(!parent.actsAsBonusSourceOnly())
|
||||
removedRedDescendant(parent);
|
||||
}
|
||||
|
||||
if (vstd::contains(parents, &parent))
|
||||
detachFromSource(parent);
|
||||
|
||||
if (vstd::contains(parentsToPropagate, &parent))
|
||||
{
|
||||
parents -= &parent;
|
||||
parentsToPropagate -= &parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -284,6 +293,30 @@ void CBonusSystemNode::detachFrom(CBonusSystemNode & parent)
|
||||
CBonusSystemNode::treeHasChanged();
|
||||
}
|
||||
|
||||
|
||||
void CBonusSystemNode::detachFromSource(const CBonusSystemNode & parent)
|
||||
{
|
||||
assert(vstd::contains(parentsToInherit, &parent));
|
||||
|
||||
if(!isHypothetic())
|
||||
{
|
||||
if(parent.actsAsBonusSourceOnly())
|
||||
parent.removedRedDescendant(*this);
|
||||
}
|
||||
|
||||
if (vstd::contains(parentsToPropagate, &parent))
|
||||
{
|
||||
parentsToInherit -= &parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
logBonus->error("Error on Detach. Node %s (nodeType=%d) has not parent %s (nodeType=%d)"
|
||||
, nodeShortInfo(), nodeType, parent.nodeShortInfo(), parent.nodeType);
|
||||
}
|
||||
|
||||
CBonusSystemNode::treeHasChanged();
|
||||
}
|
||||
|
||||
void CBonusSystemNode::removeBonusesRecursive(const CSelector & s)
|
||||
{
|
||||
removeBonuses(s);
|
||||
@@ -410,13 +443,16 @@ void CBonusSystemNode::childDetached(CBonusSystemNode & child)
|
||||
|
||||
void CBonusSystemNode::detachFromAll()
|
||||
{
|
||||
while(!parents.empty())
|
||||
detachFrom(*parents.front());
|
||||
while(!parentsToPropagate.empty())
|
||||
detachFrom(*parentsToPropagate.front());
|
||||
|
||||
while(!parentsToInherit.empty())
|
||||
detachFromSource(*parentsToInherit.front());
|
||||
}
|
||||
|
||||
bool CBonusSystemNode::isIndependentNode() const
|
||||
{
|
||||
return parents.empty() && children.empty();
|
||||
return parentsToInherit.empty() && parentsToPropagate.empty() && children.empty();
|
||||
}
|
||||
|
||||
std::string CBonusSystemNode::nodeName() const
|
||||
@@ -434,7 +470,6 @@ std::string CBonusSystemNode::nodeShortInfo() const
|
||||
void CBonusSystemNode::deserializationFix()
|
||||
{
|
||||
exportBonuses();
|
||||
|
||||
}
|
||||
|
||||
void CBonusSystemNode::getRedParents(TCNodes & out) const
|
||||
@@ -460,9 +495,7 @@ void CBonusSystemNode::getRedParents(TCNodes & out) const
|
||||
|
||||
void CBonusSystemNode::getRedChildren(TNodes &out)
|
||||
{
|
||||
TNodes lparents;
|
||||
getParents(lparents);
|
||||
for(CBonusSystemNode *pname : lparents)
|
||||
for(CBonusSystemNode *pname : parentsToPropagate)
|
||||
{
|
||||
if(!pname->actsAsBonusSourceOnly())
|
||||
{
|
||||
@@ -479,7 +512,7 @@ void CBonusSystemNode::getRedChildren(TNodes &out)
|
||||
}
|
||||
}
|
||||
|
||||
void CBonusSystemNode::newRedDescendant(CBonusSystemNode & descendant)
|
||||
void CBonusSystemNode::newRedDescendant(CBonusSystemNode & descendant) const
|
||||
{
|
||||
for(const auto & b : exportedBonuses)
|
||||
{
|
||||
@@ -489,7 +522,7 @@ void CBonusSystemNode::newRedDescendant(CBonusSystemNode & descendant)
|
||||
TCNodes redParents;
|
||||
getRedAncestors(redParents); //get all red parents recursively
|
||||
|
||||
for(auto * parent : redParents)
|
||||
for(const auto * parent : redParents)
|
||||
{
|
||||
for(const auto & b : parent->exportedBonuses)
|
||||
{
|
||||
@@ -499,7 +532,7 @@ void CBonusSystemNode::newRedDescendant(CBonusSystemNode & descendant)
|
||||
}
|
||||
}
|
||||
|
||||
void CBonusSystemNode::removedRedDescendant(CBonusSystemNode & descendant)
|
||||
void CBonusSystemNode::removedRedDescendant(CBonusSystemNode & descendant) const
|
||||
{
|
||||
for(const auto & b : exportedBonuses)
|
||||
if(b->propagator)
|
||||
@@ -550,7 +583,7 @@ CBonusSystemNode::ENodeTypes CBonusSystemNode::getNodeType() const
|
||||
|
||||
const TNodesVector& CBonusSystemNode::getParentNodes() const
|
||||
{
|
||||
return parents;
|
||||
return parentsToPropagate;
|
||||
}
|
||||
|
||||
void CBonusSystemNode::setNodeType(CBonusSystemNode::ENodeTypes type)
|
||||
|
@@ -19,6 +19,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
using TNodes = std::set<CBonusSystemNode *>;
|
||||
using TCNodes = std::set<const CBonusSystemNode *>;
|
||||
using TNodesVector = std::vector<CBonusSystemNode *>;
|
||||
using TCNodesVector = std::vector<const CBonusSystemNode *>;
|
||||
|
||||
class DLL_LINKAGE CBonusSystemNode : public virtual IBonusBearer, public boost::noncopyable
|
||||
{
|
||||
@@ -33,7 +34,8 @@ private:
|
||||
BonusList bonuses; //wielded bonuses (local or up-propagated here)
|
||||
BonusList exportedBonuses; //bonuses coming from this node (wielded or propagated away)
|
||||
|
||||
TNodesVector parents; // we inherit bonuses from them, we may attach our bonuses to them
|
||||
TCNodesVector parentsToInherit; // we inherit bonuses from them
|
||||
TNodesVector parentsToPropagate; // we may attach our bonuses to them
|
||||
TNodesVector children;
|
||||
|
||||
ENodeTypes nodeType;
|
||||
@@ -66,8 +68,8 @@ private:
|
||||
void unpropagateBonus(const std::shared_ptr<Bonus> & b);
|
||||
bool actsAsBonusSourceOnly() const;
|
||||
|
||||
void newRedDescendant(CBonusSystemNode & descendant); //propagation needed
|
||||
void removedRedDescendant(CBonusSystemNode & descendant); //de-propagation needed
|
||||
void newRedDescendant(CBonusSystemNode & descendant) const; //propagation needed
|
||||
void removedRedDescendant(CBonusSystemNode & descendant) const; //de-propagation needed
|
||||
|
||||
std::string nodeShortInfo() const;
|
||||
|
||||
@@ -89,11 +91,12 @@ public:
|
||||
std::shared_ptr<const Bonus> getBonusLocalFirst(const CSelector & selector) const;
|
||||
|
||||
//non-const interface
|
||||
void getParents(TNodes &out); //retrieves list of parent nodes (nodes to inherit bonuses from)
|
||||
std::shared_ptr<Bonus> getBonusLocalFirst(const CSelector & selector);
|
||||
|
||||
void attachTo(CBonusSystemNode & parent);
|
||||
void attachToSource(const CBonusSystemNode & parent);
|
||||
void detachFrom(CBonusSystemNode & parent);
|
||||
void detachFromSource(const CBonusSystemNode & parent);
|
||||
void detachFromAll();
|
||||
virtual void addNewBonus(const std::shared_ptr<Bonus>& b);
|
||||
void accumulateBonus(const std::shared_ptr<Bonus>& b); //add value of bonus with same type/subtype or create new
|
||||
|
Reference in New Issue
Block a user