LuaSpellEffect.cpp 4.5 KB

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