2
0

CObjectConstructor.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. #include "StdInc.h"
  2. #include "CObjectConstructor.h"
  3. #include "CRandomGenerator.h"
  4. #include "StringConstants.h"
  5. #include "CCreatureHandler.h"
  6. /*
  7. * CObjectConstructor.cpp, part of VCMI engine
  8. *
  9. * Authors: listed in file AUTHORS in main folder
  10. *
  11. * License: GNU General Public License v2.0 or later
  12. * Full text of license available in license.txt file, in main folder
  13. *
  14. */
  15. namespace {
  16. si32 loadValue(const JsonNode & value, CRandomGenerator & rng, si32 defaultValue = 0)
  17. {
  18. if (value.isNull())
  19. return defaultValue;
  20. if (value.getType() == JsonNode::DATA_FLOAT)
  21. return value.Float();
  22. si32 min = value["min"].Float();
  23. si32 max = value["max"].Float();
  24. return rng.getIntRange(min, max)();
  25. }
  26. TResources loadResources(const JsonNode & value, CRandomGenerator & rng)
  27. {
  28. TResources ret;
  29. for (size_t i=0; i<GameConstants::RESOURCE_QUANTITY; i++)
  30. {
  31. ret[i] = loadValue(value[GameConstants::RESOURCE_NAMES[i]], rng);
  32. }
  33. return ret;
  34. }
  35. std::vector<si32> loadPrimary(const JsonNode & value, CRandomGenerator & rng)
  36. {
  37. std::vector<si32> ret;
  38. for (auto & name : PrimarySkill::names)
  39. {
  40. ret.push_back(loadValue(value[name], rng));
  41. }
  42. return ret;
  43. }
  44. std::map<SecondarySkill, si32> loadSecondary(const JsonNode & value, CRandomGenerator & rng)
  45. {
  46. std::map<SecondarySkill, si32> ret;
  47. for (auto & pair : value.Struct())
  48. {
  49. SecondarySkill id(VLC->modh->identifiers.getIdentifier(pair.second.meta, "skill", pair.first).get());
  50. ret[id] = loadValue(pair.second, rng);
  51. }
  52. return ret;
  53. }
  54. std::vector<ArtifactID> loadArtifacts(const JsonNode & value, CRandomGenerator & rng)
  55. {
  56. std::vector<ArtifactID> ret;
  57. for (const JsonNode & entry : value.Vector())
  58. {
  59. ArtifactID art(VLC->modh->identifiers.getIdentifier("artifact", entry).get());
  60. ret.push_back(art);
  61. }
  62. return ret;
  63. }
  64. std::vector<SpellID> loadSpells(const JsonNode & value, CRandomGenerator & rng)
  65. {
  66. std::vector<SpellID> ret;
  67. for (const JsonNode & entry : value.Vector())
  68. {
  69. SpellID spell(VLC->modh->identifiers.getIdentifier("spell", entry).get());
  70. ret.push_back(spell);
  71. }
  72. return ret;
  73. }
  74. std::vector<CStackBasicDescriptor> loadCreatures(const JsonNode & value, CRandomGenerator & rng)
  75. {
  76. std::vector<CStackBasicDescriptor> ret;
  77. for (auto & pair : value.Struct())
  78. {
  79. CStackBasicDescriptor stack;
  80. stack.type = VLC->creh->creatures[VLC->modh->identifiers.getIdentifier(pair.second.meta, "creature", pair.first).get()];
  81. stack.count = loadValue(pair.second, rng);
  82. ret.push_back(stack);
  83. }
  84. return ret;
  85. }
  86. std::vector<Bonus> loadBonuses(const JsonNode & value)
  87. {
  88. std::vector<Bonus> ret;
  89. for (const JsonNode & entry : value.Vector())
  90. {
  91. Bonus * bonus = JsonUtils::parseBonus(entry);
  92. ret.push_back(*bonus);
  93. delete bonus;
  94. }
  95. return ret;
  96. }
  97. std::vector<Component> loadComponents(const JsonNode & value)
  98. {
  99. //TODO
  100. }
  101. MetaString loadMessage(const JsonNode & value)
  102. {
  103. MetaString ret;
  104. if (value.getType() == JsonNode::DATA_FLOAT)
  105. ret.addTxt(MetaString::ADVOB_TXT, value.Float());
  106. else
  107. ret << value.String();
  108. return ret;
  109. }
  110. bool testForKey(const JsonNode & value, const std::string & key)
  111. {
  112. for( auto & reward : value["rewards"].Vector() )
  113. {
  114. if (!reward[key].isNull())
  115. return true;
  116. }
  117. return false;
  118. }
  119. }
  120. void CRandomRewardObjectInfo::init(const JsonNode & objectConfig)
  121. {
  122. parameters = objectConfig;
  123. }
  124. void CRandomRewardObjectInfo::configureObject(CObjectWithReward * object, CRandomGenerator & rng) const
  125. {
  126. std::map<si32, si32> thrownDice;
  127. for (const JsonNode & reward : parameters["rewards"].Vector())
  128. {
  129. if (!reward["appearChance"].isNull())
  130. {
  131. JsonNode chance = reward["appearChance"];
  132. si32 diceID = chance["dice"].Float();
  133. if (thrownDice.count(diceID) == 0)
  134. thrownDice[diceID] = rng.getIntRange(1, 100)();
  135. if (!chance["min"].isNull())
  136. {
  137. int min = chance["min"].Float();
  138. if (min > thrownDice[diceID])
  139. continue;
  140. }
  141. if (!chance["max"].isNull())
  142. {
  143. int max = chance["max"].Float();
  144. if (max < thrownDice[diceID])
  145. continue;
  146. }
  147. }
  148. const JsonNode & limiter = reward["limiter"];
  149. CVisitInfo info;
  150. // load limiter
  151. info.limiter.numOfGrants = loadValue(limiter["numOfGrants"], rng);
  152. info.limiter.dayOfWeek = loadValue(limiter["dayOfWeek"], rng);
  153. info.limiter.minLevel = loadValue(limiter["minLevel"], rng);
  154. info.limiter.resources = loadResources(limiter["resources"], rng);
  155. info.limiter.primary = loadPrimary(limiter["primary"], rng);
  156. info.limiter.secondary = loadSecondary(limiter["secondary"], rng);
  157. info.limiter.artifacts = loadArtifacts(limiter["artifacts"], rng);
  158. info.limiter.creatures = loadCreatures(limiter["creatures"], rng);
  159. info.reward.resources = loadResources(reward["resources"], rng);
  160. info.reward.gainedExp = loadValue(reward["gainedExp"], rng);
  161. info.reward.gainedLevels = loadValue(reward["gainedLevels"], rng);
  162. info.reward.manaDiff = loadValue(reward["manaPoints"], rng);
  163. info.reward.manaPercentage = loadValue(reward["manaPercentage"], rng, -1);
  164. info.reward.movePoints = loadValue(reward["movePoints"], rng);
  165. info.reward.movePercentage = loadValue(reward["movePercentage"], rng, -1);
  166. info.reward.bonuses = loadBonuses(reward["bonuses"]);
  167. info.reward.primary = loadPrimary(reward["primary"], rng);
  168. info.reward.secondary = loadSecondary(reward["secondary"], rng);
  169. info.reward.artifacts = loadArtifacts(reward["artifacts"], rng);
  170. info.reward.spells = loadSpells(reward["spells"], rng);
  171. info.reward.creatures = loadCreatures(reward["creatures"], rng);
  172. info.message = loadMessage(reward["message"]);
  173. info.selectChance = loadValue(reward["selectChance"], rng);
  174. }
  175. object->onSelect = loadMessage(parameters["onSelectMessage"]);
  176. object->onVisited = loadMessage(parameters["onVisitedMessage"]);
  177. object->onEmpty = loadMessage(parameters["onEmptyMessage"]);
  178. //TODO: visitMode and selectMode
  179. object->soundID = parameters["soundID"].Float();
  180. object->resetDuration = parameters["resetDuration"].Float();
  181. object->canRefuse =parameters["canRefuse"].Bool();
  182. }
  183. bool CRandomRewardObjectInfo::givesResources() const
  184. {
  185. return testForKey(parameters, "resources");
  186. }
  187. bool CRandomRewardObjectInfo::givesExperience() const
  188. {
  189. return testForKey(parameters, "gainedExp") || testForKey(parameters, "gainedLevels");
  190. }
  191. bool CRandomRewardObjectInfo::givesMana() const
  192. {
  193. return testForKey(parameters, "manaPoints") || testForKey(parameters, "manaPercentage");
  194. }
  195. bool CRandomRewardObjectInfo::givesMovement() const
  196. {
  197. return testForKey(parameters, "movePoints") || testForKey(parameters, "movePercentage");
  198. }
  199. bool CRandomRewardObjectInfo::givesPrimarySkills() const
  200. {
  201. return testForKey(parameters, "primary");
  202. }
  203. bool CRandomRewardObjectInfo::givesSecondarySkills() const
  204. {
  205. return testForKey(parameters, "secondary");
  206. }
  207. bool CRandomRewardObjectInfo::givesArtifacts() const
  208. {
  209. return testForKey(parameters, "artifacts");
  210. }
  211. bool CRandomRewardObjectInfo::givesCreatures() const
  212. {
  213. return testForKey(parameters, "spells");
  214. }
  215. bool CRandomRewardObjectInfo::givesSpells() const
  216. {
  217. return testForKey(parameters, "creatures");
  218. }
  219. bool CRandomRewardObjectInfo::givesBonuses() const
  220. {
  221. return testForKey(parameters, "bonuses");
  222. }
  223. CObjectWithRewardConstructor::CObjectWithRewardConstructor()
  224. {
  225. }
  226. void CObjectWithRewardConstructor::init(const JsonNode & config)
  227. {
  228. AObjectTypeHandler::init(config);
  229. objectInfo.init(config);
  230. }
  231. CGObjectInstance * CObjectWithRewardConstructor::create(ObjectTemplate tmpl) const
  232. {
  233. auto ret = new CObjectWithReward();
  234. ret->appearance = tmpl;
  235. return ret;
  236. }
  237. void CObjectWithRewardConstructor::configureObject(CGObjectInstance * object, CRandomGenerator & rng) const
  238. {
  239. objectInfo.configureObject(dynamic_cast<CObjectWithReward*>(object), rng);
  240. }
  241. const IObjectInfo * CObjectWithRewardConstructor::getObjectInfo(ObjectTemplate tmpl) const
  242. {
  243. return &objectInfo;
  244. }