SummonBoatEffect.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /*
  2. * SummonBoatEffect.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 "SummonBoatEffect.h"
  12. #include "../CSpellHandler.h"
  13. #include "../../mapObjects/CGHeroInstance.h"
  14. #include "../../mapObjects/MiscObjects.h"
  15. #include "../../mapping/CMap.h"
  16. #include "../../networkPacks/PacksForClient.h"
  17. VCMI_LIB_NAMESPACE_BEGIN
  18. SummonBoatEffect::SummonBoatEffect(const CSpell * s, const JsonNode & config)
  19. : owner(s)
  20. , useExistingBoat(config["useExistingBoat"].Bool())
  21. , createNewBoat(config["createNewBoat"].Bool())
  22. {
  23. }
  24. bool SummonBoatEffect::canCreateNewBoat() const
  25. {
  26. return createNewBoat;
  27. }
  28. int SummonBoatEffect::getSuccessChance(const spells::Caster * caster) const
  29. {
  30. const auto schoolLevel = caster->getSpellSchoolLevel(owner);
  31. return owner->getLevelPower(schoolLevel);
  32. }
  33. bool SummonBoatEffect::canBeCastImpl(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster) const
  34. {
  35. if(!caster->getHeroCaster())
  36. return false;
  37. if(caster->getHeroCaster()->inBoat())
  38. {
  39. MetaString message = MetaString::createFromTextID("core.genrltxt.333");
  40. caster->getCasterName(message);
  41. problem.add(std::move(message));
  42. return false;
  43. }
  44. int3 summonPos = caster->getHeroCaster()->bestLocation();
  45. if(summonPos.x < 0)
  46. {
  47. MetaString message = MetaString::createFromTextID("core.genrltxt.334");
  48. caster->getCasterName(message);
  49. problem.add(std::move(message));
  50. return false;
  51. }
  52. return true;
  53. }
  54. ESpellCastResult SummonBoatEffect::applyAdventureEffects(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const
  55. {
  56. //check if spell works at all
  57. if(env->getRNG()->nextInt(0, 99) >= getSuccessChance(parameters.caster)) //power is % chance of success
  58. {
  59. InfoWindow iw;
  60. iw.player = parameters.caster->getCasterOwner();
  61. iw.text.appendLocalString(EMetaText::GENERAL_TXT, 336); //%s tried to summon a boat, but failed.
  62. parameters.caster->getCasterName(iw.text);
  63. env->apply(iw);
  64. return ESpellCastResult::OK;
  65. }
  66. //try to find unoccupied boat to summon
  67. const CGBoat * nearest = nullptr;
  68. if (useExistingBoat)
  69. {
  70. double dist = 0;
  71. for(const auto & b : env->getMap()->getObjects<CGBoat>())
  72. {
  73. if(b->getBoardedHero() || b->layer != EPathfindingLayer::SAIL)
  74. continue; //we're looking for unoccupied boat
  75. double nDist = b->visitablePos().dist2d(parameters.caster->getHeroCaster()->visitablePos());
  76. if(!nearest || nDist < dist) //it's first boat or closer than previous
  77. {
  78. nearest = b;
  79. dist = nDist;
  80. }
  81. }
  82. }
  83. int3 summonPos = parameters.caster->getHeroCaster()->bestLocation();
  84. if(nullptr != nearest) //we found boat to summon
  85. {
  86. ChangeObjPos cop;
  87. cop.objid = nearest->id;
  88. cop.nPos = summonPos;
  89. cop.initiator = parameters.caster->getCasterOwner();
  90. env->apply(cop);
  91. }
  92. else if(!createNewBoat) //none or basic level -> cannot create boat :(
  93. {
  94. InfoWindow iw;
  95. iw.player = parameters.caster->getCasterOwner();
  96. iw.text.appendLocalString(EMetaText::GENERAL_TXT, 335); //There are no boats to summon.
  97. env->apply(iw);
  98. return ESpellCastResult::ERROR;
  99. }
  100. else //create boat
  101. {
  102. env->createBoat(summonPos, BoatId::NECROPOLIS, parameters.caster->getCasterOwner());
  103. }
  104. return ESpellCastResult::OK;
  105. }
  106. VCMI_LIB_NAMESPACE_END