CSkillHandler.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * CSkillHandler.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 <cctype>
  12. #include "CSkillHandler.h"
  13. #include "CGeneralTextHandler.h"
  14. #include "filesystem/Filesystem.h"
  15. #include "JsonNode.h"
  16. #include "CModHandler.h"
  17. #include "StringConstants.h"
  18. #include "CStack.h"
  19. #include "battle/BattleInfo.h"
  20. #include "battle/CBattleInfoCallback.h"
  21. ///CSkill
  22. CSkill::CSkill(SecondarySkill id) : id(id)
  23. {
  24. if(id == SecondarySkill::DEFAULT)
  25. identifier = "default";
  26. else
  27. identifier = NSecondarySkill::names[id];
  28. // init bonus levels
  29. BonusList emptyList;
  30. for(auto level : NSecondarySkill::levels)
  31. bonusByLevel.push_back(emptyList);
  32. }
  33. CSkill::~CSkill()
  34. {
  35. }
  36. void CSkill::addNewBonus(const std::shared_ptr<Bonus>& b, int level)
  37. {
  38. b->source = Bonus::SECONDARY_SKILL;
  39. b->duration = Bonus::PERMANENT;
  40. b->description = identifier;
  41. bonusByLevel[level].push_back(b);
  42. }
  43. BonusList CSkill::getBonus(int level)
  44. {
  45. return bonusByLevel[level];
  46. }
  47. ///CSkillHandler
  48. CSkillHandler::CSkillHandler()
  49. {
  50. for(int id = 0; id < GameConstants::SKILL_QUANTITY; id++)
  51. {
  52. CSkill * skill = new CSkill(SecondarySkill(id));
  53. for(int level = 1; level < NSecondarySkill::levels.size(); level++)
  54. skill->addNewBonus(defaultBonus(SecondarySkill(id), level), level);
  55. objects.push_back(skill);
  56. }
  57. }
  58. std::vector<JsonNode> CSkillHandler::loadLegacyData(size_t dataSize)
  59. {
  60. // not supported - no legacy data to load
  61. std::vector<JsonNode> legacyData;
  62. return legacyData;
  63. }
  64. const std::string CSkillHandler::getTypeName() const
  65. {
  66. return "secondarySkill";
  67. }
  68. CSkill * CSkillHandler::loadFromJson(const JsonNode & json, const std::string & identifier)
  69. {
  70. CSkill * skill = NULL;
  71. for(int id = 0; id < GameConstants::SKILL_QUANTITY; id++)
  72. {
  73. if(NSecondarySkill::names[id].compare(identifier) == 0)
  74. {
  75. skill = new CSkill(SecondarySkill(id));
  76. break;
  77. }
  78. }
  79. if(!skill)
  80. {
  81. logGlobal->errorStream() << "unknown secondary skill " << identifier;
  82. throw std::runtime_error("invalid skill");
  83. }
  84. for(int level = 1; level < NSecondarySkill::levels.size(); level++)
  85. {
  86. const std::string & levelName = NSecondarySkill::levels[level]; // basic, advanced, expert
  87. for(auto b : json[levelName].Vector())
  88. {
  89. auto bonus = JsonUtils::parseBonus(b);
  90. bonus->sid = skill->id;
  91. skill->addNewBonus(bonus, level);
  92. }
  93. }
  94. return skill;
  95. }
  96. void CSkillHandler::afterLoadFinalization()
  97. {
  98. }
  99. void CSkillHandler::beforeValidate(JsonNode & object)
  100. {
  101. }
  102. CSkillHandler::~CSkillHandler()
  103. {
  104. }
  105. std::vector<bool> CSkillHandler::getDefaultAllowed() const
  106. {
  107. std::vector<bool> allowedSkills(objects.size(), true);
  108. return allowedSkills;
  109. }
  110. // HMM3 default bonus provided by secondary skill
  111. const std::shared_ptr<Bonus> CSkillHandler::defaultBonus(SecondarySkill skill, int level) const
  112. {
  113. Bonus::BonusType bonusType = Bonus::SECONDARY_SKILL_PREMY;
  114. Bonus::ValueType valueType = Bonus::BASE_NUMBER;
  115. int bonusVal = level;
  116. static const int archery_bonus[] = { 10, 25, 50 };
  117. switch (skill)
  118. {
  119. case SecondarySkill::LEADERSHIP:
  120. bonusType = Bonus::MORALE; break;
  121. case SecondarySkill::LUCK:
  122. bonusType = Bonus::LUCK; break;
  123. case SecondarySkill::DIPLOMACY:
  124. bonusType = Bonus::SURRENDER_DISCOUNT;
  125. bonusVal = 20 * level; break;
  126. case SecondarySkill::ARCHERY:
  127. bonusVal = archery_bonus[level-1]; break;
  128. case SecondarySkill::LOGISTICS:
  129. bonusVal = 10 * level; break;
  130. case SecondarySkill::NAVIGATION:
  131. bonusVal = 50 * level; break;
  132. case SecondarySkill::MYSTICISM:
  133. bonusVal = level; break;
  134. case SecondarySkill::EAGLE_EYE:
  135. bonusVal = 30 + 10 * level; break;
  136. case SecondarySkill::NECROMANCY:
  137. bonusVal = 10 * level; break;
  138. case SecondarySkill::LEARNING:
  139. bonusVal = 5 * level; break;
  140. case SecondarySkill::OFFENCE:
  141. bonusVal = 10 * level; break;
  142. case SecondarySkill::ARMORER:
  143. bonusVal = 5 * level; break;
  144. case SecondarySkill::INTELLIGENCE:
  145. bonusVal = 25 << (level-1); break;
  146. case SecondarySkill::SORCERY:
  147. bonusVal = 5 * level; break;
  148. case SecondarySkill::RESISTANCE:
  149. bonusVal = 5 << (level-1); break;
  150. case SecondarySkill::FIRST_AID:
  151. bonusVal = 25 + 25 * level; break;
  152. case SecondarySkill::ESTATES:
  153. bonusVal = 125 << (level-1); break;
  154. default:
  155. valueType = Bonus::INDEPENDENT_MIN; break;
  156. }
  157. return std::make_shared<Bonus>(Bonus::PERMANENT, bonusType, Bonus::SECONDARY_SKILL, bonusVal, skill, skill, valueType);
  158. }