diff --git a/lib/CHeroHandler.cpp b/lib/CHeroHandler.cpp index 14c6a2cb6..268929ea3 100644 --- a/lib/CHeroHandler.cpp +++ b/lib/CHeroHandler.cpp @@ -230,6 +230,14 @@ CHeroClass * CHeroClassHandler::loadFromJson(const std::string & scope, const Js fillPrimarySkillData(node, heroClass, PrimarySkill::SPELL_POWER); fillPrimarySkillData(node, heroClass, PrimarySkill::KNOWLEDGE); + auto percentSumm = std::accumulate(heroClass->primarySkillLowLevel.begin(), heroClass->primarySkillLowLevel.end(), 0); + if(percentSumm != 100) + logMod->error("Hero class %s has wrong lowLevelChance values: summ should be 100, but %d instead", heroClass->identifier, percentSumm); + + percentSumm = std::accumulate(heroClass->primarySkillHighLevel.begin(), heroClass->primarySkillHighLevel.end(), 0); + if(percentSumm != 100) + logMod->error("Hero class %s has wrong highLevelChance values: summ should be 100, but %d instead", heroClass->identifier, percentSumm); + for(auto skillPair : node["secondarySkills"].Struct()) { int probability = static_cast(skillPair.second.Integer()); diff --git a/lib/GameConstants.h b/lib/GameConstants.h index a15c9e04b..ce0236bea 100644 --- a/lib/GameConstants.h +++ b/lib/GameConstants.h @@ -56,7 +56,8 @@ namespace GameConstants const int SKILL_GOLD_COST = 2000; const int BATTLE_PENALTY_DISTANCE = 10; //if the distance is > than this, then shooting stack has distance penalty const int ARMY_SIZE = 7; - const int SKILL_PER_HERO=8; + const int SKILL_PER_HERO = 8; + const ui32 HERO_HIGH_LEVEL = 10; // affects primary skill upgrade order const int SKILL_QUANTITY=28; const int PRIMARY_SKILLS=4; diff --git a/lib/mapObjects/CGHeroInstance.cpp b/lib/mapObjects/CGHeroInstance.cpp index b6641b9eb..c5ce1bbb8 100644 --- a/lib/mapObjects/CGHeroInstance.cpp +++ b/lib/mapObjects/CGHeroInstance.cpp @@ -1213,7 +1213,8 @@ PrimarySkill::PrimarySkill CGHeroInstance::nextPrimarySkill(CRandomGenerator & r { assert(gainsLevel()); int randomValue = rand.nextInt(99), pom = 0, primarySkill = 0; - const auto & skillChances = (level > 9) ? type->heroClass->primarySkillLowLevel : type->heroClass->primarySkillHighLevel; + const auto isLowLevelHero = level < GameConstants::HERO_HIGH_LEVEL; + const auto & skillChances = isLowLevelHero ? type->heroClass->primarySkillLowLevel : type->heroClass->primarySkillHighLevel; for(; primarySkill < GameConstants::PRIMARY_SKILLS; ++primarySkill) { @@ -1223,7 +1224,12 @@ PrimarySkill::PrimarySkill CGHeroInstance::nextPrimarySkill(CRandomGenerator & r break; } } - + if(primarySkill >= GameConstants::PRIMARY_SKILLS) + { + primarySkill = rand.nextInt(GameConstants::PRIMARY_SKILLS - 1); + logGlobal->error("Wrong values in primarySkill%sLevel for hero class %s", isLowLevelHero ? "Low" : "High", type->heroClass->identifier); + randomValue = 100 / GameConstants::PRIMARY_SKILLS; + } logGlobal->trace("The hero gets the primary skill %d with a probability of %d %%.", primarySkill, randomValue); return static_cast(primarySkill); }