mirror of
https://github.com/vcmi/vcmi.git
synced 2025-10-08 23:22:25 +02:00
Update low level battle stacks accessor for ghost selection support.
This commit is contained in:
@@ -1139,9 +1139,24 @@ std::string CStack::getName() const
|
|||||||
return (count > 1) ? type->namePl : type->nameSing; //War machines can't use base
|
return (count > 1) ? type->namePl : type->nameSing; //War machines can't use base
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CStack::isValidTarget(bool allowDead/* = false*/) const /*alive non-turret stacks (can be attacked or be object of magic effect) */
|
bool CStack::isValidTarget(bool allowDead/* = false*/) const
|
||||||
{
|
{
|
||||||
return !isGhost() && (alive() || allowDead) && position.isValid();
|
return (alive() || (allowDead && isDead())) && position.isValid() && !isTurret();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CStack::isDead() const
|
||||||
|
{
|
||||||
|
return !alive() && !isGhost();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CStack::isGhost() const
|
||||||
|
{
|
||||||
|
return vstd::contains(state,EBattleStackState::GHOST);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CStack::isTurret() const
|
||||||
|
{
|
||||||
|
return type->idNumber == CreatureID::ARROW_TOWERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CStack::canBeHealed() const
|
bool CStack::canBeHealed() const
|
||||||
|
@@ -289,11 +289,11 @@ public:
|
|||||||
{
|
{
|
||||||
return vstd::contains(state,EBattleStackState::ALIVE);
|
return vstd::contains(state,EBattleStackState::ALIVE);
|
||||||
}
|
}
|
||||||
bool isGhost() const //determines if stack was removed
|
|
||||||
{
|
bool isDead() const;
|
||||||
return vstd::contains(state,EBattleStackState::GHOST);
|
bool isGhost() const; //determines if stack was removed
|
||||||
}
|
bool isValidTarget(bool allowDead = false) const; //non-turret non-ghost stacks (can be attacked or be object of magic effect)
|
||||||
bool isValidTarget(bool allowDead = false) const; //alive non-turret stacks (can be attacked or be object of magic effect)
|
bool isTurret() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CMP_stack
|
class DLL_LINKAGE CMP_stack
|
||||||
|
@@ -180,33 +180,33 @@ bool CBattleInfoEssentials::battleHasNativeStack(ui8 side) const
|
|||||||
|
|
||||||
TStacks CBattleInfoEssentials::battleGetAllStacks(bool includeTurrets /*= false*/) const
|
TStacks CBattleInfoEssentials::battleGetAllStacks(bool includeTurrets /*= false*/) const
|
||||||
{
|
{
|
||||||
return battleGetStacksIf([](const CStack * s){return true;},includeTurrets);
|
return battleGetStacksIf([=](const CStack * s)
|
||||||
|
{
|
||||||
|
return !s->isGhost() && (includeTurrets || !s->isTurret());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
TStacks CBattleInfoEssentials::battleGetStacksIf(TStackFilter predicate, bool includeTurrets /*= false*/) const
|
TStacks CBattleInfoEssentials::battleGetStacksIf(TStackFilter predicate) const
|
||||||
{
|
{
|
||||||
TStacks ret;
|
TStacks ret;
|
||||||
RETURN_IF_NOT_BATTLE(ret);
|
RETURN_IF_NOT_BATTLE(ret);
|
||||||
|
|
||||||
vstd::copy_if(getBattle()->stacks, std::back_inserter(ret), [=](const CStack * s){
|
vstd::copy_if(getBattle()->stacks, std::back_inserter(ret), predicate);
|
||||||
return predicate(s) && (!s->isGhost()) && (includeTurrets || !(s->type->idNumber == CreatureID::ARROW_TOWERS));
|
|
||||||
});
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TStacks CBattleInfoEssentials::battleAliveStacks() const
|
TStacks CBattleInfoEssentials::battleAliveStacks() const
|
||||||
{
|
{
|
||||||
return battleGetStacksIf([](const CStack * s){
|
return battleGetStacksIf([](const CStack * s){
|
||||||
return s->alive();
|
return s->isValidTarget(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
TStacks CBattleInfoEssentials::battleAliveStacks(ui8 side) const
|
TStacks CBattleInfoEssentials::battleAliveStacks(ui8 side) const
|
||||||
{
|
{
|
||||||
return battleGetStacksIf([=](const CStack * s){
|
return battleGetStacksIf([=](const CStack * s){
|
||||||
return s->alive() && s->attackerOwned == !side;
|
return s->isValidTarget(false) && s->attackerOwned == !side;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1304,8 +1304,8 @@ std::pair<const CStack *, BattleHex> CBattleInfoCallback::getNearestStack(const
|
|||||||
|
|
||||||
std::vector<const CStack *> possibleStacks = battleGetStacksIf([=](const CStack * s)
|
std::vector<const CStack *> possibleStacks = battleGetStacksIf([=](const CStack * s)
|
||||||
{
|
{
|
||||||
return s != closest && s->alive() && (boost::logic::indeterminate(attackerOwned) || s->attackerOwned == attackerOwned);
|
return s->isValidTarget(false) && s != closest && (boost::logic::indeterminate(attackerOwned) || s->attackerOwned == attackerOwned);
|
||||||
}, false);
|
});
|
||||||
|
|
||||||
for(const CStack * st : possibleStacks)
|
for(const CStack * st : possibleStacks)
|
||||||
for(BattleHex hex : avHexes)
|
for(BattleHex hex : avHexes)
|
||||||
@@ -2225,8 +2225,8 @@ TStacks CPlayerBattleCallback::battleGetStacks(EStackOwnership whose /*= MINE_AN
|
|||||||
const bool ownerMatches = (whose == MINE_AND_ENEMY)
|
const bool ownerMatches = (whose == MINE_AND_ENEMY)
|
||||||
|| (whose == ONLY_MINE && s->owner == player)
|
|| (whose == ONLY_MINE && s->owner == player)
|
||||||
|| (whose == ONLY_ENEMY && s->owner != player);
|
|| (whose == ONLY_ENEMY && s->owner != player);
|
||||||
const bool alivenessMatches = s->alive() || !onlyAlive;
|
|
||||||
return ownerMatches && alivenessMatches;
|
return ownerMatches && s->isValidTarget(!onlyAlive);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -178,7 +178,7 @@ public:
|
|||||||
* @return filtered stacks
|
* @return filtered stacks
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
TStacks battleGetStacksIf(TStackFilter predicate, bool includeTurrets = false) const;
|
TStacks battleGetStacksIf(TStackFilter predicate) const;
|
||||||
|
|
||||||
bool battleHasNativeStack(ui8 side) const;
|
bool battleHasNativeStack(ui8 side) const;
|
||||||
int battleGetMoatDmg() const; //what dmg unit will suffer if ending turn in the moat
|
int battleGetMoatDmg() const; //what dmg unit will suffer if ending turn in the moat
|
||||||
|
@@ -360,9 +360,8 @@ void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, BattleS
|
|||||||
TStacks mirrorTargets = parameters.cb->battleGetStacksIf([this, parameters](const CStack * battleStack)
|
TStacks mirrorTargets = parameters.cb->battleGetStacksIf([this, parameters](const CStack * battleStack)
|
||||||
{
|
{
|
||||||
//Get all enemy stacks. Magic mirror can reflect to immune creature (with no effect)
|
//Get all enemy stacks. Magic mirror can reflect to immune creature (with no effect)
|
||||||
return battleStack->owner == parameters.casterColor;
|
return battleStack->owner == parameters.casterColor && battleStack->isValidTarget(false);
|
||||||
},
|
});
|
||||||
true);//turrets included
|
|
||||||
|
|
||||||
if(!mirrorTargets.empty())
|
if(!mirrorTargets.empty())
|
||||||
{
|
{
|
||||||
@@ -711,7 +710,6 @@ std::set<const CStack *> DefaultSpellMechanics::getAffectedStacks(SpellTargeting
|
|||||||
//for massive spells add all targets
|
//for massive spells add all targets
|
||||||
for (auto stack : stacks)
|
for (auto stack : stacks)
|
||||||
attackedCres.insert(stack);
|
attackedCres.insert(stack);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -309,8 +309,9 @@ void CSpell::getEffects(std::vector<Bonus> & lst, const int level) const
|
|||||||
ESpellCastProblem::ESpellCastProblem CSpell::isImmuneAt(const CBattleInfoCallback * cb, const ISpellCaster * caster, ECastingMode::ECastingMode mode, BattleHex destination) const
|
ESpellCastProblem::ESpellCastProblem CSpell::isImmuneAt(const CBattleInfoCallback * cb, const ISpellCaster * caster, ECastingMode::ECastingMode mode, BattleHex destination) const
|
||||||
{
|
{
|
||||||
// Get all stacks at destination hex. only alive if not rising spell
|
// Get all stacks at destination hex. only alive if not rising spell
|
||||||
TStacks stacks = cb->battleGetStacksIf([=](const CStack * s){
|
TStacks stacks = cb->battleGetStacksIf([=](const CStack * s)
|
||||||
return s->coversPos(destination) && (isRisingSpell() || s->alive());
|
{
|
||||||
|
return s->coversPos(destination) && s->isValidTarget(isRisingSpell());
|
||||||
});
|
});
|
||||||
|
|
||||||
if(!stacks.empty())
|
if(!stacks.empty())
|
||||||
|
@@ -5703,7 +5703,8 @@ void CGameHandler::runBattle()
|
|||||||
|
|
||||||
if(next->getCreature()->idNumber == CreatureID::FIRST_AID_TENT)
|
if(next->getCreature()->idNumber == CreatureID::FIRST_AID_TENT)
|
||||||
{
|
{
|
||||||
TStacks possibleStacks = battleGetStacksIf([&](const CStack * s){
|
TStacks possibleStacks = battleGetStacksIf([=](const CStack * s)
|
||||||
|
{
|
||||||
return s->owner == next->owner && s->canBeHealed();
|
return s->owner == next->owner && s->canBeHealed();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user