CommonConstructors.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /*
  2. * CommonConstructors.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 "CommonConstructors.h"
  12. #include "../texts/CGeneralTextHandler.h"
  13. #include "../IGameCallback.h"
  14. #include "../json/JsonRandom.h"
  15. #include "../constants/StringConstants.h"
  16. #include "../TerrainHandler.h"
  17. #include "../VCMI_Lib.h"
  18. #include "../entities/faction/CTownHandler.h"
  19. #include "../entities/hero/CHeroClass.h"
  20. #include "../mapObjects/CGHeroInstance.h"
  21. #include "../mapObjects/CGMarket.h"
  22. #include "../mapObjects/CGTownInstance.h"
  23. #include "../mapObjects/MiscObjects.h"
  24. #include "../mapObjects/ObjectTemplate.h"
  25. #include "../modding/IdentifierStorage.h"
  26. #include "../mapping/CMapDefines.h"
  27. VCMI_LIB_NAMESPACE_BEGIN
  28. bool CObstacleConstructor::isStaticObject()
  29. {
  30. return true;
  31. }
  32. bool CreatureInstanceConstructor::hasNameTextID() const
  33. {
  34. return true;
  35. }
  36. std::string CreatureInstanceConstructor::getNameTextID() const
  37. {
  38. return VLC->creatures()->getByIndex(getSubIndex())->getNamePluralTextID();
  39. }
  40. bool ResourceInstanceConstructor::hasNameTextID() const
  41. {
  42. return true;
  43. }
  44. std::string ResourceInstanceConstructor::getNameTextID() const
  45. {
  46. return TextIdentifier("core", "restypes", getSubIndex()).get();
  47. }
  48. void CTownInstanceConstructor::initTypeData(const JsonNode & input)
  49. {
  50. VLC->identifiers()->requestIdentifier("faction", input["faction"], [&](si32 index)
  51. {
  52. faction = (*VLC->townh)[index];
  53. });
  54. filtersJson = input["filters"];
  55. // change scope of "filters" to scope of object that is being loaded
  56. // since this filters require to resolve building ID's
  57. filtersJson.setModScope(input["faction"].getModScope());
  58. }
  59. void CTownInstanceConstructor::afterLoadFinalization()
  60. {
  61. assert(faction);
  62. for(const auto & entry : filtersJson.Struct())
  63. {
  64. filters[entry.first] = LogicalExpression<BuildingID>(entry.second, [this](const JsonNode & node)
  65. {
  66. return BuildingID(VLC->identifiers()->getIdentifier("building." + faction->getJsonKey(), node.Vector()[0]).value_or(-1));
  67. });
  68. }
  69. }
  70. bool CTownInstanceConstructor::objectFilter(const CGObjectInstance * object, std::shared_ptr<const ObjectTemplate> templ) const
  71. {
  72. const auto * town = dynamic_cast<const CGTownInstance *>(object);
  73. auto buildTest = [&](const BuildingID & id)
  74. {
  75. return town->hasBuilt(id);
  76. };
  77. return filters.count(templ->stringID) != 0 && filters.at(templ->stringID).test(buildTest);
  78. }
  79. void CTownInstanceConstructor::initializeObject(CGTownInstance * obj) const
  80. {
  81. obj->tempOwner = PlayerColor::NEUTRAL;
  82. }
  83. void CTownInstanceConstructor::randomizeObject(CGTownInstance * object, vstd::RNG & rng) const
  84. {
  85. auto templ = getOverride(object->cb->getTile(object->pos)->terType->getId(), object);
  86. if(templ)
  87. object->appearance = templ;
  88. }
  89. bool CTownInstanceConstructor::hasNameTextID() const
  90. {
  91. return true;
  92. }
  93. std::string CTownInstanceConstructor::getNameTextID() const
  94. {
  95. return faction->getNameTextID();
  96. }
  97. void CHeroInstanceConstructor::initTypeData(const JsonNode & input)
  98. {
  99. VLC->identifiers()->requestIdentifier(
  100. "heroClass",
  101. input["heroClass"],
  102. [&](si32 index) { heroClass = HeroClassID(index).toHeroClass(); });
  103. filtersJson = input["filters"];
  104. }
  105. void CHeroInstanceConstructor::afterLoadFinalization()
  106. {
  107. for(const auto & entry : filtersJson.Struct())
  108. {
  109. filters[entry.first] = LogicalExpression<HeroTypeID>(entry.second, [](const JsonNode & node)
  110. {
  111. return HeroTypeID(VLC->identifiers()->getIdentifier("hero", node.Vector()[0]).value_or(-1));
  112. });
  113. }
  114. }
  115. bool CHeroInstanceConstructor::objectFilter(const CGObjectInstance * object, std::shared_ptr<const ObjectTemplate> templ) const
  116. {
  117. const auto * hero = dynamic_cast<const CGHeroInstance *>(object);
  118. auto heroTest = [&](const HeroTypeID & id)
  119. {
  120. return hero->getHeroTypeID() == id;
  121. };
  122. if(filters.count(templ->stringID))
  123. {
  124. return filters.at(templ->stringID).test(heroTest);
  125. }
  126. return false;
  127. }
  128. void CHeroInstanceConstructor::randomizeObject(CGHeroInstance * object, vstd::RNG & rng) const
  129. {
  130. }
  131. bool CHeroInstanceConstructor::hasNameTextID() const
  132. {
  133. return true;
  134. }
  135. std::string CHeroInstanceConstructor::getNameTextID() const
  136. {
  137. return heroClass->getNameTextID();
  138. }
  139. void BoatInstanceConstructor::initTypeData(const JsonNode & input)
  140. {
  141. layer = EPathfindingLayer::SAIL;
  142. int pos = vstd::find_pos(NPathfindingLayer::names, input["layer"].String());
  143. if(pos != -1)
  144. layer = EPathfindingLayer(pos);
  145. else
  146. logMod->error("Unknown layer %s found in boat!", input["layer"].String());
  147. onboardAssaultAllowed = input["onboardAssaultAllowed"].Bool();
  148. onboardVisitAllowed = input["onboardVisitAllowed"].Bool();
  149. actualAnimation = AnimationPath::fromJson(input["actualAnimation"]);
  150. overlayAnimation = AnimationPath::fromJson(input["overlayAnimation"]);
  151. for(int i = 0; i < flagAnimations.size() && i < input["flagAnimations"].Vector().size(); ++i)
  152. flagAnimations[i] = AnimationPath::fromJson(input["flagAnimations"].Vector()[i]);
  153. bonuses = JsonRandom::loadBonuses(input["bonuses"]);
  154. }
  155. void BoatInstanceConstructor::initializeObject(CGBoat * boat) const
  156. {
  157. boat->layer = layer;
  158. boat->actualAnimation = actualAnimation;
  159. boat->overlayAnimation = overlayAnimation;
  160. boat->flagAnimations = flagAnimations;
  161. boat->onboardAssaultAllowed = onboardAssaultAllowed;
  162. boat->onboardVisitAllowed = onboardVisitAllowed;
  163. for(auto & b : bonuses)
  164. boat->addNewBonus(std::make_shared<Bonus>(b));
  165. }
  166. AnimationPath BoatInstanceConstructor::getBoatAnimationName() const
  167. {
  168. return actualAnimation;
  169. }
  170. void MarketInstanceConstructor::initTypeData(const JsonNode & input)
  171. {
  172. for(auto & element : input["modes"].Vector())
  173. {
  174. if(MappedKeys::MARKET_NAMES_TO_TYPES.count(element.String()))
  175. marketModes.insert(MappedKeys::MARKET_NAMES_TO_TYPES.at(element.String()));
  176. }
  177. marketEfficiency = input["efficiency"].isNull() ? 5 : input["efficiency"].Integer();
  178. predefinedOffer = input["offer"];
  179. title = input["title"].String();
  180. speech = input["speech"].String();
  181. }
  182. CGMarket * MarketInstanceConstructor::createObject(IGameCallback * cb) const
  183. {
  184. if(marketModes.size() == 1)
  185. {
  186. switch(*marketModes.begin())
  187. {
  188. case EMarketMode::ARTIFACT_RESOURCE:
  189. case EMarketMode::RESOURCE_ARTIFACT:
  190. return new CGBlackMarket(cb);
  191. case EMarketMode::RESOURCE_SKILL:
  192. return new CGUniversity(cb);
  193. }
  194. }
  195. return new CGMarket(cb);
  196. }
  197. void MarketInstanceConstructor::initializeObject(CGMarket * market) const
  198. {
  199. market->marketEfficiency = marketEfficiency;
  200. if(auto university = dynamic_cast<CGUniversity*>(market))
  201. {
  202. university->title = market->getObjectName();
  203. if(!title.empty())
  204. university->title = VLC->generaltexth->translate(title);
  205. if(!speech.empty())
  206. university->speech = VLC->generaltexth->translate(speech);
  207. }
  208. }
  209. const std::set<EMarketMode> & MarketInstanceConstructor::availableModes() const
  210. {
  211. return marketModes;
  212. }
  213. void MarketInstanceConstructor::randomizeObject(CGMarket * object, vstd::RNG & rng) const
  214. {
  215. JsonRandom randomizer(object->cb);
  216. JsonRandom::Variables emptyVariables;
  217. if(auto * university = dynamic_cast<CGUniversity *>(object))
  218. {
  219. for(auto skill : randomizer.loadSecondaries(predefinedOffer, rng, emptyVariables))
  220. university->skills.push_back(skill.first);
  221. }
  222. }
  223. VCMI_LIB_NAMESPACE_END