mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-03 00:46:55 +02:00
+SpecialRisingSpellMechanics::isImmuneByStack
This commit is contained in:
@ -159,18 +159,6 @@ CStack * BattleInfo::generateNewStack(const CStackBasicDescriptor &base, bool at
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//All spells casted by hero 9resurrection, cure, sacrifice)
|
|
||||||
ui32 CBattleInfoCallback::calculateHealedHP(const CGHeroInstance * caster, const CSpell * spell, const CStack * stack, const CStack * sacrificedStack) const
|
|
||||||
{
|
|
||||||
bool resurrect = spell->isRisingSpell();
|
|
||||||
int healedHealth;
|
|
||||||
if (spell->id == SpellID::SACRIFICE && sacrificedStack)
|
|
||||||
healedHealth = (caster->getPrimSkillLevel(PrimarySkill::SPELL_POWER) + sacrificedStack->MaxHealth() + spell->getPower(caster->getSpellSchoolLevel(spell))) * sacrificedStack->count;
|
|
||||||
else
|
|
||||||
healedHealth = caster->getPrimSkillLevel(PrimarySkill::SPELL_POWER) * spell->power + spell->getPower(caster->getSpellSchoolLevel(spell)); //???
|
|
||||||
healedHealth = spell->calculateBonus(healedHealth, caster, stack);
|
|
||||||
return std::min<ui32>(healedHealth, stack->MaxHealth() - stack->firstHPleft + (resurrect ? stack->baseAmount * stack->MaxHealth() : 0));
|
|
||||||
}
|
|
||||||
//Archangel
|
//Archangel
|
||||||
ui32 CBattleInfoCallback::calculateHealedHP(int healedHealth, const CSpell * spell, const CStack * stack) const
|
ui32 CBattleInfoCallback::calculateHealedHP(int healedHealth, const CSpell * spell, const CStack * stack) const
|
||||||
{
|
{
|
||||||
|
@ -1627,22 +1627,7 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleStackIsImmune(co
|
|||||||
return immuneResult;
|
return immuneResult;
|
||||||
|
|
||||||
//TODO: move to spellhandler
|
//TODO: move to spellhandler
|
||||||
if (spell->isRisingSpell() && spell->id != SpellID::SACRIFICE)
|
if(spell->id == SpellID::HYPNOTIZE && caster) //do not resist hypnotize casted after attack, for example
|
||||||
{
|
|
||||||
// following does apply to resurrect and animate dead(?) only
|
|
||||||
// for sacrifice health calculation and health limit check don't matter
|
|
||||||
|
|
||||||
if(subject->count >= subject->baseAmount)
|
|
||||||
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
|
|
||||||
|
|
||||||
if (caster) //FIXME: Archangels can cast immune stack
|
|
||||||
{
|
|
||||||
auto maxHealth = calculateHealedHP (caster, spell, subject);
|
|
||||||
if (maxHealth < subject->MaxHealth()) //must be able to rise at least one full creature
|
|
||||||
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else 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?
|
//TODO: what with other creatures casting hypnotize, Faerie Dragons style?
|
||||||
ui64 subjectHealth = (subject->count - 1) * subject->MaxHealth() + subject->firstHPleft;
|
ui64 subjectHealth = (subject->count - 1) * subject->MaxHealth() + subject->firstHPleft;
|
||||||
|
@ -282,7 +282,6 @@ public:
|
|||||||
ESpellCastProblem::ESpellCastProblem battleCanCreatureCastThisSpell(const CSpell * spell, BattleHex destination) const; //determines if creature can cast a spell here
|
ESpellCastProblem::ESpellCastProblem battleCanCreatureCastThisSpell(const CSpell * spell, BattleHex destination) const; //determines if creature can cast a spell here
|
||||||
std::vector<BattleHex> battleGetPossibleTargets(PlayerColor player, const CSpell *spell) const;
|
std::vector<BattleHex> battleGetPossibleTargets(PlayerColor player, const CSpell *spell) const;
|
||||||
ui32 calculateSpellDmg(const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature, int spellSchoolLevel, int usedSpellPower) const; //calculates damage inflicted by spell
|
ui32 calculateSpellDmg(const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature, int spellSchoolLevel, int usedSpellPower) const; //calculates damage inflicted by spell
|
||||||
ui32 calculateHealedHP(const CGHeroInstance * caster, const CSpell * spell, const CStack * stack, const CStack * sacrificedStack = nullptr) const; //Sacrifice
|
|
||||||
ui32 calculateHealedHP(int healedHealth, const CSpell * spell, const CStack * stack) const; //for Archangel
|
ui32 calculateHealedHP(int healedHealth, const CSpell * spell, const CStack * stack) const; //for Archangel
|
||||||
ui32 calculateHealedHP(const CSpell * spell, int usedSpellPower, int spellSchoolLevel, const CStack * stack) const; //healing spells casted by stacks
|
ui32 calculateHealedHP(const CSpell * spell, int usedSpellPower, int spellSchoolLevel, const CStack * stack) const; //healing spells casted by stacks
|
||||||
std::set<const CStack*> getAffectedCreatures(const CSpell * s, int skillLevel, PlayerColor attackerOwner, BattleHex destinationTile); //calculates stack affected by given spell
|
std::set<const CStack*> getAffectedCreatures(const CSpell * s, int skillLevel, PlayerColor attackerOwner, BattleHex destinationTile); //calculates stack affected by given spell
|
||||||
|
@ -182,6 +182,12 @@ 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 SacrificeMechanics: public RisingSpellMechanics
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
///CloneMechanics
|
///CloneMechanics
|
||||||
ESpellCastProblem::ESpellCastProblem CloneMechnics::isImmuneByStack(const CGHeroInstance* caster, ECastingMode::ECastingMode mode, const CStack * obj)
|
ESpellCastProblem::ESpellCastProblem CloneMechnics::isImmuneByStack(const CGHeroInstance* caster, ECastingMode::ECastingMode mode, const CStack * obj)
|
||||||
{
|
{
|
||||||
@ -236,18 +242,20 @@ namespace
|
|||||||
///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)
|
||||||
{
|
{
|
||||||
// // following does apply to resurrect and animate dead(?) only
|
// following does apply to resurrect and animate dead(?) only
|
||||||
// // for sacrifice health calculation and health limit check don't matter
|
// for sacrifice health calculation and health limit check don't matter
|
||||||
//
|
|
||||||
// if(obj->count >= obj->baseAmount)
|
if(obj->count >= obj->baseAmount)
|
||||||
// return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
|
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
|
||||||
//
|
|
||||||
// if (caster) //FIXME: Archangels can cast immune stack
|
if (caster) //FIXME: Archangels can cast immune stack
|
||||||
// {
|
{
|
||||||
// auto maxHealth = calculateHealedHP (caster, spell, obj);
|
auto maxHealth = 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;
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
return CSpellMechanics::isImmuneByStack(caster,mode,obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -321,6 +329,28 @@ ui32 CSpell::calculateBonus(ui32 baseDamage, const CGHeroInstance* caster, const
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui32 CSpell::calculateHealedHP(const CGHeroInstance* caster, const CStack* stack, const CStack* sacrificedStack) const
|
||||||
|
{
|
||||||
|
//todo: use Mechanics class
|
||||||
|
int healedHealth;
|
||||||
|
|
||||||
|
if(!isHealingSpell())
|
||||||
|
{
|
||||||
|
logGlobal->errorStream() << "calculateHealedHP called for nonhealing spell "<< name;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int spellPowerSkill = caster->getPrimSkillLevel(PrimarySkill::SPELL_POWER);
|
||||||
|
const int levelPower = getPower(caster->getSpellSchoolLevel(this));
|
||||||
|
|
||||||
|
if (id == SpellID::SACRIFICE && sacrificedStack)
|
||||||
|
healedHealth = (spellPowerSkill + sacrificedStack->MaxHealth() + levelPower) * sacrificedStack->count;
|
||||||
|
else
|
||||||
|
healedHealth = spellPowerSkill * power + levelPower); //???
|
||||||
|
healedHealth = calculateBonus(healedHealth, caster, stack);
|
||||||
|
return std::min<ui32>(healedHealth, stack->MaxHealth() - stack->firstHPleft + (isRisingSpell() ? stack->baseAmount * stack->MaxHealth() : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<BattleHex> CSpell::rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool *outDroppedHexes) const
|
std::vector<BattleHex> CSpell::rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool *outDroppedHexes) const
|
||||||
{
|
{
|
||||||
@ -474,6 +504,10 @@ bool CSpell::isNeutral() const
|
|||||||
return positiveness == NEUTRAL;
|
return positiveness == NEUTRAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CSpell::isHealingSpell() const
|
||||||
|
{
|
||||||
|
return isRisingSpell() || (id == SpellID::CURE);
|
||||||
|
}
|
||||||
|
|
||||||
bool CSpell::isRisingSpell() const
|
bool CSpell::isRisingSpell() const
|
||||||
{
|
{
|
||||||
@ -691,9 +725,15 @@ void CSpell::setupMechanics()
|
|||||||
break;
|
break;
|
||||||
case SpellID::DISPEL_HELPFUL_SPELLS:
|
case SpellID::DISPEL_HELPFUL_SPELLS:
|
||||||
mechanics = new DispellHelpfulMechanics(this);
|
mechanics = new DispellHelpfulMechanics(this);
|
||||||
break;
|
break;
|
||||||
default:
|
case SpellID::SACRIFICE:
|
||||||
mechanics = new CSpellMechanics(this);
|
mechanics = new SacrificeMechanics(this);
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
if(isRisingSpell())
|
||||||
|
mechanics = new SpecialRisingSpellMechanics(this);
|
||||||
|
else
|
||||||
|
mechanics = new CSpellMechanics(this);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,8 +113,9 @@ public:
|
|||||||
bool isNegative() const;
|
bool isNegative() const;
|
||||||
bool isNeutral() const;
|
bool isNeutral() const;
|
||||||
|
|
||||||
bool isRisingSpell() const;
|
|
||||||
bool isDamageSpell() const;
|
bool isDamageSpell() const;
|
||||||
|
bool isHealingSpell() const;
|
||||||
|
bool isRisingSpell() const;
|
||||||
bool isOffensiveSpell() const;
|
bool isOffensiveSpell() const;
|
||||||
|
|
||||||
bool isSpecialSpell() const;
|
bool isSpecialSpell() const;
|
||||||
@ -130,6 +131,9 @@ public:
|
|||||||
|
|
||||||
//applying secondary skills
|
//applying secondary skills
|
||||||
ui32 calculateBonus(ui32 baseDamage, const CGHeroInstance * caster, const CStack * affectedCreature) const;
|
ui32 calculateBonus(ui32 baseDamage, const CGHeroInstance * caster, const CStack * affectedCreature) const;
|
||||||
|
|
||||||
|
///calculate healed HP for all spells casted by hero
|
||||||
|
ui32 calculateHealedHP(const CGHeroInstance * caster, const CStack * stack, const CStack * sacrificedStack = nullptr) const;
|
||||||
|
|
||||||
si32 getCost(const int skillLevel) const;
|
si32 getCost(const int skillLevel) const;
|
||||||
|
|
||||||
|
@ -4205,7 +4205,7 @@ void CGameHandler::handleSpellCasting( SpellID spellID, int spellLvl, BattleHex
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spell->isRisingSpell() || spell->id == SpellID::CURE)
|
if(spell->isHealingSpell())
|
||||||
{
|
{
|
||||||
int hpGained = 0;
|
int hpGained = 0;
|
||||||
if (stack)
|
if (stack)
|
||||||
@ -4233,7 +4233,7 @@ void CGameHandler::handleSpellCasting( SpellID spellID, int spellLvl, BattleHex
|
|||||||
hi.healedHP = gs->curB->calculateHealedHP(spell, usedSpellPower, spellLvl, attackedCre); //any typical spell (commander's cure or animate dead)
|
hi.healedHP = gs->curB->calculateHealedHP(spell, usedSpellPower, spellLvl, attackedCre); //any typical spell (commander's cure or animate dead)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
hi.healedHP = gs->curB->calculateHealedHP(caster, spell, attackedCre, gs->curB->battleGetStackByID(selectedStack)); //Casted by hero
|
hi.healedHP = spell->calculateHealedHP(caster, attackedCre, gs->curB->battleGetStackByID(selectedStack)); //Casted by hero
|
||||||
hi.lowLevelResurrection = spellLvl <= 1;
|
hi.lowLevelResurrection = spellLvl <= 1;
|
||||||
shr.healedStacks.push_back(hi);
|
shr.healedStacks.push_back(hi);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user