|
@@ -131,7 +131,7 @@ public:
|
|
|
BONUS_NAME(SPELL_AFTER_ATTACK) /* subtype - spell id, value - chance %, additional info % 1000 - level, (additional info)/1000 -> [0 - all attacks, 1 - shot only, 2 - melee only*/ \
|
|
|
BONUS_NAME(SPELL_BEFORE_ATTACK) /* subtype - spell id, value - chance %, additional info % 1000 - level, (additional info)/1000 -> [0 - all attacks, 1 - shot only, 2 - melee only*/ \
|
|
|
BONUS_NAME(SPELL_RESISTANCE_AURA) /*eg. unicorns, value - resistance bonus in % for adjacent creatures*/ \
|
|
|
- BONUS_NAME(LEVEL_SPELL_IMMUNITY) /*creature is immune to all spell with level below or equal to value of this bonus*/ \
|
|
|
+ BONUS_NAME(LEVEL_SPELL_IMMUNITY) /*creature is immune to all spell with level below or equal to value of this bonus */ \
|
|
|
BONUS_NAME(BLOCK_MAGIC_ABOVE) /*blocks casting spells of the level > value */ \
|
|
|
BONUS_NAME(BLOCK_ALL_MAGIC) /*blocks casting spells*/ \
|
|
|
BONUS_NAME(TWO_HEX_ATTACK_BREATH) /*eg. dragons*/ \
|
|
@@ -245,11 +245,11 @@ public:
|
|
|
BONUS_VALUE(BASE_NUMBER)\
|
|
|
BONUS_VALUE(PERCENT_TO_ALL)\
|
|
|
BONUS_VALUE(PERCENT_TO_BASE)\
|
|
|
- BONUS_VALUE(INDEPENDENT_MAX) /*used for SPELL bonus*/ \
|
|
|
+ BONUS_VALUE(INDEPENDENT_MAX) /*used for SPELL bonus */\
|
|
|
BONUS_VALUE(INDEPENDENT_MIN) //used for SECONDARY_SKILL_PREMY bonus
|
|
|
|
|
|
/// Struct for handling bonuses of several types. Can be transferred to any hero
|
|
|
-struct DLL_LINKAGE Bonus
|
|
|
+struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>
|
|
|
{
|
|
|
enum { EVERY_TYPE = -1 };
|
|
|
|
|
@@ -267,7 +267,7 @@ struct DLL_LINKAGE Bonus
|
|
|
ONE_WEEK = 8, //at the end of week (bonus lasts till the end of week, thats NOT 7 days
|
|
|
N_TURNS = 16, //used during battles, after battle bonus is always removed
|
|
|
N_DAYS = 32,
|
|
|
- UNITL_BEING_ATTACKED = 64,/*removed after attack and counterattacks are performed*/
|
|
|
+ UNITL_BEING_ATTACKED = 64, /*removed after attack and counterattacks are performed*/
|
|
|
UNTIL_ATTACK = 128, /*removed after attack and counterattacks are performed*/
|
|
|
STACK_GETS_TURN = 256, /*removed when stack gets its turn - used for defensive stance*/
|
|
|
COMMANDER_KILLED = 512
|
|
@@ -334,7 +334,8 @@ struct DLL_LINKAGE Bonus
|
|
|
h & duration & type & subtype & source & val & sid & description & additionalInfo & turnsRemain & valType & effectRange & limiter & propagator;
|
|
|
}
|
|
|
|
|
|
- static bool compareByAdditionalInfo(const Bonus *a, const Bonus *b)
|
|
|
+ template <typename Ptr>
|
|
|
+ static bool compareByAdditionalInfo(const Ptr& a, const Ptr& b)
|
|
|
{
|
|
|
return a->additionalInfo < b->additionalInfo;
|
|
|
}
|
|
@@ -378,9 +379,9 @@ struct DLL_LINKAGE Bonus
|
|
|
{
|
|
|
return hb->duration & Bonus::COMMANDER_KILLED;
|
|
|
}
|
|
|
- static bool IsFrom(const Bonus &hb, ui8 source, ui32 id) //if id==0xffffff then id doesn't matter
|
|
|
+ static bool IsFrom(const Bonus *hb, ui8 source, ui32 id) //if id==0xffffff then id doesn't matter
|
|
|
{
|
|
|
- return hb.source==source && (id==0xffffff || hb.sid==id);
|
|
|
+ return hb->source==source && (id==0xffffff || hb->sid==id);
|
|
|
}
|
|
|
inline bool operator == (const BonusType & cf) const
|
|
|
{
|
|
@@ -398,8 +399,8 @@ struct DLL_LINKAGE Bonus
|
|
|
|
|
|
std::string Description() const;
|
|
|
|
|
|
- Bonus *addLimiter(TLimiterPtr Limiter); //returns this for convenient chain-calls
|
|
|
- Bonus *addPropagator(TPropagatorPtr Propagator); //returns this for convenient chain-calls
|
|
|
+ std::shared_ptr<Bonus> addLimiter(TLimiterPtr Limiter); //returns this for convenient chain-calls
|
|
|
+ std::shared_ptr<Bonus> addPropagator(TPropagatorPtr Propagator); //returns this for convenient chain-calls
|
|
|
};
|
|
|
|
|
|
DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus);
|
|
@@ -407,9 +408,10 @@ DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus);
|
|
|
|
|
|
class DLL_LINKAGE BonusList
|
|
|
{
|
|
|
-private:
|
|
|
- typedef std::vector<Bonus*> TInternalContainer;
|
|
|
+public:
|
|
|
+ typedef std::vector<std::shared_ptr<Bonus>> TInternalContainer;
|
|
|
|
|
|
+private:
|
|
|
TInternalContainer bonuses;
|
|
|
bool belongsToTree;
|
|
|
void changed();
|
|
@@ -427,24 +429,23 @@ public:
|
|
|
BonusList& operator=(const BonusList &bonusList);
|
|
|
|
|
|
// wrapper functions of the STL vector container
|
|
|
- std::vector<Bonus*>::size_type size() const { return bonuses.size(); }
|
|
|
- void push_back(Bonus* const &x);
|
|
|
- std::vector<Bonus*>::iterator erase (const int position);
|
|
|
+ TInternalContainer::size_type size() const { return bonuses.size(); }
|
|
|
+ void push_back(std::shared_ptr<Bonus> x);
|
|
|
+ TInternalContainer::iterator erase (const int position);
|
|
|
void clear();
|
|
|
bool empty() const { return bonuses.empty(); }
|
|
|
- void resize(std::vector<Bonus*>::size_type sz, Bonus* c = nullptr );
|
|
|
- void insert(std::vector<Bonus*>::iterator position, std::vector<Bonus*>::size_type n, Bonus* const &x);
|
|
|
- Bonus *const &operator[] (std::vector<Bonus*>::size_type n) { return bonuses[n]; }
|
|
|
- Bonus *const &operator[] (std::vector<Bonus*>::size_type n) const { return bonuses[n]; }
|
|
|
- Bonus *const &back() { return bonuses.back(); }
|
|
|
- Bonus *const &front() { return bonuses.front(); }
|
|
|
- Bonus *const &back() const { return bonuses.back(); }
|
|
|
- Bonus *const &front() const { return bonuses.front(); }
|
|
|
+ void resize(TInternalContainer::size_type sz, std::shared_ptr<Bonus> c = nullptr );
|
|
|
+ std::shared_ptr<Bonus> &operator[] (TInternalContainer::size_type n) { return bonuses[n]; }
|
|
|
+ const std::shared_ptr<Bonus> &operator[] (TInternalContainer::size_type n) const { return bonuses[n]; }
|
|
|
+ std::shared_ptr<Bonus> &back() { return bonuses.back(); }
|
|
|
+ std::shared_ptr<Bonus> &front() { return bonuses.front(); }
|
|
|
+ const std::shared_ptr<Bonus> &back() const { return bonuses.back(); }
|
|
|
+ const std::shared_ptr<Bonus> &front() const { return bonuses.front(); }
|
|
|
|
|
|
// There should be no non-const access to provide solid,robust bonus caching
|
|
|
- std::vector<Bonus*>::const_iterator begin() const { return bonuses.begin(); }
|
|
|
- std::vector<Bonus*>::const_iterator end() const { return bonuses.end(); }
|
|
|
- std::vector<Bonus*>::size_type operator-=(Bonus* const &i);
|
|
|
+ TInternalContainer::const_iterator begin() const { return bonuses.begin(); }
|
|
|
+ TInternalContainer::const_iterator end() const { return bonuses.end(); }
|
|
|
+ TInternalContainer::size_type operator-=(std::shared_ptr<Bonus> const &i);
|
|
|
|
|
|
// BonusList functions
|
|
|
int totalValue() const; //subtype -> subtype of bonus, if -1 then any
|
|
@@ -454,8 +455,8 @@ public:
|
|
|
void getBonuses(BonusList & out, const CSelector &selector) const;
|
|
|
|
|
|
//special find functions
|
|
|
- Bonus *getFirst(const CSelector &select);
|
|
|
- const Bonus *getFirst(const CSelector &select) const;
|
|
|
+ std::shared_ptr<Bonus> getFirst(const CSelector &select);
|
|
|
+ const std::shared_ptr<Bonus> getFirst(const CSelector &select) const;
|
|
|
int valOfBonuses(const CSelector &select) const;
|
|
|
|
|
|
//void limit(const CBonusSystemNode &node); //erases bonuses using limitor
|
|
@@ -468,8 +469,8 @@ public:
|
|
|
BonusList newList;
|
|
|
for (ui32 i = 0; i < bonuses.size(); i++)
|
|
|
{
|
|
|
- Bonus *b = bonuses[i];
|
|
|
- if (!pred(b))
|
|
|
+ auto b = bonuses[i];
|
|
|
+ if (!pred(b.get()))
|
|
|
newList.push_back(b);
|
|
|
}
|
|
|
bonuses.clear();
|
|
@@ -479,10 +480,12 @@ public:
|
|
|
|
|
|
template <class InputIterator>
|
|
|
void insert(const int position, InputIterator first, InputIterator last);
|
|
|
+ void insert(TInternalContainer::iterator position, TInternalContainer::size_type n, std::shared_ptr<Bonus> const &x);
|
|
|
|
|
|
- template <typename Handler> void serialize(Handler &h, const int version)
|
|
|
+ template <typename Handler>
|
|
|
+ void serialize(Handler &h, const int version)
|
|
|
{
|
|
|
- h & static_cast<std::vector<Bonus*>&>(bonuses);
|
|
|
+ h & static_cast<TInternalContainer&>(bonuses);
|
|
|
}
|
|
|
|
|
|
// C++ for range support
|
|
@@ -549,7 +552,7 @@ public:
|
|
|
|
|
|
struct BonusLimitationContext
|
|
|
{
|
|
|
- const Bonus *b;
|
|
|
+ const std::shared_ptr<Bonus> b;
|
|
|
const CBonusSystemNode &node;
|
|
|
const BonusList &alreadyAccepted;
|
|
|
};
|
|
@@ -583,7 +586,7 @@ public:
|
|
|
const TBonusListPtr getBonuses(const CSelector &selector, const std::string &cachingStr = "") const;
|
|
|
|
|
|
const TBonusListPtr getAllBonuses() const;
|
|
|
- const Bonus *getBonus(const CSelector &selector) const; //returns any bonus visible on node that matches (or nullptr if none matches)
|
|
|
+ const std::shared_ptr<Bonus> getBonus(const CSelector &selector) const; //returns any bonus visible on node that matches (or nullptr if none matches)
|
|
|
|
|
|
//legacy interface
|
|
|
int valOfBonuses(Bonus::BonusType type, const CSelector &selector) const;
|
|
@@ -603,7 +606,7 @@ public:
|
|
|
bool isLiving() const; //non-undead, non-non living or alive
|
|
|
virtual si32 magicResistance() const;
|
|
|
ui32 Speed(int turn = 0, bool useBind = false) const; //get speed of creature with all modificators
|
|
|
- const Bonus * getEffect(ui16 id, int turn = 0) const; //effect id (SP)
|
|
|
+ const std::shared_ptr<Bonus> getEffect(ui16 id, int turn = 0) const; //effect id (SP)
|
|
|
ui8 howManyEffectsSet(ui16 id) const; //returns amount of effects with given id set for this stack
|
|
|
|
|
|
si32 manaLimit() const; //maximum mana value for this hero (basically 10*knowledge)
|
|
@@ -652,7 +655,7 @@ public:
|
|
|
TBonusListPtr limitBonuses(const BonusList &allBonuses) const; //same as above, returns out by val for convienence
|
|
|
const TBonusListPtr getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = nullptr, const std::string &cachingStr = "") const override;
|
|
|
void getParents(TCNodes &out) const; //retrieves list of parent nodes (nodes to inherit bonuses from),
|
|
|
- const Bonus *getBonusLocalFirst(const CSelector &selector) const;
|
|
|
+ const std::shared_ptr<Bonus> getBonusLocalFirst(const CSelector &selector) const;
|
|
|
|
|
|
//non-const interface
|
|
|
void getParents(TNodes &out); //retrieves list of parent nodes (nodes to inherit bonuses from)
|
|
@@ -660,35 +663,35 @@ public:
|
|
|
void getRedAncestors(TNodes &out);
|
|
|
void getRedChildren(TNodes &out);
|
|
|
void getRedDescendants(TNodes &out);
|
|
|
- Bonus *getBonusLocalFirst(const CSelector &selector);
|
|
|
+ std::shared_ptr<Bonus> getBonusLocalFirst(const CSelector &selector);
|
|
|
|
|
|
void attachTo(CBonusSystemNode *parent);
|
|
|
void detachFrom(CBonusSystemNode *parent);
|
|
|
void detachFromAll();
|
|
|
- virtual void addNewBonus(Bonus *b); //b will be deleted with destruction of node
|
|
|
- void accumulateBonus(Bonus &b); //add value of bonus with same type/subtype or create new
|
|
|
+ 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
|
|
|
|
|
|
void newChildAttached(CBonusSystemNode *child);
|
|
|
void childDetached(CBonusSystemNode *child);
|
|
|
- void propagateBonus(Bonus * b);
|
|
|
- void unpropagateBonus(Bonus * b);
|
|
|
+ void propagateBonus(std::shared_ptr<Bonus> b);
|
|
|
+ void unpropagateBonus(std::shared_ptr<Bonus> b);
|
|
|
//void addNewBonus(const Bonus &b); //b will copied
|
|
|
- void removeBonus(Bonus *b);
|
|
|
+ void removeBonus(const std::shared_ptr<Bonus>& b);
|
|
|
void newRedDescendant(CBonusSystemNode *descendant); //propagation needed
|
|
|
void removedRedDescendant(CBonusSystemNode *descendant); //de-propagation needed
|
|
|
void battleTurnPassed(); //updates count of remaining turns and removed outdated bonuses
|
|
|
|
|
|
bool isIndependentNode() const; //node is independent when it has no parents nor children
|
|
|
bool actsAsBonusSourceOnly() const;
|
|
|
- //bool isLimitedOnUs(Bonus *b) const; //if bonus should be removed from list acquired from this node
|
|
|
+ //bool isLimitedOnUs(std::shared_ptr<Bonus>b) const; //if bonus should be removed from list acquired from this node
|
|
|
|
|
|
void popBonuses(const CSelector &s);
|
|
|
void updateBonuses(const CSelector &s);
|
|
|
- virtual std::string bonusToString(const Bonus *bonus, bool description) const {return "";}; //description or bonus name
|
|
|
+ virtual std::string bonusToString(const std::shared_ptr<Bonus>& bonus, bool description) const {return "";}; //description or bonus name
|
|
|
virtual std::string nodeName() const;
|
|
|
|
|
|
void deserializationFix();
|
|
|
- void exportBonus(Bonus * b);
|
|
|
+ void exportBonus(std::shared_ptr<Bonus> b);
|
|
|
void exportBonuses();
|
|
|
|
|
|
const BonusList &getBonusList() const;
|
|
@@ -736,9 +739,9 @@ inline Bonus makeFeatureVal(Bonus::BonusType type, ui8 duration, si16 subtype, s
|
|
|
}
|
|
|
|
|
|
///generates HeroBonus from given data
|
|
|
-inline Bonus * makeFeature(Bonus::BonusType type, ui8 duration, si16 subtype, si32 value, Bonus::BonusSource source, ui16 turnsRemain = 0, si32 additionalInfo = 0)
|
|
|
+inline std::shared_ptr<Bonus> makeFeature(Bonus::BonusType type, ui8 duration, si16 subtype, si32 value, Bonus::BonusSource source, ui16 turnsRemain = 0, si32 additionalInfo = 0)
|
|
|
{
|
|
|
- return new Bonus(makeFeatureVal(type, duration, subtype, value, source, turnsRemain, additionalInfo));
|
|
|
+ return std::make_shared<Bonus>(makeFeatureVal(type, duration, subtype, value, source, turnsRemain, additionalInfo));
|
|
|
}
|
|
|
|
|
|
template<typename T>
|