From b502dc12f0883cf21a698bdfc0234359e1fd8ac4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com>
Date: Sun, 6 Mar 2022 20:02:03 +0200
Subject: [PATCH] Add prng to World instance and serialize state in Save

---
 apps/openmw/mwbase/world.hpp     |  3 +++
 apps/openmw/mwworld/worldimp.cpp | 20 ++++++++++++++++++++
 apps/openmw/mwworld/worldimp.hpp |  5 ++++-
 components/esm/defs.hpp          |  3 +++
 components/esm3/savedgame.cpp    |  2 +-
 5 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp
index 0b55484278..23e687be5a 100644
--- a/apps/openmw/mwbase/world.hpp
+++ b/apps/openmw/mwbase/world.hpp
@@ -9,6 +9,7 @@
 #include <deque>
 
 #include <components/esm3/cellid.hpp>
+#include <components/misc/rng.hpp>
 
 #include <osg/Timer>
 
@@ -658,6 +659,8 @@ namespace MWBase
             virtual void reportStats(unsigned int frameNumber, osg::Stats& stats) const = 0;
 
             virtual std::vector<MWWorld::Ptr> getAll(const std::string& id) = 0;
+
+            virtual Misc::Rng::Generator& getPrng() = 0;
     };
 }
 
diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp
index a5ab0968ee..afb248bf08 100644
--- a/apps/openmw/mwworld/worldimp.cpp
+++ b/apps/openmw/mwworld/worldimp.cpp
@@ -359,6 +359,12 @@ namespace MWWorld
         writer.writeHNT("LEVT", mLevitationEnabled);
         writer.endRecord(ESM::REC_ENAB);
 
+        std::stringstream ssPrng;
+        ssPrng << mPrng;
+        writer.startRecord(ESM::REC_RAND);
+        writer.writeHString(ssPrng.str());
+        writer.endRecord(ESM::REC_RAND);
+
         writer.startRecord(ESM::REC_CAM_);
         writer.writeHNT("FIRS", isFirstPerson());
         writer.endRecord(ESM::REC_CAM_);
@@ -376,6 +382,14 @@ namespace MWWorld
                 reader.getHNT(mTeleportEnabled, "TELE");
                 reader.getHNT(mLevitationEnabled, "LEVT");
                 return;
+            case ESM::REC_RAND:
+                {
+                    std::stringstream ssPrng;
+                    ssPrng << reader.getHString();
+                    ssPrng.seekg(0);
+                    ssPrng >> mPrng;
+                }
+                break;
             case ESM::REC_PLAY:
                 mStore.checkPlayer();
                 mPlayer->readRecord(reader, type);
@@ -3999,4 +4013,10 @@ namespace MWWorld
     {
         return mCells.getAll(id);
     }
+
+    Misc::Rng::Generator& World::getPrng()
+    {
+        return mPrng;
+    }
+
 }
diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp
index 61154afb59..eb089f04d7 100644
--- a/apps/openmw/mwworld/worldimp.hpp
+++ b/apps/openmw/mwworld/worldimp.hpp
@@ -4,6 +4,7 @@
 #include <osg/ref_ptr>
 
 #include <components/settings/settings.hpp>
+#include <components/misc/rng.hpp>
 
 #include "../mwbase/world.hpp"
 
@@ -84,7 +85,7 @@ namespace MWWorld
             GroundcoverStore mGroundcoverStore;
             LocalScripts mLocalScripts;
             MWWorld::Globals mGlobalVariables;
-
+            Misc::Rng::Generator mPrng;
             Cells mCells;
 
             std::string mCurrentWorldSpace;
@@ -736,6 +737,8 @@ namespace MWWorld
             void reportStats(unsigned int frameNumber, osg::Stats& stats) const override;
 
             std::vector<MWWorld::Ptr> getAll(const std::string& id) override;
+
+            Misc::Rng::Generator& getPrng() override;
     };
 }
 
diff --git a/components/esm/defs.hpp b/components/esm/defs.hpp
index f587fc6690..60d34a9355 100644
--- a/components/esm/defs.hpp
+++ b/components/esm/defs.hpp
@@ -173,6 +173,9 @@ enum RecNameInts : unsigned int
 
     // format 16 - Lua scripts in saved games
     REC_LUAM = fourCC("LUAM"),  // LuaManager data
+
+    // format 21 - Random state in saved games.
+    REC_RAND = fourCC("RAND"),  // Random state.
 };
 
 /// Common subrecords
diff --git a/components/esm3/savedgame.cpp b/components/esm3/savedgame.cpp
index 18498abe2c..667dbdfbce 100644
--- a/components/esm3/savedgame.cpp
+++ b/components/esm3/savedgame.cpp
@@ -4,7 +4,7 @@
 #include "esmwriter.hpp"
 
 unsigned int ESM::SavedGame::sRecordId = ESM::REC_SAVE;
-int ESM::SavedGame::sCurrentFormat = 20;
+int ESM::SavedGame::sCurrentFormat = 21;
 
 void ESM::SavedGame::load (ESMReader &esm)
 {