1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-02-03 13:01:33 +02:00

Calculate magic mirror effect at same time as magic resistance.

This commit is contained in:
AlexVinS 2015-09-14 11:52:56 +03:00
parent caf8ae62cc
commit 329c1d6b94

View File

@ -261,24 +261,36 @@ void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, BattleS
auto creatures = owner->getAffectedStacks(parameters.cb, parameters.mode, parameters.casterColor, parameters.spellLvl, parameters.destination, parameters.casterHero);
std::copy(creatures.begin(), creatures.end(), std::back_inserter(attackedCres));
std::vector <const CStack*> reflected;//for magic mirror
//checking if creatures resist
//resistance is applied only to negative spells
//resistance/reflection is applied only to negative spells
if(owner->isNegative())
{
//it is actual spell and can be reflected to single target, no recurrence
const bool tryMagicMirror = parameters.mode != ECastingMode::MAGIC_MIRROR && owner->level && owner->getLevelInfo(0).range == "0";
std::vector <const CStack*> resisted;
for(auto s : attackedCres)
{
//magic resistance
const int prob = std::min((s)->magicResistance(), 100); //probability of resistance in %
if(env->getRandomGenerator().nextInt(99) < prob)
{
resisted.push_back(s);
}
//magic mirror
if(tryMagicMirror)
{
const int mirrorChance = (s)->valOfBonuses(Bonus::MAGIC_MIRROR);
if(env->getRandomGenerator().nextInt(99) < mirrorChance)
reflected.push_back(s);
}
}
vstd::erase_if(attackedCres, [&resisted](const CStack * s)
vstd::erase_if(attackedCres, [&resisted, reflected](const CStack * s)
{
return vstd::contains(resisted, s);
return vstd::contains(resisted, s) || vstd::contains(reflected, s);
});
for(auto s : resisted)
@ -288,6 +300,13 @@ void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, BattleS
effect.stack = s->ID;
sc.customEffects.push_back(effect);
}
for(auto s : reflected)
{
BattleSpellCast::CustomEffect effect;
effect.effect = 3;
effect.stack = s->ID;
sc.customEffects.push_back(effect);
}
}
for(auto cre : attackedCres)
@ -341,41 +360,31 @@ void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, BattleS
}
//Magic Mirror effect
if(owner->isNegative() && parameters.mode != ECastingMode::MAGIC_MIRROR && owner->level && owner->getLevelInfo(0).range == "0") //it is actual spell and can be reflected to single target, no recurrence
for(auto & attackedCre : reflected)
{
for(auto & attackedCre : attackedCres)
TStacks mirrorTargets = parameters.cb->battleGetStacksIf([this, parameters](const CStack * battleStack)
{
int mirrorChance = (attackedCre)->valOfBonuses(Bonus::MAGIC_MIRROR);
if(mirrorChance > env->getRandomGenerator().nextInt(99))
{
std::vector<const CStack *> mirrorTargets;
auto battleStacks = parameters.cb->battleGetAllStacks(true);
for(auto & battleStack : battleStacks)
{
if(battleStack->owner == parameters.casterColor) //get enemy stacks which can be affected by this spell
{
if (ESpellCastProblem::OK == owner->isImmuneByStack(nullptr, battleStack))
mirrorTargets.push_back(battleStack);
}
}
if(!mirrorTargets.empty())
{
int targetHex = (*RandomGeneratorUtil::nextItem(mirrorTargets, env->getRandomGenerator()))->position;
//Get all enemy stacks. Magic mirror can reflect to immune creature (with no effect)
return battleStack->owner == parameters.casterColor;
},
true);//turrets included
BattleSpellCastParameters mirrorParameters = parameters;
mirrorParameters.spellLvl = 0;
mirrorParameters.casterSide = 1-parameters.casterSide;
mirrorParameters.casterColor = (attackedCre)->owner;
mirrorParameters.casterHero = nullptr;
mirrorParameters.destination = targetHex;
mirrorParameters.secHero = parameters.casterHero;
mirrorParameters.mode = ECastingMode::MAGIC_MIRROR;
mirrorParameters.casterStack = (attackedCre);
mirrorParameters.selectedStack = nullptr;
if(!mirrorTargets.empty())
{
int targetHex = (*RandomGeneratorUtil::nextItem(mirrorTargets, env->getRandomGenerator()))->position;
battleCast(env, mirrorParameters);
}
}
BattleSpellCastParameters mirrorParameters = parameters;
mirrorParameters.spellLvl = 0;
mirrorParameters.casterSide = 1-parameters.casterSide;
mirrorParameters.casterColor = (attackedCre)->owner;
mirrorParameters.casterHero = nullptr;
mirrorParameters.destination = targetHex;
mirrorParameters.secHero = parameters.casterHero;
mirrorParameters.mode = ECastingMode::MAGIC_MIRROR;
mirrorParameters.casterStack = (attackedCre);
mirrorParameters.selectedStack = nullptr;
battleCast(env, mirrorParameters);
}
}
}