1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-06-20 12:11:32 +00:00

Use std::minstd_rand and split serialization from save/load

This commit is contained in:
ζeh Matt 2022-03-17 17:35:34 +02:00
parent 0611a8c3a7
commit f8f3bb2421
No known key found for this signature in database
GPG key ID: 18CE582C71A225B0
3 changed files with 27 additions and 41 deletions

View file

@ -342,7 +342,7 @@ namespace MWWorld
void World::write (ESM::ESMWriter& writer, Loading::Listener& progress) const void World::write (ESM::ESMWriter& writer, Loading::Listener& progress) const
{ {
writer.startRecord(ESM::REC_RAND); writer.startRecord(ESM::REC_RAND);
writer.writeHNT("RAND", mPrng.getSeed()); writer.writeHNOString("RAND", Misc::Rng::serialize(mPrng));
writer.endRecord(ESM::REC_RAND); writer.endRecord(ESM::REC_RAND);
// Active cells could have a dirty fog of war, sync it to the CellStore first // Active cells could have a dirty fog of war, sync it to the CellStore first
@ -385,11 +385,8 @@ namespace MWWorld
return; return;
case ESM::REC_RAND: case ESM::REC_RAND:
{ {
Misc::Rng::Generator::result_type seed{}; auto data = reader.getHNOString("RAND");
reader.getHNT(seed, "RAND"); Misc::Rng::deserialize(data, mPrng);
Log(Debug::Info) << "---- World random state: " << seed << " ----";
mPrng.seed(seed);
Misc::Rng::getGenerator().seed(seed);
} }
break; break;
case ESM::REC_PLAY: case ESM::REC_PLAY:

View file

@ -2,6 +2,7 @@
#include <chrono> #include <chrono>
#include <random> #include <random>
#include <sstream>
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
@ -14,6 +15,23 @@ namespace Misc::Rng
return sGenerator; return sGenerator;
} }
std::string serialize(const Generator& prng)
{
std::stringstream ss;
ss << prng;
return ss.str();
}
void deserialize(std::string_view data, Generator& prng)
{
std::stringstream ss;
ss << data;
ss.seekg(0);
ss >> prng;
}
unsigned int generateDefaultSeed() unsigned int generateDefaultSeed()
{ {
auto res = static_cast<unsigned int>(std::chrono::high_resolution_clock::now().time_since_epoch().count()); auto res = static_cast<unsigned int>(std::chrono::high_resolution_clock::now().time_since_epoch().count());
@ -65,4 +83,5 @@ namespace Misc::Rng
{ {
return std::uniform_real_distribution<float>(mean - deviation, mean + deviation)(prng); return std::uniform_real_distribution<float>(mean - deviation, mean + deviation)(prng);
} }
} }

View file

@ -3,50 +3,20 @@
#include <cassert> #include <cassert>
#include <random> #include <random>
#include <string_view>
/* /*
Provides central implementation of the RNG logic Provides central implementation of the RNG logic
*/ */
namespace Misc::Rng namespace Misc::Rng
{ {
class Generator using Generator = std::minstd_rand;
{
uint32_t mState{};
public:
using result_type = uint32_t;
constexpr Generator() = default;
constexpr Generator(result_type seed) : mState{ seed } {}
constexpr result_type operator()() noexcept
{
mState = (214013 * mState + 2531011);
return (mState >> 16) & max();
}
static constexpr result_type min() noexcept
{
return 0u;
}
static constexpr result_type max() noexcept
{
return 0x7FFFu;
}
void seed(result_type val) noexcept
{
mState = val;
}
uint32_t getSeed() const noexcept
{
return mState;
}
};
Generator& getGenerator(); Generator& getGenerator();
std::string serialize(const Generator& prng);
void deserialize(std::string_view data, Generator& prng);
/// returns default seed for RNG /// returns default seed for RNG
unsigned int generateDefaultSeed(); unsigned int generateDefaultSeed();