CBonusTypeHandler.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * CBonusTypeHandler.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. #define INSTANTIATE_CBonusTypeHandler_HERE
  12. #include "CBonusTypeHandler.h"
  13. #include "filesystem/Filesystem.h"
  14. #include "CCreatureHandler.h"
  15. #include "GameConstants.h"
  16. #include "GameLibrary.h"
  17. #include "modding/ModScope.h"
  18. #include "modding/IdentifierStorage.h"
  19. #include "spells/CSpellHandler.h"
  20. #include "texts/CGeneralTextHandler.h"
  21. #include "json/JsonUtils.h"
  22. template class std::vector<VCMI_LIB_WRAP_NAMESPACE(CBonusType)>;
  23. VCMI_LIB_NAMESPACE_BEGIN
  24. ///CBonusType
  25. CBonusType::CBonusType():
  26. hidden(true)
  27. {}
  28. std::string CBonusType::getDescriptionTextID() const
  29. {
  30. return TextIdentifier( "core", "bonus", identifier, "description").get();
  31. }
  32. ///CBonusTypeHandler
  33. CBonusTypeHandler::CBonusTypeHandler()
  34. {
  35. //register predefined bonus types
  36. #define BONUS_NAME(x) { #x },
  37. bonusNames = {
  38. BONUS_LIST
  39. };
  40. #undef BONUS_NAME
  41. #define BONUS_NAME(x) \
  42. do { \
  43. bonusTypes.push_back(CBonusType()); \
  44. } while(0);
  45. BONUS_LIST;
  46. #undef BONUS_NAME
  47. }
  48. CBonusTypeHandler::~CBonusTypeHandler() = default;
  49. std::string CBonusTypeHandler::bonusToString(const std::shared_ptr<Bonus> & bonus, const IBonusBearer * bearer) const
  50. {
  51. const CBonusType & bt = bonusTypes[vstd::to_underlying(bonus->type)];
  52. int bonusValue = bearer->valOfBonuses(bonus->type, bonus->subtype);
  53. if(bt.hidden)
  54. return "";
  55. std::string textID = bt.getDescriptionTextID();
  56. std::string text = LIBRARY->generaltexth->translate(textID);
  57. auto subtype = bonus->subtype.getNum();
  58. if (bt.subtypeDescriptions.count(subtype))
  59. {
  60. std::string fullTextID = textID + '.' + bt.subtypeDescriptions.at(subtype);
  61. text = LIBRARY->generaltexth->translate(fullTextID);
  62. }
  63. else if (bt.valueDescriptions.count(bonusValue))
  64. {
  65. std::string fullTextID = textID + '.' + bt.valueDescriptions.at(bonusValue);
  66. text = LIBRARY->generaltexth->translate(fullTextID);
  67. }
  68. if (text.find("${val}") != std::string::npos)
  69. boost::algorithm::replace_all(text, "${val}", std::to_string(bonusValue));
  70. if (text.find("${subtype.creature}") != std::string::npos && bonus->subtype.as<CreatureID>().hasValue())
  71. boost::algorithm::replace_all(text, "${subtype.creature}", bonus->subtype.as<CreatureID>().toCreature()->getNamePluralTranslated());
  72. if (text.find("${subtype.spell}") != std::string::npos && bonus->subtype.as<SpellID>().hasValue())
  73. boost::algorithm::replace_all(text, "${subtype.spell}", bonus->subtype.as<SpellID>().toSpell()->getNameTranslated());
  74. return text;
  75. }
  76. ImagePath CBonusTypeHandler::bonusToGraphics(const std::shared_ptr<Bonus> & bonus) const
  77. {
  78. const CBonusType & bt = bonusTypes[vstd::to_underlying(bonus->type)];
  79. if (bonus->type == BonusType::SPELL_IMMUNITY && bonus->subtype.as<SpellID>().hasValue())
  80. {
  81. const CSpell * sp = bonus->subtype.as<SpellID>().toSpell();
  82. return sp->getIconImmune();
  83. }
  84. if (bt.subtypeIcons.count(bonus->subtype.getNum()))
  85. return bt.subtypeIcons.at(bonus->subtype.getNum());
  86. if (bt.valueIcons.count(bonus->val))
  87. return bt.valueIcons.at(bonus->val);
  88. return bt.icon;
  89. }
  90. std::vector<JsonNode> CBonusTypeHandler::loadLegacyData()
  91. {
  92. return {};
  93. }
  94. void CBonusTypeHandler::loadObject(std::string scope, std::string name, const JsonNode & data)
  95. {
  96. BonusType bonus = stringToBonus(name);
  97. CBonusType & bt = bonusTypes[vstd::to_underlying(bonus)];
  98. loadItem(data, bt, name);
  99. logBonus->trace("Loaded bonus type %s", name);
  100. }
  101. void CBonusTypeHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index)
  102. {
  103. assert(0);
  104. }
  105. void CBonusTypeHandler::loadItem(const JsonNode & source, CBonusType & dest, const std::string & name) const
  106. {
  107. dest.identifier = name;
  108. dest.hidden = source["hidden"].Bool(); //Null -> false
  109. if (!dest.hidden)
  110. LIBRARY->generaltexth->registerString( "vcmi", dest.getDescriptionTextID(), source["description"]);
  111. const JsonNode & graphics = source["graphics"];
  112. if(!graphics.isNull())
  113. dest.icon = ImagePath::fromJson(graphics["icon"]);
  114. for (const auto & additionalIcon : graphics["subtypeIcons"].Struct())
  115. {
  116. auto path = ImagePath::fromJson(additionalIcon.second);
  117. LIBRARY->identifiers()->requestIdentifier(additionalIcon.second.getModScope(), additionalIcon.first, [&dest, path](int32_t index)
  118. {
  119. dest.subtypeIcons[index] = path;
  120. });
  121. }
  122. for (const auto & additionalIcon : graphics["valueIcons"].Struct())
  123. {
  124. auto path = ImagePath::fromJson(additionalIcon.second);
  125. int value = std::stoi(additionalIcon.first);
  126. dest.valueIcons[value] = path;
  127. }
  128. for (const auto & additionalDescription : source["subtypeDescriptions"].Struct())
  129. {
  130. LIBRARY->generaltexth->registerString( "vcmi", dest.getDescriptionTextID() + "." + additionalDescription.first, additionalDescription.second);
  131. auto stringID = additionalDescription.first;
  132. LIBRARY->identifiers()->requestIdentifier(additionalDescription.second.getModScope(), additionalDescription.first, [&dest, stringID](int32_t index)
  133. {
  134. dest.subtypeDescriptions[index] = stringID;
  135. });
  136. }
  137. for (const auto & additionalDescription : source["valueDescriptions"].Struct())
  138. {
  139. LIBRARY->generaltexth->registerString( "vcmi", dest.getDescriptionTextID() + "." + additionalDescription.first, additionalDescription.second);
  140. auto stringID = additionalDescription.first;
  141. int value = std::stoi(additionalDescription.first);
  142. dest.valueDescriptions[value] = stringID;
  143. }
  144. }
  145. BonusType CBonusTypeHandler::stringToBonus(const std::string & name) const
  146. {
  147. auto it = boost::range::find(bonusNames, name);
  148. if (it != bonusNames.end())
  149. return static_cast<BonusType>(it - bonusNames.begin());
  150. return BonusType::NONE;
  151. }
  152. const std::string CBonusTypeHandler::bonusToString(BonusType bonus) const
  153. {
  154. return bonusNames.at(static_cast<int>(bonus));
  155. }
  156. std::vector<BonusType> CBonusTypeHandler::getAllObjets() const
  157. {
  158. std::vector<BonusType> ret;
  159. for (int i = 0; i < bonusNames.size(); ++i)
  160. ret.push_back(static_cast<BonusType>(i));
  161. return ret;
  162. }
  163. VCMI_LIB_NAMESPACE_END