Browse Source

* a few fixes for CStack.effects removal - more should come

mateuszb 15 years ago
parent
commit
608e26b453
6 changed files with 62 additions and 32 deletions
  1. 5 4
      client/CBattleInterface.cpp
  2. 6 8
      client/GUIClasses.cpp
  3. 25 3
      lib/CGameState.cpp
  4. 2 0
      lib/CGameState.h
  5. 23 17
      lib/HeroBonus.cpp
  6. 1 0
      lib/HeroBonus.h

+ 5 - 4
client/CBattleInterface.cpp

@@ -3010,17 +3010,18 @@ void CBattleInterface::showAliveStack(int ID, const std::map<int, CStack> & stac
 
 		//blitting amoutn background box
 		SDL_Surface *amountBG = NULL;
-		if(!curStack.bonuses.size())
+		BonusList spellEffects = curStack.getSpellBonuses();
+		if(!spellEffects.size())
 		{
 			amountBG = amountNormal;
 		}
 		else
 		{
 			int pos=0; //determining total positiveness of effects
-			for(BonusList::const_iterator it = curStack.bonuses.begin(); it != curStack.bonuses.end(); it++)
+			std::vector<si32> spellIds = curStack.activeSpells();
+			for(std::vector<si32>::const_iterator it = spellIds.begin(); it != spellIds.end(); it++)
 			{
-				if (it->source == Bonus::CASTED_SPELL)
-					pos += CGI->spellh->spells[ it->id ].positiveness;
+				pos += CGI->spellh->spells[ *it ].positiveness;
 			}
 			if(pos > 0)
 			{

+ 6 - 8
client/GUIClasses.cpp

@@ -2148,15 +2148,13 @@ CCreInfoWindow::CCreInfoWindow(const CStackInstance &st, int Type, boost::functi
 	{
 		//spell effects
 		int printed=0; //how many effect pics have been printed
-		BOOST_FOREACH(const Bonus effect, battleStack->bonuses)
+		std::vector<si32> spells = battleStack->activeSpells();
+		BOOST_FOREACH(si32 effect, spells)
 		{
-			if (effect.source == Bonus::CASTED_SPELL)
-			{
-				blitAt(graphics->spellEffectsPics->ourImages[effect.id + 1].bitmap, 127 + 52 * printed, 186, *bitmap); 
-				++printed;
-				if(printed >= 3) //we can fit only 3 effects
-					break;
-			}
+			blitAt(graphics->spellEffectsPics->ourImages[effect + 1].bitmap, 127 + 52 * printed, 186, *bitmap); 
+			++printed;
+			if(printed >= 3) //we can fit only 3 effects
+				break;
 		}
 
 		//print current health

+ 25 - 3
lib/CGameState.cpp

@@ -746,7 +746,7 @@ const Bonus * CStack::getEffect( ui16 id, int turn /*= 0*/ ) const
 {
 	for (BonusList::const_iterator it = bonuses.begin(); it != bonuses.end(); it++)
 	{
-		if(it->id == id)
+		if(it->source == Bonus::SPELL_EFFECT && it->id == id)
 		{
 			if(!turn || it->turnsRemain > turn)
 				return &(*it);
@@ -926,7 +926,7 @@ ui8 CStack::howManyEffectsSet(ui16 id) const
 {
 	ui8 ret = 0;
 	for (BonusList::const_iterator it = bonuses.begin(); it != bonuses.end(); it++)
-		if(it->id == id) //effect found
+		if(it->source == Bonus::SPELL_EFFECT && it->id == id) //effect found
 		{
 			++ret;
 		}
@@ -973,6 +973,28 @@ int CStack::occupiedHex() const
 		return -1;
 	}
 }
+BonusList CStack::getSpellBonuses() const
+{
+	return getBonuses(Selector::sourceTypeSel(Bonus::SPELL_EFFECT));
+}
+
+std::vector<si32> CStack::activeSpells() const
+{
+	//spell ID deduplication (some spells have many corresponding bonuses)
+	//TODO: what about spells that casted multiple times, have their effect muliplied? std::pair<spell id, time> or what?
+	std::vector<si32> ret;
+
+	BonusList spellEffects = getSpellBonuses();
+	std::set<int> spellIds;
+	for(BonusList::const_iterator it = spellEffects.begin(); it != spellEffects.end(); it++)
+	{
+		spellIds.insert(it->id);
+	}
+	ret.resize(spellIds.size());
+	std::copy(spellIds.begin(), spellIds.end(), ret.begin());
+
+	return ret;
+}
 
 CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, int player, const CTown *town, std::map<ui32,CGHeroInstance *> &available, const CHeroClass *bannedClass /*= NULL*/) const
 {
@@ -3219,7 +3241,7 @@ std::pair<ui32, ui32> BattleInfo::calculateDmgRange( const CStack* attacker, con
 		{
 			for (BonusList::const_iterator it = stack->bonuses.begin(); it != stack->bonuses.end(); it++)
 			{
-				if (it->id == 28 && it->val >= 2)
+				if (it->source == Bonus::SPELL_EFFECT && it->id == 28 && it->val >= 2)
 				{
 					return true;
 				}

+ 2 - 0
lib/CGameState.h

@@ -272,7 +272,9 @@ public:
 	bool moved(int turn = 0) const; //if stack was already moved this turn
 	bool canMove(int turn = 0) const; //if stack can move
 	ui32 Speed(int turn = 0) const; //get speed of creature with all modificators
+	BonusList getSpellBonuses() const;
 	void stackEffectToFeature(BonusList & sf, const Bonus & sse);
+	std::vector<si32> activeSpells() const; //returns vector of active spell IDs sorted by time of cast
 
 	static inline Bonus featureGenerator(Bonus::BonusType type, si16 subtype, si32 value, ui16 turnsRemain, si32 additionalInfo = 0, si32 limit = Bonus::NO_LIMIT)
 	{

+ 23 - 17
lib/HeroBonus.cpp

@@ -98,26 +98,27 @@ void DLL_EXPORT BonusList::getBonuses(BonusList &out, const CSelector &selector,
 		if(selector(*i) && (!limit || limit(*i)))
 			out.push_back(*i);
 }
-void DLL_EXPORT BonusList::removeSpells(Bonus::BonusSource sourceType)
+
+namespace HHLP
 {
-limit_start:
-	for(iterator i = begin(); i != end(); i++)
-	{ 
-		if (i->source == sourceType)
+	class SourceComp
+	{
+	public:
+		Bonus::BonusSource src;
+		SourceComp(Bonus::BonusSource _src) : src(src)
 		{
-			iterator toErase = i;
-			if(i != begin())
-			{
-				i--;
-				erase(toErase);
-			}
-			else
-			{
-				erase(toErase);
-				goto limit_start;
-			}
 		}
-	}
+		bool operator()(const Bonus & bon)
+		{
+			return bon.source == src;
+		}
+	};
+}
+
+
+void DLL_EXPORT BonusList::removeSpells(Bonus::BonusSource sourceType)
+{
+	std::remove_if(begin(), end(), HHLP::SourceComp(sourceType));
 }
 
 void BonusList::limit(const CBonusSystemNode &node)
@@ -454,6 +455,11 @@ namespace Selector
 		return CSelectFieldEqual<ui8>(&Bonus::source, source) && CSelectFieldEqual<ui32>(&Bonus::id, sourceID);
 	}
 
+	CSelector DLL_EXPORT sourceTypeSel(ui8 source)
+	{
+		return CSelectFieldEqual<ui8>(&Bonus::source, source);
+	}
+
 	bool DLL_EXPORT matchesType(const CSelector &sel, TBonusType type)
 	{
 		Bonus dummy;

+ 1 - 0
lib/HeroBonus.h

@@ -526,6 +526,7 @@ namespace Selector
 	CSelector DLL_EXPORT typeSybtype(TBonusType Type, TBonusSubtype Subtype);
 	CSelector DLL_EXPORT typeSybtypeInfo(TBonusType type, TBonusSubtype subtype, si32 info);
 	CSelector DLL_EXPORT source(ui8 source, ui32 sourceID);
+	CSelector DLL_EXPORT sourceTypeSel(ui8 source);
 
 	bool DLL_EXPORT matchesType(const CSelector &sel, TBonusType type);
 	bool DLL_EXPORT matchesTypeSubtype(const CSelector &sel, TBonusType type, TBonusSubtype subtype);