1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-25 21:38:59 +02:00

CGameState: don't use RNG directly for easier desync debugging

Only access random generator via CGameState::getRandomGenerator
This commit is contained in:
Arseniy Shestakov 2016-08-22 01:58:52 +03:00
parent 6747555339
commit 960d93ff5f

View File

@ -476,13 +476,13 @@ int CGameState::pickUnusedHeroTypeRandomly(PlayerColor owner)
// select random hero native to "our" faction
if(!factionHeroes.empty())
{
return RandomGeneratorUtil::nextItem(factionHeroes, rand)->getNum();
return RandomGeneratorUtil::nextItem(factionHeroes, getRandomGenerator())->getNum();
}
logGlobal->warnStream() << "Cannot find free hero of appropriate faction for player " << owner << " - trying to get first available...";
if(!otherHeroes.empty())
{
return RandomGeneratorUtil::nextItem(otherHeroes, rand)->getNum();
return RandomGeneratorUtil::nextItem(otherHeroes, getRandomGenerator())->getNum();
}
logGlobal->error("No free allowed heroes!");
@ -500,29 +500,29 @@ std::pair<Obj,int> CGameState::pickObject (CGObjectInstance *obj)
switch(obj->ID)
{
case Obj::RANDOM_ART:
return std::make_pair(Obj::ARTIFACT, VLC->arth->pickRandomArtifact(rand, CArtifact::ART_TREASURE | CArtifact::ART_MINOR | CArtifact::ART_MAJOR | CArtifact::ART_RELIC));
return std::make_pair(Obj::ARTIFACT, VLC->arth->pickRandomArtifact(getRandomGenerator(), CArtifact::ART_TREASURE | CArtifact::ART_MINOR | CArtifact::ART_MAJOR | CArtifact::ART_RELIC));
case Obj::RANDOM_TREASURE_ART:
return std::make_pair(Obj::ARTIFACT, VLC->arth->pickRandomArtifact(rand, CArtifact::ART_TREASURE));
return std::make_pair(Obj::ARTIFACT, VLC->arth->pickRandomArtifact(getRandomGenerator(), CArtifact::ART_TREASURE));
case Obj::RANDOM_MINOR_ART:
return std::make_pair(Obj::ARTIFACT, VLC->arth->pickRandomArtifact(rand, CArtifact::ART_MINOR));
return std::make_pair(Obj::ARTIFACT, VLC->arth->pickRandomArtifact(getRandomGenerator(), CArtifact::ART_MINOR));
case Obj::RANDOM_MAJOR_ART:
return std::make_pair(Obj::ARTIFACT, VLC->arth->pickRandomArtifact(rand, CArtifact::ART_MAJOR));
return std::make_pair(Obj::ARTIFACT, VLC->arth->pickRandomArtifact(getRandomGenerator(), CArtifact::ART_MAJOR));
case Obj::RANDOM_RELIC_ART:
return std::make_pair(Obj::ARTIFACT, VLC->arth->pickRandomArtifact(rand, CArtifact::ART_RELIC));
return std::make_pair(Obj::ARTIFACT, VLC->arth->pickRandomArtifact(getRandomGenerator(), CArtifact::ART_RELIC));
case Obj::RANDOM_HERO:
return std::make_pair(Obj::HERO, pickNextHeroType(obj->tempOwner));
case Obj::RANDOM_MONSTER:
return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(rand));
return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(getRandomGenerator()));
case Obj::RANDOM_MONSTER_L1:
return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(rand, 1));
return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(getRandomGenerator(), 1));
case Obj::RANDOM_MONSTER_L2:
return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(rand, 2));
return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(getRandomGenerator(), 2));
case Obj::RANDOM_MONSTER_L3:
return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(rand, 3));
return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(getRandomGenerator(), 3));
case Obj::RANDOM_MONSTER_L4:
return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(rand, 4));
return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(getRandomGenerator(), 4));
case Obj::RANDOM_RESOURCE:
return std::make_pair(Obj::RESOURCE,rand.nextInt(6)); //now it's OH3 style, use %8 for mithril
return std::make_pair(Obj::RESOURCE,getRandomGenerator().nextInt(6)); //now it's OH3 style, use %8 for mithril
case Obj::RANDOM_TOWN:
{
PlayerColor align = PlayerColor((static_cast<CGTownInstance*>(obj))->alignment);
@ -542,18 +542,18 @@ std::pair<Obj,int> CGameState::pickObject (CGObjectInstance *obj)
{
do
{
f = rand.nextInt(VLC->townh->factions.size() - 1);
f = getRandomGenerator().nextInt(VLC->townh->factions.size() - 1);
}
while (VLC->townh->factions[f]->town == nullptr); // find playable faction
}
return std::make_pair(Obj::TOWN,f);
}
case Obj::RANDOM_MONSTER_L5:
return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(rand, 5));
return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(getRandomGenerator(), 5));
case Obj::RANDOM_MONSTER_L6:
return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(rand, 6));
return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(getRandomGenerator(), 6));
case Obj::RANDOM_MONSTER_L7:
return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(rand, 7));
return std::make_pair(Obj::MONSTER, VLC->creh->pickRandomMonster(getRandomGenerator(), 7));
case Obj::RANDOM_DWELLING:
case Obj::RANDOM_DWELLING_LVL:
case Obj::RANDOM_DWELLING_FACTION:
@ -564,7 +564,7 @@ std::pair<Obj,int> CGameState::pickObject (CGObjectInstance *obj)
//if castle alignment available
if (auto info = dynamic_cast<CCreGenAsCastleInfo*>(dwl->info))
{
faction = rand.nextInt(VLC->townh->factions.size() - 1);
faction = getRandomGenerator().nextInt(VLC->townh->factions.size() - 1);
if (info->asCastle)
{
for(auto & elem : map->objects)
@ -593,7 +593,7 @@ std::pair<Obj,int> CGameState::pickObject (CGObjectInstance *obj)
{
if((faction>7) && (info->castles[1]&(1<<(faction-8))))
break;
faction = rand.nextInt(GameConstants::F_NUMBER - 1);
faction = getRandomGenerator().nextInt(GameConstants::F_NUMBER - 1);
}
}
}
@ -605,7 +605,7 @@ std::pair<Obj,int> CGameState::pickObject (CGObjectInstance *obj)
//if level set to range
if (auto info = dynamic_cast<CCreGenLeveledInfo*>(dwl->info))
{
level = rand.nextInt(info->minLevel, info->maxLevel);
level = getRandomGenerator().nextInt(info->minLevel, info->maxLevel);
}
else // fixed level
{
@ -639,7 +639,7 @@ std::pair<Obj,int> CGameState::pickObject (CGObjectInstance *obj)
if (result.first == Obj::NO_OBJ)
{
logGlobal->errorStream() << "Error: failed to find dwelling for "<< VLC->townh->factions[faction]->name << " of level " << int(level);
result = std::make_pair(Obj::CREATURE_GENERATOR1, *RandomGeneratorUtil::nextItem(VLC->objtypeh->knownSubObjects(Obj::CREATURE_GENERATOR1), rand));
result = std::make_pair(Obj::CREATURE_GENERATOR1, *RandomGeneratorUtil::nextItem(VLC->objtypeh->knownSubObjects(Obj::CREATURE_GENERATOR1), getRandomGenerator()));
}
return result;
@ -743,7 +743,7 @@ BattleInfo * CGameState::setupBattle(int3 tile, const CArmedInstance *armies[2],
void CGameState::init(StartInfo * si)
{
logGlobal->infoStream() << "\tUsing random seed: "<< si->seedToBeUsed;
rand.setSeed(si->seedToBeUsed);
getRandomGenerator().setSeed(si->seedToBeUsed);
scenarioOps = CMemorySerializer::deepCopy(*si).release();
initialOpts = CMemorySerializer::deepCopy(*si).release();
si = nullptr;
@ -800,7 +800,7 @@ void CGameState::init(StartInfo * si)
logGlobal->debug("\tChecking objectives");
map->checkForObjectives(); //needs to be run when all objects are properly placed
auto seedAfterInit = rand.nextInt();
auto seedAfterInit = getRandomGenerator().nextInt();
logGlobal->infoStream() << "Seed after init is " << seedAfterInit << " (before was " << scenarioOps->seedToBeUsed << ")";
if(scenarioOps->seedPostInit > 0)
{
@ -1026,7 +1026,7 @@ void CGameState::initGrailPosition()
if(!allowedPos.empty())
{
map->grailPos = *RandomGeneratorUtil::nextItem(allowedPos, rand);
map->grailPos = *RandomGeneratorUtil::nextItem(allowedPos, getRandomGenerator());
}
else
{
@ -1042,7 +1042,7 @@ void CGameState::initRandomFactionsForPlayers()
{
if(elem.second.castle==-1)
{
auto randomID = rand.nextInt(map->players[elem.first.getNum()].allowedFactions.size() - 1);
auto randomID = getRandomGenerator().nextInt(map->players[elem.first.getNum()].allowedFactions.size() - 1);
auto iter = map->players[elem.first.getNum()].allowedFactions.begin();
std::advance(iter, randomID);
@ -1171,7 +1171,7 @@ void CGameState::placeCampaignHeroes()
auto unusedHeroTypeIds = getUnusedAllowedHeroes();
if(!unusedHeroTypeIds.empty())
{
heroTypeId = (*RandomGeneratorUtil::nextItem(unusedHeroTypeIds, rand)).getNum();
heroTypeId = (*RandomGeneratorUtil::nextItem(unusedHeroTypeIds, getRandomGenerator())).getNum();
}
else
{
@ -1660,24 +1660,24 @@ void CGameState::initStartingBonus()
{
//starting bonus
if(scenarioOps->playerInfos[elem.first].bonus==PlayerSettings::RANDOM)
scenarioOps->playerInfos[elem.first].bonus = static_cast<PlayerSettings::Ebonus>(rand.nextInt(2));
scenarioOps->playerInfos[elem.first].bonus = static_cast<PlayerSettings::Ebonus>(getRandomGenerator().nextInt(2));
switch(scenarioOps->playerInfos[elem.first].bonus)
{
case PlayerSettings::GOLD:
elem.second.resources[Res::GOLD] += rand.nextInt(5, 10) * 100;
elem.second.resources[Res::GOLD] += getRandomGenerator().nextInt(5, 10) * 100;
break;
case PlayerSettings::RESOURCE:
{
int res = VLC->townh->factions[scenarioOps->playerInfos[elem.first].castle]->town->primaryRes;
if(res == Res::WOOD_AND_ORE)
{
int amount = rand.nextInt(5, 10);
int amount = getRandomGenerator().nextInt(5, 10);
elem.second.resources[Res::WOOD] += amount;
elem.second.resources[Res::ORE] += amount;
}
else
{
elem.second.resources[res] += rand.nextInt(3, 6);
elem.second.resources[res] += getRandomGenerator().nextInt(3, 6);
}
break;
}
@ -1689,7 +1689,7 @@ void CGameState::initStartingBonus()
break;
}
CArtifact *toGive;
toGive = VLC->arth->artifacts[VLC->arth->pickRandomArtifact(rand, CArtifact::ART_TREASURE)];
toGive = VLC->arth->artifacts[VLC->arth->pickRandomArtifact(getRandomGenerator(), CArtifact::ART_TREASURE)];
CGHeroInstance *hero = elem.second.heroes[0];
giveHeroArtifact(hero, toGive->id);
@ -1742,7 +1742,7 @@ void CGameState::initTowns()
}
if(vti->name.empty())
{
vti->name = *RandomGeneratorUtil::nextItem(vti->town->names, rand);
vti->name = *RandomGeneratorUtil::nextItem(vti->town->names, getRandomGenerator());
}
//init buildings
@ -1754,7 +1754,7 @@ void CGameState::initTowns()
vti->builtBuildings.insert(BuildingID::TAVERN);
vti->builtBuildings.insert(BuildingID::DWELL_FIRST);
if(rand.nextInt(1) == 1)
if(getRandomGenerator().nextInt(1) == 1)
{
vti->builtBuildings.insert(BuildingID::DWELL_LVL_2);
}
@ -1826,7 +1826,7 @@ void CGameState::initTowns()
if (total == 0) // remaining spells have 0 probability
break;
auto r = rand.nextInt(total - 1);
auto r = getRandomGenerator().nextInt(total - 1);
for(ui32 ps=0; ps<vti->possibleSpells.size();ps++)
{
r -= vti->possibleSpells[ps].toSpell()->getProbability(vti->subID);
@ -3266,6 +3266,10 @@ TeamState::TeamState(TeamState && other):
CRandomGenerator & CGameState::getRandomGenerator()
{
//if(scenarioOps && scenarioOps->seedPostInit)
//{
// logGlobal->trace("CGameState::getRandomGenerator used after initialization!");
//}
//logGlobal->traceStream() << "Fetching CGameState::rand with seed " << rand.nextInt();
return rand;
}