CreatureSpellMechanics.cpp 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * CreatureSpellMechanics.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "CreatureSpellMechanics.h"
  12. #include "../NetPacks.h"
  13. #include "../BattleState.h"
  14. ///AcidBreathDamageMechanics
  15. void AcidBreathDamageMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
  16. {
  17. //todo: this should be effectValue
  18. //calculating dmg to display
  19. ctx.sc.dmgToDisplay = parameters.effectPower;
  20. for(auto & attackedCre : ctx.attackedCres) //no immunities
  21. {
  22. BattleStackAttacked bsa;
  23. bsa.flags |= BattleStackAttacked::SPELL_EFFECT;
  24. bsa.spellID = owner->id;
  25. bsa.damageAmount = parameters.effectPower; //damage times the number of attackers
  26. bsa.stackAttacked = (attackedCre)->ID;
  27. bsa.attackerID = -1;
  28. (attackedCre)->prepareAttacked(bsa, env->getRandomGenerator());
  29. ctx.si.stacks.push_back(bsa);
  30. }
  31. }
  32. ///DeathStareMechanics
  33. void DeathStareMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
  34. {
  35. //calculating dmg to display
  36. ctx.sc.dmgToDisplay = parameters.effectPower;
  37. if(!ctx.attackedCres.empty())
  38. vstd::amin(ctx.sc.dmgToDisplay, (*ctx.attackedCres.begin())->count); //stack is already reduced after attack
  39. for(auto & attackedCre : ctx.attackedCres)
  40. {
  41. BattleStackAttacked bsa;
  42. bsa.flags |= BattleStackAttacked::SPELL_EFFECT;
  43. bsa.spellID = owner->id;
  44. bsa.damageAmount = parameters.effectPower * (attackedCre)->valOfBonuses(Bonus::STACK_HEALTH);//todo: move here all DeathStare calculation
  45. bsa.stackAttacked = (attackedCre)->ID;
  46. bsa.attackerID = -1;
  47. (attackedCre)->prepareAttacked(bsa, env->getRandomGenerator());
  48. ctx.si.stacks.push_back(bsa);
  49. }
  50. }
  51. ///DispellHelpfulMechanics
  52. void DispellHelpfulMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
  53. {
  54. DefaultSpellMechanics::applyBattle(battle, packet);
  55. doDispell(battle, packet, Selector::positiveSpellEffects);
  56. }
  57. ESpellCastProblem::ESpellCastProblem DispellHelpfulMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
  58. {
  59. TBonusListPtr spellBon = obj->getSpellBonuses();
  60. bool hasPositiveSpell = false;
  61. for(const Bonus * b : *spellBon)
  62. {
  63. if(SpellID(b->sid).toSpell()->isPositive())
  64. {
  65. hasPositiveSpell = true;
  66. break;
  67. }
  68. }
  69. if(!hasPositiveSpell)
  70. {
  71. return ESpellCastProblem::NO_SPELLS_TO_DISPEL;
  72. }
  73. //use default algorithm only if there is no mechanics-related problem
  74. return DefaultSpellMechanics::isImmuneByStack(caster,obj);
  75. }