get rid of CBattleInfoCallback::battleStackIsImmune

This commit is contained in:
AlexVinS committed 2014-11-12 09:20:20 +03:00
1 parent ddf98a5920
commit e4b726151d
5 files changed
+40 -38

No files matched your search

+1 -1
View File
@@ -461,7 +461,7 @@ void CBattleAI::attemptCastingSpell()
auto stacksSuffering = cb->getAffectedCreatures(ps.spell, skillLevel, playerID, ps.dest); auto stacksSuffering = cb->getAffectedCreatures(ps.spell, skillLevel, playerID, ps.dest);
vstd::erase_if(stacksSuffering, [&](const CStack * s) -> bool vstd::erase_if(stacksSuffering, [&](const CStack * s) -> bool
{ {
return ESpellCastProblem::OK != cb->battleStackIsImmune(hero, ps.spell, ECastingMode::HERO_CASTING, s); return ESpellCastProblem::OK != ps.spell->isImmuneByStack(hero, ECastingMode::HERO_CASTING, s);
}); });
if(stacksSuffering.empty()) if(stacksSuffering.empty())
+4 -26
View File
@@ -1582,7 +1582,7 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleIsImmune(const C
for(auto s : stacks) for(auto s : stacks)
{ {
ESpellCastProblem::ESpellCastProblem res = battleStackIsImmune(caster,spell,mode,s); ESpellCastProblem::ESpellCastProblem res = spell->isImmuneByStack(caster,mode,s);
if(res == ESpellCastProblem::OK) if(res == ESpellCastProblem::OK)
{ {
@@ -1619,28 +1619,6 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleIsImmune(const C
return ESpellCastProblem::OK; return ESpellCastProblem::OK;
} }
ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleStackIsImmune(const CGHeroInstance * caster, const CSpell * spell, ECastingMode::ECastingMode mode, const CStack * subject) const
{
const auto immuneResult = spell->isImmuneByStack(caster, mode, subject);
if (ESpellCastProblem::NOT_DECIDED != immuneResult)
return immuneResult;
//TODO: move to spellhandler
if(spell->id == SpellID::HYPNOTIZE && caster) //do not resist hypnotize casted after attack, for example
{
//TODO: what with other creatures casting hypnotize, Faerie Dragons style?
ui64 subjectHealth = (subject->count - 1) * subject->MaxHealth() + subject->firstHPleft;
//apply 'damage' bonus for hypnotize, including hero specialty
ui64 maxHealth = spell->calculateBonus (caster->getPrimSkillLevel(PrimarySkill::SPELL_POWER)
* spell->power + spell->getPower(caster->getSpellSchoolLevel(spell)), caster, subject);
if (subjectHealth > maxHealth)
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
}
return ESpellCastProblem::OK;
}
ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell( PlayerColor player, const CSpell * spell, ECastingMode::ECastingMode mode ) const ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell( PlayerColor player, const CSpell * spell, ECastingMode::ECastingMode mode ) const
{ {
RETURN_IF_NOT_BATTLE(ESpellCastProblem::INVALID); RETURN_IF_NOT_BATTLE(ESpellCastProblem::INVALID);
@@ -1683,7 +1661,7 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell
auto stacks = spell->isNegative() ? battleAliveStacks(!side) : battleAliveStacks(); auto stacks = spell->isNegative() ? battleAliveStacks(!side) : battleAliveStacks();
for(auto stack : stacks) for(auto stack : stacks)
{ {
if( ESpellCastProblem::OK == battleStackIsImmune(castingHero, spell, mode, stack)) if(ESpellCastProblem::OK == spell->isImmuneByStack(castingHero, mode, stack))
{ {
allStacksImmune = false; allStacksImmune = false;
break; break;
@@ -1727,7 +1705,7 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell
for(const CStack * stack : battleGetAllStacks()) //dead stacks will be immune anyway for(const CStack * stack : battleGetAllStacks()) //dead stacks will be immune anyway
{ {
bool immune = ESpellCastProblem::OK != battleStackIsImmune(caster, spell, mode, stack); bool immune = ESpellCastProblem::OK != spell->isImmuneByStack(caster, mode, stack);
bool casterStack = stack->owner == caster->getOwner(); bool casterStack = stack->owner == caster->getOwner();
if(spell->id == SpellID::SACRIFICE) if(spell->id == SpellID::SACRIFICE)
@@ -1796,7 +1774,7 @@ std::vector<BattleHex> CBattleInfoCallback::battleGetPossibleTargets(PlayerColor
for(const CStack * stack : battleAliveStacks()) for(const CStack * stack : battleAliveStacks())
{ {
bool immune = ESpellCastProblem::OK != battleStackIsImmune(caster, spell, mode, stack); bool immune = ESpellCastProblem::OK != spell->isImmuneByStack(caster, mode, stack);
bool casterStack = stack->owner == caster->getOwner(); bool casterStack = stack->owner == caster->getOwner();
if(!immune) if(!immune)
-4
View File
@@ -290,10 +290,6 @@ public:
SpellID getRandomBeneficialSpell(const CStack * subject) const; SpellID getRandomBeneficialSpell(const CStack * subject) const;
SpellID getRandomCastedSpell(const CStack * caster) const; //called at the beginning of turn for Faerie Dragon SpellID getRandomCastedSpell(const CStack * caster) const; //called at the beginning of turn for Faerie Dragon
//checks for creature immunity / anything that prevent casting *at given hex* - doesn't take into acount general problems such as not having spellbook or mana points etc.
ESpellCastProblem::ESpellCastProblem battleStackIsImmune(const CGHeroInstance * caster, const CSpell * spell, ECastingMode::ECastingMode mode, const CStack * subject) const;
const CStack * getStackIf(std::function<bool(const CStack*)> pred) const; const CStack * getStackIf(std::function<bool(const CStack*)> pred) const;
si8 battleHasShootingPenalty(const CStack * stack, BattleHex destHex) si8 battleHasShootingPenalty(const CStack * stack, BattleHex destHex)
+33 -5
View File
@@ -166,6 +166,13 @@ namespace
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const CGHeroInstance * caster, ECastingMode::ECastingMode mode, const CStack * obj) override; ESpellCastProblem::ESpellCastProblem isImmuneByStack(const CGHeroInstance * caster, ECastingMode::ECastingMode mode, const CStack * obj) override;
}; };
class HypnotizeMechanics: public CSpellMechanics
{
public:
HypnotizeMechanics(CSpell * s): CSpellMechanics(s){};
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const CGHeroInstance * caster, ECastingMode::ECastingMode mode, const CStack * obj) override;
};
///all rising spells ///all rising spells
class RisingSpellMechanics: public CSpellMechanics class RisingSpellMechanics: public CSpellMechanics
{ {
@@ -185,7 +192,7 @@ namespace
class SacrificeMechanics: public RisingSpellMechanics class SacrificeMechanics: public RisingSpellMechanics
{ {
public: public:
SacrificeMechanics(CSpell * s): RisingSpellMechanics(s){};
}; };
///CloneMechanics ///CloneMechanics
@@ -239,6 +246,23 @@ namespace
return CSpellMechanics::isImmuneByStack(caster,mode,obj); return CSpellMechanics::isImmuneByStack(caster,mode,obj);
} }
///HypnotizeMechanics
ESpellCastProblem::ESpellCastProblem HypnotizeMechanics::isImmuneByStack(const CGHeroInstance* caster, ECastingMode::ECastingMode mode, const CStack* obj)
{
if(nullptr != caster) //do not resist hypnotize casted after attack, for example
{
//TODO: what with other creatures casting hypnotize, Faerie Dragons style?
ui64 subjectHealth = (obj->count - 1) * obj->MaxHealth() + obj->firstHPleft;
//apply 'damage' bonus for hypnotize, including hero specialty
ui64 maxHealth = owner->calculateBonus(caster->getPrimSkillLevel(PrimarySkill::SPELL_POWER)
* owner->power + owner->getPower(caster->getSpellSchoolLevel(owner)), caster, obj);
if (subjectHealth > maxHealth)
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
}
return CSpellMechanics::isImmuneByStack(caster,mode,obj);
}
///SpecialRisingSpellMechanics ///SpecialRisingSpellMechanics
ESpellCastProblem::ESpellCastProblem SpecialRisingSpellMechanics::isImmuneByStack(const CGHeroInstance* caster, ECastingMode::ECastingMode mode, const CStack* obj) ESpellCastProblem::ESpellCastProblem SpecialRisingSpellMechanics::isImmuneByStack(const CGHeroInstance* caster, ECastingMode::ECastingMode mode, const CStack* obj)
{ {
@@ -250,7 +274,7 @@ namespace
if (caster) //FIXME: Archangels can cast immune stack if (caster) //FIXME: Archangels can cast immune stack
{ {
auto maxHealth = calculateHealedHP (caster, obj); auto maxHealth = owner->calculateHealedHP (caster, obj);
if (maxHealth < obj->MaxHealth()) //must be able to rise at least one full creature if (maxHealth < obj->MaxHealth()) //must be able to rise at least one full creature
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL; return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
} }
@@ -346,7 +370,7 @@ ui32 CSpell::calculateHealedHP(const CGHeroInstance* caster, const CStack* stack
if (id == SpellID::SACRIFICE && sacrificedStack) if (id == SpellID::SACRIFICE && sacrificedStack)
healedHealth = (spellPowerSkill + sacrificedStack->MaxHealth() + levelPower) * sacrificedStack->count; healedHealth = (spellPowerSkill + sacrificedStack->MaxHealth() + levelPower) * sacrificedStack->count;
else else
healedHealth = spellPowerSkill * power + levelPower); //??? healedHealth = spellPowerSkill * power + levelPower; //???
healedHealth = calculateBonus(healedHealth, caster, stack); healedHealth = calculateBonus(healedHealth, caster, stack);
return std::min<ui32>(healedHealth, stack->MaxHealth() - stack->firstHPleft + (isRisingSpell() ? stack->baseAmount * stack->MaxHealth() : 0)); return std::min<ui32>(healedHealth, stack->MaxHealth() - stack->firstHPleft + (isRisingSpell() ? stack->baseAmount * stack->MaxHealth() : 0));
} }
@@ -684,7 +708,11 @@ ESpellCastProblem::ESpellCastProblem CSpell::isImmuneBy(const IBonusBearer* obj)
ESpellCastProblem::ESpellCastProblem CSpell::isImmuneByStack(const CGHeroInstance* caster, ECastingMode::ECastingMode mode, const CStack* obj) const ESpellCastProblem::ESpellCastProblem CSpell::isImmuneByStack(const CGHeroInstance* caster, ECastingMode::ECastingMode mode, const CStack* obj) const
{ {
return mechanics->isImmuneByStack(caster,mode,obj); const auto immuneResult = mechanics->isImmuneByStack(caster,mode,obj);
if (ESpellCastProblem::NOT_DECIDED != immuneResult)
return immuneResult;
return ESpellCastProblem::OK;
} }
@@ -728,7 +756,7 @@ void CSpell::setupMechanics()
break; break;
case SpellID::SACRIFICE: case SpellID::SACRIFICE:
mechanics = new SacrificeMechanics(this); mechanics = new SacrificeMechanics(this);
break break;
default: default:
if(isRisingSpell()) if(isRisingSpell())
mechanics = new SpecialRisingSpellMechanics(this); mechanics = new SpecialRisingSpellMechanics(this);
+2 -2
View File
@@ -4040,7 +4040,7 @@ void CGameHandler::handleSpellCasting( SpellID spellID, int spellLvl, BattleHex
} }
vstd::erase_if(attackedCres,[=](const CStack * s){ vstd::erase_if(attackedCres,[=](const CStack * s){
return ESpellCastProblem::OK != gs->curB->battleStackIsImmune(caster,spell,mode,s); return ESpellCastProblem::OK != spell->isImmuneByStack(caster,mode,s);
}); });
for (auto cre : attackedCres) for (auto cre : attackedCres)
@@ -4453,7 +4453,7 @@ void CGameHandler::handleSpellCasting( SpellID spellID, int spellLvl, BattleHex
{ {
if(battleStack->owner == gs->curB->sides.at(casterSide).color) //get enemy stacks which can be affected by this spell if(battleStack->owner == gs->curB->sides.at(casterSide).color) //get enemy stacks which can be affected by this spell
{ {
if (ESpellCastProblem::OK == gs->curB->battleStackIsImmune(nullptr, spell, ECastingMode::MAGIC_MIRROR, battleStack)) if (ESpellCastProblem::OK == spell->isImmuneByStack(nullptr, ECastingMode::MAGIC_MIRROR, battleStack))
mirrorTargets.push_back(battleStack); mirrorTargets.push_back(battleStack);
} }
} }