mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
Implemented persistent random seed for hero pool
This commit is contained in:
parent
a2d2ecc96f
commit
539c508870
@ -20,6 +20,11 @@ CRandomGenerator::CRandomGenerator()
|
||||
resetSeed();
|
||||
}
|
||||
|
||||
CRandomGenerator::CRandomGenerator(int seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
void CRandomGenerator::setSeed(int seed)
|
||||
{
|
||||
rand.seed(seed);
|
||||
|
@ -30,6 +30,9 @@ public:
|
||||
/// current thread ID.
|
||||
CRandomGenerator();
|
||||
|
||||
/// Seeds the generator with provided initial seed
|
||||
explicit CRandomGenerator(int seed);
|
||||
|
||||
void setSeed(int seed);
|
||||
|
||||
/// Resets the seed to the product of the current time in milliseconds and the
|
||||
|
@ -68,7 +68,7 @@ void HeroPoolProcessor::selectNewHeroForSlot(const PlayerColor & color, TavernHe
|
||||
sah.slotID = static_cast<int>(slot);
|
||||
|
||||
//first hero - native if possible, second hero -> any other class
|
||||
CGHeroInstance *h = pickHeroFor(needNativeHero, color, gameHandler->getPlayerSettings(color)->castle, gameHandler->getRandomGenerator(), nullptr);
|
||||
CGHeroInstance *h = pickHeroFor(needNativeHero, color);
|
||||
|
||||
if (h)
|
||||
{
|
||||
@ -76,7 +76,7 @@ void HeroPoolProcessor::selectNewHeroForSlot(const PlayerColor & color, TavernHe
|
||||
|
||||
if (giveArmy)
|
||||
{
|
||||
h->initArmy(gameHandler->getRandomGenerator(), &sah.army);
|
||||
h->initArmy(getRandomGenerator(color), &sah.army);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -212,7 +212,7 @@ std::set<CGHeroInstance *> HeroPoolProcessor::findAvailableHeroesFor(const Playe
|
||||
return result;
|
||||
}
|
||||
|
||||
const CHeroClass * HeroPoolProcessor::pickClassFor(bool isNative, const PlayerColor & player, const FactionID & factionID, CRandomGenerator & rand) const
|
||||
const CHeroClass * HeroPoolProcessor::pickClassFor(bool isNative, const PlayerColor & player)
|
||||
{
|
||||
if(player >= PlayerColor::PLAYER_LIMIT)
|
||||
{
|
||||
@ -220,6 +220,7 @@ const CHeroClass * HeroPoolProcessor::pickClassFor(bool isNative, const PlayerCo
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FactionID factionID = gameHandler->getPlayerSettings(player)->castle;
|
||||
const auto & hpool = gameHandler->gameState()->hpool;
|
||||
const auto & currentTavern = hpool->getHeroesFor(player);
|
||||
|
||||
@ -257,7 +258,7 @@ const CHeroClass * HeroPoolProcessor::pickClassFor(bool isNative, const PlayerCo
|
||||
for(const auto & heroClass : possibleClasses)
|
||||
totalWeight += heroClass->selectionProbability.at(factionID);
|
||||
|
||||
int roll = rand.nextInt(totalWeight - 1);
|
||||
int roll = getRandomGenerator(player).nextInt(totalWeight - 1);
|
||||
for(const auto & heroClass : possibleClasses)
|
||||
{
|
||||
roll -= heroClass->selectionProbability.at(factionID);
|
||||
@ -268,13 +269,9 @@ const CHeroClass * HeroPoolProcessor::pickClassFor(bool isNative, const PlayerCo
|
||||
return *possibleClasses.rbegin();
|
||||
}
|
||||
|
||||
CGHeroInstance * HeroPoolProcessor::pickHeroFor(bool isNative,
|
||||
const PlayerColor & player,
|
||||
const FactionID & factionID,
|
||||
CRandomGenerator & rand,
|
||||
const CHeroClass * bannedClass) const
|
||||
CGHeroInstance * HeroPoolProcessor::pickHeroFor(bool isNative, const PlayerColor & player)
|
||||
{
|
||||
const CHeroClass * heroClass = pickClassFor(isNative, player, factionID, rand);
|
||||
const CHeroClass * heroClass = pickClassFor(isNative, player);
|
||||
|
||||
if(!heroClass)
|
||||
return nullptr;
|
||||
@ -285,5 +282,13 @@ CGHeroInstance * HeroPoolProcessor::pickHeroFor(bool isNative,
|
||||
if(possibleHeroes.empty())
|
||||
return nullptr;
|
||||
|
||||
return *RandomGeneratorUtil::nextItem(possibleHeroes, rand);
|
||||
return *RandomGeneratorUtil::nextItem(possibleHeroes, getRandomGenerator(player));
|
||||
}
|
||||
|
||||
CRandomGenerator & HeroPoolProcessor::getRandomGenerator(const PlayerColor & player)
|
||||
{
|
||||
if (playerSeed.count(player) == 0)
|
||||
playerSeed.emplace(player, CRandomGenerator(gameHandler->getRandomGenerator().nextInt()));
|
||||
|
||||
return playerSeed.at(player);
|
||||
}
|
||||
|
@ -28,15 +28,20 @@ class HeroPoolProcessor : boost::noncopyable
|
||||
{
|
||||
CGameHandler * gameHandler;
|
||||
|
||||
/// per-player random generators
|
||||
std::map<PlayerColor, CRandomGenerator> playerSeed;
|
||||
|
||||
void clearHeroFromSlot(const PlayerColor & color, TavernHeroSlot slot);
|
||||
void selectNewHeroForSlot(const PlayerColor & color, TavernHeroSlot slot, bool needNativeHero, bool giveStartingArmy);
|
||||
|
||||
std::set<const CHeroClass *> findAvailableClassesFor(const PlayerColor & player) const;
|
||||
std::set<CGHeroInstance *> findAvailableHeroesFor(const PlayerColor & player, const CHeroClass * heroClass) const;
|
||||
|
||||
const CHeroClass * pickClassFor(bool isNative, const PlayerColor & player, const FactionID & faction, CRandomGenerator & rand) const;
|
||||
const CHeroClass * pickClassFor(bool isNative, const PlayerColor & player);
|
||||
|
||||
CGHeroInstance * pickHeroFor(bool isNative, const PlayerColor & player, const FactionID & faction, CRandomGenerator & rand, const CHeroClass * bannedClass) const;
|
||||
CGHeroInstance * pickHeroFor(bool isNative, const PlayerColor & player);
|
||||
|
||||
CRandomGenerator & getRandomGenerator(const PlayerColor & player);
|
||||
public:
|
||||
HeroPoolProcessor();
|
||||
HeroPoolProcessor(CGameHandler * gameHandler);
|
||||
@ -51,5 +56,6 @@ public:
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & gameHandler;
|
||||
h & playerSeed;
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user