mirror of
https://github.com/vcmi/vcmi.git
synced 2025-04-27 12:22:45 +02:00
move checks for invincible bonus to UnitState & cache
This commit is contained in:
parent
5cff9af236
commit
48473b18f6
@ -298,7 +298,7 @@ BattleHexArray CStack::meleeAttackHexes(const battle::Unit * attacker, const bat
|
|||||||
|
|
||||||
bool CStack::isMeleeAttackPossible(const battle::Unit * attacker, const battle::Unit * defender, BattleHex attackerPos, BattleHex defenderPos)
|
bool CStack::isMeleeAttackPossible(const battle::Unit * attacker, const battle::Unit * defender, BattleHex attackerPos, BattleHex defenderPos)
|
||||||
{
|
{
|
||||||
if(defender->hasBonusOfType(BonusType::INVINCIBLE))
|
if(defender->isInvincible())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !meleeAttackHexes(attacker, defender, attackerPos, defenderPos).empty();
|
return !meleeAttackHexes(attacker, defender, attackerPos, defenderPos).empty();
|
||||||
|
@ -675,7 +675,7 @@ bool CBattleInfoCallback::battleCanAttack(const battle::Unit * stack, const batt
|
|||||||
if (!stack || !target)
|
if (!stack || !target)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(target->hasBonusOfType(BonusType::INVINCIBLE))
|
if(target->isInvincible())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!battleMatchOwner(stack, target))
|
if(!battleMatchOwner(stack, target))
|
||||||
@ -744,7 +744,7 @@ bool CBattleInfoCallback::battleCanShoot(const battle::Unit * attacker, BattleHe
|
|||||||
if(!defender)
|
if(!defender)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(defender->hasBonusOfType(BonusType::INVINCIBLE))
|
if(defender->isInvincible())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -810,7 +810,7 @@ DamageEstimation CBattleInfoCallback::battleEstimateDamage(const BattleAttackInf
|
|||||||
if (!bai.defender->ableToRetaliate())
|
if (!bai.defender->ableToRetaliate())
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (bai.attacker->hasBonusOfType(BonusType::BLOCKS_RETALIATION) || bai.attacker->hasBonusOfType(BonusType::INVINCIBLE))
|
if (bai.attacker->hasBonusOfType(BonusType::BLOCKS_RETALIATION) || bai.attacker->isInvincible())
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
//TODO: rewrite using boost::numeric::interval
|
//TODO: rewrite using boost::numeric::interval
|
||||||
|
@ -700,6 +700,11 @@ bool CUnitState::isHypnotized() const
|
|||||||
return bonusCache.getBonusValue(UnitBonusValuesProxy::HYPNOTIZED);
|
return bonusCache.getBonusValue(UnitBonusValuesProxy::HYPNOTIZED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CUnitState::isInvincible() const
|
||||||
|
{
|
||||||
|
return bonusCache.getBonusValue(UnitBonusValuesProxy::INVINCIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
int CUnitState::getTotalAttacks(bool ranged) const
|
int CUnitState::getTotalAttacks(bool ranged) const
|
||||||
{
|
{
|
||||||
return 1 + (ranged ?
|
return 1 + (ranged ?
|
||||||
|
@ -193,6 +193,7 @@ public:
|
|||||||
bool isValidTarget(bool allowDead = false) const override;
|
bool isValidTarget(bool allowDead = false) const override;
|
||||||
|
|
||||||
bool isHypnotized() const override;
|
bool isHypnotized() const override;
|
||||||
|
bool isInvincible() const override;
|
||||||
|
|
||||||
bool isClone() const override;
|
bool isClone() const override;
|
||||||
bool hasClone() const override;
|
bool hasClone() const override;
|
||||||
|
@ -87,6 +87,7 @@ public:
|
|||||||
virtual bool isValidTarget(bool allowDead = false) const = 0; //non-turret non-ghost stacks (can be attacked or be object of magic effect)
|
virtual bool isValidTarget(bool allowDead = false) const = 0; //non-turret non-ghost stacks (can be attacked or be object of magic effect)
|
||||||
|
|
||||||
virtual bool isHypnotized() const = 0;
|
virtual bool isHypnotized() const = 0;
|
||||||
|
virtual bool isInvincible() const = 0;
|
||||||
|
|
||||||
virtual bool isClone() const = 0;
|
virtual bool isClone() const = 0;
|
||||||
virtual bool hasClone() const = 0;
|
virtual bool hasClone() const = 0;
|
||||||
|
@ -203,6 +203,7 @@ const UnitBonusValuesProxy::SelectorsArray * UnitBonusValuesProxy::generateSelec
|
|||||||
Selector::type()(BonusType::FORGETFULL),//FORGETFULL,
|
Selector::type()(BonusType::FORGETFULL),//FORGETFULL,
|
||||||
Selector::type()(BonusType::FREE_SHOOTING).Or(Selector::type()(BonusType::SIEGE_WEAPON)),//HAS_FREE_SHOOTING,
|
Selector::type()(BonusType::FREE_SHOOTING).Or(Selector::type()(BonusType::SIEGE_WEAPON)),//HAS_FREE_SHOOTING,
|
||||||
Selector::type()(BonusType::STACK_HEALTH),//STACK_HEALTH,
|
Selector::type()(BonusType::STACK_HEALTH),//STACK_HEALTH,
|
||||||
|
Selector::type()(BonusType::INVINCIBLE),//INVINCIBLE,
|
||||||
Selector::type()(BonusType::NONE).And(Selector::source(BonusSource::SPELL_EFFECT, BonusSourceID(SpellID(SpellID::CLONE))))
|
Selector::type()(BonusType::NONE).And(Selector::source(BonusSource::SPELL_EFFECT, BonusSourceID(SpellID(SpellID::CLONE))))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -116,6 +116,7 @@ public:
|
|||||||
FORGETFULL,
|
FORGETFULL,
|
||||||
HAS_FREE_SHOOTING,
|
HAS_FREE_SHOOTING,
|
||||||
STACK_HEALTH,
|
STACK_HEALTH,
|
||||||
|
INVINCIBLE,
|
||||||
|
|
||||||
CLONE_MARKER,
|
CLONE_MARKER,
|
||||||
|
|
||||||
|
@ -231,7 +231,7 @@ bool BattleSpellMechanics::canBeCastAt(const Target & target, Problem & problem)
|
|||||||
if(mainTarget && mainTarget == caster)
|
if(mainTarget && mainTarget == caster)
|
||||||
return false; // can't cast on self
|
return false; // can't cast on self
|
||||||
|
|
||||||
if(mainTarget && mainTarget->hasBonusOfType(BonusType::INVINCIBLE) && !getSpell()->getPositiveness())
|
if(mainTarget && mainTarget->isInvincible() && !getSpell()->getPositiveness())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if(getSpell()->canCastOnlyOnSelf())
|
else if(getSpell()->canCastOnlyOnSelf())
|
||||||
@ -259,7 +259,7 @@ std::vector<const CStack *> BattleSpellMechanics::getAffectedStacks(const Target
|
|||||||
|
|
||||||
for(const Destination & dest : all)
|
for(const Destination & dest : all)
|
||||||
{
|
{
|
||||||
if(dest.unitValue && !dest.unitValue->hasBonusOfType(BonusType::INVINCIBLE))
|
if(dest.unitValue && !dest.unitValue->isInvincible())
|
||||||
{
|
{
|
||||||
//FIXME: remove and return battle::Unit
|
//FIXME: remove and return battle::Unit
|
||||||
stacks.insert(battle()->battleGetStackByID(dest.unitValue->unitId(), false));
|
stacks.insert(battle()->battleGetStackByID(dest.unitValue->unitId(), false));
|
||||||
|
@ -434,7 +434,7 @@ int64_t CSpell::adjustRawDamage(const spells::Caster * caster, const battle::Uni
|
|||||||
}
|
}
|
||||||
|
|
||||||
//invincible
|
//invincible
|
||||||
if(bearer->hasBonusOfType(BonusType::INVINCIBLE))
|
if(affectedCreature->isInvincible())
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
ret = caster->getSpellBonus(this, ret, affectedCreature);
|
ret = caster->getSpellBonus(this, ret, affectedCreature);
|
||||||
|
@ -276,7 +276,7 @@ bool BattleActionProcessor::doAttackAction(const CBattleInfoCallback & battle, c
|
|||||||
for (int i = 0; i < totalAttacks; ++i)
|
for (int i = 0; i < totalAttacks; ++i)
|
||||||
{
|
{
|
||||||
//first strike
|
//first strike
|
||||||
if(i == 0 && firstStrike && retaliation && !stack->hasBonusOfType(BonusType::BLOCKS_RETALIATION) && !stack->hasBonusOfType(BonusType::INVINCIBLE))
|
if(i == 0 && firstStrike && retaliation && !stack->hasBonusOfType(BonusType::BLOCKS_RETALIATION) && !stack->isInvincible())
|
||||||
{
|
{
|
||||||
makeAttack(battle, destinationStack, stack, 0, stack->getPosition(), true, false, true);
|
makeAttack(battle, destinationStack, stack, 0, stack->getPosition(), true, false, true);
|
||||||
}
|
}
|
||||||
@ -303,7 +303,7 @@ bool BattleActionProcessor::doAttackAction(const CBattleInfoCallback & battle, c
|
|||||||
//we check retaliation twice, so if it unblocked during attack it will work only on next attack
|
//we check retaliation twice, so if it unblocked during attack it will work only on next attack
|
||||||
if(stack->alive()
|
if(stack->alive()
|
||||||
&& !stack->hasBonusOfType(BonusType::BLOCKS_RETALIATION)
|
&& !stack->hasBonusOfType(BonusType::BLOCKS_RETALIATION)
|
||||||
&& !stack->hasBonusOfType(BonusType::INVINCIBLE)
|
&& !stack->isInvincible()
|
||||||
&& (i == 0 && !firstStrike)
|
&& (i == 0 && !firstStrike)
|
||||||
&& retaliation && destinationStack->ableToRetaliate())
|
&& retaliation && destinationStack->ableToRetaliate())
|
||||||
{
|
{
|
||||||
|
@ -76,6 +76,11 @@ public:
|
|||||||
return hasBonusOfType(BonusType::HYPNOTIZED);
|
return hasBonusOfType(BonusType::HYPNOTIZED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isInvincible() const override
|
||||||
|
{
|
||||||
|
return hasBonusOfType(BonusType::INVINCIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
void redirectBonusesToFake()
|
void redirectBonusesToFake()
|
||||||
{
|
{
|
||||||
ON_CALL(*this, getAllBonuses(_, _, _)).WillByDefault(Invoke(&bonusFake, &BonusBearerMock::getAllBonuses));
|
ON_CALL(*this, getAllBonuses(_, _, _)).WillByDefault(Invoke(&bonusFake, &BonusBearerMock::getAllBonuses));
|
||||||
|
@ -58,6 +58,7 @@ public:
|
|||||||
MOCK_CONST_METHOD1(isValidTarget, bool(bool));
|
MOCK_CONST_METHOD1(isValidTarget, bool(bool));
|
||||||
|
|
||||||
MOCK_CONST_METHOD0(isHypnotized, bool());
|
MOCK_CONST_METHOD0(isHypnotized, bool());
|
||||||
|
MOCK_CONST_METHOD0(isInvincible, bool());
|
||||||
MOCK_CONST_METHOD0(isClone, bool());
|
MOCK_CONST_METHOD0(isClone, bool());
|
||||||
MOCK_CONST_METHOD0(hasClone, bool());
|
MOCK_CONST_METHOD0(hasClone, bool());
|
||||||
MOCK_CONST_METHOD0(canCast, bool());
|
MOCK_CONST_METHOD0(canCast, bool());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user