Browse Source

- Some work on bonus system, effect range can be ignored. TODO: usage of bonus with any subtype.
- Fixed #1156

DjWarmonger 12 năm trước cách đây
mục cha
commit
928d1d2121
3 tập tin đã thay đổi với 48 bổ sung2 xóa
  1. 1 1
      client/CCreatureWindow.cpp
  2. 3 1
      lib/HeroBonus.cpp
  3. 44 0
      lib/HeroBonus.h

+ 1 - 1
client/CCreatureWindow.cpp

@@ -248,7 +248,7 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
 	}
 
 	BonusList bl, blTemp;
-	blTemp = (*(stackNode->getBonuses(Selector::durationType(Bonus::PERMANENT))));
+	blTemp = (*(stackNode->getBonuses(Selector::durationType(Bonus::PERMANENT) && Selector::anyRange())));
 
 	while (blTemp.size())
 	{

+ 3 - 1
lib/HeroBonus.cpp

@@ -496,7 +496,7 @@ const TBonusListPtr IBonusBearer::getSpellBonuses() const
 {
 	std::stringstream cachingStr;
 	cachingStr << "source_" << Bonus::SPELL_EFFECT;
-	return getBonuses(Selector::sourceType(Bonus::SPELL_EFFECT), cachingStr.str());
+	return getBonuses(Selector::sourceType(Bonus::SPELL_EFFECT), Selector::anyRange(), cachingStr.str());
 }
 
 const Bonus * IBonusBearer::getEffect(ui16 id, int turn /*= 0*/) const
@@ -1183,6 +1183,8 @@ namespace Selector
 	DLL_LINKAGE CSelectFieldEqual<Bonus::BonusSource> sourceType(&Bonus::source, Bonus::OTHER);
 	DLL_LINKAGE CSelectFieldEqual<Bonus::LimitEffect> effectRange(&Bonus::effectRange, Bonus::NO_LIMIT);
 	DLL_LINKAGE CWillLastTurns turns;
+	DLL_LINKAGE CSelectFieldAny<Bonus::LimitEffect> anyRange (&Bonus::effectRange);
+	DLL_LINKAGE CSelectFieldEqualOrEvery<TBonusSubtype> everySubtype (&Bonus::subtype, 0);
 
 	CSelector DLL_LINKAGE typeSubtype(Bonus::BonusType Type, TBonusSubtype Subtype)
 	{

+ 44 - 0
lib/HeroBonus.h

@@ -209,6 +209,8 @@ typedef boost::function<bool(const Bonus*)> CSelector;
 /// Struct for handling bonuses of several types. Can be transferred to any hero
 struct DLL_LINKAGE Bonus
 {
+	#define EVERY_TYPE -1;
+
 	enum BonusType
 	{
 #define BONUS_NAME(x) x,
@@ -730,6 +732,46 @@ public:
 	}
 };
 
+template<typename T>
+class CSelectFieldAny //allows to ignore value of certain field, that is to accept any value
+{
+	T Bonus::*ptr;
+public:
+	CSelectFieldAny(T Bonus::*Ptr)
+		: ptr(Ptr)
+	{
+	}
+	bool operator()(const Bonus *bonus) const
+	{
+		return true;
+	}
+	CSelectFieldAny& operator()()
+	{
+		return *this;
+	}
+};
+
+template<typename T> //can be same, needed for subtype field
+class CSelectFieldEqualOrEvery
+{
+	T Bonus::*ptr;
+	T val;
+public:
+	CSelectFieldEqualOrEvery(T Bonus::*Ptr, const T &Val)
+		: ptr(Ptr), val(Val)
+	{
+	}
+	bool operator()(const Bonus *bonus) const
+	{
+		return (bonus->*ptr == val) || (bonus->*ptr == static_cast<T>(Bonus::EVERY_TYPE));
+	}
+	CSelectFieldEqualOrEvery& operator()(const T &setVal)
+	{
+		val = setVal;
+		return *this;
+	}
+};
+
 class DLL_LINKAGE CWillLastTurns
 {
 public:
@@ -887,6 +929,8 @@ namespace Selector
 	extern DLL_LINKAGE CSelectFieldEqual<Bonus::BonusSource> sourceType;
 	extern DLL_LINKAGE CSelectFieldEqual<Bonus::LimitEffect> effectRange;
 	extern DLL_LINKAGE CWillLastTurns turns;
+	extern DLL_LINKAGE CSelectFieldAny<Bonus::LimitEffect> anyRange;
+	extern DLL_LINKAGE CSelectFieldEqualOrEvery<TBonusSubtype> everySubtype;
 
 	CSelector DLL_LINKAGE typeSubtype(Bonus::BonusType Type, TBonusSubtype Subtype);
 	CSelector DLL_LINKAGE typeSubtypeInfo(Bonus::BonusType type, TBonusSubtype subtype, si32 info);