BonusSystem.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /*
  2. * BonusSystem.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 "BonusSystem.h"
  12. #include "../../../lib/JsonNode.h"
  13. #include "../../../lib/bonuses/BonusList.h"
  14. #include "../../../lib/bonuses/Bonus.h"
  15. #include "../../../lib/bonuses/IBonusBearer.h"
  16. #include "Registry.h"
  17. #include "../LuaStack.h"
  18. #include "../LuaCallWrapper.h"
  19. VCMI_LIB_NAMESPACE_BEGIN
  20. namespace scripting
  21. {
  22. namespace api
  23. {
  24. VCMI_REGISTER_SCRIPT_API(BonusProxy, "Bonus");
  25. const std::vector<BonusProxy::CustomRegType> BonusProxy::REGISTER_CUSTOM =
  26. {
  27. {"getType", &BonusProxy::getType, false},
  28. {"getSubtype", &BonusProxy::getSubtype, false},
  29. {"getDuration", &BonusProxy::getDuration, false},
  30. {"getTurns", &BonusProxy::getTurns, false},
  31. {"getValueType", &BonusProxy::getValueType, false},
  32. {"getVal", &BonusProxy::getVal, false},
  33. {"getSource", &BonusProxy::getSource, false},
  34. {"getSourceID", &BonusProxy::getSourceID, false},
  35. {"getEffectRange", &BonusProxy::getEffectRange, false},
  36. {"getStacking", &BonusProxy::getStacking, false},
  37. {"getDescription", &BonusProxy::getDescription, false},
  38. {"toJsonNode", &BonusProxy::toJsonNode, false}
  39. };
  40. int BonusProxy::getType(lua_State * L)
  41. {
  42. LuaStack S(L);
  43. std::shared_ptr<const Bonus> object;
  44. if(!S.tryGet(1, object))
  45. return S.retNil();
  46. return LuaStack::quickRetInt(L, object->type);
  47. }
  48. int BonusProxy::getSubtype(lua_State * L)
  49. {
  50. LuaStack S(L);
  51. std::shared_ptr<const Bonus> object;
  52. if(!S.tryGet(1, object))
  53. return S.retNil();
  54. return LuaStack::quickRetInt(L, object->subtype.getNum());
  55. }
  56. int BonusProxy::getDuration(lua_State * L)
  57. {
  58. LuaStack S(L);
  59. std::shared_ptr<const Bonus> object;
  60. if(!S.tryGet(1, object))
  61. return S.retNil();
  62. return LuaStack::quickRetInt(L, object->duration);
  63. }
  64. int BonusProxy::getTurns(lua_State * L)
  65. {
  66. LuaStack S(L);
  67. std::shared_ptr<const Bonus> object;
  68. if(!S.tryGet(1, object))
  69. return S.retNil();
  70. return LuaStack::quickRetInt(L, object->turnsRemain);
  71. }
  72. int BonusProxy::getValueType(lua_State * L)
  73. {
  74. LuaStack S(L);
  75. std::shared_ptr<const Bonus> object;
  76. if(!S.tryGet(1, object))
  77. return S.retNil();
  78. return LuaStack::quickRetInt(L, object->valType);
  79. }
  80. int BonusProxy::getVal(lua_State * L)
  81. {
  82. LuaStack S(L);
  83. std::shared_ptr<const Bonus> object;
  84. if(!S.tryGet(1, object))
  85. return S.retNil();
  86. return LuaStack::quickRetInt(L, object->val);
  87. }
  88. int BonusProxy::getSource(lua_State * L)
  89. {
  90. LuaStack S(L);
  91. std::shared_ptr<const Bonus> object;
  92. if(!S.tryGet(1, object))
  93. return S.retNil();
  94. return LuaStack::quickRetInt(L, object->source);
  95. }
  96. int BonusProxy::getSourceID(lua_State * L)
  97. {
  98. LuaStack S(L);
  99. std::shared_ptr<const Bonus> object;
  100. if(!S.tryGet(1, object))
  101. return S.retNil();
  102. return LuaStack::quickRetInt(L, object->sid.getNum());
  103. }
  104. int BonusProxy::getEffectRange(lua_State * L)
  105. {
  106. LuaStack S(L);
  107. std::shared_ptr<const Bonus> object;
  108. if(!S.tryGet(1, object))
  109. return S.retNil();
  110. return LuaStack::quickRetInt(L, object->effectRange);
  111. }
  112. int BonusProxy::getStacking(lua_State * L)
  113. {
  114. LuaStack S(L);
  115. std::shared_ptr<const Bonus> object;
  116. if(!S.tryGet(1, object))
  117. return S.retNil();
  118. return LuaStack::quickRetStr(L, object->stacking);
  119. }
  120. int BonusProxy::getDescription(lua_State * L)
  121. {
  122. LuaStack S(L);
  123. std::shared_ptr<const Bonus> object;
  124. if(!S.tryGet(1, object))
  125. return S.retNil();
  126. return LuaStack::quickRetStr(L, object->description);
  127. }
  128. int BonusProxy::toJsonNode(lua_State * L)
  129. {
  130. LuaStack S(L);
  131. std::shared_ptr<const Bonus> object;
  132. if(!S.tryGet(1, object))
  133. return S.retNil();
  134. S.clear();
  135. S.push(object->toJsonNode());
  136. return 1;
  137. }
  138. template <typename T, typename N>
  139. static void publishMap(lua_State * L, const std::map<T , N> & map)
  140. {
  141. for(auto & p : map)
  142. {
  143. const std::string & name = p.first;
  144. auto id = static_cast<int32_t>(p.second);
  145. lua_pushstring(L, name.c_str());
  146. lua_pushinteger(L, id);
  147. lua_rawset(L, -3);
  148. }
  149. }
  150. template <typename T, std::size_t N>
  151. static void publishMap(lua_State * L, const std::map<T , std::bitset<N>> & map)
  152. {
  153. for(auto & p : map)
  154. {
  155. const std::string & name = p.first;
  156. auto id = static_cast<int32_t>(p.second.to_ulong());
  157. lua_pushstring(L, name.c_str());
  158. lua_pushinteger(L, id);
  159. lua_rawset(L, -3);
  160. }
  161. }
  162. void BonusProxy::adjustStaticTable(lua_State * L) const
  163. {
  164. publishMap(L, bonusNameMap);
  165. publishMap(L, bonusValueMap);
  166. publishMap(L, bonusSourceMap);
  167. publishMap(L, bonusDurationMap);
  168. }
  169. VCMI_REGISTER_SCRIPT_API(BonusListProxy, "BonusList");
  170. const std::vector<BonusListProxy::CustomRegType> BonusListProxy::REGISTER_CUSTOM =
  171. {
  172. };
  173. std::shared_ptr<const Bonus> BonusListProxy::index(std::shared_ptr<const BonusList> self, int key)
  174. {
  175. //field = __index(self, key)
  176. std::shared_ptr<const Bonus> ret;
  177. if((key >= 1) && (key <= self->size()))
  178. ret = (*self)[key-1];
  179. return ret;
  180. }
  181. void BonusListProxy::adjustMetatable(lua_State * L) const
  182. {
  183. lua_pushstring(L, "__index");
  184. lua_pushcclosure(L, LuaFunctionWrapper<decltype(&BonusListProxy::index), &BonusListProxy::index>::invoke, 0);
  185. lua_rawset(L, -3);
  186. }
  187. VCMI_REGISTER_SCRIPT_API(BonusBearerProxy, "BonusBearer");
  188. const std::vector<BonusBearerProxy::CustomRegType> BonusBearerProxy::REGISTER_CUSTOM =
  189. {
  190. {"getBonuses", &BonusBearerProxy::getBonuses, false},
  191. };
  192. int BonusBearerProxy::getBonuses(lua_State * L)
  193. {
  194. LuaStack S(L);
  195. const IBonusBearer * object = nullptr;
  196. if(!S.tryGet(1, object))
  197. return S.retNil();
  198. TConstBonusListPtr ret;
  199. const bool hasSelector = S.isFunction(2);
  200. const bool hasRangeSelector = S.isFunction(3);
  201. if(hasSelector)
  202. {
  203. auto selector = [](const Bonus * b)
  204. {
  205. return false; //TODO: BonusBearerProxy::getBonuses selector
  206. };
  207. if(hasRangeSelector)
  208. {
  209. auto rangeSelector = [](const Bonus * b)
  210. {
  211. return false;//TODO: BonusBearerProxy::getBonuses rangeSelector
  212. };
  213. ret = object->getBonuses(selector, rangeSelector);
  214. }
  215. else
  216. {
  217. ret = object->getBonuses(selector, Selector::all);
  218. }
  219. }
  220. else
  221. {
  222. ret = object->getBonuses(Selector::all, Selector::all);
  223. }
  224. S.clear();
  225. S.push(ret);
  226. return S.retPushed();
  227. }
  228. }
  229. }
  230. VCMI_LIB_NAMESPACE_END