mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Partial fix for 1791
This commit is contained in:
parent
a44c606277
commit
253b850ac3
@ -1324,9 +1324,16 @@
|
||||
"bonuses" : [
|
||||
{
|
||||
"type" : "NEGATE_ALL_NATURAL_IMMUNITIES",
|
||||
"subtype" : 0,
|
||||
"val" : 0,
|
||||
"valueType" : "BASE_NUMBER",
|
||||
"propagator": "BATTLE_WIDE"
|
||||
},
|
||||
{
|
||||
"type" : "NEGATE_ALL_NATURAL_IMMUNITIES",
|
||||
"subtype" : 1,
|
||||
"val" : 0,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
}
|
||||
],
|
||||
"index" : 93,
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "../NetPacks.h"
|
||||
#include "../BattleState.h"
|
||||
#include "../mapObjects/CGHeroInstance.h"
|
||||
|
||||
///HealingSpellMechanics
|
||||
void HealingSpellMechanics::applyBattleEffects(const SpellCastEnvironment* env, BattleSpellCastParameters& parameters, SpellCastContext& ctx) const
|
||||
@ -506,12 +507,17 @@ ESpellCastProblem::ESpellCastProblem SacrificeMechanics::canBeCasted(const CBatt
|
||||
bool targetExists = false;
|
||||
bool targetToSacrificeExists = false;
|
||||
|
||||
const CGHeroInstance * caster = nullptr; //todo: use ISpellCaster
|
||||
|
||||
if(cb->battleHasHero(cb->playerToSide(player)))
|
||||
caster = cb->battleGetFightingHero(cb->playerToSide(player));
|
||||
|
||||
for(const CStack * stack : cb->battleGetAllStacks())
|
||||
{
|
||||
//using isImmuneBy directly as this mechanics does not have overridden immunity check
|
||||
//therefore we do not need to check caster and casting mode
|
||||
//TODO: check that we really should check immunity for both stacks
|
||||
ESpellCastProblem::ESpellCastProblem res = owner->isImmuneBy(stack);
|
||||
ESpellCastProblem::ESpellCastProblem res = owner->internalIsImmune(caster, stack);
|
||||
const bool immune = ESpellCastProblem::OK != res && ESpellCastProblem::NOT_DECIDED != res;
|
||||
const bool casterStack = stack->owner == player;
|
||||
|
||||
|
@ -746,7 +746,7 @@ ESpellCastProblem::ESpellCastProblem DefaultSpellMechanics::canBeCasted(const CB
|
||||
ESpellCastProblem::ESpellCastProblem DefaultSpellMechanics::isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const
|
||||
{
|
||||
//by default use general algorithm
|
||||
return owner->isImmuneBy(obj);
|
||||
return owner->internalIsImmune(caster, obj);
|
||||
}
|
||||
|
||||
void DefaultSpellMechanics::doDispell(BattleInfo * battle, const BattleSpellCast * packet, const CSelector & selector) const
|
||||
|
@ -402,7 +402,7 @@ int CSpell::calculateRawEffectValue(int effectLevel, int effectPower) const
|
||||
return effectPower * power + getPower(effectLevel);
|
||||
}
|
||||
|
||||
ESpellCastProblem::ESpellCastProblem CSpell::isImmuneBy(const IBonusBearer* obj) const
|
||||
ESpellCastProblem::ESpellCastProblem CSpell::internalIsImmune(const ISpellCaster * caster, const CStack *obj) const
|
||||
{
|
||||
//todo: use new bonus API
|
||||
//1. Check absolute limiters
|
||||
@ -435,9 +435,21 @@ ESpellCastProblem::ESpellCastProblem CSpell::isImmuneBy(const IBonusBearer* obj)
|
||||
return ESpellCastProblem::OK;
|
||||
|
||||
//3. Check negation
|
||||
//FIXME: Orb of vulnerability mechanics is not such trivial
|
||||
if(obj->hasBonusOfType(Bonus::NEGATE_ALL_NATURAL_IMMUNITIES)) //Orb of vulnerability
|
||||
//Orb of vulnerability
|
||||
//FIXME: Orb of vulnerability mechanics is not such trivial (issue 1791)
|
||||
const bool battleWideNegation = obj->hasBonusOfType(Bonus::NEGATE_ALL_NATURAL_IMMUNITIES, 0);
|
||||
const bool heroNegation = obj->hasBonusOfType(Bonus::NEGATE_ALL_NATURAL_IMMUNITIES, 1);
|
||||
//anyone can cast on artifact holder`s stacks
|
||||
if(heroNegation)
|
||||
return ESpellCastProblem::NOT_DECIDED;
|
||||
//this stack is from other player
|
||||
//todo: check that caster is always present (not trivial is this case)
|
||||
//todo: NEGATE_ALL_NATURAL_IMMUNITIES special cases: dispell, chain lightning
|
||||
else if(battleWideNegation && caster)
|
||||
{
|
||||
if(obj->owner != caster->getOwner())
|
||||
return ESpellCastProblem::NOT_DECIDED;
|
||||
}
|
||||
|
||||
//4. Check negatable limit
|
||||
for(auto b : limiters)
|
||||
|
@ -298,7 +298,7 @@ public://internal, for use only by Mechanics classes
|
||||
///returns raw damage or healed HP
|
||||
int calculateRawEffectValue(int effectLevel, int effectPower) const;
|
||||
///generic immunity calculation
|
||||
ESpellCastProblem::ESpellCastProblem isImmuneBy(const IBonusBearer *obj) const;
|
||||
ESpellCastProblem::ESpellCastProblem internalIsImmune(const ISpellCaster * caster, const CStack *obj) const;
|
||||
|
||||
private:
|
||||
void setIsOffensive(const bool val);
|
||||
|
Loading…
Reference in New Issue
Block a user