فهرست منبع

Banned skills known by hero now have non-zero selection chance

Ivan Savenko 11 ماه پیش
والد
کامیت
51c5536b50
1فایلهای تغییر یافته به همراه8 افزوده شده و 17 حذف شده
  1. 8 17
      lib/entities/hero/CHeroClass.cpp

+ 8 - 17
lib/entities/hero/CHeroClass.cpp

@@ -23,29 +23,20 @@ SecondarySkill CHeroClass::chooseSecSkill(const std::set<SecondarySkill> & possi
 {
 	assert(!possibles.empty());
 
-	if (possibles.size() == 1)
-		return *possibles.begin();
+	std::vector<int> weights;
+	std::vector<SecondarySkill> skills;
 
-	int totalProb = 0;
-	for(const auto & possible : possibles)
-		if (secSkillProbability.count(possible) != 0)
-			totalProb += secSkillProbability.at(possible);
-
-	if (totalProb == 0) // may trigger if set contains only banned skills (0 probability)
-		return *RandomGeneratorUtil::nextItem(possibles, rand);
-
-	auto ran = rand.nextInt(totalProb - 1);
 	for(const auto & possible : possibles)
 	{
+		skills.push_back(possible);
 		if (secSkillProbability.count(possible) != 0)
-			ran -= secSkillProbability.at(possible);
-
-		if(ran < 0)
-			return possible;
+			weights.push_back(secSkillProbability.at(possible));
+		else
+			weights.push_back(1); // H3 behavior - banned skills have minimal (1) chance to be picked
 	}
 
-	assert(0); // should not be possible
-	return *possibles.begin();
+	int selectedIndex = RandomGeneratorUtil::nextItemWeighted(weights, rand);
+	return skills.at(selectedIndex);
 }
 
 bool CHeroClass::isMagicHero() const