CSkillHandler.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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. DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const CSkill &skill)
  48. {
  49. out << "Skill(" << (int)skill.id << "," << skill.identifier << "): " << skill.bonusByLevel;
  50. return out;
  51. }
  52. ///CSkillHandler
  53. CSkillHandler::CSkillHandler()
  54. {
  55. for(int id = 0; id < GameConstants::SKILL_QUANTITY; id++)
  56. {
  57. CSkill * skill = new CSkill(SecondarySkill(id));
  58. for(int level = 1; level < NSecondarySkill::levels.size(); level++)
  59. skill->addNewBonus(defaultBonus(SecondarySkill(id), level), level);
  60. objects.push_back(skill);
  61. }
  62. }
  63. std::vector<JsonNode> CSkillHandler::loadLegacyData(size_t dataSize)
  64. {
  65. // not supported - no legacy data to load
  66. std::vector<JsonNode> legacyData;
  67. return legacyData;
  68. }
  69. const std::string CSkillHandler::getTypeName() const
  70. {
  71. return "secondarySkill";
  72. }
  73. CSkill * CSkillHandler::loadFromJson(const JsonNode & json, const std::string & identifier)
  74. {
  75. CSkill * skill = NULL;
  76. for(int id = 0; id < GameConstants::SKILL_QUANTITY; id++)
  77. {
  78. if(NSecondarySkill::names[id].compare(identifier) == 0)
  79. {
  80. skill = new CSkill(SecondarySkill(id));
  81. break;
  82. }
  83. }
  84. if(!skill)
  85. {
  86. logGlobal->errorStream() << "unknown secondary skill " << identifier;
  87. throw std::runtime_error("invalid skill");
  88. }
  89. for(int level = 1; level < NSecondarySkill::levels.size(); level++)
  90. {
  91. const std::string & levelName = NSecondarySkill::levels[level]; // basic, advanced, expert
  92. for(auto b : json[levelName].Vector())
  93. {
  94. auto bonus = JsonUtils::parseBonus(b);
  95. bonus->sid = skill->id;
  96. skill->addNewBonus(bonus, level);
  97. }
  98. }
  99. CLogger * logger = CLogger::getLogger(CLoggerDomain("skills"));
  100. logger->debugStream() << "loaded secondary skill " << identifier << "(" << (int)skill->id << ")";
  101. logger->traceStream() << *skill;
  102. return skill;
  103. }
  104. void CSkillHandler::afterLoadFinalization()
  105. {
  106. }
  107. void CSkillHandler::beforeValidate(JsonNode & object)
  108. {
  109. }
  110. CSkillHandler::~CSkillHandler()
  111. {
  112. }
  113. std::vector<bool> CSkillHandler::getDefaultAllowed() const
  114. {
  115. std::vector<bool> allowedSkills(objects.size(), true);
  116. return allowedSkills;
  117. }
  118. // HMM3 default bonus provided by secondary skill
  119. const std::shared_ptr<Bonus> CSkillHandler::defaultBonus(SecondarySkill skill, int level) const
  120. {
  121. Bonus::BonusType bonusType = Bonus::SECONDARY_SKILL_PREMY;
  122. Bonus::ValueType valueType = Bonus::BASE_NUMBER;
  123. int bonusVal = level;
  124. static const int archery_bonus[] = { 10, 25, 50 };
  125. switch (skill)
  126. {
  127. case SecondarySkill::LEADERSHIP:
  128. bonusType = Bonus::MORALE; break;
  129. case SecondarySkill::LUCK:
  130. bonusType = Bonus::LUCK; break;
  131. case SecondarySkill::DIPLOMACY:
  132. bonusType = Bonus::SURRENDER_DISCOUNT;
  133. bonusVal = 20 * level; break;
  134. case SecondarySkill::ARCHERY:
  135. bonusVal = archery_bonus[level-1]; break;
  136. case SecondarySkill::LOGISTICS:
  137. bonusVal = 10 * level; break;
  138. case SecondarySkill::NAVIGATION:
  139. bonusVal = 50 * level; break;
  140. case SecondarySkill::MYSTICISM:
  141. bonusVal = level; break;
  142. case SecondarySkill::EAGLE_EYE:
  143. bonusVal = 30 + 10 * level; break;
  144. case SecondarySkill::NECROMANCY:
  145. bonusVal = 10 * level; break;
  146. case SecondarySkill::LEARNING:
  147. bonusVal = 5 * level; break;
  148. case SecondarySkill::OFFENCE:
  149. bonusVal = 10 * level; break;
  150. case SecondarySkill::ARMORER:
  151. bonusVal = 5 * level; break;
  152. case SecondarySkill::INTELLIGENCE:
  153. bonusVal = 25 << (level-1); break;
  154. case SecondarySkill::SORCERY:
  155. bonusVal = 5 * level; break;
  156. case SecondarySkill::RESISTANCE:
  157. bonusVal = 5 << (level-1); break;
  158. case SecondarySkill::FIRST_AID:
  159. bonusVal = 25 + 25 * level; break;
  160. case SecondarySkill::ESTATES:
  161. bonusVal = 125 << (level-1); break;
  162. default:
  163. valueType = Bonus::INDEPENDENT_MIN; break;
  164. }
  165. return std::make_shared<Bonus>(Bonus::PERMANENT, bonusType, Bonus::SECONDARY_SKILL, bonusVal, skill, skill, valueType);
  166. }