Refactor and rename some things around Misc::Rng

pull/3226/head
ζeh Matt 3 years ago
parent 9396cc7592
commit d83a381f79
No known key found for this signature in database
GPG Key ID: 18CE582C71A225B0

@ -19,14 +19,14 @@ namespace MWMechanics
{
/// @return ID of resulting item, or empty if none
inline std::string getLevelledItem (const ESM::LevelledListBase* levItem, bool creature, Misc::Rng::Seed& seed = Misc::Rng::getSeed())
inline std::string getLevelledItem (const ESM::LevelledListBase* levItem, bool creature, Misc::Rng::Generator& prng = Misc::Rng::getGenerator())
{
const std::vector<ESM::LevelledListBase::LevelItem>& items = levItem->mList;
const MWWorld::Ptr& player = getPlayer();
int playerLevel = player.getClass().getCreatureStats(player).getLevel();
if (Misc::Rng::roll0to99(seed) < levItem->mChanceNone)
if (Misc::Rng::roll0to99(prng) < levItem->mChanceNone)
return std::string();
std::vector<std::string> candidates;
@ -55,7 +55,7 @@ namespace MWMechanics
}
if (candidates.empty())
return std::string();
std::string item = candidates[Misc::Rng::rollDice(candidates.size(), seed)];
std::string item = candidates[Misc::Rng::rollDice(candidates.size(), prng)];
// Vanilla doesn't fail on nonexistent items in levelled lists
if (!MWBase::Environment::get().getWorld()->getStore().find(Misc::StringUtils::lowerCase(item)))
@ -74,9 +74,9 @@ namespace MWMechanics
else
{
if (ref.getPtr().getType() == ESM::ItemLevList::sRecordId)
return getLevelledItem(ref.getPtr().get<ESM::ItemLevList>()->mBase, false, seed);
return getLevelledItem(ref.getPtr().get<ESM::ItemLevList>()->mBase, false, prng);
else
return getLevelledItem(ref.getPtr().get<ESM::CreatureLevList>()->mBase, true, seed);
return getLevelledItem(ref.getPtr().get<ESM::CreatureLevList>()->mBase, true, prng);
}
}

