From d7b586f1fdbf1620376d9e023fa4c4eb536ab321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20W=2E=20Urba=C5=84czyk?= Date: Sun, 27 Feb 2011 11:26:18 +0000 Subject: [PATCH] Eliminating duplicated bonuses. Smarter getting [no code duplication]. --- lib/HeroBonus.cpp | 57 +++++++++++++++++++++++++++++++++-------------- lib/HeroBonus.h | 18 +++++++-------- 2 files changed, 49 insertions(+), 26 deletions(-) diff --git a/lib/HeroBonus.cpp b/lib/HeroBonus.cpp index 88a8fae7d..84cbdff27 100644 --- a/lib/HeroBonus.cpp +++ b/lib/HeroBonus.cpp @@ -113,17 +113,19 @@ void DLL_EXPORT BonusList::getModifiersWDescr(TModDescr &out) const out.push_back(std::make_pair(i->val, i->Description())); } -void DLL_EXPORT BonusList::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *source /*= NULL*/) const +void DLL_EXPORT BonusList::getBonuses(BonusList &out, const CSelector &selector) const { - BOOST_FOREACH(Bonus *i, *this) - if(selector(i) && i->effectRange == Bonus::NO_LIMIT) - out.push_back(i); +// BOOST_FOREACH(Bonus *i, *this) +// if(selector(i) && i->effectRange == Bonus::NO_LIMIT) +// out.push_back(i); + + getBonuses(out, selector, 0); } -void DLL_EXPORT BonusList::getBonuses(BonusList &out, const CSelector &selector, const CSelector &limit, const CBonusSystemNode *source /*= NULL*/) const +void DLL_EXPORT BonusList::getBonuses(BonusList &out, const CSelector &selector, const CSelector &limit) const { BOOST_FOREACH(Bonus *i, *this) - if(selector(i) && (!limit || limit(i))) + if(selector(i) && (!limit && i->effectRange == Bonus::NO_LIMIT || limit && limit(i))) //add matching bonuses that matches limit predicate or have NO_LIMIT if no given predicate out.push_back(i); } @@ -132,6 +134,12 @@ void BonusList::limit(const CBonusSystemNode &node) remove_if(boost::bind(&CBonusSystemNode::isLimitedOnUs, boost::ref(node), _1)); } +void DLL_EXPORT BonusList::eliminateDuplicates() +{ + sort(); + unique(); +} + int CBonusSystemNode::valOfBonuses(Bonus::BonusType type, const CSelector &selector) const { return valOfBonuses(Selector::type(type) && selector); @@ -220,13 +228,14 @@ void CBonusSystemNode::getParents(TNodes &out) void CBonusSystemNode::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const { - FOREACH_CONST_PARENT(p) //unwinded macro - p->getBonuses(out, selector, root ? root : this); - - bonuses.getBonuses(out, selector); - - if(!root) - out.limit(*this); + getBonuses(out, selector, 0, root); +// FOREACH_CONST_PARENT(p) +// p->getBonuses(out, selector, root ? root : this); +// +// bonuses.getBonuses(out, selector); +// +// if(!root) +// out.limit(*this); } BonusList CBonusSystemNode::getBonuses(const CSelector &selector) const @@ -236,11 +245,14 @@ BonusList CBonusSystemNode::getBonuses(const CSelector &selector) const return ret; } -void CBonusSystemNode::getBonuses(BonusList &out, const CSelector &selector, const CSelector &limit) const +void CBonusSystemNode::getBonuses(BonusList &out, const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root /*= NULL*/) const { - getBonuses(out, selector); //first get all the bonuses - out.remove_if(std::not1(limit)); //now remove the ones we don't like - out.limit(*this); //apply bonuses' limiters + getAllBonuses(out, selector, limit, root); + out.eliminateDuplicates(); +// +// getBonuses(out, selector); //first get all the bonuses +// out.remove_if(std::not1(limit)); //now remove the ones we don't like +// out.limit(*this); //apply bonuses' limiters } BonusList CBonusSystemNode::getBonuses(const CSelector &selector, const CSelector &limit) const @@ -250,6 +262,17 @@ BonusList CBonusSystemNode::getBonuses(const CSelector &selector, const CSelecto return ret; } +void CBonusSystemNode::getAllBonuses(BonusList &out, const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root /*= NULL*/) const +{ + FOREACH_CONST_PARENT(p) + p->getBonuses(out, selector, limit, root ? root : this); + + bonuses.getBonuses(out, selector, limit); + + if(!root) + out.limit(*this); +} + bool CBonusSystemNode::hasBonusFrom(ui8 source, ui32 sourceID) const { return hasBonus(Selector::source(source,sourceID)); diff --git a/lib/HeroBonus.h b/lib/HeroBonus.h index 82454ec48..e28e43ef4 100644 --- a/lib/HeroBonus.h +++ b/lib/HeroBonus.h @@ -312,15 +312,17 @@ class BonusList : public std::list { public: int DLL_EXPORT totalValue() const; //subtype -> subtype of bonus, if -1 then any - void DLL_EXPORT getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *source = NULL) const; - void DLL_EXPORT getBonuses(BonusList &out, const CSelector &selector, const CSelector &limit, const CBonusSystemNode *source = NULL) const; + void DLL_EXPORT getBonuses(BonusList &out, const CSelector &selector, const CSelector &limit) const; void DLL_EXPORT getModifiersWDescr(TModDescr &out) const; + void DLL_EXPORT getBonuses(BonusList &out, const CSelector &selector) const; + //special find functions DLL_EXPORT Bonus * getFirst(const CSelector &select); DLL_EXPORT const Bonus * getFirst(const CSelector &select) const; void limit(const CBonusSystemNode &node); //erases bonuses using limitor + void DLL_EXPORT eliminateDuplicates(); template void serialize(Handler &h, const int version) { @@ -385,20 +387,17 @@ public: //new bonusing node interface // * selector is predicate that tests if HeroBonus matches our criteria // * root is node on which call was made (NULL will be replaced with this) - void getParents(TCNodes &out) const; //retrieves list of parent nodes (nodes to inherit bonuses from), source is the prinary asker - void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const; - - virtual std::string bonusToString(Bonus *bonus, bool description) const {return "";}; //description or bonus name - - ////////////////////////////////////////////////////////////////////////// //interface + void getAllBonuses(BonusList &out, const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = NULL) const; + void getBonuses(BonusList &out, const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = NULL) const; //as above but without duplicates + void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const; void getModifiersWDescr(TModDescr &out, const CSelector &selector) const; //out: pairs int getBonusesCount(const CSelector &selector) const; int valOfBonuses(const CSelector &selector) const; bool hasBonus(const CSelector &selector) const; BonusList getBonuses(const CSelector &selector, const CSelector &limit) const; - void getBonuses(BonusList &out, const CSelector &selector, const CSelector &limit) const; BonusList getBonuses(const CSelector &selector) const; + void getParents(TCNodes &out) const; //retrieves list of parent nodes (nodes to inherit bonuses from), //legacy interface int valOfBonuses(Bonus::BonusType type, const CSelector &selector) const; @@ -446,6 +445,7 @@ public: void battleTurnPassed(); //updates count of remaining turns and removed outdated bonuses void popBonuses(const CSelector &s); + virtual std::string bonusToString(Bonus *bonus, bool description) const {return "";}; //description or bonus name virtual std::string nodeName() const; void deserializationFix(); void exportBonus(Bonus * b);