浏览代码

Use new battleGetStacksIf method

AlexVinS 11 年之前
父节点
当前提交
d9368ca5ba
共有 4 个文件被更改,包括 27 次插入34 次删除
  1. 17 28
      lib/CBattleCallback.cpp
  2. 6 0
      lib/CSpellHandler.cpp
  3. 1 0
      lib/CSpellHandler.h
  4. 3 6
      server/CGameHandler.cpp

+ 17 - 28
lib/CBattleCallback.cpp

@@ -2097,31 +2097,24 @@ std::set<const CStack*> CBattleInfoCallback::getAffectedCreatures(const CSpell *
 	}
 	else if(spell->getTargetType() == CSpell::CREATURE)
 	{
-		//start with all stacks. 
-		TStacks stacks = battleGetAllStacks();
-		
-		//for single target spells remove stacks from other hexes
-		if(!ti.massive)
-		{
-			vstd::erase_if(stacks,[&](const CStack * stack){
-				return !vstd::contains(stack->getHexes(), destinationTile);
-			});
-		}
+		auto predicate = [=](const CStack * s){
+			const bool positiveToAlly = spell->isPositive() && s->owner == attackerOwner;
+			const bool negativeToEnemy = spell->isNegative() && s->owner != attackerOwner;
+			const bool validTarget = s->isValidTarget(!onlyAlive); //todo: this should be handled by spell class
+	
+			//for single target spells select stacks covering destination tile
+			const bool rangeCovers = ti.massive || s->coversPos(destinationTile);
+			//handle smart targeting
+			const bool positivenessFlag = !ti.smart || spell->isNeutral() || positiveToAlly || negativeToEnemy;
+			
+			return rangeCovers  && positivenessFlag && validTarget;		
+		};
 		
-		//now handle smart targeting and remove invalid targets
-		const bool smartNegative = ti.smart && spell->isNegative();
-		const bool smartPositive = ti.smart && spell->isPositive();
+		TStacks stacks = battleGetStacksIf(predicate);
 		
-		vstd::erase_if(stacks,[&](const CStack * stack){
-			const bool negativeToAlly = smartNegative && stack->owner == attackerOwner;
-			const bool positiveToEnemy = smartPositive && stack->owner != attackerOwner;
-			const bool invalidTarget = !stack->isValidTarget(!onlyAlive); //todo: this should be handled by spell class
-			return negativeToAlly || positiveToEnemy || invalidTarget;
-		});
-
 		if (ti.massive)
 		{
-			//for massive spells add all remaining targets
+			//for massive spells add all targets
 			for (auto stack : stacks)
 				attackedCres.insert(stack);
 
@@ -2462,22 +2455,18 @@ bool CPlayerBattleCallback::battleCanFlee() const
 
 TStacks CPlayerBattleCallback::battleGetStacks(EStackOwnership whose /*= MINE_AND_ENEMY*/, bool onlyAlive /*= true*/) const
 {
-	TStacks ret;
-	RETURN_IF_NOT_BATTLE(ret);
 	if(whose != MINE_AND_ENEMY)
 	{
 		ASSERT_IF_CALLED_WITH_PLAYER
 	}
-	vstd::copy_if(battleGetAllStacks(), std::back_inserter(ret), [=](const CStack *s) -> bool
-	{
+	
+	return battleGetStacksIf([=](const CStack * s){
 		const bool ownerMatches = (whose == MINE_AND_ENEMY)
 			|| (whose == ONLY_MINE && s->owner == player)
 			|| (whose == ONLY_ENEMY && s->owner != player);
 		const bool alivenessMatches = s->alive()  ||  !onlyAlive;
-		return ownerMatches && alivenessMatches;
+		return ownerMatches && alivenessMatches;		
 	});
-
-	return ret;
 }
 
 int CPlayerBattleCallback::battleGetSurrenderCost() const

+ 6 - 0
lib/CSpellHandler.cpp

@@ -317,6 +317,12 @@ bool CSpell::isNegative() const
 	return positiveness == NEGATIVE;
 }
 
+bool CSpell::isNeutral() const
+{
+	return positiveness == NEUTRAL;
+}
+
+
 bool CSpell::isRisingSpell() const
 {
 	return isRising;

+ 1 - 0
lib/CSpellHandler.h

@@ -96,6 +96,7 @@ public:
 
 	bool isPositive() const;
 	bool isNegative() const;
+	bool isNeutral() const;
 
 	bool isRisingSpell() const;
 	bool isDamageSpell() const;

+ 3 - 6
server/CGameHandler.cpp

@@ -5983,12 +5983,9 @@ void CGameHandler::runBattle()
 
 			if(next->getCreature()->idNumber == CreatureID::FIRST_AID_TENT)
 			{
-				std::vector< const CStack * > possibleStacks;
-
-				//is there any clean algorithm for that? (boost.range seems to lack copy_if) -> remove_copy_if?
-				for(const CStack *s : battleGetAllStacks())
-					if(s->owner == next->owner  &&  s->canBeHealed())
-						possibleStacks.push_back(s);
+				TStacks possibleStacks = battleGetStacksIf([&](const CStack * s){
+					return s->owner == next->owner  &&  s->canBeHealed();
+				});
 
 				if(!possibleStacks.size())
 				{