@ -514,12 +514,12 @@ int MWWorld::ContainerStore::remove(const Ptr& item, int count, const Ptr& actor
return count - toRemove;
}
void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const std::string& owner, Misc::Rng::Seed& seed)
void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const std::string& owner, Misc::Rng::Generator& prng)
{
for (const ESM::ContItem& iter : items.mList)
{
std::string id = Misc::StringUtils::lowerCase(iter.mItem);
addInitialItem(id, owner, iter.mCount, &seed);
addInitialItem(id, owner, iter.mCount, &prng);
}
flagAsModified();
@ -540,7 +540,7 @@ void MWWorld::ContainerStore::fillNonRandom (const ESM::InventoryList& items, co
}
void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::string& owner, int count,
Misc::Rng::Seed* seed, bool topLevel)
Misc::Rng::Generator* prng, bool topLevel)
{
if (count == 0) return; //Don't restock with nothing.
try
@ -548,13 +548,13 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::
ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), id, count);
if (ref.getPtr().getClass().getScript(ref.getPtr()).empty())
{
addInitialItemImp(ref.getPtr(), owner, count, seed, topLevel);
addInitialItemImp(ref.getPtr(), owner, count, prng, topLevel);
}
else
{
// Adding just one item per time to make sure there isn't a stack of scripted items
for (int i = 0; i < std::abs(count); i++)
addInitialItemImp(ref.getPtr(), owner, count < 0 ? -1 : 1, seed, topLevel);
addInitialItemImp(ref.getPtr(), owner, count < 0 ? -1 : 1, prng, topLevel);
}
}
catch (const std::exception& e)
@ -564,26 +564,26 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::
}
void MWWorld::ContainerStore::addInitialItemImp(const MWWorld::Ptr& ptr, const std::string& owner, int count,
Misc::Rng::Seed* seed, bool topLevel)
Misc::Rng::Generator* prng, bool topLevel)
{
if (ptr.getType()==ESM::ItemLevList::sRecordId)
{
if(!seed)
if(!prng)
return;
const ESM::ItemLevList* levItemList = ptr.get<ESM::ItemLevList>()->mBase;
if (topLevel && std::abs(count) > 1 && levItemList->mFlags & ESM::ItemLevList::Each)
{
for (int i=0; i<std::abs(count); ++i)
addInitialItem(ptr.getCellRef().getRefId(), owner, count > 0 ? 1 : -1, seed, true);
addInitialItem(ptr.getCellRef().getRefId(), owner, count > 0 ? 1 : -1, prng, true);
return;
}
else
{
std::string itemId = MWMechanics::getLevelledItem(ptr.get<ESM::ItemLevList>()->mBase, false, *seed);
std::string itemId = MWMechanics::getLevelledItem(ptr.get<ESM::ItemLevList>()->mBase, false, *prng);
if (itemId.empty())
return;
addInitialItem(itemId, owner, count, seed, false);
addInitialItem(itemId, owner, count, prng, false);
}
}
else
@ -619,8 +619,8 @@ void MWWorld::ContainerStore::resolve()
{
for(const auto&& ptr : *this)
ptr.getRefData().setCount(0);
Misc::Rng::Seed seed{mSeed};
fill(mPtr.get<ESM::Container>()->mBase->mInventory, "", seed);
Misc::Rng::Generator prng{mSeed};
fill(mPtr.get<ESM::Container>()->mBase->mInventory, "", prng);
addScripts(*this, mPtr.mCell);
}
mModified = true;
@ -640,8 +640,8 @@ MWWorld::ResolutionHandle MWWorld::ContainerStore::resolveTemporarily()
{
for(const auto&& ptr : *this)
ptr.getRefData().setCount(0);
Misc::Rng::Seed seed{mSeed};
fill(mPtr.get<ESM::Container>()->mBase->mInventory, "", seed);
Misc::Rng::Generator prng{mSeed};
fill(mPtr.get<ESM::Container>()->mBase->mInventory, "", prng);
addScripts(*this, mPtr.mCell);
}
return {listener};

@ -126,8 +126,8 @@ namespace MWWorld
std::weak_ptr<ResolutionListener> mResolutionListener;
ContainerStoreIterator addImp (const Ptr& ptr, int count, bool markModified = true);
void addInitialItem (const std::string& id, const std::string& owner, int count, Misc::Rng::Seed* seed, bool topLevel=true);
void addInitialItemImp (const MWWorld::Ptr& ptr, const std::string& owner, int count, Misc::Rng::Seed* seed, bool topLevel=true);
void addInitialItem (const std::string& id, const std::string& owner, int count, Misc::Rng::Generator* prng, bool topLevel=true);
void addInitialItemImp (const MWWorld::Ptr& ptr, const std::string& owner, int count, Misc::Rng::Generator* prng, bool topLevel=true);
template<typename T>
ContainerStoreIterator getState (CellRefList<T>& collection,
@ -221,7 +221,7 @@ namespace MWWorld
virtual bool stacks (const ConstPtr& ptr1, const ConstPtr& ptr2) const;
///< @return true if the two specified objects can stack with each other
void fill (const ESM::InventoryList& items, const std::string& owner, Misc::Rng::Seed& seed = Misc::Rng::getSeed());
void fill (const ESM::InventoryList& items, const std::string& owner, Misc::Rng::Generator& seed = Misc::Rng::getGenerator());
///< Insert items into *this.
void fillNonRandom (const ESM::InventoryList& items, const std::string& owner, unsigned int seed);

@ -3,50 +3,42 @@
#include <chrono>
#include <random>
namespace
namespace Misc::Rng
{
Misc::Rng::Seed sSeed;
}
namespace Misc
{
Rng::Seed::Seed(unsigned int seed)
{
mGenerator.seed(seed);
}
static Generator sGenerator;
Rng::Seed& Rng::getSeed()
Generator& getGenerator()
{
return sSeed;
return sGenerator;
}
void Rng::init(unsigned int seed)
void init(unsigned int seed)
{
sSeed.mGenerator.seed(seed);
sGenerator.seed(seed);
}
float Rng::rollProbability(Seed& seed)
float rollProbability(Generator& prng)
{
return std::uniform_real_distribution<float>(0, 1 - std::numeric_limits<float>::epsilon())(seed.mGenerator);
return std::uniform_real_distribution<float>(0, 1 - std::numeric_limits<float>::epsilon())(prng);
}
float Rng::rollClosedProbability(Seed& seed)
float rollClosedProbability(Generator& prng)
{
return std::uniform_real_distribution<float>(0, 1)(seed.mGenerator);
return std::uniform_real_distribution<float>(0, 1)(prng);
}
int Rng::rollDice(int max, Seed& seed)
int rollDice(int max, Generator& prng)
{
return max > 0 ? std::uniform_int_distribution<int>(0, max - 1)(seed.mGenerator) : 0;
return max > 0 ? std::uniform_int_distribution<int>(0, max - 1)(prng) : 0;
}
unsigned int Rng::generateDefaultSeed()
unsigned int generateDefaultSeed()
{
return static_cast<unsigned int>(std::chrono::high_resolution_clock::now().time_since_epoch().count());
}
float Rng::deviate(float mean, float deviation, Seed& seed)
float deviate(float mean, float deviation, Generator& prng)
{
return std::uniform_real_distribution<float>(mean - deviation, mean + deviation)(seed.mGenerator);
return std::uniform_real_distribution<float>(mean - deviation, mean + deviation)(prng);
}
}

@ -4,47 +4,35 @@
#include <cassert>
#include <random>
namespace Misc
{
/*
Provides central implementation of the RNG logic
*/
class Rng
namespace Misc::Rng
{
public:
class Seed
{
std::mt19937 mGenerator;
public:
Seed() = default;
Seed(const Seed&) = delete;
Seed(unsigned int seed);
friend class Rng;
};
static Seed& getSeed();
using Generator = std::mt19937;
Generator& getGenerator();
/// returns default seed for RNG
unsigned int generateDefaultSeed();
/// seed the RNG
static void init(unsigned int seed = generateDefaultSeed());
void init(unsigned int seed = generateDefaultSeed());
/// return value in range [0.0f, 1.0f) <- note open upper range.
static float rollProbability(Seed& seed = getSeed());
float rollProbability(Generator& prng = getGenerator());
/// return value in range [0.0f, 1.0f] <- note closed upper range.
static float rollClosedProbability(Seed& seed = getSeed());
float rollClosedProbability(Generator& prng = getGenerator());
/// return value in range [0, max) <- note open upper range.
static int rollDice(int max, Seed& seed = getSeed());
int rollDice(int max, Generator& prng = getGenerator());
/// return value in range [0, 99]
static int roll0to99(Seed& seed = getSeed()) { return rollDice(100, seed); }
/// returns default seed for RNG
static unsigned int generateDefaultSeed();
inline int roll0to99(Generator& prng = getGenerator()) { return rollDice(100, prng); }
static float deviate(float mean, float deviation, Seed& seed = getSeed());
};
float deviate(float mean, float deviation, Generator& prng = getGenerator());
}

Loading…
Cancel
Save