CBonusTypeHandler.cpp 6.3 KB

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