LuaSpellEffect.cpp 4.6 KB

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