瀏覽代碼

Merge pull request #139 from ArseniyShestakov/fixDaysBonusDuration

Bonus system: N_DAYS duration support and new CWillLastDays selector
ArseniyShestakov 10 年之前
父節點
當前提交
b8ccb5916c
共有 3 個文件被更改,包括 45 次插入12 次删除
  1. 17 12
      lib/HeroBonus.cpp
  2. 27 0
      lib/HeroBonus.h
  3. 1 0
      lib/NetPacksLib.cpp

+ 17 - 12
lib/HeroBonus.cpp

@@ -763,6 +763,21 @@ void CBonusSystemNode::popBonuses(const CSelector &s)
 		child->popBonuses(s);
 }
 
+void CBonusSystemNode::updateBonuses(const CSelector &s)
+{
+	BonusList bl;
+	exportedBonuses.getBonuses(bl, s);
+	for(Bonus *b : bl)
+	{
+		b->turnsRemain--;
+		if(b->turnsRemain <= 0)
+			removeBonus(b);
+	}
+
+	for(CBonusSystemNode *child : children)
+		child->updateBonuses(s);
+}
+
 void CBonusSystemNode::addNewBonus(Bonus *b)
 {
 	assert(!vstd::contains(exportedBonuses,b));
@@ -950,18 +965,7 @@ void CBonusSystemNode::getRedDescendants(TNodes &out)
 
 void CBonusSystemNode::battleTurnPassed()
 {
-	BonusList bonusesCpy = exportedBonuses; //copy, because removing bonuses invalidates iters
-	for (auto & elem : bonusesCpy)
-	{
-		Bonus *b = elem;
-
-		if(b->duration & Bonus::N_TURNS)
-		{
-			b->turnsRemain--;
-			if(b->turnsRemain <= 0)
-				removeBonus(b);
-		}
-	}
+	updateBonuses(Bonus::NTurns);
 }
 
 void CBonusSystemNode::exportBonus(Bonus * b)
@@ -1183,6 +1187,7 @@ namespace Selector
 	DLL_LINKAGE CSelectFieldEqual<Bonus::BonusSource> sourceType(&Bonus::source);
 	DLL_LINKAGE CSelectFieldEqual<Bonus::LimitEffect> effectRange(&Bonus::effectRange);
 	DLL_LINKAGE CWillLastTurns turns;
+	DLL_LINKAGE CWillLastDays days;
 	DLL_LINKAGE CSelectFieldAny<Bonus::LimitEffect> anyRange(&Bonus::effectRange);
 
 	CSelector DLL_LINKAGE typeSubtype(Bonus::BonusType Type, TBonusSubtype Subtype)

+ 27 - 0
lib/HeroBonus.h

@@ -686,6 +686,7 @@ public:
 	//bool isLimitedOnUs(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 nodeName() const;
 
@@ -820,6 +821,31 @@ public:
 	}
 };
 
+class DLL_LINKAGE CWillLastDays
+{
+public:
+	int daysRequested;
+
+	bool operator()(const Bonus *bonus) const
+	{
+		if(daysRequested <= 0)
+			return true;
+		else if(bonus->duration & Bonus::ONE_DAY)
+			return false;
+		else if(bonus->duration & Bonus::N_DAYS)
+		{
+			return bonus->turnsRemain > daysRequested;
+		}
+
+		return false; // TODO: ONE_WEEK need support for turnsRemain, but for now we'll exclude all unhandled durations
+	}
+	CWillLastDays& operator()(const int &setVal)
+	{
+		daysRequested = setVal;
+		return *this;
+	}
+};
+
 //Stores multiple limiters. If any of them fails -> bonus is dropped.
 class DLL_LINKAGE LimiterList : public ILimiter
 {
@@ -958,6 +984,7 @@ namespace Selector
 	extern DLL_LINKAGE CSelectFieldEqual<Bonus::BonusSource> sourceType;
 	extern DLL_LINKAGE CSelectFieldEqual<Bonus::LimitEffect> effectRange;
 	extern DLL_LINKAGE CWillLastTurns turns;
+	extern DLL_LINKAGE CWillLastDays days;
 	extern DLL_LINKAGE CSelectFieldAny<Bonus::LimitEffect> anyRange;
 
 	CSelector DLL_LINKAGE typeSubtype(Bonus::BonusType Type, TBonusSubtype Subtype);

+ 1 - 0
lib/NetPacksLib.cpp

@@ -1026,6 +1026,7 @@ DLL_LINKAGE void NewTurn::applyGs( CGameState *gs )
 	if(gs->getDate(Date::DAY_OF_WEEK) == 1) //new week
 		gs->globalEffects.popBonuses(Bonus::OneWeek); //works for children -> all game objs
 
+	gs->globalEffects.updateBonuses(Bonus::NDays);
 	//TODO not really a single root hierarchy, what about bonuses placed elsewhere? [not an issue with H3 mechanics but in the future...]
 
 	for(CGTownInstance* t : gs->map->towns)