I took another look at the code. If it is intentional, then it could be misleading:
/**
* Generates a random integer number, inclusive.
*/
int RandomState::generate(int min, int max)
{
return (int)(next() % (max - min + 1) + min);
}
Within WeightOptions, the selection code is:
size_t var = RNG::generate(0, _totalWeight);
auto ii = _choices.begin();
for (; ii != _choices.end(); ++ii)
{
if (var <= ii->second)
break;
var -= ii->second;
}
If we take a super simple example, with exactly 3 options each with weight 1, then _totalWeight is 3, but var can be any one of 4 values:
0, 1, 2, 3
Both 0 and 1 would return the 0th option, then 2 returns the next option, and 3 returns the final option.
It's a slight bias toward the 0th option and probably would go unnoticed in most X-Com games, since the mission weights tend to total to 100. I can see mods that use small sets of options with small weights being noticeably biased, however.
It might be worthwhile to do a bigger refactor and change generate() to return a non-inclusive end (by removing the +1 in generate()). Most random number generators behave in that manner because it eliminates a lot of +1s and -1s scattered through the code to make things work. For example, percent() would call generate(0, 100), and end - start always gives you the number of distinct possible values for generate.