Reward.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. * Reward.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 "Reward.h"
  12. #include "../mapObjects/CGHeroInstance.h"
  13. #include "../serializer/JsonSerializeFormat.h"
  14. #include "../constants/StringConstants.h"
  15. #include "../CSkillHandler.h"
  16. VCMI_LIB_NAMESPACE_BEGIN
  17. void Rewardable::RewardRevealTiles::serializeJson(JsonSerializeFormat & handler)
  18. {
  19. // TODO
  20. }
  21. Rewardable::Reward::Reward()
  22. : heroExperience(0)
  23. , heroLevel(0)
  24. , manaDiff(0)
  25. , manaPercentage(-1)
  26. , movePoints(0)
  27. , movePercentage(-1)
  28. , primary(4, 0)
  29. , removeObject(false)
  30. , spellCast(SpellID::NONE, SecSkillLevel::NONE)
  31. {
  32. }
  33. Rewardable::Reward::~Reward() = default;
  34. si32 Rewardable::Reward::calculateManaPoints(const CGHeroInstance * hero) const
  35. {
  36. si32 manaScaled = hero->mana;
  37. if (manaPercentage >= 0)
  38. manaScaled = hero->manaLimit() * manaPercentage / 100;
  39. si32 manaMissing = std::max(0, hero->manaLimit() - manaScaled);
  40. si32 manaGranted = std::min(manaMissing, manaDiff);
  41. si32 manaOverflow = manaDiff - manaGranted;
  42. si32 manaOverLimit = manaOverflow * manaOverflowFactor / 100;
  43. si32 manaOutput = manaScaled + manaGranted + manaOverLimit;
  44. return manaOutput;
  45. }
  46. Component Rewardable::Reward::getDisplayedComponent(const CGHeroInstance * h) const
  47. {
  48. std::vector<Component> comps;
  49. loadComponents(comps, h);
  50. assert(!comps.empty());
  51. return comps.front();
  52. }
  53. void Rewardable::Reward::loadComponents(std::vector<Component> & comps,
  54. const CGHeroInstance * h) const
  55. {
  56. for (auto comp : extraComponents)
  57. comps.push_back(comp);
  58. for (auto & bonus : bonuses)
  59. {
  60. if (bonus.type == BonusType::MORALE)
  61. comps.emplace_back(Component::EComponentType::MORALE, 0, bonus.val, 0);
  62. if (bonus.type == BonusType::LUCK)
  63. comps.emplace_back(Component::EComponentType::LUCK, 0, bonus.val, 0);
  64. }
  65. if (heroExperience)
  66. {
  67. comps.emplace_back(Component::EComponentType::EXPERIENCE, 0, static_cast<si32>(h->calculateXp(heroExperience)), 0);
  68. }
  69. if (heroLevel)
  70. comps.emplace_back(Component::EComponentType::EXPERIENCE, 1, heroLevel, 0);
  71. if (manaDiff || manaPercentage >= 0)
  72. comps.emplace_back(Component::EComponentType::PRIM_SKILL, 5, calculateManaPoints(h) - h->mana, 0);
  73. for (size_t i=0; i<primary.size(); i++)
  74. {
  75. if (primary[i] != 0)
  76. comps.emplace_back(Component::EComponentType::PRIM_SKILL, static_cast<ui16>(i), primary[i], 0);
  77. }
  78. for(const auto & entry : secondary)
  79. comps.emplace_back(Component::EComponentType::SEC_SKILL, entry.first, entry.second, 0);
  80. for(const auto & entry : artifacts)
  81. comps.emplace_back(Component::EComponentType::ARTIFACT, entry, 1, 0);
  82. for(const auto & entry : spells)
  83. comps.emplace_back(Component::EComponentType::SPELL, entry, 1, 0);
  84. for(const auto & entry : creatures)
  85. comps.emplace_back(Component::EComponentType::CREATURE, entry.type->getId(), entry.count, 0);
  86. for (size_t i=0; i<resources.size(); i++)
  87. {
  88. if (resources[i] !=0)
  89. comps.emplace_back(Component::EComponentType::RESOURCE, static_cast<ui16>(i), resources[i], 0);
  90. }
  91. }
  92. void Rewardable::Reward::serializeJson(JsonSerializeFormat & handler)
  93. {
  94. resources.serializeJson(handler, "resources");
  95. handler.serializeBool("removeObject", removeObject);
  96. handler.serializeInt("manaPercentage", manaPercentage);
  97. handler.serializeInt("movePercentage", movePercentage);
  98. handler.serializeInt("heroExperience", heroExperience);
  99. handler.serializeInt("heroLevel", heroLevel);
  100. handler.serializeInt("manaDiff", manaDiff);
  101. handler.serializeInt("manaOverflowFactor", manaOverflowFactor);
  102. handler.serializeInt("movePoints", movePoints);
  103. handler.serializeIdArray("artifacts", artifacts);
  104. handler.serializeIdArray("spells", spells);
  105. handler.enterArray("creatures").serializeStruct(creatures);
  106. handler.enterArray("primary").serializeArray(primary);
  107. {
  108. auto a = handler.enterArray("secondary");
  109. std::vector<std::pair<SecondarySkill, si32>> fieldValue(secondary.begin(), secondary.end());
  110. a.serializeStruct<std::pair<SecondarySkill, si32>>(fieldValue, [](JsonSerializeFormat & h, std::pair<SecondarySkill, si32> & e)
  111. {
  112. h.serializeId("skill", e.first, SecondarySkill{}, VLC->skillh->decodeSkill, VLC->skillh->encodeSkill);
  113. h.serializeId("level", e.second, 0, [](const std::string & i){return vstd::find_pos(NSecondarySkill::levels, i);}, [](si32 i){return NSecondarySkill::levels.at(i);});
  114. });
  115. a.syncSize(fieldValue);
  116. secondary = std::map<SecondarySkill, si32>(fieldValue.begin(), fieldValue.end());
  117. }
  118. {
  119. auto a = handler.enterArray("creaturesChange");
  120. std::vector<std::pair<CreatureID, CreatureID>> fieldValue(creaturesChange.begin(), creaturesChange.end());
  121. a.serializeStruct<std::pair<CreatureID, CreatureID>>(fieldValue, [](JsonSerializeFormat & h, std::pair<CreatureID, CreatureID> & e)
  122. {
  123. h.serializeId("creature", e.first, CreatureID{});
  124. h.serializeId("amount", e.second, CreatureID{});
  125. });
  126. creaturesChange = std::map<CreatureID, CreatureID>(fieldValue.begin(), fieldValue.end());
  127. }
  128. {
  129. auto a = handler.enterStruct("spellCast");
  130. a->serializeId("spell", spellCast.first, SpellID{});
  131. a->serializeInt("level", spellCast.second);
  132. }
  133. }
  134. VCMI_LIB_NAMESPACE_END