CommonConstructors.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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. }
  79. bool CHeroInstanceConstructor::objectFilter(const CGObjectInstance * object, const ObjectTemplate & templ) const
  80. {
  81. return false;
  82. }
  83. CGObjectInstance * CHeroInstanceConstructor::create(ObjectTemplate tmpl) const
  84. {
  85. CGHeroInstance * obj = createTyped(tmpl);
  86. obj->type = nullptr; //FIXME: set to valid value. somehow.
  87. return obj;
  88. }
  89. void CHeroInstanceConstructor::configureObject(CGObjectInstance * object, CRandomGenerator & rng) const
  90. {
  91. }
  92. CDwellingInstanceConstructor::CDwellingInstanceConstructor()
  93. {
  94. }
  95. void CDwellingInstanceConstructor::initTypeData(const JsonNode & input)
  96. {
  97. const JsonVector & levels = input["creatures"].Vector();
  98. availableCreatures.resize(levels.size());
  99. for (size_t i=0; i<levels.size(); i++)
  100. {
  101. const JsonVector & creatures = levels[i].Vector();
  102. availableCreatures[i].resize(creatures.size());
  103. for (size_t j=0; j<creatures.size(); j++)
  104. {
  105. VLC->modh->identifiers.requestIdentifier("creature", creatures[j], [=] (si32 index)
  106. {
  107. availableCreatures[i][j] = VLC->creh->creatures[index];
  108. });
  109. }
  110. }
  111. guards = input["guards"];
  112. }
  113. bool CDwellingInstanceConstructor::objectFilter(const CGObjectInstance *, const ObjectTemplate &) const
  114. {
  115. return false;
  116. }
  117. CGObjectInstance * CDwellingInstanceConstructor::create(ObjectTemplate tmpl) const
  118. {
  119. CGDwelling * obj = createTyped(tmpl);
  120. obj->creatures.resize(availableCreatures.size());
  121. for (auto & entry : availableCreatures)
  122. {
  123. for (const CCreature * cre : entry)
  124. obj->creatures.back().second.push_back(cre->idNumber);
  125. }
  126. return obj;
  127. }
  128. namespace
  129. {
  130. si32 loadValue(const JsonNode & value, CRandomGenerator & rng, si32 defaultValue = 0)
  131. {
  132. if (value.isNull())
  133. return defaultValue;
  134. if (value.getType() == JsonNode::DATA_FLOAT)
  135. return value.Float();
  136. si32 min = value["min"].Float();
  137. si32 max = value["max"].Float();
  138. return rng.getIntRange(min, max)();
  139. }
  140. std::vector<CStackBasicDescriptor> loadCreatures(const JsonNode & value, CRandomGenerator & rng)
  141. {
  142. std::vector<CStackBasicDescriptor> ret;
  143. for (auto & pair : value.Struct())
  144. {
  145. CStackBasicDescriptor stack;
  146. stack.type = VLC->creh->creatures[VLC->modh->identifiers.getIdentifier(pair.second.meta, "creature", pair.first).get()];
  147. stack.count = loadValue(pair.second, rng);
  148. ret.push_back(stack);
  149. }
  150. return ret;
  151. }
  152. }
  153. void CDwellingInstanceConstructor::configureObject(CGObjectInstance * object, CRandomGenerator &rng) const
  154. {
  155. CGDwelling * dwelling = dynamic_cast<CGDwelling*>(object);
  156. dwelling->creatures.clear();
  157. dwelling->creatures.resize(availableCreatures.size());
  158. for (auto & entry : availableCreatures)
  159. {
  160. for (const CCreature * cre : entry)
  161. dwelling->creatures.back().second.push_back(cre->idNumber);
  162. }
  163. if (guards.getType() == JsonNode::DATA_BOOL)
  164. {
  165. const CCreature * crea = availableCreatures.at(0).at(0);
  166. dwelling->putStack(SlotID(0), new CStackInstance(crea->idNumber, crea->growth * 3 ));
  167. }
  168. else for (auto & stack : loadCreatures(guards, rng))
  169. {
  170. dwelling->putStack(SlotID(dwelling->stacksCount()), new CStackInstance(stack.type->idNumber, stack.count));
  171. }
  172. }
  173. bool CDwellingInstanceConstructor::producesCreature(const CCreature * crea) const
  174. {
  175. for (auto & entry : availableCreatures)
  176. {
  177. for (const CCreature * cre : entry)
  178. if (crea == cre)
  179. return true;
  180. }
  181. return false;
  182. }