CreatureSpellMechanics.cpp 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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.setDamageToDisplay(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. void AcidBreathDamageMechanics::handleImmunities(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx, std::vector<const CStack*> & stacks) const
  33. {
  34. //no immunities
  35. }
  36. ///DeathStareMechanics
  37. void DeathStareMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
  38. {
  39. //calculating dmg to display
  40. si32 dmgToDisplay = parameters.effectPower;
  41. if(!ctx.attackedCres.empty())
  42. vstd::amin(dmgToDisplay, (*ctx.attackedCres.begin())->count); //stack is already reduced after attack
  43. ctx.setDamageToDisplay(dmgToDisplay);
  44. for(auto & attackedCre : ctx.attackedCres)
  45. {
  46. BattleStackAttacked bsa;
  47. bsa.flags |= BattleStackAttacked::SPELL_EFFECT;
  48. bsa.spellID = owner->id;
  49. bsa.damageAmount = parameters.effectPower * (attackedCre)->valOfBonuses(Bonus::STACK_HEALTH);//todo: move here all DeathStare calculation
  50. bsa.stackAttacked = (attackedCre)->ID;
  51. bsa.attackerID = -1;
  52. (attackedCre)->prepareAttacked(bsa, env->getRandomGenerator());
  53. ctx.si.stacks.push_back(bsa);
  54. }
  55. }
  56. ///DispellHelpfulMechanics
  57. void DispellHelpfulMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
  58. {
  59. DefaultSpellMechanics::applyBattle(battle, packet);
  60. doDispell(battle, packet, Selector::positiveSpellEffects);
  61. }
  62. ESpellCastProblem::ESpellCastProblem DispellHelpfulMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
  63. {
  64. TBonusListPtr spellBon = obj->getSpellBonuses();
  65. bool hasPositiveSpell = false;
  66. for(const Bonus * b : *spellBon)
  67. {
  68. if(SpellID(b->sid).toSpell()->isPositive())
  69. {
  70. hasPositiveSpell = true;
  71. break;
  72. }
  73. }
  74. if(!hasPositiveSpell)
  75. {
  76. return ESpellCastProblem::NO_SPELLS_TO_DISPEL;
  77. }
  78. //use default algorithm only if there is no mechanics-related problem
  79. return DefaultSpellMechanics::isImmuneByStack(caster,obj);
  80. }