CommonConstructors.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. #include "StdInc.h"
  2. #include "CommonConstructors.h"
  3. #include "CGTownInstance.h"
  4. #include "CGHeroInstance.h"
  5. #include "../mapping/CMap.h"
  6. #include "../CHeroHandler.h"
  7. #include "../CCreatureHandler.h"
  8. /*
  9. * CommonConstructors.cpp, part of VCMI engine
  10. *
  11. * Authors: listed in file AUTHORS in main folder
  12. *
  13. * License: GNU General Public License v2.0 or later
  14. * Full text of license available in license.txt file, in main folder
  15. *
  16. */
  17. CObstacleConstructor::CObstacleConstructor()
  18. {
  19. }
  20. bool CObstacleConstructor::isStaticObject()
  21. {
  22. return true;
  23. }
  24. CTownInstanceConstructor::CTownInstanceConstructor():
  25. faction(nullptr)
  26. {
  27. }
  28. void CTownInstanceConstructor::initTypeData(const JsonNode & input)
  29. {
  30. VLC->modh->identifiers.requestIdentifier("faction", input["faction"], [&](si32 index)
  31. {
  32. faction = VLC->townh->factions[index];
  33. });
  34. filtersJson = input["filters"];
  35. }
  36. void CTownInstanceConstructor::afterLoadFinalization()
  37. {
  38. assert(faction);
  39. for (auto entry : filtersJson.Struct())
  40. {
  41. filters[entry.first] = LogicalExpression<BuildingID>(entry.second, [this](const JsonNode & node)
  42. {
  43. return BuildingID(VLC->modh->identifiers.getIdentifier("building." + faction->identifier, node.Vector()[0]).get());
  44. });
  45. }
  46. }
  47. bool CTownInstanceConstructor::objectFilter(const CGObjectInstance * object, const ObjectTemplate & templ) const
  48. {
  49. auto town = dynamic_cast<const CGTownInstance *>(object);
  50. auto buildTest = [&](const BuildingID & id)
  51. {
  52. return town->hasBuilt(id);
  53. };
  54. if (filters.count(templ.stringID))
  55. return filters.at(templ.stringID).test(buildTest);
  56. return false;
  57. }
  58. CGObjectInstance * CTownInstanceConstructor::create(ObjectTemplate tmpl) const
  59. {
  60. CGTownInstance * obj = createTyped(tmpl);
  61. obj->town = faction->town;
  62. obj->tempOwner = PlayerColor::NEUTRAL;
  63. return obj;
  64. }
  65. void CTownInstanceConstructor::configureObject(CGObjectInstance * object, CRandomGenerator & rng) const
  66. {
  67. auto templ = getOverride(object->cb->getTile(object->pos)->terType, object);
  68. if (templ)
  69. object->appearance = templ.get();
  70. }
  71. CHeroInstanceConstructor::CHeroInstanceConstructor()
  72. {
  73. }
  74. void CHeroInstanceConstructor::initTypeData(const JsonNode & input)
  75. {
  76. VLC->modh->identifiers.requestIdentifier("heroClass", input["heroClass"],
  77. [&](si32 index) { heroClass = VLC->heroh->classes.heroClasses[index]; });
  78. filtersJson = input["filters"];
  79. }
  80. void CHeroInstanceConstructor::afterLoadFinalization()
  81. {
  82. for (auto entry : filtersJson.Struct())
  83. {
  84. filters[entry.first] = LogicalExpression<HeroTypeID>(entry.second, [this](const JsonNode & node)
  85. {
  86. return HeroTypeID(VLC->modh->identifiers.getIdentifier("hero", node.Vector()[0]).get());
  87. });
  88. }
  89. }
  90. bool CHeroInstanceConstructor::objectFilter(const CGObjectInstance * object, const ObjectTemplate & templ) const
  91. {
  92. auto hero = dynamic_cast<const CGHeroInstance *>(object);
  93. auto heroTest = [&](const HeroTypeID & id)
  94. {
  95. return hero->type->ID == id;
  96. };
  97. if (filters.count(templ.stringID))
  98. {
  99. return filters.at(templ.stringID).test(heroTest);
  100. }
  101. return false;
  102. }
  103. CGObjectInstance * CHeroInstanceConstructor::create(ObjectTemplate tmpl) const
  104. {
  105. CGHeroInstance * obj = createTyped(tmpl);
  106. obj->type = nullptr; //FIXME: set to valid value. somehow.
  107. return obj;
  108. }
  109. void CHeroInstanceConstructor::configureObject(CGObjectInstance * object, CRandomGenerator & rng) const
  110. {
  111. }
  112. CDwellingInstanceConstructor::CDwellingInstanceConstructor()
  113. {
  114. }
  115. void CDwellingInstanceConstructor::initTypeData(const JsonNode & input)
  116. {
  117. const JsonVector & levels = input["creatures"].Vector();
  118. availableCreatures.resize(levels.size());
  119. for (size_t i=0; i<levels.size(); i++)
  120. {
  121. const JsonVector & creatures = levels[i].Vector();
  122. availableCreatures[i].resize(creatures.size());
  123. for (size_t j=0; j<creatures.size(); j++)
  124. {
  125. VLC->modh->identifiers.requestIdentifier("creature", creatures[j], [=] (si32 index)
  126. {
  127. availableCreatures[i][j] = VLC->creh->creatures[index];
  128. });
  129. }
  130. }
  131. guards = input["guards"];
  132. }
  133. bool CDwellingInstanceConstructor::objectFilter(const CGObjectInstance *, const ObjectTemplate &) const
  134. {
  135. return false;
  136. }
  137. CGObjectInstance * CDwellingInstanceConstructor::create(ObjectTemplate tmpl) const
  138. {
  139. CGDwelling * obj = createTyped(tmpl);
  140. obj->creatures.resize(availableCreatures.size());
  141. for (auto & entry : availableCreatures)
  142. {
  143. for (const CCreature * cre : entry)
  144. obj->creatures.back().second.push_back(cre->idNumber);
  145. }
  146. return obj;
  147. }
  148. namespace
  149. {
  150. si32 loadValue(const JsonNode & value, CRandomGenerator & rng, si32 defaultValue = 0)
  151. {
  152. if (value.isNull())
  153. return defaultValue;
  154. if (value.getType() == JsonNode::DATA_FLOAT)
  155. return value.Float();
  156. si32 min = value["min"].Float();
  157. si32 max = value["max"].Float();
  158. return rng.getIntRange(min, max)();
  159. }
  160. std::vector<CStackBasicDescriptor> loadCreatures(const JsonNode & value, CRandomGenerator & rng)
  161. {
  162. std::vector<CStackBasicDescriptor> ret;
  163. for (auto & pair : value.Struct())
  164. {
  165. CStackBasicDescriptor stack;
  166. stack.type = VLC->creh->creatures[VLC->modh->identifiers.getIdentifier(pair.second.meta, "creature", pair.first).get()];
  167. stack.count = loadValue(pair.second, rng);
  168. ret.push_back(stack);
  169. }
  170. return ret;
  171. }
  172. }
  173. void CDwellingInstanceConstructor::configureObject(CGObjectInstance * object, CRandomGenerator &rng) const
  174. {
  175. CGDwelling * dwelling = dynamic_cast<CGDwelling*>(object);
  176. dwelling->creatures.clear();
  177. dwelling->creatures.resize(availableCreatures.size());
  178. for (auto & entry : availableCreatures)
  179. {
  180. for (const CCreature * cre : entry)
  181. dwelling->creatures.back().second.push_back(cre->idNumber);
  182. }
  183. if (guards.getType() == JsonNode::DATA_BOOL)
  184. {
  185. const CCreature * crea = availableCreatures.at(0).at(0);
  186. dwelling->putStack(SlotID(0), new CStackInstance(crea->idNumber, crea->growth * 3 ));
  187. }
  188. else for (auto & stack : loadCreatures(guards, rng))
  189. {
  190. dwelling->putStack(SlotID(dwelling->stacksCount()), new CStackInstance(stack.type->idNumber, stack.count));
  191. }
  192. }
  193. bool CDwellingInstanceConstructor::producesCreature(const CCreature * crea) const
  194. {
  195. for (auto & entry : availableCreatures)
  196. {
  197. for (const CCreature * cre : entry)
  198. if (crea == cre)
  199. return true;
  200. }
  201. return false;
  202. }