1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-25 21:38:59 +02:00

Use new battleGetStacksIf method

This commit is contained in:
AlexVinS 2014-05-17 14:36:49 +04:00
parent 0e93ec28c5
commit d9368ca5ba
4 changed files with 27 additions and 34 deletions

View File

@ -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();
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;
};
//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);
});
}
TStacks stacks = battleGetStacksIf(predicate);
//now handle smart targeting and remove invalid targets
const bool smartNegative = ti.smart && spell->isNegative();
const bool smartPositive = ti.smart && spell->isPositive();
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

View File

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

View File

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

View File

@ -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())
{