2
0

LuaSpellEffect.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * LuaSpellEffect.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 "LuaSpellEffect.h"
  12. #include <vcmi/scripting/Service.h>
  13. #include "../../lib/spells/effects/Registry.h"
  14. #include "../../lib/spells/ISpellMechanics.h"
  15. #include "../../lib/battle/Unit.h"
  16. #include "../../lib/battle/CBattleInfoCallback.h"
  17. #include "../../lib/serializer/JsonSerializeFormat.h"
  18. static const std::string APPLICABLE_GENERAL = "applicable";
  19. static const std::string APPLICABLE_TARGET = "applicableTarget";
  20. static const std::string APPLY = "apply";
  21. namespace spells
  22. {
  23. namespace effects
  24. {
  25. LuaSpellEffectFactory::LuaSpellEffectFactory(const Script * script_)
  26. : script(script_)
  27. {
  28. }
  29. LuaSpellEffectFactory::~LuaSpellEffectFactory() = default;
  30. Effect * LuaSpellEffectFactory::create() const
  31. {
  32. return new LuaSpellEffect(script);
  33. }
  34. LuaSpellEffect::LuaSpellEffect(const Script * script_)
  35. : script(script_)
  36. {
  37. }
  38. LuaSpellEffect::~LuaSpellEffect() = default;
  39. void LuaSpellEffect::adjustTargetTypes(std::vector<TargetType> & types) const
  40. {
  41. }
  42. void LuaSpellEffect::adjustAffectedHexes(std::set<BattleHex> & hexes, const Mechanics * m, const Target & spellTarget) const
  43. {
  44. }
  45. bool LuaSpellEffect::applicable(Problem & problem, const Mechanics * m) const
  46. {
  47. std::shared_ptr<scripting::Context> context = resolveScript(m);
  48. if(!context)
  49. return false;
  50. setContextVariables(m, context);
  51. JsonNode response = context->callGlobal(APPLICABLE_GENERAL, JsonNode());
  52. if(response.getType() != JsonNode::JsonType::DATA_BOOL)
  53. {
  54. logMod->error("Invalid API response from script %s.", script->getName());
  55. logMod->debug(response.toJson(true));
  56. return false;
  57. }
  58. return response.Bool();
  59. }
  60. bool LuaSpellEffect::applicable(Problem & problem, const Mechanics * m, const EffectTarget & target) const
  61. {
  62. std::shared_ptr<scripting::Context> context = resolveScript(m);
  63. if(!context)
  64. return false;
  65. setContextVariables(m, context);
  66. JsonNode requestP;
  67. if(target.empty())
  68. return false;
  69. for(auto & dest : target)
  70. {
  71. JsonNode targetData;
  72. targetData.Vector().push_back(JsonUtils::intNode(dest.hexValue.hex));
  73. if(dest.unitValue)
  74. targetData.Vector().push_back(JsonUtils::intNode(dest.unitValue->unitId()));
  75. else
  76. targetData.Vector().push_back(JsonUtils::intNode(-1));
  77. requestP.Vector().push_back(targetData);
  78. }
  79. JsonNode request;
  80. request.Vector().push_back(requestP);
  81. JsonNode response = context->callGlobal(APPLICABLE_TARGET, request);
  82. if(response.getType() != JsonNode::JsonType::DATA_BOOL)
  83. {
  84. logMod->error("Invalid API response from script %s.", script->getName());
  85. logMod->debug(response.toJson(true));
  86. return false;
  87. }
  88. return response.Bool();
  89. }
  90. void LuaSpellEffect::apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const
  91. {
  92. if(target.empty())
  93. return;
  94. std::shared_ptr<scripting::Context> context = resolveScript(m);
  95. if(!context)
  96. {
  97. server->complain("Unable to create scripting context");
  98. return;
  99. }
  100. setContextVariables(m, context);
  101. JsonNode requestP;
  102. for(auto & dest : target)
  103. {
  104. JsonNode targetData;
  105. targetData.Vector().push_back(JsonUtils::intNode(dest.hexValue.hex));
  106. if(dest.unitValue)
  107. targetData.Vector().push_back(JsonUtils::intNode(dest.unitValue->unitId()));
  108. else
  109. targetData.Vector().push_back(JsonUtils::intNode(-1));
  110. requestP.Vector().push_back(targetData);
  111. }
  112. JsonNode request;
  113. request.Vector().push_back(requestP);
  114. context->callGlobal(server, APPLY, request);
  115. }
  116. EffectTarget LuaSpellEffect::filterTarget(const Mechanics * m, const EffectTarget & target) const
  117. {
  118. return EffectTarget(target);
  119. }
  120. EffectTarget LuaSpellEffect::transformTarget(const Mechanics * m, const Target & aimPoint, const Target & spellTarget) const
  121. {
  122. return EffectTarget(spellTarget);
  123. }
  124. void LuaSpellEffect::serializeJsonEffect(JsonSerializeFormat & handler)
  125. {
  126. //TODO: load everything and provide to script
  127. }
  128. std::shared_ptr<Context> LuaSpellEffect::resolveScript(const Mechanics * m) const
  129. {
  130. return m->battle()->getContextPool()->getContext(script);
  131. }
  132. void LuaSpellEffect::setContextVariables(const Mechanics * m, std::shared_ptr<Context> context) const
  133. {
  134. context->setGlobal("effectLevel", m->getEffectLevel());
  135. context->setGlobal("effectRangeLevel", m->getRangeLevel());
  136. context->setGlobal("effectPower", m->getEffectPower());
  137. context->setGlobal("effectDuration", m->getEffectDuration());
  138. context->setGlobal("effectValue", static_cast<int>(m->getEffectValue()));
  139. }
  140. }
  141. }