فهرست منبع

Replaced most of usages of CRandomGenerator with vstd::RNG in library

Ivan Savenko 1 سال پیش
والد
کامیت
63bcf7d83c
100فایلهای تغییر یافته به همراه556 افزوده شده و 381 حذف شده
  1. 24 1
      AI/BattleAI/StackWithBonuses.h
  2. 11 5
      client/CPlayerInterface.cpp
  3. 7 2
      client/HeroMovementController.cpp
  4. 7 2
      client/adventureMap/MapAudioPlayer.cpp
  5. 1 0
      client/windows/GUIClasses.cpp
  6. 22 0
      include/vstd/RNG.h
  7. 0 1
      lib/CArtHandler.h
  8. 3 2
      lib/CCreatureHandler.cpp
  9. 6 2
      lib/CCreatureHandler.h
  10. 3 2
      lib/CHeroHandler.cpp
  11. 6 2
      lib/CHeroHandler.h
  12. 11 9
      lib/CRandomGenerator.cpp
  13. 8 6
      lib/CRandomGenerator.h
  14. 4 1
      lib/IGameCallback.cpp
  15. 6 2
      lib/IGameCallback.h
  16. 1 1
      lib/battle/BattleInfo.cpp
  17. 3 3
      lib/battle/CBattleInfoCallback.cpp
  18. 7 3
      lib/battle/CBattleInfoCallback.h
  19. 11 8
      lib/gameState/CGameState.cpp
  20. 11 11
      lib/gameState/CGameState.h
  21. 2 0
      lib/gameState/CGameStateCampaign.cpp
  22. 0 1
      lib/gameState/TavernHeroesPool.h
  23. 17 17
      lib/json/JsonRandom.cpp
  24. 21 17
      lib/json/JsonRandom.h
  25. 6 2
      lib/mapObjectConstructors/AObjectTypeHandler.h
  26. 4 3
      lib/mapObjectConstructors/CBankInstanceConstructor.cpp
  27. 2 2
      lib/mapObjectConstructors/CBankInstanceConstructor.h
  28. 2 2
      lib/mapObjectConstructors/CDefaultObjectTypeHandler.h
  29. 0 1
      lib/mapObjectConstructors/CObjectClassesHandler.h
  30. 1 1
      lib/mapObjectConstructors/CRewardableConstructor.cpp
  31. 1 1
      lib/mapObjectConstructors/CRewardableConstructor.h
  32. 3 3
      lib/mapObjectConstructors/CommonConstructors.cpp
  33. 3 3
      lib/mapObjectConstructors/CommonConstructors.h
  34. 1 1
      lib/mapObjectConstructors/DwellingInstanceConstructor.cpp
  35. 1 1
      lib/mapObjectConstructors/DwellingInstanceConstructor.h
  36. 2 2
      lib/mapObjects/CBank.cpp
  37. 2 2
      lib/mapObjects/CBank.h
  38. 7 5
      lib/mapObjects/CGCreature.cpp
  39. 3 3
      lib/mapObjects/CGCreature.h
  40. 7 5
      lib/mapObjects/CGDwelling.cpp
  41. 5 5
      lib/mapObjects/CGDwelling.h
  42. 11 11
      lib/mapObjects/CGHeroInstance.cpp
  43. 11 11
      lib/mapObjects/CGHeroInstance.h
  44. 2 2
      lib/mapObjects/CGMarket.cpp
  45. 2 2
      lib/mapObjects/CGMarket.h
  46. 9 7
      lib/mapObjects/CGObjectInstance.cpp
  47. 5 5
      lib/mapObjects/CGObjectInstance.h
  48. 1 1
      lib/mapObjects/CGPandoraBox.cpp
  49. 1 1
      lib/mapObjects/CGPandoraBox.h
  50. 5 3
      lib/mapObjects/CGTownBuilding.cpp
  51. 3 3
      lib/mapObjects/CGTownBuilding.h
  52. 7 5
      lib/mapObjects/CGTownInstance.cpp
  53. 5 5
      lib/mapObjects/CGTownInstance.h
  54. 7 6
      lib/mapObjects/CQuest.cpp
  55. 5 5
      lib/mapObjects/CQuest.h
  56. 4 2
      lib/mapObjects/CRewardableObject.cpp
  57. 2 2
      lib/mapObjects/CRewardableObject.h
  58. 3 3
      lib/mapObjects/IObjectInterface.cpp
  59. 8 4
      lib/mapObjects/IObjectInterface.h
  60. 19 17
      lib/mapObjects/MiscObjects.cpp
  61. 14 14
      lib/mapObjects/MiscObjects.h
  62. 5 4
      lib/mapping/CDrawRoadsOperation.cpp
  63. 4 4
      lib/mapping/CDrawRoadsOperation.h
  64. 2 0
      lib/mapping/CMap.cpp
  65. 10 8
      lib/mapping/CMapEditManager.cpp
  66. 10 6
      lib/mapping/CMapEditManager.h
  67. 4 3
      lib/mapping/CMapOperation.cpp
  68. 8 4
      lib/mapping/CMapOperation.h
  69. 6 4
      lib/mapping/ObstacleProxy.cpp
  70. 4 5
      lib/mapping/ObstacleProxy.h
  71. 1 0
      lib/registerTypes/RegisterTypesLobbyPacks.h
  72. 9 8
      lib/rewardable/Info.cpp
  73. 12 9
      lib/rewardable/Info.h
  74. 5 5
      lib/rmg/CMapGenOptions.cpp
  75. 6 3
      lib/rmg/CMapGenOptions.h
  76. 12 9
      lib/rmg/CMapGenerator.cpp
  77. 1 2
      lib/rmg/CMapGenerator.h
  78. 11 12
      lib/rmg/CZonePlacer.cpp
  79. 9 5
      lib/rmg/CZonePlacer.h
  80. 3 1
      lib/rmg/Functions.cpp
  81. 1 2
      lib/rmg/Functions.h
  82. 3 1
      lib/rmg/PenroseTiling.cpp
  83. 7 3
      lib/rmg/PenroseTiling.h
  84. 1 1
      lib/rmg/RmgMap.cpp
  85. 6 2
      lib/rmg/RmgMap.h
  86. 7 5
      lib/rmg/RmgObject.cpp
  87. 10 6
      lib/rmg/RmgObject.h
  88. 10 4
      lib/rmg/Zone.cpp
  89. 4 5
      lib/rmg/Zone.h
  90. 2 0
      lib/rmg/modificators/ConnectionsPlacer.cpp
  91. 2 0
      lib/rmg/modificators/MinePlacer.cpp
  92. 2 0
      lib/rmg/modificators/ObjectDistributor.cpp
  93. 2 0
      lib/rmg/modificators/ObjectManager.cpp
  94. 0 1
      lib/rmg/modificators/ObstaclePlacer.cpp
  95. 3 1
      lib/rmg/modificators/PrisonHeroPlacer.cpp
  96. 0 2
      lib/rmg/modificators/PrisonHeroPlacer.h
  97. 4 2
      lib/rmg/modificators/QuestArtifactPlacer.cpp
  98. 2 4
      lib/rmg/modificators/QuestArtifactPlacer.h
  99. 2 0
      lib/rmg/modificators/RiverPlacer.cpp
  100. 0 1
      lib/rmg/modificators/RockFiller.cpp

+ 24 - 1
AI/BattleAI/StackWithBonuses.h

@@ -21,9 +21,19 @@
 class HypotheticBattle;
 
 ///Fake random generator, used by AI to evaluate random server behavior
-class RNGStub : public vstd::RNG
+class RNGStub final : public vstd::RNG
 {
 public:
+	virtual int nextInt() override
+	{
+		return 0;
+	}
+
+	int nextBinomialInt(int coinsCount, double coinChance) override
+	{
+		return coinsCount * coinChance;
+	}
+
 	int nextInt(int lower, int upper) override
 	{
 		return (lower + upper) / 2;
@@ -36,6 +46,19 @@ public:
 	{
 		return (lower + upper) / 2;
 	}
+
+	int nextInt(int upper) override
+	{
+		return upper / 2;
+	}
+	int64_t nextInt64(int64_t upper) override
+	{
+		return upper / 2;
+	}
+	double nextDouble(double upper) override
+	{
+		return upper / 2;
+	}
 };
 
 class StackWithBonuses : public battle::CUnitState, public virtual IBonusBearer

+ 11 - 5
client/CPlayerInterface.cpp

@@ -70,6 +70,7 @@
 #include "../lib/CGeneralTextHandler.h"
 #include "../lib/CHeroHandler.h"
 #include "../lib/CPlayerState.h"
+#include "../lib/CRandomGenerator.h"
 #include "../lib/CStack.h"
 #include "../lib/CStopWatch.h"
 #include "../lib/CThreadHelper.h"
@@ -413,8 +414,9 @@ void CPlayerInterface::heroVisit(const CGHeroInstance * visitor, const CGObjectI
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	if(start && visitedObj)
 	{
-		if(visitedObj->getVisitSound())
-			CCS->soundh->playSound(visitedObj->getVisitSound().value());
+		auto visitSound = visitedObj->getVisitSound(CRandomGenerator::getDefault());
+		if (visitSound)
+			CCS->soundh->playSound(visitSound.value());
 	}
 }
 
@@ -1410,10 +1412,14 @@ void CPlayerInterface::centerView (int3 pos, int focusTime)
 void CPlayerInterface::objectRemoved(const CGObjectInstance * obj, const PlayerColor & initiator)
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
-	if(playerID == initiator && obj->getRemovalSound())
+	if(playerID == initiator)
 	{
-		waitWhileDialog();
-		CCS->soundh->playSound(obj->getRemovalSound().value());
+		auto removalSound = obj->getRemovalSound(CRandomGenerator::getDefault());
+		if (removalSound)
+		{
+			waitWhileDialog();
+			CCS->soundh->playSound(removalSound.value());
+		}
 	}
 	CGI->mh->waitForOngoingAnimations();
 

+ 7 - 2
client/HeroMovementController.cpp

@@ -24,6 +24,7 @@
 
 #include "ConditionalWait.h"
 #include "../lib/CConfigHandler.h"
+#include "../lib/CRandomGenerator.h"
 #include "../lib/pathfinder/CGPathNode.h"
 #include "../lib/mapObjects/CGHeroInstance.h"
 #include "../lib/networkPacks/PacksForClient.h"
@@ -153,8 +154,12 @@ void HeroMovementController::onTryMoveHero(const CGHeroInstance * hero, const Tr
 
 	if(details.result == TryMoveHero::EMBARK || details.result == TryMoveHero::DISEMBARK)
 	{
-		if(hero->getRemovalSound() && hero->tempOwner == LOCPLINT->playerID)
-			CCS->soundh->playSound(hero->getRemovalSound().value());
+		if (hero->tempOwner == LOCPLINT->playerID)
+		{
+			auto removalSound = hero->getRemovalSound(CRandomGenerator::getDefault());
+			if (removalSound)
+				CCS->soundh->playSound(removalSound.value());
+		}
 	}
 
 	bool directlyAttackingCreature =

+ 7 - 2
client/adventureMap/MapAudioPlayer.cpp

@@ -17,6 +17,7 @@
 #include "../media/IMusicPlayer.h"
 #include "../media/ISoundPlayer.h"
 
+#include "../../lib/CRandomGenerator.h"
 #include "../../lib/TerrainHandler.h"
 #include "../../lib/mapObjects/CArmedInstance.h"
 #include "../../lib/mapObjects/CGHeroInstance.h"
@@ -136,8 +137,12 @@ std::vector<AudioPath> MapAudioPlayer::getAmbientSounds(const int3 & tile)
 		if (!object)
 			logGlobal->warn("Already removed object %d found on tile! (%d %d %d)", objectID.getNum(), tile.x, tile.y, tile.z);
 
-		if(object && object->getAmbientSound())
-			result.push_back(object->getAmbientSound().value());
+		if(object)
+		{
+			auto ambientSound = object->getAmbientSound(CRandomGenerator::getDefault());
+			if (ambientSound)
+				result.push_back(ambientSound.value());
+		}
 	}
 
 	if(CGI->mh->getMap()->isCoastalTile(tile))

+ 1 - 0
client/windows/GUIClasses.cpp

@@ -54,6 +54,7 @@
 #include "../lib/CHeroHandler.h"
 #include "../lib/GameSettings.h"
 #include "ConditionalWait.h"
+#include "../lib/CRandomGenerator.h"
 #include "../lib/CSkillHandler.h"
 #include "../lib/CSoundBase.h"
 

+ 22 - 0
include/vstd/RNG.h

@@ -20,9 +20,31 @@ class DLL_LINKAGE RNG
 public:
 	virtual ~RNG() = default;
 
+	/// Returns random number in range [lower, upper]
 	virtual int nextInt(int lower, int upper) = 0;
+
+	/// Returns random number in range [lower, upper]
 	virtual int64_t nextInt64(int64_t lower, int64_t upper) = 0;
+
+	/// Returns random number in range [lower, upper]
 	virtual double nextDouble(double lower, double upper) = 0;
+
+	/// Returns random number in range [0, upper]
+	virtual int nextInt(int upper) = 0;
+
+	/// Returns random number in range [0, upper]
+	virtual int64_t nextInt64(int64_t upper) = 0;
+
+	/// Returns random number in range [0, upper]
+	virtual double nextDouble(double upper) = 0;
+
+	/// Generates an integer between 0 and the maximum value it can hold.
+	/// Should be only used for seeding other generators
+	virtual int nextInt() = 0;
+
+	/// Returns integer using binomial distribution
+	/// returned value is number of successfull coin flips with chance 'coinChance' out of 'coinsCount' attempts
+	virtual int nextBinomialInt(int coinsCount, double coinChance) = 0;
 };
 
 }

+ 0 - 1
lib/CArtHandler.h

@@ -25,7 +25,6 @@ class CArtHandler;
 class CGHeroInstance;
 class CArtifactSet;
 class CArtifactInstance;
-class CRandomGenerator;
 class CMap;
 class JsonSerializeFormat;
 

+ 3 - 2
lib/CCreatureHandler.cpp

@@ -14,7 +14,6 @@
 #include "ResourceSet.h"
 #include "filesystem/Filesystem.h"
 #include "VCMI_Lib.h"
-#include "CRandomGenerator.h"
 #include "CTownHandler.h"
 #include "GameSettings.h"
 #include "constants/StringConstants.h"
@@ -28,6 +27,8 @@
 #include "modding/CModHandler.h"
 #include "ExceptionsCommon.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 const std::map<CCreature::CreatureQuantityId, std::string> CCreature::creatureQuantityRanges =
@@ -1362,7 +1363,7 @@ CCreatureHandler::~CCreatureHandler()
 		p.first = nullptr;
 }
 
-CreatureID CCreatureHandler::pickRandomMonster(CRandomGenerator & rand, int tier) const
+CreatureID CCreatureHandler::pickRandomMonster(vstd::RNG & rand, int tier) const
 {
 	std::vector<CreatureID> allowed;
 	for(const auto & creature : objects)

+ 6 - 2
lib/CCreatureHandler.h

@@ -23,11 +23,15 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
+namespace vstd
+{
+class RNG;
+}
+
 class CLegacyConfigParser;
 class CCreatureHandler;
 class CCreature;
 class JsonSerializeFormat;
-class CRandomGenerator;
 
 class DLL_LINKAGE CCreature : public Creature, public CBonusSystemNode
 {
@@ -225,7 +229,7 @@ public:
 	std::vector< std::vector <ui8> > skillLevels; //how much of a bonus will be given to commander with every level. SPELL_POWER also gives CASTS and RESISTANCE
 	std::vector <std::pair <std::shared_ptr<Bonus>, std::pair <ui8, ui8> > > skillRequirements; // first - Bonus, second - which two skills are needed to use it
 
-	CreatureID pickRandomMonster(CRandomGenerator & rand, int tier = -1) const; //tier <1 - CREATURES_PER_TOWN> or -1 for any
+	CreatureID pickRandomMonster(vstd::RNG & rand, int tier = -1) const; //tier <1 - CREATURES_PER_TOWN> or -1 for any
 
 	CCreatureHandler();
 	~CCreatureHandler();

+ 3 - 2
lib/CHeroHandler.cpp

@@ -17,7 +17,6 @@
 #include "battle/BattleHex.h"
 #include "CCreatureHandler.h"
 #include "GameSettings.h"
-#include "CRandomGenerator.h"
 #include "CTownHandler.h"
 #include "CSkillHandler.h"
 #include "BattleFieldHandler.h"
@@ -29,6 +28,8 @@
 #include "mapObjectConstructors/CObjectClassesHandler.h"
 #include "modding/IdentifierStorage.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 CHero::CHero() = default;
@@ -123,7 +124,7 @@ void CHero::serializeJson(JsonSerializeFormat & handler)
 }
 
 
-SecondarySkill CHeroClass::chooseSecSkill(const std::set<SecondarySkill> & possibles, CRandomGenerator & rand) const //picks secondary skill out from given possibilities
+SecondarySkill CHeroClass::chooseSecSkill(const std::set<SecondarySkill> & possibles, vstd::RNG & rand) const //picks secondary skill out from given possibilities
 {
 	assert(!possibles.empty());
 

+ 6 - 2
lib/CHeroHandler.h

@@ -23,11 +23,15 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
+namespace vstd
+{
+class RNG;
+}
+
 class CHeroClass;
 class CGHeroInstance;
 struct BattleHex;
 class JsonNode;
-class CRandomGenerator;
 class JsonSerializeFormat;
 class BattleField;
 
@@ -148,7 +152,7 @@ public:
 	std::string getNameTextID() const override;
 
 	bool isMagicHero() const;
-	SecondarySkill chooseSecSkill(const std::set<SecondarySkill> & possibles, CRandomGenerator & rand) const; //picks secondary skill out from given possibilities
+	SecondarySkill chooseSecSkill(const std::set<SecondarySkill> & possibles, vstd::RNG & rand) const; //picks secondary skill out from given possibilities
 
 	void updateFrom(const JsonNode & data);
 	void serializeJson(JsonSerializeFormat & handler);

+ 11 - 9
lib/CRandomGenerator.cpp

@@ -40,6 +40,11 @@ int CRandomGenerator::nextInt(int upper)
 	return nextInt(0, upper);
 }
 
+int64_t CRandomGenerator::nextInt64(int64_t upper)
+{
+	return nextInt64(0, upper);
+}
+
 int CRandomGenerator::nextInt(int lower, int upper)
 {
 	if (lower > upper)
@@ -53,6 +58,12 @@ int CRandomGenerator::nextInt()
 	return TIntDist()(rand);
 }
 
+int CRandomGenerator::nextBinomialInt(int coinsCount, double coinChance)
+{
+	std::binomial_distribution<> distribution(coinsCount, coinChance);
+	return distribution(rand);
+}
+
 int64_t CRandomGenerator::nextInt64(int64_t lower, int64_t upper)
 {
 	if (lower > upper)
@@ -74,20 +85,11 @@ double CRandomGenerator::nextDouble(double lower, double upper)
 	return TRealDist(lower, upper)(rand);
 }
 
-//double CRandomGenerator::nextDouble()
-//{
-//	return TRealDist()(rand);
-//}
-
 CRandomGenerator & CRandomGenerator::getDefault()
 {
 	static thread_local CRandomGenerator defaultRand;
 	return defaultRand;
 }
 
-TGenerator & CRandomGenerator::getStdGenerator()
-{
-	return rand;
-}
 
 VCMI_LIB_NAMESPACE_END

+ 8 - 6
lib/CRandomGenerator.h

@@ -46,18 +46,23 @@ public:
 
 	/// Generates an integer between 0 and upper.
 	/// requires: 0 <= upper
-	int nextInt(int upper);
+	int nextInt(int upper) override;
+	int64_t nextInt64(int64_t upper) override;
 
 	/// requires: lower <= upper
 	int nextInt(int lower, int upper) override;
 	int64_t nextInt64(int64_t lower, int64_t upper) override;
 
 	/// Generates an integer between 0 and the maximum value it can hold.
-	int nextInt();
+	int nextInt() override;
+
+	///
+	int nextBinomialInt(int coinsCount, double coinChance) override;
+
 
 	/// Generates a double between 0 and upper.
 	/// requires: 0 <= upper
-	double nextDouble(double upper);
+	double nextDouble(double upper) override;
 
 	/// requires: lower <= upper
 	double nextDouble(double lower, double upper) override;
@@ -66,9 +71,6 @@ public:
 	/// seed a combination of the thread ID and current time in milliseconds will be used.
 	static CRandomGenerator & getDefault();
 
-	/// Provide method so that this RNG can be used with legacy std:: API
-	TGenerator & getStdGenerator();
-
 private:
 	TGenerator rand;
 

+ 4 - 1
lib/IGameCallback.cpp

@@ -14,6 +14,7 @@
 #include "spells/CSpellHandler.h"// for CSpell
 #include "CSkillHandler.h"// for CSkill
 #include "CBonusTypeHandler.h"
+#include "CRandomGenerator.h"
 #include "BattleFieldHandler.h"
 #include "ObstacleHandler.h"
 #include "bonuses/Limiters.h"
@@ -51,6 +52,8 @@
 #include "RiverHandler.h"
 #include "TerrainHandler.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 void CPrivilegedInfoCallback::getFreeTiles(std::vector<int3> & tiles) const
@@ -146,7 +149,7 @@ void CPrivilegedInfoCallback::getAllTiles(std::unordered_set<int3> & tiles, std:
 	}
 }
 
-void CPrivilegedInfoCallback::pickAllowedArtsSet(std::vector<const CArtifact *> & out, CRandomGenerator & rand)
+void CPrivilegedInfoCallback::pickAllowedArtsSet(std::vector<const CArtifact *> & out, vstd::RNG & rand)
 {
 	for (int j = 0; j < 3 ; j++)
 		out.push_back(gameState()->pickRandomArtifact(rand, CArtifact::ART_TREASURE).toArtifact());

+ 6 - 2
lib/IGameCallback.h

@@ -16,13 +16,17 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
+namespace vstd
+{
+class RNG;
+}
+
 struct SetMovePoints;
 struct GiveBonus;
 struct BlockingDialog;
 struct TeleportDialog;
 struct StackLocation;
 struct ArtifactLocation;
-class CRandomGenerator;
 class CCreatureSet;
 class CStackBasicDescriptor;
 class CGCreature;
@@ -61,7 +65,7 @@ public:
 	void getAllTiles(std::unordered_set<int3> &tiles, std::optional<PlayerColor> player, int level, std::function<bool(const TerrainTile *)> filter) const;
 
 	//gives 3 treasures, 3 minors, 1 major -> used by Black Market and Artifact Merchant
-	void pickAllowedArtsSet(std::vector<const CArtifact *> & out, CRandomGenerator & rand);
+	void pickAllowedArtsSet(std::vector<const CArtifact *> & out, vstd::RNG & rand);
 	void getAllowedSpells(std::vector<SpellID> &out, std::optional<ui16> level = std::nullopt);
 
 	template<typename Saver>

+ 1 - 1
lib/battle/BattleInfo.cpp

@@ -12,7 +12,6 @@
 #include "CObstacleInstance.h"
 #include "bonuses/Limiters.h"
 #include "bonuses/Updaters.h"
-#include "../CRandomGenerator.h"
 #include "../CStack.h"
 #include "../CHeroHandler.h"
 #include "../filesystem/Filesystem.h"
@@ -21,6 +20,7 @@
 #include "../BattleFieldHandler.h"
 #include "../ObstacleHandler.h"
 
+#include <vstd/RNG.h>
 
 //TODO: remove
 #include "../IGameCallback.h"

+ 3 - 3
lib/battle/CBattleInfoCallback.cpp

@@ -11,6 +11,7 @@
 #include "CBattleInfoCallback.h"
 
 #include <vcmi/scripting/Service.h>
+#include <vstd/RNG.h>
 
 #include "../CStack.h"
 #include "BattleInfo.h"
@@ -25,7 +26,6 @@
 #include "../networkPacks/PacksForClientBattle.h"
 #include "../BattleFieldHandler.h"
 #include "../Rect.h"
-#include "../CRandomGenerator.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 
@@ -1602,7 +1602,7 @@ std::set<const battle::Unit *> CBattleInfoCallback::battleAdjacentUnits(const ba
 	return ret;
 }
 
-SpellID CBattleInfoCallback::getRandomBeneficialSpell(CRandomGenerator & rand, const battle::Unit * caster, const battle::Unit * subject) const
+SpellID CBattleInfoCallback::getRandomBeneficialSpell(vstd::RNG & rand, const battle::Unit * caster, const battle::Unit * subject) const
 {
 	RETURN_IF_NOT_BATTLE(SpellID::NONE);
 	//This is complete list. No spells from mods.
@@ -1748,7 +1748,7 @@ SpellID CBattleInfoCallback::getRandomBeneficialSpell(CRandomGenerator & rand, c
 	}
 }
 
-SpellID CBattleInfoCallback::getRandomCastedSpell(CRandomGenerator & rand,const CStack * caster) const
+SpellID CBattleInfoCallback::getRandomCastedSpell(vstd::RNG & rand,const CStack * caster) const
 {
 	RETURN_IF_NOT_BATTLE(SpellID::NONE);
 

+ 7 - 3
lib/battle/CBattleInfoCallback.h

@@ -23,9 +23,13 @@ class SpellCastEnvironment;
 class CSpell;
 struct CObstacleInstance;
 class IBonusBearer;
-class CRandomGenerator;
 class PossiblePlayerBattleAction;
 
+namespace vstd
+{
+class RNG;
+}
+
 namespace spells
 {
 	class Caster;
@@ -116,8 +120,8 @@ public:
 	int32_t battleGetSpellCost(const spells::Spell * sp, const CGHeroInstance * caster) const; //returns cost of given spell
 	ESpellCastProblem battleCanCastSpell(const spells::Caster * caster, spells::Mode mode) const; //returns true if there are no general issues preventing from casting a spell
 
-	SpellID getRandomBeneficialSpell(CRandomGenerator & rand, const battle::Unit * caster, const battle::Unit * target) const;
-	SpellID getRandomCastedSpell(CRandomGenerator & rand, const CStack * caster) const; //called at the beginning of turn for Faerie Dragon
+	SpellID getRandomBeneficialSpell(vstd::RNG & rand, const battle::Unit * caster, const battle::Unit * target) const;
+	SpellID getRandomCastedSpell(vstd::RNG & rand, const CStack * caster) const; //called at the beginning of turn for Faerie Dragon
 
 	std::vector<PossiblePlayerBattleAction> getClientActionsForStack(const CStack * stack, const BattleClientInterfaceData & data);
 	PossiblePlayerBattleAction getCasterAction(const CSpell * spell, const spells::Caster * caster, spells::Mode mode) const;

+ 11 - 8
lib/gameState/CGameState.cpp

@@ -21,6 +21,7 @@
 #include "../CGeneralTextHandler.h"
 #include "../CHeroHandler.h"
 #include "../CPlayerState.h"
+#include "../CRandomGenerator.h"
 #include "../CStopWatch.h"
 #include "../GameSettings.h"
 #include "../StartInfo.h"
@@ -53,6 +54,8 @@
 #include "../serializer/CTypeList.h"
 #include "../spells/CSpellHandler.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 boost::shared_mutex CGameState::mutex;
@@ -183,7 +186,7 @@ void CGameState::init(const IMapService * mapService, StartInfo * si, Load::Prog
 	assert(services);
 	assert(callback);
 	logGlobal->info("\tUsing random seed: %d", si->seedToBeUsed);
-	getRandomGenerator().setSeed(si->seedToBeUsed);
+	rand = std::make_unique<CRandomGenerator>(si->seedToBeUsed);
 	scenarioOps = CMemorySerializer::deepCopy(*si).release();
 	initialOpts = CMemorySerializer::deepCopy(*si).release();
 	si = nullptr;
@@ -1072,7 +1075,7 @@ BattleInfo * CGameState::getBattle(const BattleID & battle)
 	return nullptr;
 }
 
-BattleField CGameState::battleGetBattlefieldType(int3 tile, CRandomGenerator & rand)
+BattleField CGameState::battleGetBattlefieldType(int3 tile, vstd::RNG & rand)
 {
 	assert(tile.valid());
 
@@ -1961,12 +1964,12 @@ TeamState::TeamState()
 	setNodeType(TEAM);
 }
 
-CRandomGenerator & CGameState::getRandomGenerator()
+vstd::RNG & CGameState::getRandomGenerator()
 {
-	return rand;
+	return *rand;
 }
 
-ArtifactID CGameState::pickRandomArtifact(CRandomGenerator & rand, int flags, std::function<bool(ArtifactID)> accepts)
+ArtifactID CGameState::pickRandomArtifact(vstd::RNG & rand, int flags, std::function<bool(ArtifactID)> accepts)
 {
 	std::set<ArtifactID> potentialPicks;
 
@@ -2001,7 +2004,7 @@ ArtifactID CGameState::pickRandomArtifact(CRandomGenerator & rand, int flags, st
 	return pickRandomArtifact(rand, potentialPicks);
 }
 
-ArtifactID CGameState::pickRandomArtifact(CRandomGenerator & rand, std::set<ArtifactID> potentialPicks)
+ArtifactID CGameState::pickRandomArtifact(vstd::RNG & rand, std::set<ArtifactID> potentialPicks)
 {
 	// No allowed artifacts at all - give Grail - this can't be banned (hopefully)
 	// FIXME: investigate how such cases are handled by H3 - some heavily customized user-made maps likely rely on H3 behavior
@@ -2030,12 +2033,12 @@ ArtifactID CGameState::pickRandomArtifact(CRandomGenerator & rand, std::set<Arti
 	return artID;
 }
 
-ArtifactID CGameState::pickRandomArtifact(CRandomGenerator & rand, std::function<bool(ArtifactID)> accepts)
+ArtifactID CGameState::pickRandomArtifact(vstd::RNG & rand, std::function<bool(ArtifactID)> accepts)
 {
 	return pickRandomArtifact(rand, 0xff, std::move(accepts));
 }
 
-ArtifactID CGameState::pickRandomArtifact(CRandomGenerator & rand, int flags)
+ArtifactID CGameState::pickRandomArtifact(vstd::RNG & rand, int flags)
 {
 	return pickRandomArtifact(rand, flags, [](const ArtifactID &) { return true; });
 }

+ 11 - 11
lib/gameState/CGameState.h

@@ -13,7 +13,6 @@
 #include "IGameCallback.h"
 #include "LoadProgress.h"
 #include "ConstTransitivePtr.h"
-#include "../CRandomGenerator.h"
 
 namespace boost
 {
@@ -34,6 +33,7 @@ class CStackInstance;
 class CGameStateCampaign;
 class TavernHeroesPool;
 struct SThievesGuildInfo;
+class CRandomGenerator;
 
 template<typename T> class CApplier;
 class CBaseForGSApply;
@@ -126,7 +126,7 @@ public:
 	HeroTypeID pickNextHeroType(const PlayerColor & owner);
 
 	void apply(CPack *pack);
-	BattleField battleGetBattlefieldType(int3 tile, CRandomGenerator & rand);
+	BattleField battleGetBattlefieldType(int3 tile, vstd::RNG & rand);
 
 	void fillUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, UpgradeInfo &out) const override;
 	PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2) const override;
@@ -138,10 +138,10 @@ public:
 	void updateRumor();
 
 	/// Gets a artifact ID randomly and removes the selected artifact from this handler.
-	ArtifactID pickRandomArtifact(CRandomGenerator & rand, int flags);
-	ArtifactID pickRandomArtifact(CRandomGenerator & rand, std::function<bool(ArtifactID)> accepts);
-	ArtifactID pickRandomArtifact(CRandomGenerator & rand, int flags, std::function<bool(ArtifactID)> accepts);
-	ArtifactID pickRandomArtifact(CRandomGenerator & rand, std::set<ArtifactID> filtered);
+	ArtifactID pickRandomArtifact(vstd::RNG & rand, int flags);
+	ArtifactID pickRandomArtifact(vstd::RNG & rand, std::function<bool(ArtifactID)> accepts);
+	ArtifactID pickRandomArtifact(vstd::RNG & rand, int flags, std::function<bool(ArtifactID)> accepts);
+	ArtifactID pickRandomArtifact(vstd::RNG & rand, std::set<ArtifactID> filtered);
 
 	/// Returns battle in which selected player is engaged, or nullptr if none.
 	/// Can NOT be used with neutral player, use battle by ID instead
@@ -169,11 +169,11 @@ public:
 	/// This RNG should only be used inside GS or CPackForClient-derived applyGs
 	/// If this doesn't work for your code that mean you need a new netpack
 	///
-	/// Client-side must use CRandomGenerator::getDefault which is not serialized
+	/// Client-side must use vstd::RNG::getDefault which is not serialized
 	///
-	/// CGameHandler have it's own getter for CRandomGenerator::getDefault
-	/// Any server-side code outside of GH must use CRandomGenerator::getDefault
-	CRandomGenerator & getRandomGenerator();
+	/// CGameHandler have it's own getter for vstd::RNG::getDefault
+	/// Any server-side code outside of GH must use vstd::RNG::getDefault
+	vstd::RNG & getRandomGenerator();
 
 	template <typename Handler> void serialize(Handler &h)
 	{
@@ -234,7 +234,7 @@ private:
 
 	// ---- data -----
 	std::shared_ptr<CApplier<CBaseForGSApply>> applier;
-	CRandomGenerator rand;
+	std::unique_ptr<CRandomGenerator> rand;
 	Services * services;
 
 	/// Pointer to campaign state manager. Nullptr for single scenarios

+ 2 - 0
lib/gameState/CGameStateCampaign.cpp

@@ -28,6 +28,8 @@
 #include "../CPlayerState.h"
 #include "../serializer/CMemorySerializer.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 CampaignHeroReplacement::CampaignHeroReplacement(CGHeroInstance * hero, const ObjectInstanceID & heroPlaceholderId):

+ 0 - 1
lib/gameState/TavernHeroesPool.h

@@ -18,7 +18,6 @@ VCMI_LIB_NAMESPACE_BEGIN
 
 class CGHeroInstance;
 class CTown;
-class CRandomGenerator;
 class CHeroClass;
 class CGameState;
 class CSimpleArmy;

+ 17 - 17
lib/json/JsonRandom.cpp

@@ -12,10 +12,10 @@
 #include "JsonRandom.h"
 
 #include <vstd/StringUtils.h>
+#include <vstd/RNG.h>
 
 #include "JsonBonus.h"
 
-#include "../CRandomGenerator.h"
 #include "../constants/StringConstants.h"
 #include "../VCMI_Lib.h"
 #include "../CArtHandler.h"
@@ -50,7 +50,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 		return variables.at(variableID);
 	}
 
-	si32 JsonRandom::loadValue(const JsonNode & value, CRandomGenerator & rng, const Variables & variables, si32 defaultValue)
+	si32 JsonRandom::loadValue(const JsonNode & value, vstd::RNG & rng, const Variables & variables, si32 defaultValue)
 	{
 		if(value.isNull())
 			return defaultValue;
@@ -256,7 +256,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 		return valuesSet;
 	}
 
-	TResources JsonRandom::loadResources(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
+	TResources JsonRandom::loadResources(const JsonNode & value, vstd::RNG & rng, const Variables & variables)
 	{
 		TResources ret;
 
@@ -274,7 +274,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 		return ret;
 	}
 
-	TResources JsonRandom::loadResource(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
+	TResources JsonRandom::loadResource(const JsonNode & value, vstd::RNG & rng, const Variables & variables)
 	{
 		std::set<GameResID> defaultResources{
 			GameResID::WOOD,
@@ -295,7 +295,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 		return ret;
 	}
 
-	PrimarySkill JsonRandom::loadPrimary(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
+	PrimarySkill JsonRandom::loadPrimary(const JsonNode & value, vstd::RNG & rng, const Variables & variables)
 	{
 		std::set<PrimarySkill> defaultSkills{
 			PrimarySkill::ATTACK,
@@ -307,7 +307,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 		return *RandomGeneratorUtil::nextItem(potentialPicks, rng);
 	}
 
-	std::vector<si32> JsonRandom::loadPrimaries(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
+	std::vector<si32> JsonRandom::loadPrimaries(const JsonNode & value, vstd::RNG & rng, const Variables & variables)
 	{
 		std::vector<si32> ret(GameConstants::PRIMARY_SKILLS, 0);
 		std::set<PrimarySkill> defaultSkills{
@@ -339,7 +339,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 		return ret;
 	}
 
-	SecondarySkill JsonRandom::loadSecondary(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
+	SecondarySkill JsonRandom::loadSecondary(const JsonNode & value, vstd::RNG & rng, const Variables & variables)
 	{
 		std::set<SecondarySkill> defaultSkills;
 		for(const auto & skill : VLC->skillh->objects)
@@ -350,7 +350,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 		return *RandomGeneratorUtil::nextItem(potentialPicks, rng);
 	}
 
-	std::map<SecondarySkill, si32> JsonRandom::loadSecondaries(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
+	std::map<SecondarySkill, si32> JsonRandom::loadSecondaries(const JsonNode & value, vstd::RNG & rng, const Variables & variables)
 	{
 		std::map<SecondarySkill, si32> ret;
 		if(value.isStruct())
@@ -380,7 +380,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 		return ret;
 	}
 
-	ArtifactID JsonRandom::loadArtifact(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
+	ArtifactID JsonRandom::loadArtifact(const JsonNode & value, vstd::RNG & rng, const Variables & variables)
 	{
 		std::set<ArtifactID> allowedArts;
 		for(const auto & artifact : VLC->arth->objects)
@@ -392,7 +392,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 		return cb->gameState()->pickRandomArtifact(rng, potentialPicks);
 	}
 
-	std::vector<ArtifactID> JsonRandom::loadArtifacts(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
+	std::vector<ArtifactID> JsonRandom::loadArtifacts(const JsonNode & value, vstd::RNG & rng, const Variables & variables)
 	{
 		std::vector<ArtifactID> ret;
 		for (const JsonNode & entry : value.Vector())
@@ -402,7 +402,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 		return ret;
 	}
 
-	SpellID JsonRandom::loadSpell(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
+	SpellID JsonRandom::loadSpell(const JsonNode & value, vstd::RNG & rng, const Variables & variables)
 	{
 		std::set<SpellID> defaultSpells;
 		for(const auto & spell : VLC->spellh->objects)
@@ -419,7 +419,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 		return *RandomGeneratorUtil::nextItem(potentialPicks, rng);
 	}
 
-	std::vector<SpellID> JsonRandom::loadSpells(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
+	std::vector<SpellID> JsonRandom::loadSpells(const JsonNode & value, vstd::RNG & rng, const Variables & variables)
 	{
 		std::vector<SpellID> ret;
 		for (const JsonNode & entry : value.Vector())
@@ -429,7 +429,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 		return ret;
 	}
 
-	std::vector<PlayerColor> JsonRandom::loadColors(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
+	std::vector<PlayerColor> JsonRandom::loadColors(const JsonNode & value, vstd::RNG & rng, const Variables & variables)
 	{
 		std::vector<PlayerColor> ret;
 		std::set<PlayerColor> defaultPlayers;
@@ -445,7 +445,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 		return ret;
 	}
 
-	std::vector<HeroTypeID> JsonRandom::loadHeroes(const JsonNode & value, CRandomGenerator & rng)
+	std::vector<HeroTypeID> JsonRandom::loadHeroes(const JsonNode & value, vstd::RNG & rng)
 	{
 		std::vector<HeroTypeID> ret;
 		for(auto & entry : value.Vector())
@@ -455,7 +455,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 		return ret;
 	}
 
-	std::vector<HeroClassID> JsonRandom::loadHeroClasses(const JsonNode & value, CRandomGenerator & rng)
+	std::vector<HeroClassID> JsonRandom::loadHeroClasses(const JsonNode & value, vstd::RNG & rng)
 	{
 		std::vector<HeroClassID> ret;
 		for(auto & entry : value.Vector())
@@ -465,7 +465,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 		return ret;
 	}
 
-	CStackBasicDescriptor JsonRandom::loadCreature(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
+	CStackBasicDescriptor JsonRandom::loadCreature(const JsonNode & value, vstd::RNG & rng, const Variables & variables)
 	{
 		CStackBasicDescriptor stack;
 
@@ -494,7 +494,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 		return stack;
 	}
 
-	std::vector<CStackBasicDescriptor> JsonRandom::loadCreatures(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)
+	std::vector<CStackBasicDescriptor> JsonRandom::loadCreatures(const JsonNode & value, vstd::RNG & rng, const Variables & variables)
 	{
 		std::vector<CStackBasicDescriptor> ret;
 		for (const JsonNode & node : value.Vector())

+ 21 - 17
lib/json/JsonRandom.h

@@ -15,9 +15,13 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
+namespace vstd
+{
+class RNG;
+}
+
 class JsonNode;
 using JsonVector = std::vector<JsonNode>;
-class CRandomGenerator;
 
 struct Bonus;
 struct Component;
@@ -53,28 +57,28 @@ public:
 		si32 maxAmount;
 	};
 
-	si32 loadValue(const JsonNode & value, CRandomGenerator & rng, const Variables & variables, si32 defaultValue = 0);
+	si32 loadValue(const JsonNode & value, vstd::RNG & rng, const Variables & variables, si32 defaultValue = 0);
 
-	TResources loadResources(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
-	TResources loadResource(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
-	PrimarySkill loadPrimary(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
-	std::vector<si32> loadPrimaries(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
-	SecondarySkill loadSecondary(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
-	std::map<SecondarySkill, si32> loadSecondaries(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
+	TResources loadResources(const JsonNode & value, vstd::RNG & rng, const Variables & variables);
+	TResources loadResource(const JsonNode & value, vstd::RNG & rng, const Variables & variables);
+	PrimarySkill loadPrimary(const JsonNode & value, vstd::RNG & rng, const Variables & variables);
+	std::vector<si32> loadPrimaries(const JsonNode & value, vstd::RNG & rng, const Variables & variables);
+	SecondarySkill loadSecondary(const JsonNode & value, vstd::RNG & rng, const Variables & variables);
+	std::map<SecondarySkill, si32> loadSecondaries(const JsonNode & value, vstd::RNG & rng, const Variables & variables);
 
-	ArtifactID loadArtifact(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
-	std::vector<ArtifactID> loadArtifacts(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
+	ArtifactID loadArtifact(const JsonNode & value, vstd::RNG & rng, const Variables & variables);
+	std::vector<ArtifactID> loadArtifacts(const JsonNode & value, vstd::RNG & rng, const Variables & variables);
 
-	SpellID loadSpell(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
-	std::vector<SpellID> loadSpells(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
+	SpellID loadSpell(const JsonNode & value, vstd::RNG & rng, const Variables & variables);
+	std::vector<SpellID> loadSpells(const JsonNode & value, vstd::RNG & rng, const Variables & variables);
 
-	CStackBasicDescriptor loadCreature(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
-	std::vector<CStackBasicDescriptor> loadCreatures(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
+	CStackBasicDescriptor loadCreature(const JsonNode & value, vstd::RNG & rng, const Variables & variables);
+	std::vector<CStackBasicDescriptor> loadCreatures(const JsonNode & value, vstd::RNG & rng, const Variables & variables);
 	std::vector<RandomStackInfo> evaluateCreatures(const JsonNode & value, const Variables & variables);
 
-	std::vector<PlayerColor> loadColors(const JsonNode & value, CRandomGenerator & rng, const Variables & variables);
-	std::vector<HeroTypeID> loadHeroes(const JsonNode & value, CRandomGenerator & rng);
-	std::vector<HeroClassID> loadHeroClasses(const JsonNode & value, CRandomGenerator & rng);
+	std::vector<PlayerColor> loadColors(const JsonNode & value, vstd::RNG & rng, const Variables & variables);
+	std::vector<HeroTypeID> loadHeroes(const JsonNode & value, vstd::RNG & rng);
+	std::vector<HeroClassID> loadHeroClasses(const JsonNode & value, vstd::RNG & rng);
 
 	static std::vector<Bonus> loadBonuses(const JsonNode & value);
 };

+ 6 - 2
lib/mapObjectConstructors/AObjectTypeHandler.h

@@ -15,9 +15,13 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
+namespace vstd
+{
+class RNG;
+}
+
 class ObjectTemplate;
 class CGObjectInstance;
-class CRandomGenerator;
 class IObjectInfo;
 class IGameCallback;
 
@@ -114,7 +118,7 @@ public:
 
 	/// Configures object properties. Should be re-entrable, resetting state of the object if necessarily
 	/// This should set remaining properties, including randomized or depending on map
-	virtual void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const = 0;
+	virtual void configureObject(CGObjectInstance * object, vstd::RNG & rng) const = 0;
 
 	/// Returns object configuration, if available. Otherwise returns NULL
 	virtual std::unique_ptr<IObjectInfo> getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const;

+ 4 - 3
lib/mapObjectConstructors/CBankInstanceConstructor.cpp

@@ -13,7 +13,8 @@
 #include "../json/JsonRandom.h"
 #include "../CGeneralTextHandler.h"
 #include "../IGameCallback.h"
-#include "../CRandomGenerator.h"
+
+#include <vstd/RNG.h>
 
 VCMI_LIB_NAMESPACE_BEGIN
 
@@ -36,7 +37,7 @@ void CBankInstanceConstructor::initTypeData(const JsonNode & input)
 	regularUnitPlacement = input["regularUnitPlacement"].Bool();
 }
 
-BankConfig CBankInstanceConstructor::generateConfig(IGameCallback * cb, const JsonNode & level, CRandomGenerator & rng) const
+BankConfig CBankInstanceConstructor::generateConfig(IGameCallback * cb, const JsonNode & level, vstd::RNG & rng) const
 {
 	BankConfig bc;
 	JsonRandom randomizer(cb);
@@ -53,7 +54,7 @@ BankConfig CBankInstanceConstructor::generateConfig(IGameCallback * cb, const Js
 	return bc;
 }
 
-void CBankInstanceConstructor::randomizeObject(CBank * bank, CRandomGenerator & rng) const
+void CBankInstanceConstructor::randomizeObject(CBank * bank, vstd::RNG & rng) const
 {
 	bank->resetDuration = bankResetDuration;
 	bank->blockVisit = blockVisit;

+ 2 - 2
lib/mapObjectConstructors/CBankInstanceConstructor.h

@@ -69,7 +69,7 @@ public:
 
 class CBankInstanceConstructor : public CDefaultObjectTypeHandler<CBank>
 {
-	BankConfig generateConfig(IGameCallback * cb, const JsonNode & conf, CRandomGenerator & rng) const;
+	BankConfig generateConfig(IGameCallback * cb, const JsonNode & conf, vstd::RNG & rng) const;
 
 	JsonVector levels;
 
@@ -87,7 +87,7 @@ protected:
 
 public:
 
-	void randomizeObject(CBank * object, CRandomGenerator & rng) const override;
+	void randomizeObject(CBank * object, vstd::RNG & rng) const override;
 
 	bool hasNameTextID() const override;
 

+ 2 - 2
lib/mapObjectConstructors/CDefaultObjectTypeHandler.h

@@ -17,7 +17,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 template<class ObjectType>
 class CDefaultObjectTypeHandler : public AObjectTypeHandler
 {
-	void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const final
+	void configureObject(CGObjectInstance * object, vstd::RNG & rng) const final
 	{
 		ObjectType * castedObject = dynamic_cast<ObjectType*>(object);
 
@@ -43,7 +43,7 @@ class CDefaultObjectTypeHandler : public AObjectTypeHandler
 
 protected:
 	virtual void initializeObject(ObjectType * object) const {}
-	virtual void randomizeObject(ObjectType * object, CRandomGenerator & rng) const {}
+	virtual void randomizeObject(ObjectType * object, vstd::RNG & rng) const {}
 	virtual ObjectType * createObject(IGameCallback * cb) const
 	{
 		return new ObjectType(cb);

+ 0 - 1
lib/mapObjectConstructors/CObjectClassesHandler.h

@@ -15,7 +15,6 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-class CRandomGenerator;
 class AObjectTypeHandler;
 class ObjectTemplate;
 struct SObjectSounds;

+ 1 - 1
lib/mapObjectConstructors/CRewardableConstructor.cpp

@@ -40,7 +40,7 @@ CGObjectInstance * CRewardableConstructor::create(IGameCallback * cb, std::share
 	return ret;
 }
 
-void CRewardableConstructor::configureObject(CGObjectInstance * object, CRandomGenerator & rng) const
+void CRewardableConstructor::configureObject(CGObjectInstance * object, vstd::RNG & rng) const
 {
 	if(auto * rewardableObject = dynamic_cast<CRewardableObject*>(object))
 	{

+ 1 - 1
lib/mapObjectConstructors/CRewardableConstructor.h

@@ -27,7 +27,7 @@ public:
 
 	CGObjectInstance * create(IGameCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl = nullptr) const override;
 
-	void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const override;
+	void configureObject(CGObjectInstance * object, vstd::RNG & rng) const override;
 
 	std::unique_ptr<IObjectInfo> getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const override;
 };

+ 3 - 3
lib/mapObjectConstructors/CommonConstructors.cpp

@@ -100,7 +100,7 @@ void CTownInstanceConstructor::initializeObject(CGTownInstance * obj) const
 	obj->tempOwner = PlayerColor::NEUTRAL;
 }
 
-void CTownInstanceConstructor::randomizeObject(CGTownInstance * object, CRandomGenerator & rng) const
+void CTownInstanceConstructor::randomizeObject(CGTownInstance * object, vstd::RNG & rng) const
 {
 	auto templ = getOverride(object->cb->getTile(object->pos)->terType->getId(), object);
 	if(templ)
@@ -159,7 +159,7 @@ void CHeroInstanceConstructor::initializeObject(CGHeroInstance * obj) const
 	obj->type = nullptr; //FIXME: set to valid value. somehow.
 }
 
-void CHeroInstanceConstructor::randomizeObject(CGHeroInstance * object, CRandomGenerator & rng) const
+void CHeroInstanceConstructor::randomizeObject(CGHeroInstance * object, vstd::RNG & rng) const
 {
 
 }
@@ -259,7 +259,7 @@ void MarketInstanceConstructor::initializeObject(CGMarket * market) const
 		market->speech = VLC->generaltexth->translate(speech);
 }
 
-void MarketInstanceConstructor::randomizeObject(CGMarket * object, CRandomGenerator & rng) const
+void MarketInstanceConstructor::randomizeObject(CGMarket * object, vstd::RNG & rng) const
 {
 	JsonRandom randomizer(object->cb);
 	JsonRandom::Variables emptyVariables;

+ 3 - 3
lib/mapObjectConstructors/CommonConstructors.h

@@ -63,7 +63,7 @@ public:
 	std::map<std::string, LogicalExpression<BuildingID>> filters;
 
 	void initializeObject(CGTownInstance * object) const override;
-	void randomizeObject(CGTownInstance * object, CRandomGenerator & rng) const override;
+	void randomizeObject(CGTownInstance * object, vstd::RNG & rng) const override;
 	void afterLoadFinalization() override;
 
 	bool hasNameTextID() const override;
@@ -82,7 +82,7 @@ public:
 	std::map<std::string, LogicalExpression<HeroTypeID>> filters;
 
 	void initializeObject(CGHeroInstance * object) const override;
-	void randomizeObject(CGHeroInstance * object, CRandomGenerator & rng) const override;
+	void randomizeObject(CGHeroInstance * object, vstd::RNG & rng) const override;
 	void afterLoadFinalization() override;
 
 	bool hasNameTextID() const override;
@@ -125,7 +125,7 @@ protected:
 public:
 	CGMarket * createObject(IGameCallback * cb) const override;
 	void initializeObject(CGMarket * object) const override;
-	void randomizeObject(CGMarket * object, CRandomGenerator & rng) const override;
+	void randomizeObject(CGMarket * object, vstd::RNG & rng) const override;
 
 };
 

+ 1 - 1
lib/mapObjectConstructors/DwellingInstanceConstructor.cpp

@@ -74,7 +74,7 @@ void DwellingInstanceConstructor::initializeObject(CGDwelling * obj) const
 	}
 }
 
-void DwellingInstanceConstructor::randomizeObject(CGDwelling * dwelling, CRandomGenerator &rng) const
+void DwellingInstanceConstructor::randomizeObject(CGDwelling * dwelling, vstd::RNG &rng) const
 {
 	JsonRandom randomizer(dwelling->cb);
 

+ 1 - 1
lib/mapObjectConstructors/DwellingInstanceConstructor.h

@@ -33,7 +33,7 @@ public:
 	bool hasNameTextID() const override;
 
 	void initializeObject(CGDwelling * object) const override;
-	void randomizeObject(CGDwelling * object, CRandomGenerator & rng) const override;
+	void randomizeObject(CGDwelling * object, vstd::RNG & rng) const override;
 
 	bool isBannedForRandomDwelling() const;
 	bool producesCreature(const CCreature * crea) const;

+ 2 - 2
lib/mapObjects/CBank.cpp

@@ -44,7 +44,7 @@ CBank::CBank(IGameCallback *cb)
 //must be instantiated in .cpp file for access to complete types of all member fields
 CBank::~CBank() = default;
 
-void CBank::initObj(CRandomGenerator & rand)
+void CBank::initObj(vstd::RNG & rand)
 {
 	daycounter = 0;
 	resetDuration = 0;
@@ -117,7 +117,7 @@ void CBank::setPropertyDer (ObjProperty what, ObjPropertyID identifier)
 	}
 }
 
-void CBank::newTurn(CRandomGenerator & rand) const
+void CBank::newTurn(vstd::RNG & rand) const
 {
 	if (bankConfig == nullptr)
 	{

+ 2 - 2
lib/mapObjects/CBank.h

@@ -33,9 +33,9 @@ public:
 
 	void setConfig(const BankConfig & bc);
 
-	void initObj(CRandomGenerator & rand) override;
+	void initObj(vstd::RNG & rand) override;
 	std::string getHoverText(PlayerColor player) const override;
-	void newTurn(CRandomGenerator & rand) const override;
+	void newTurn(vstd::RNG & rand) const override;
 	bool wasVisited (PlayerColor player) const override;
 	bool isCoastVisitable() const override;
 	void onHeroVisit(const CGHeroInstance * h) const override;

+ 7 - 5
lib/mapObjects/CGCreature.cpp

@@ -16,12 +16,14 @@
 #include "../CConfigHandler.h"
 #include "../GameSettings.h"
 #include "../IGameCallback.h"
+#include "../gameState/CGameState.h"
 #include "../mapObjectConstructors/CObjectClassesHandler.h"
 #include "../networkPacks/PacksForClient.h"
 #include "../networkPacks/PacksForClientBattle.h"
 #include "../networkPacks/StackLocation.h"
 #include "../serializer/JsonSerializeFormat.h"
-#include "../CRandomGenerator.h"
+
+#include <vstd/RNG.h>
 
 VCMI_LIB_NAMESPACE_BEGIN
 
@@ -189,7 +191,7 @@ CreatureID CGCreature::getCreature() const
 	return CreatureID(getObjTypeIndex().getNum());
 }
 
-void CGCreature::pickRandomObject(CRandomGenerator & rand)
+void CGCreature::pickRandomObject(vstd::RNG & rand)
 {
 	switch(ID.toEnum())
 	{
@@ -234,7 +236,7 @@ void CGCreature::pickRandomObject(CRandomGenerator & rand)
 	setType(ID, subID);
 }
 
-void CGCreature::initObj(CRandomGenerator & rand)
+void CGCreature::initObj(vstd::RNG & rand)
 {
 	blockVisit = true;
 	switch(character)
@@ -274,7 +276,7 @@ void CGCreature::initObj(CRandomGenerator & rand)
 	refusedJoining = false;
 }
 
-void CGCreature::newTurn(CRandomGenerator & rand) const
+void CGCreature::newTurn(vstd::RNG & rand) const
 {//Works only for stacks of single type of size up to 2 millions
 	if (!notGrowingTeam)
 	{
@@ -457,7 +459,7 @@ void CGCreature::fight( const CGHeroInstance *h ) const
 			const auto & upgrades = getStack(slotID).type->upgrades;
 			if(!upgrades.empty())
 			{
-				auto it = RandomGeneratorUtil::nextItem(upgrades, CRandomGenerator::getDefault());
+				auto it = RandomGeneratorUtil::nextItem(upgrades, cb->gameState()->getRandomGenerator());
 				cb->changeStackType(StackLocation(this, slotID), it->toCreature());
 			}
 		}

+ 3 - 3
lib/mapObjects/CGCreature.h

@@ -45,9 +45,9 @@ public:
 	std::string getPopupText(PlayerColor player) const override;
 	std::string getPopupText(const CGHeroInstance * hero) const override;
 	std::vector<Component> getPopupComponents(PlayerColor player) const override;
-	void initObj(CRandomGenerator & rand) override;
-	void pickRandomObject(CRandomGenerator & rand) override;
-	void newTurn(CRandomGenerator & rand) const override;
+	void initObj(vstd::RNG & rand) override;
+	void pickRandomObject(vstd::RNG & rand) override;
+	void newTurn(vstd::RNG & rand) const override;
 	void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
 	void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
 	CreatureID getCreature() const;

+ 7 - 5
lib/mapObjects/CGDwelling.cpp

@@ -27,6 +27,8 @@
 #include "../GameSettings.h"
 #include "../CConfigHandler.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 void CGDwellingRandomizationInfo::serializeJson(JsonSerializeFormat & handler)
@@ -50,7 +52,7 @@ CGDwelling::CGDwelling(IGameCallback *cb):
 
 CGDwelling::~CGDwelling() = default;
 
-FactionID CGDwelling::randomizeFaction(CRandomGenerator & rand)
+FactionID CGDwelling::randomizeFaction(vstd::RNG & rand)
 {
 	if (ID == Obj::RANDOM_DWELLING_FACTION)
 		return FactionID(subID.getNum());
@@ -108,7 +110,7 @@ FactionID CGDwelling::randomizeFaction(CRandomGenerator & rand)
 	return *RandomGeneratorUtil::nextItem(potentialPicks, rand);
 }
 
-int CGDwelling::randomizeLevel(CRandomGenerator & rand)
+int CGDwelling::randomizeLevel(vstd::RNG & rand)
 {
 	if (ID == Obj::RANDOM_DWELLING_LVL)
 		return subID.getNum();
@@ -125,7 +127,7 @@ int CGDwelling::randomizeLevel(CRandomGenerator & rand)
 	return rand.nextInt(randomizationInfo->minLevel, randomizationInfo->maxLevel) - 1;
 }
 
-void CGDwelling::pickRandomObject(CRandomGenerator & rand)
+void CGDwelling::pickRandomObject(vstd::RNG & rand)
 {
 	if (ID == Obj::RANDOM_DWELLING || ID == Obj::RANDOM_DWELLING_LVL || ID == Obj::RANDOM_DWELLING_FACTION)
 	{
@@ -172,7 +174,7 @@ void CGDwelling::pickRandomObject(CRandomGenerator & rand)
 	}
 }
 
-void CGDwelling::initObj(CRandomGenerator & rand)
+void CGDwelling::initObj(vstd::RNG & rand)
 {
 	switch(ID.toEnum())
 	{
@@ -298,7 +300,7 @@ void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const
 	cb->showBlockingDialog(&bd);
 }
 
-void CGDwelling::newTurn(CRandomGenerator & rand) const
+void CGDwelling::newTurn(vstd::RNG & rand) const
 {
 	if(cb->getDate(Date::DAY_OF_WEEK) != 1) //not first day of week
 		return;

+ 5 - 5
lib/mapObjects/CGDwelling.h

@@ -45,13 +45,13 @@ protected:
 	void serializeJsonOptions(JsonSerializeFormat & handler) override;
 
 private:
-	FactionID randomizeFaction(CRandomGenerator & rand);
-	int randomizeLevel(CRandomGenerator & rand);
+	FactionID randomizeFaction(vstd::RNG & rand);
+	int randomizeLevel(vstd::RNG & rand);
 
-	void pickRandomObject(CRandomGenerator & rand) override;
-	void initObj(CRandomGenerator & rand) override;
+	void pickRandomObject(vstd::RNG & rand) override;
+	void initObj(vstd::RNG & rand) override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
-	void newTurn(CRandomGenerator & rand) const override;
+	void newTurn(vstd::RNG & rand) const override;
 	void setPropertyDer(ObjProperty what, ObjPropertyID identifier) override;
 	void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
 	void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;

+ 11 - 11
lib/mapObjects/CGHeroInstance.cpp

@@ -313,13 +313,13 @@ void CGHeroInstance::setHeroType(HeroTypeID heroType)
 	subID = heroType;
 }
 
-void CGHeroInstance::initHero(CRandomGenerator & rand, const HeroTypeID & SUBID)
+void CGHeroInstance::initHero(vstd::RNG & rand, const HeroTypeID & SUBID)
 {
 	subID = SUBID.getNum();
 	initHero(rand);
 }
 
-void CGHeroInstance::initHero(CRandomGenerator & rand)
+void CGHeroInstance::initHero(vstd::RNG & rand)
 {
 	assert(validTypes(true));
 	if(!type)
@@ -422,7 +422,7 @@ void CGHeroInstance::initHero(CRandomGenerator & rand)
 	mana = manaLimit(); //after all bonuses are taken into account, make sure this line is the last one
 }
 
-void CGHeroInstance::initArmy(CRandomGenerator & rand, IArmyDescriptor * dst)
+void CGHeroInstance::initArmy(vstd::RNG & rand, IArmyDescriptor * dst)
 {
 	if(!dst)
 		dst = this;
@@ -589,7 +589,7 @@ void CGHeroInstance::SecondarySkillsInfo::resetWisdomCounter()
 	wisdomCounter = 0;
 }
 
-void CGHeroInstance::pickRandomObject(CRandomGenerator & rand)
+void CGHeroInstance::pickRandomObject(vstd::RNG & rand)
 {
 	assert(ID == Obj::HERO || ID == Obj::PRISON || ID == Obj::RANDOM_HERO);
 
@@ -614,7 +614,7 @@ void CGHeroInstance::pickRandomObject(CRandomGenerator & rand)
 	this->subID = oldSubID;
 }
 
-void CGHeroInstance::initObj(CRandomGenerator & rand)
+void CGHeroInstance::initObj(vstd::RNG & rand)
 {
 
 }
@@ -959,7 +959,7 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b
  * @param raisedStack Pair where the first element represents ID of the raised creature
  * and the second element the amount.
  */
-void CGHeroInstance::showNecromancyDialog(const CStackBasicDescriptor &raisedStack, CRandomGenerator & rand) const
+void CGHeroInstance::showNecromancyDialog(const CStackBasicDescriptor &raisedStack, vstd::RNG & rand) const
 {
 	InfoWindow iw;
 	iw.type = EInfoWindowMode::AUTO;
@@ -1068,7 +1068,7 @@ EAlignment CGHeroInstance::getAlignment() const
 	return type->heroClass->getAlignment();
 }
 
-void CGHeroInstance::initExp(CRandomGenerator & rand)
+void CGHeroInstance::initExp(vstd::RNG & rand)
 {
 	exp = rand.nextInt(40, 89);
 }
@@ -1286,7 +1286,7 @@ ArtBearer::ArtBearer CGHeroInstance::bearerType() const
 	return ArtBearer::HERO;
 }
 
-std::vector<SecondarySkill> CGHeroInstance::getLevelUpProposedSecondarySkills(CRandomGenerator & rand) const
+std::vector<SecondarySkill> CGHeroInstance::getLevelUpProposedSecondarySkills(vstd::RNG & rand) const
 {
 	auto getObligatorySkills = [](CSkill::Obligatory obl){
 		std::set<SecondarySkill> obligatory;
@@ -1365,7 +1365,7 @@ std::vector<SecondarySkill> CGHeroInstance::getLevelUpProposedSecondarySkills(CR
 	return skills;
 }
 
-PrimarySkill CGHeroInstance::nextPrimarySkill(CRandomGenerator & rand) const
+PrimarySkill CGHeroInstance::nextPrimarySkill(vstd::RNG & rand) const
 {
 	assert(gainsLevel());
 	const auto isLowLevelHero = level < GameConstants::HERO_HIGH_LEVEL;
@@ -1381,7 +1381,7 @@ PrimarySkill CGHeroInstance::nextPrimarySkill(CRandomGenerator & rand) const
 	return static_cast<PrimarySkill>(RandomGeneratorUtil::nextItemWeighted(skillChances, rand));
 }
 
-std::optional<SecondarySkill> CGHeroInstance::nextSecondarySkill(CRandomGenerator & rand) const
+std::optional<SecondarySkill> CGHeroInstance::nextSecondarySkill(vstd::RNG & rand) const
 {
 	assert(gainsLevel());
 
@@ -1469,7 +1469,7 @@ void CGHeroInstance::levelUp(const std::vector<SecondarySkill> & skills)
 	treeHasChanged();
 }
 
-void CGHeroInstance::levelUpAutomatically(CRandomGenerator & rand)
+void CGHeroInstance::levelUpAutomatically(vstd::RNG & rand)
 {
 	while(gainsLevel())
 	{

+ 11 - 11
lib/mapObjects/CGHeroInstance.h

@@ -187,13 +187,13 @@ public:
 	bool gainsLevel() const;
 
 	/// Returns the next primary skill on level up. Can only be called if hero can gain a level up.
-	PrimarySkill nextPrimarySkill(CRandomGenerator & rand) const;
+	PrimarySkill nextPrimarySkill(vstd::RNG & rand) const;
 
 	/// Returns the next secondary skill randomly on level up. Can only be called if hero can gain a level up.
-	std::optional<SecondarySkill> nextSecondarySkill(CRandomGenerator & rand) const;
+	std::optional<SecondarySkill> nextSecondarySkill(vstd::RNG & rand) const;
 
 	/// Gets 0, 1 or 2 secondary skills which are proposed on hero level up.
-	std::vector<SecondarySkill> getLevelUpProposedSecondarySkills(CRandomGenerator & rand) const;
+	std::vector<SecondarySkill> getLevelUpProposedSecondarySkills(vstd::RNG & rand) const;
 
 	ui8 getSecSkillLevel(const SecondarySkill & skill) const; //0 - no skill
 
@@ -225,7 +225,7 @@ public:
 	TExpType calculateXp(TExpType exp) const; //apply learning skill
 
 	CStackBasicDescriptor calculateNecromancy (const BattleResult &battleResult) const;
-	void showNecromancyDialog(const CStackBasicDescriptor &raisedStack, CRandomGenerator & rand) const;
+	void showNecromancyDialog(const CStackBasicDescriptor &raisedStack, vstd::RNG & rand) const;
 	EDiggingStatus diggingStatus() const;
 
 	//////////////////////////////////////////////////////////////////////////
@@ -233,13 +233,13 @@ public:
 	HeroTypeID getHeroType() const;
 	void setHeroType(HeroTypeID type);
 
-	void initHero(CRandomGenerator & rand);
-	void initHero(CRandomGenerator & rand, const HeroTypeID & SUBID);
+	void initHero(vstd::RNG & rand);
+	void initHero(vstd::RNG & rand, const HeroTypeID & SUBID);
 
 	ArtPlacementMap putArtifact(ArtifactPosition pos, CArtifactInstance * art) override;
 	void removeArtifact(ArtifactPosition pos) override;
-	void initExp(CRandomGenerator & rand);
-	void initArmy(CRandomGenerator & rand, IArmyDescriptor *dst = nullptr);
+	void initExp(vstd::RNG & rand);
+	void initArmy(vstd::RNG & rand, IArmyDescriptor *dst = nullptr);
 	void pushPrimSkill(PrimarySkill which, int val);
 	ui8 maxlevelsToMagicSchool() const;
 	ui8 maxlevelsToWisdom() const;
@@ -293,8 +293,8 @@ public:
 	void boatDeserializationFix();
 	void deserializationFix();
 
-	void initObj(CRandomGenerator & rand) override;
-	void pickRandomObject(CRandomGenerator & rand) override;
+	void initObj(vstd::RNG & rand) override;
+	void pickRandomObject(vstd::RNG & rand) override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	std::string getObjectName() const override;
 
@@ -318,7 +318,7 @@ protected:
 	void serializeJsonOptions(JsonSerializeFormat & handler) override;
 
 private:
-	void levelUpAutomatically(CRandomGenerator & rand);
+	void levelUpAutomatically(vstd::RNG & rand);
 
 public:
 	std::string getHeroTypeName() const;

+ 2 - 2
lib/mapObjects/CGMarket.cpp

@@ -23,7 +23,7 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-void CGMarket::initObj(CRandomGenerator & rand)
+void CGMarket::initObj(vstd::RNG & rand)
 {
 	getObjectHandler()->configureObject(this, rand);
 }
@@ -80,7 +80,7 @@ std::vector<TradeItemBuy> CGBlackMarket::availableItemsIds(EMarketMode mode) con
 	}
 }
 
-void CGBlackMarket::newTurn(CRandomGenerator & rand) const
+void CGBlackMarket::newTurn(vstd::RNG & rand) const
 {
 	int resetPeriod = VLC->settings()->getInteger(EGameSettings::MARKETS_BLACK_MARKET_RESTOCK_PERIOD);
 

+ 2 - 2
lib/mapObjects/CGMarket.h

@@ -29,7 +29,7 @@ public:
 	CGMarket(IGameCallback *cb);
 	///IObjectInterface
 	void onHeroVisit(const CGHeroInstance * h) const override; //open trading window
-	void initObj(CRandomGenerator & rand) override;//set skills for trade
+	void initObj(vstd::RNG & rand) override;//set skills for trade
 
 	///IMarket
 	int getMarketEfficiency() const override;
@@ -54,7 +54,7 @@ public:
 
 	std::vector<const CArtifact *> artifacts; //available artifacts
 
-	void newTurn(CRandomGenerator & rand) const override; //reset artifacts for black market every month
+	void newTurn(vstd::RNG & rand) const override; //reset artifacts for black market every month
 	std::vector<TradeItemBuy> availableItemsIds(EMarketMode mode) const override;
 
 	template <typename Handler> void serialize(Handler &h)

+ 9 - 7
lib/mapObjects/CGObjectInstance.cpp

@@ -25,6 +25,8 @@
 #include "../networkPacks/PacksForClient.h"
 #include "../serializer/JsonSerializeFormat.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 //TODO: remove constructor
@@ -164,12 +166,12 @@ void CGObjectInstance::setType(MapObjectID newID, MapObjectSubID newSubID)
 	cb->gameState()->map->addBlockVisTiles(this);
 }
 
-void CGObjectInstance::pickRandomObject(CRandomGenerator & rand)
+void CGObjectInstance::pickRandomObject(vstd::RNG & rand)
 {
 	// no-op
 }
 
-void CGObjectInstance::initObj(CRandomGenerator & rand)
+void CGObjectInstance::initObj(vstd::RNG & rand)
 {
 	// no-op
 }
@@ -232,7 +234,7 @@ std::string CGObjectInstance::getObjectName() const
 	return VLC->objtypeh->getObjectName(ID, subID);
 }
 
-std::optional<AudioPath> CGObjectInstance::getAmbientSound() const
+std::optional<AudioPath> CGObjectInstance::getAmbientSound(vstd::RNG & rng) const
 {
 	const auto & sounds = VLC->objtypeh->getObjectSounds(ID, subID).ambient;
 	if(!sounds.empty())
@@ -241,20 +243,20 @@ std::optional<AudioPath> CGObjectInstance::getAmbientSound() const
 	return std::nullopt;
 }
 
-std::optional<AudioPath> CGObjectInstance::getVisitSound() const
+std::optional<AudioPath> CGObjectInstance::getVisitSound(vstd::RNG & rng) const
 {
 	const auto & sounds = VLC->objtypeh->getObjectSounds(ID, subID).visit;
 	if(!sounds.empty())
-		return *RandomGeneratorUtil::nextItem(sounds, CRandomGenerator::getDefault());
+		return *RandomGeneratorUtil::nextItem(sounds, rng);
 
 	return std::nullopt;
 }
 
-std::optional<AudioPath> CGObjectInstance::getRemovalSound() const
+std::optional<AudioPath> CGObjectInstance::getRemovalSound(vstd::RNG & rng) const
 {
 	const auto & sounds = VLC->objtypeh->getObjectSounds(ID, subID).removal;
 	if(!sounds.empty())
-		return *RandomGeneratorUtil::nextItem(sounds, CRandomGenerator::getDefault());
+		return *RandomGeneratorUtil::nextItem(sounds, rng);
 
 	return std::nullopt;
 }

+ 5 - 5
lib/mapObjects/CGObjectInstance.h

@@ -97,9 +97,9 @@ public:
 
 	virtual bool isTile2Terrain() const { return false; }
 
-	std::optional<AudioPath> getAmbientSound() const;
-	std::optional<AudioPath> getVisitSound() const;
-	std::optional<AudioPath> getRemovalSound() const;
+	std::optional<AudioPath> getAmbientSound(vstd::RNG & rng) const;
+	std::optional<AudioPath> getVisitSound(vstd::RNG & rng) const;
+	std::optional<AudioPath> getRemovalSound(vstd::RNG & rng) const;
 
 	TObjectTypeHandler getObjectHandler() const;
 
@@ -128,8 +128,8 @@ public:
 
 	/** OVERRIDES OF IObjectInterface **/
 
-	void initObj(CRandomGenerator & rand) override;
-	void pickRandomObject(CRandomGenerator & rand) override;
+	void initObj(vstd::RNG & rand) override;
+	void pickRandomObject(vstd::RNG & rand) override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	/// method for synchronous update. Note: For new properties classes should override setPropertyDer instead
 	void setProperty(ObjProperty what, ObjPropertyID identifier) final;

+ 1 - 1
lib/mapObjects/CGPandoraBox.cpp

@@ -41,7 +41,7 @@ void CGPandoraBox::init()
 	}
 }
 
-void CGPandoraBox::initObj(CRandomGenerator & rand)
+void CGPandoraBox::initObj(vstd::RNG & rand)
 {
 	init();
 	

+ 1 - 1
lib/mapObjects/CGPandoraBox.h

@@ -23,7 +23,7 @@ public:
 
 	MetaString message;
 
-	void initObj(CRandomGenerator & rand) override;
+	void initObj(vstd::RNG & rand) override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
 	void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;

+ 5 - 3
lib/mapObjects/CGTownBuilding.cpp

@@ -17,6 +17,8 @@
 #include "../mapObjects/CGHeroInstance.h"
 #include "../networkPacks/PacksForClient.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 CGTownBuilding::CGTownBuilding(IGameCallback * cb)
@@ -314,7 +316,7 @@ CTownRewardableBuilding::CTownRewardableBuilding(IGameCallback *cb)
 	: CGTownBuilding(cb)
 {}
 
-CTownRewardableBuilding::CTownRewardableBuilding(const BuildingID & index, BuildingSubID::EBuildingSubID subId, CGTownInstance * cgTown, CRandomGenerator & rand)
+CTownRewardableBuilding::CTownRewardableBuilding(const BuildingID & index, BuildingSubID::EBuildingSubID subId, CGTownInstance * cgTown, vstd::RNG & rand)
 	: CGTownBuilding(cgTown)
 {
 	bID = index;
@@ -323,7 +325,7 @@ CTownRewardableBuilding::CTownRewardableBuilding(const BuildingID & index, Build
 	initObj(rand);
 }
 
-void CTownRewardableBuilding::initObj(CRandomGenerator & rand)
+void CTownRewardableBuilding::initObj(vstd::RNG & rand)
 {
 	assert(town && town->town);
 
@@ -340,7 +342,7 @@ void CTownRewardableBuilding::initObj(CRandomGenerator & rand)
 	}
 }
 
-void CTownRewardableBuilding::newTurn(CRandomGenerator & rand) const
+void CTownRewardableBuilding::newTurn(vstd::RNG & rand) const
 {
 	if (configuration.resetParameters.period != 0 && cb->getDate(Date::DAY) > 1 && ((cb->getDate(Date::DAY)-1) % configuration.resetParameters.period) == 0)
 	{

+ 3 - 3
lib/mapObjects/CGTownBuilding.h

@@ -123,17 +123,17 @@ public:
 	void setProperty(ObjProperty what, ObjPropertyID identifier) override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	
-	void newTurn(CRandomGenerator & rand) const override;
+	void newTurn(vstd::RNG & rand) const override;
 	
 	/// gives second part of reward after hero level-ups for proper granting of spells/mana
 	void heroLevelUpDone(const CGHeroInstance *hero) const override;
 	
-	void initObj(CRandomGenerator & rand) override;
+	void initObj(vstd::RNG & rand) override;
 	
 	/// applies player selection of reward
 	void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
 	
-	CTownRewardableBuilding(const BuildingID & index, BuildingSubID::EBuildingSubID subId, CGTownInstance * town, CRandomGenerator & rand);
+	CTownRewardableBuilding(const BuildingID & index, BuildingSubID::EBuildingSubID subId, CGTownInstance * town, vstd::RNG & rand);
 	CTownRewardableBuilding(IGameCallback *cb);
 	
 	template <typename Handler> void serialize(Handler &h)

+ 7 - 5
lib/mapObjects/CGTownInstance.cpp

@@ -31,6 +31,8 @@
 #include "../networkPacks/PacksForClientBattle.h"
 #include "../serializer/JsonSerializeFormat.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 int CGTownInstance::getSightRadius() const //returns sight distance
@@ -379,7 +381,7 @@ bool CGTownInstance::isBonusingBuildingAdded(BuildingID bid) const
 	return present != bonusingBuildings.end();
 }
 
-void CGTownInstance::addTownBonuses(CRandomGenerator & rand)
+void CGTownInstance::addTownBonuses(vstd::RNG & rand)
 {
 	for(const auto & kvp : town->buildings)
 	{
@@ -461,7 +463,7 @@ void CGTownInstance::deleteTownBonus(BuildingID bid)
 	delete freeIt;
 }
 
-FactionID CGTownInstance::randomizeFaction(CRandomGenerator & rand)
+FactionID CGTownInstance::randomizeFaction(vstd::RNG & rand)
 {
 	if(getOwner().isValidPlayer())
 		return cb->gameState()->scenarioOps->getIthPlayersSettings(getOwner()).castle;
@@ -479,7 +481,7 @@ FactionID CGTownInstance::randomizeFaction(CRandomGenerator & rand)
 	return *RandomGeneratorUtil::nextItem(potentialPicks, rand);
 }
 
-void CGTownInstance::pickRandomObject(CRandomGenerator & rand)
+void CGTownInstance::pickRandomObject(vstd::RNG & rand)
 {
 	assert(ID == MapObjectID::TOWN || ID == MapObjectID::RANDOM_TOWN);
 	if (ID == MapObjectID::RANDOM_TOWN)
@@ -495,7 +497,7 @@ void CGTownInstance::pickRandomObject(CRandomGenerator & rand)
 	updateAppearance();
 }
 
-void CGTownInstance::initObj(CRandomGenerator & rand) ///initialize town structures
+void CGTownInstance::initObj(vstd::RNG & rand) ///initialize town structures
 {
 	blockVisit = true;
 
@@ -521,7 +523,7 @@ void CGTownInstance::initObj(CRandomGenerator & rand) ///initialize town structu
 	updateAppearance();
 }
 
-void CGTownInstance::newTurn(CRandomGenerator & rand) const
+void CGTownInstance::newTurn(vstd::RNG & rand) const
 {
 	if (cb->getDate(Date::DAY_OF_WEEK) == 1) //reset on new week
 	{

+ 5 - 5
lib/mapObjects/CGTownInstance.h

@@ -201,11 +201,11 @@ public:
 	virtual ~CGTownInstance();
 
 	///IObjectInterface overrides
-	void newTurn(CRandomGenerator & rand) const override;
+	void newTurn(vstd::RNG & rand) const override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	void onHeroLeave(const CGHeroInstance * h) const override;
-	void initObj(CRandomGenerator & rand) override;
-	void pickRandomObject(CRandomGenerator & rand) override;
+	void initObj(vstd::RNG & rand) override;
+	void pickRandomObject(vstd::RNG & rand) override;
 	void battleFinished(const CGHeroInstance * hero, const BattleResult & result) const override;
 	std::string getObjectName() const override;
 
@@ -224,14 +224,14 @@ protected:
 	void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
 
 private:
-	FactionID randomizeFaction(CRandomGenerator & rand);
+	FactionID randomizeFaction(vstd::RNG & rand);
 	void setOwner(const PlayerColor & owner) const;
 	void onTownCaptured(const PlayerColor & winner) const;
 	int getDwellingBonus(const std::vector<CreatureID>& creatureIds, const std::vector<ConstTransitivePtr<CGDwelling> >& dwellings) const;
 	bool townEnvisagesBuilding(BuildingSubID::EBuildingSubID bid) const;
 	bool isBonusingBuildingAdded(BuildingID bid) const;
 	void initOverriddenBids();
-	void addTownBonuses(CRandomGenerator & rand);
+	void addTownBonuses(vstd::RNG & rand);
 };
 
 VCMI_LIB_NAMESPACE_END

+ 7 - 6
lib/mapObjects/CQuest.cpp

@@ -31,7 +31,8 @@
 #include "../modding/ModUtility.h"
 #include "../networkPacks/PacksForClient.h"
 #include "../spells/CSpellHandler.h"
-#include "../CRandomGenerator.h"
+
+#include <vstd/RNG.h>
 
 VCMI_LIB_NAMESPACE_BEGIN
 
@@ -441,7 +442,7 @@ void CGSeerHut::setObjToKill()
 	}
 }
 
-void CGSeerHut::init(CRandomGenerator & rand)
+void CGSeerHut::init(vstd::RNG & rand)
 {
 	auto names = VLC->generaltexth->findStringsWithPrefix("core.seerhut.names");
 
@@ -455,7 +456,7 @@ void CGSeerHut::init(CRandomGenerator & rand)
 	configuration.selectMode = Rewardable::ESelectMode::SELECT_PLAYER;
 }
 
-void CGSeerHut::initObj(CRandomGenerator & rand)
+void CGSeerHut::initObj(vstd::RNG & rand)
 {
 	init(rand);
 	
@@ -562,7 +563,7 @@ void CGSeerHut::setPropertyDer(ObjProperty what, ObjPropertyID identifier)
 	}
 }
 
-void CGSeerHut::newTurn(CRandomGenerator & rand) const
+void CGSeerHut::newTurn(vstd::RNG & rand) const
 {
 	CRewardableObject::newTurn(rand);
 	if(quest->lastDay >= 0 && quest->lastDay <= cb->getDate() - 1) //time is up
@@ -750,7 +751,7 @@ void CGSeerHut::serializeJsonOptions(JsonSerializeFormat & handler)
 	}
 }
 
-void CGQuestGuard::init(CRandomGenerator & rand)
+void CGQuestGuard::init(vstd::RNG & rand)
 {
 	blockVisit = true;
 	quest->textOption = rand.nextInt(3, 5);
@@ -818,7 +819,7 @@ void CGKeymasterTent::onHeroVisit( const CGHeroInstance * h ) const
 	h->showInfoDialog(txt_id);
 }
 
-void CGBorderGuard::initObj(CRandomGenerator & rand)
+void CGBorderGuard::initObj(vstd::RNG & rand)
 {
 	blockVisit = true;
 }

+ 5 - 5
lib/mapObjects/CQuest.h

@@ -141,19 +141,19 @@ public:
 
 	std::string seerName;
 
-	void initObj(CRandomGenerator & rand) override;
+	void initObj(vstd::RNG & rand) override;
 	std::string getHoverText(PlayerColor player) const override;
 	std::string getHoverText(const CGHeroInstance * hero) const override;
 	std::string getPopupText(PlayerColor player) const override;
 	std::string getPopupText(const CGHeroInstance * hero) const override;
 	std::vector<Component> getPopupComponents(PlayerColor player) const override;
 	std::vector<Component> getPopupComponents(const CGHeroInstance * hero) const override;
-	void newTurn(CRandomGenerator & rand) const override;
+	void newTurn(vstd::RNG & rand) const override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
 	void getVisitText (MetaString &text, std::vector<Component> &components, bool FirstVisit, const CGHeroInstance * h = nullptr) const override;
 
-	virtual void init(CRandomGenerator & rand);
+	virtual void init(vstd::RNG & rand);
 	int checkDirection() const; //calculates the region of map where monster is placed
 	void setObjToKill(); //remember creatures / heroes to kill after they are initialized
 	const CGHeroInstance *getHeroToKill(bool allowNull) const;
@@ -179,7 +179,7 @@ class DLL_LINKAGE CGQuestGuard : public CGSeerHut
 public:
 	using CGSeerHut::CGSeerHut;
 
-	void init(CRandomGenerator & rand) override;
+	void init(vstd::RNG & rand) override;
 	
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	bool passableFor(PlayerColor color) const override;
@@ -227,7 +227,7 @@ class DLL_LINKAGE CGBorderGuard : public CGKeys, public IQuestObject
 public:
 	using CGKeys::CGKeys;
 
-	void initObj(CRandomGenerator & rand) override;
+	void initObj(vstd::RNG & rand) override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
 

+ 4 - 2
lib/mapObjects/CRewardableObject.cpp

@@ -20,6 +20,8 @@
 #include "../networkPacks/PacksForClient.h"
 #include "../serializer/JsonSerializeFormat.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 void CRewardableObject::grantRewardWithMessage(const CGHeroInstance * contextHero, int index, bool markAsVisit) const
@@ -387,7 +389,7 @@ void CRewardableObject::setPropertyDer(ObjProperty what, ObjPropertyID identifie
 	}
 }
 
-void CRewardableObject::newTurn(CRandomGenerator & rand) const
+void CRewardableObject::newTurn(vstd::RNG & rand) const
 {
 	if (configuration.resetParameters.period != 0 && cb->getDate(Date::DAY) > 1 && ((cb->getDate(Date::DAY)-1) % configuration.resetParameters.period) == 0)
 	{
@@ -404,7 +406,7 @@ void CRewardableObject::newTurn(CRandomGenerator & rand) const
 	}
 }
 
-void CRewardableObject::initObj(CRandomGenerator & rand)
+void CRewardableObject::initObj(vstd::RNG & rand)
 {
 	getObjectHandler()->configureObject(this, rand);
 }

+ 2 - 2
lib/mapObjects/CRewardableObject.h

@@ -57,7 +57,7 @@ public:
 	void onHeroVisit(const CGHeroInstance *h) const override;
 
 	///possibly resets object state
-	void newTurn(CRandomGenerator & rand) const override;
+	void newTurn(vstd::RNG & rand) const override;
 
 	/// gives second part of reward after hero level-ups for proper granting of spells/mana
 	void heroLevelUpDone(const CGHeroInstance *hero) const override;
@@ -65,7 +65,7 @@ public:
 	/// applies player selection of reward
 	void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
 
-	void initObj(CRandomGenerator & rand) override;
+	void initObj(vstd::RNG & rand) override;
 	
 	void setPropertyDer(ObjProperty what, ObjPropertyID identifier) override;
 

+ 3 - 3
lib/mapObjects/IObjectInterface.cpp

@@ -38,13 +38,13 @@ void IObjectInterface::onHeroVisit(const CGHeroInstance * h) const
 void IObjectInterface::onHeroLeave(const CGHeroInstance * h) const
 {}
 
-void IObjectInterface::newTurn(CRandomGenerator & rand) const
+void IObjectInterface::newTurn(vstd::RNG & rand) const
 {}
 
-void IObjectInterface::initObj(CRandomGenerator & rand)
+void IObjectInterface::initObj(vstd::RNG & rand)
 {}
 
-void IObjectInterface::pickRandomObject(CRandomGenerator & rand)
+void IObjectInterface::pickRandomObject(vstd::RNG & rand)
 {}
 
 void IObjectInterface::setProperty(ObjProperty what, ObjPropertyID identifier)

+ 8 - 4
lib/mapObjects/IObjectInterface.h

@@ -17,11 +17,15 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
+namespace vstd
+{
+class RNG;
+}
+
 struct BattleResult;
 struct UpgradeInfo;
 class BoatId;
 class CGObjectInstance;
-class CRandomGenerator;
 class CStackInstance;
 class CGHeroInstance;
 class IGameCallback;
@@ -46,9 +50,9 @@ public:
 
 	virtual void onHeroVisit(const CGHeroInstance * h) const;
 	virtual void onHeroLeave(const CGHeroInstance * h) const;
-	virtual void newTurn(CRandomGenerator & rand) const;
-	virtual void initObj(CRandomGenerator & rand); //synchr
-	virtual void pickRandomObject(CRandomGenerator & rand);
+	virtual void newTurn(vstd::RNG & rand) const;
+	virtual void initObj(vstd::RNG & rand); //synchr
+	virtual void pickRandomObject(vstd::RNG & rand);
 	virtual void setProperty(ObjProperty what, ObjPropertyID identifier);//synchr
 
 	//Called when queries created DURING HERO VISIT are resolved

+ 19 - 17
lib/mapObjects/MiscObjects.cpp

@@ -32,6 +32,8 @@
 #include "../networkPacks/PacksForClientBattle.h"
 #include "../networkPacks/StackLocation.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 ///helpers
@@ -93,7 +95,7 @@ void CGMine::onHeroVisit( const CGHeroInstance * h ) const
 
 }
 
-void CGMine::newTurn(CRandomGenerator & rand) const
+void CGMine::newTurn(vstd::RNG & rand) const
 {
 	if(cb->getDate() == 1)
 		return;
@@ -104,7 +106,7 @@ void CGMine::newTurn(CRandomGenerator & rand) const
 	cb->giveResource(tempOwner, producedResource, producedQuantity);
 }
 
-void CGMine::initObj(CRandomGenerator & rand)
+void CGMine::initObj(vstd::RNG & rand)
 {
 	if(isAbandoned())
 	{
@@ -254,7 +256,7 @@ std::string CGResource::getHoverText(PlayerColor player) const
 	return VLC->generaltexth->restypes[resourceID().getNum()];
 }
 
-void CGResource::pickRandomObject(CRandomGenerator & rand)
+void CGResource::pickRandomObject(vstd::RNG & rand)
 {
 	assert(ID == Obj::RESOURCE || ID == Obj::RANDOM_RESOURCE);
 
@@ -269,7 +271,7 @@ void CGResource::pickRandomObject(CRandomGenerator & rand)
 	}
 }
 
-void CGResource::initObj(CRandomGenerator & rand)
+void CGResource::initObj(vstd::RNG & rand)
 {
 	blockVisit = true;
 
@@ -327,7 +329,7 @@ void CGResource::collectRes(const PlayerColor & player) const
 		sii.text.replaceName(resourceID());
 	}
 	sii.components.emplace_back(ComponentType::RESOURCE, resourceID(), amount);
-	sii.soundID = soundBase::pickup01 + CRandomGenerator::getDefault().nextInt(6);
+	sii.soundID = soundBase::pickup01 + cb->gameState()->getRandomGenerator().nextInt(6);
 	cb->showInfoDialog(&sii);
 	cb->removeObject(this, player);
 }
@@ -395,7 +397,7 @@ ObjectInstanceID CGTeleport::getRandomExit(const CGHeroInstance * h) const
 {
 	auto passableExits = getPassableExits(cb->gameState(), h, getAllExits(true));
 	if(!passableExits.empty())
-		return *RandomGeneratorUtil::nextItem(passableExits, CRandomGenerator::getDefault());
+		return *RandomGeneratorUtil::nextItem(passableExits, cb->gameState()->getRandomGenerator());
 
 	return ObjectInstanceID();
 }
@@ -530,7 +532,7 @@ void CGMonolith::teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer,
 	cb->moveHero(hero->id, hero->convertFromVisitablePos(dPos), EMovementMode::MONOLITH);
 }
 
-void CGMonolith::initObj(CRandomGenerator & rand)
+void CGMonolith::initObj(vstd::RNG & rand)
 {
 	std::vector<Obj> IDs;
 	IDs.push_back(ID);
@@ -575,7 +577,7 @@ void CGSubterraneanGate::onHeroVisit( const CGHeroInstance * h ) const
 	cb->showTeleportDialog(&td);
 }
 
-void CGSubterraneanGate::initObj(CRandomGenerator & rand)
+void CGSubterraneanGate::initObj(vstd::RNG & rand)
 {
 	type = BOTH;
 }
@@ -703,7 +705,7 @@ void CGWhirlpool::teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer
 
 		const auto * obj = cb->getObj(exit);
 		std::set<int3> tiles = obj->getBlockedPos();
-		dPos = *RandomGeneratorUtil::nextItem(tiles, CRandomGenerator::getDefault());
+		dPos = *RandomGeneratorUtil::nextItem(tiles, cb->gameState()->getRandomGenerator()));
 	}
 
 	cb->moveHero(hero->id, hero->convertFromVisitablePos(dPos), EMovementMode::MONOLITH);
@@ -724,7 +726,7 @@ ArtifactID CGArtifact::getArtifact() const
 		return getObjTypeIndex().getNum();
 }
 
-void CGArtifact::pickRandomObject(CRandomGenerator & rand)
+void CGArtifact::pickRandomObject(vstd::RNG & rand)
 {
 	switch(ID.toEnum())
 	{
@@ -754,7 +756,7 @@ void CGArtifact::pickRandomObject(CRandomGenerator & rand)
 		ID = MapObjectID::ARTIFACT;
 }
 
-void CGArtifact::initObj(CRandomGenerator & rand)
+void CGArtifact::initObj(vstd::RNG & rand)
 {
 	blockVisit = true;
 	if(ID == Obj::ARTIFACT)
@@ -936,7 +938,7 @@ void CGArtifact::serializeJsonOptions(JsonSerializeFormat& handler)
 	}
 }
 
-void CGSignBottle::initObj(CRandomGenerator & rand)
+void CGSignBottle::initObj(vstd::RNG & rand)
 {
 	//if no text is set than we pick random from the predefined ones
 	if(message.empty())
@@ -1011,7 +1013,7 @@ void CGGarrison::serializeJsonOptions(JsonSerializeFormat& handler)
 	CArmedInstance::serializeJsonOptions(handler);
 }
 
-void CGGarrison::initObj(CRandomGenerator &rand)
+void CGGarrison::initObj(vstd::RNG &rand)
 {
 	if(this->subID == MapObjectSubID::decode(this->ID, "antiMagic"))
 		addAntimagicGarrisonBonus();
@@ -1028,7 +1030,7 @@ void CGGarrison::addAntimagicGarrisonBonus()
 	this->addNewBonus(bonus);
 }
 
-void CGMagi::initObj(CRandomGenerator & rand)
+void CGMagi::initObj(vstd::RNG & rand)
 {
 	if (ID == Obj::EYE_OF_MAGI)
 		blockVisit = true;
@@ -1091,7 +1093,7 @@ bool CGBoat::isCoastVisitable() const
 	return true;
 }
 
-void CGSirens::initObj(CRandomGenerator & rand)
+void CGSirens::initObj(vstd::RNG & rand)
 {
 	blockVisit = true;
 }
@@ -1238,7 +1240,7 @@ void CGObelisk::onHeroVisit( const CGHeroInstance * h ) const
 
 }
 
-void CGObelisk::initObj(CRandomGenerator & rand)
+void CGObelisk::initObj(vstd::RNG & rand)
 {
 	cb->gameState()->map->obeliskCount++;
 }
@@ -1291,7 +1293,7 @@ void CGLighthouse::onHeroVisit( const CGHeroInstance * h ) const
 	}
 }
 
-void CGLighthouse::initObj(CRandomGenerator & rand)
+void CGLighthouse::initObj(vstd::RNG & rand)
 {
 	if(tempOwner.isValidPlayer())
 	{

+ 14 - 14
lib/mapObjects/MiscObjects.h

@@ -48,7 +48,7 @@ public:
 	MetaString message;
 
 	void onHeroVisit(const CGHeroInstance * h) const override;
-	void initObj(CRandomGenerator & rand) override;
+	void initObj(vstd::RNG & rand) override;
 
 	template <typename Handler> void serialize(Handler &h)
 	{
@@ -66,7 +66,7 @@ public:
 
 	bool removableUnits;
 
-	void initObj(CRandomGenerator &rand) override;
+	void initObj(vstd::RNG &rand) override;
 	bool passableFor(PlayerColor color) const override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
@@ -99,8 +99,8 @@ public:
 	std::vector<Component> getPopupComponents(PlayerColor player) const override;
 
 	void pick( const CGHeroInstance * h ) const;
-	void initObj(CRandomGenerator & rand) override;
-	void pickRandomObject(CRandomGenerator & rand) override;
+	void initObj(vstd::RNG & rand) override;
+	void pickRandomObject(vstd::RNG & rand) override;
 
 	void afterAddToMap(CMap * map) override;
 	BattleField getBattlefield() const override;
@@ -129,8 +129,8 @@ public:
 	MetaString message;
 
 	void onHeroVisit(const CGHeroInstance * h) const override;
-	void initObj(CRandomGenerator & rand) override;
-	void pickRandomObject(CRandomGenerator & rand) override;
+	void initObj(vstd::RNG & rand) override;
+	void pickRandomObject(vstd::RNG & rand) override;
 	void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
 	void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
 	std::string getHoverText(PlayerColor player) const override;
@@ -166,8 +166,8 @@ private:
 	void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
 
 	void flagMine(const PlayerColor & player) const;
-	void newTurn(CRandomGenerator & rand) const override;
-	void initObj(CRandomGenerator & rand) override;
+	void newTurn(vstd::RNG & rand) const override;
+	void initObj(vstd::RNG & rand) override;
 
 	std::string getObjectName() const override;
 	std::string getHoverText(PlayerColor player) const override;
@@ -248,7 +248,7 @@ class DLL_LINKAGE CGMonolith : public CGTeleport
 protected:
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	void teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer, TTeleportExitsList exits) const override;
-	void initObj(CRandomGenerator & rand) override;
+	void initObj(vstd::RNG & rand) override;
 
 public:
 	using CGTeleport::CGTeleport;
@@ -262,7 +262,7 @@ public:
 class DLL_LINKAGE CGSubterraneanGate : public CGMonolith
 {
 	void onHeroVisit(const CGHeroInstance * h) const override;
-	void initObj(CRandomGenerator & rand) override;
+	void initObj(vstd::RNG & rand) override;
 
 public:
 	using CGMonolith::CGMonolith;
@@ -297,7 +297,7 @@ public:
 
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	std::string getHoverText(const CGHeroInstance * hero) const override;
-	void initObj(CRandomGenerator & rand) override;
+	void initObj(vstd::RNG & rand) override;
 
 	template <typename Handler> void serialize(Handler &h)
 	{
@@ -369,7 +369,7 @@ class DLL_LINKAGE CGMagi : public CGObjectInstance
 public:
 	using CGObjectInstance::CGObjectInstance;
 
-	void initObj(CRandomGenerator & rand) override;
+	void initObj(vstd::RNG & rand) override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
 
 	template <typename Handler> void serialize(Handler &h)
@@ -391,7 +391,7 @@ public:
 	using CTeamVisited::CTeamVisited;
 
 	void onHeroVisit(const CGHeroInstance * h) const override;
-	void initObj(CRandomGenerator & rand) override;
+	void initObj(vstd::RNG & rand) override;
 	std::string getHoverText(PlayerColor player) const override;
 
 	template <typename Handler> void serialize(Handler &h)
@@ -408,7 +408,7 @@ public:
 	using CGObjectInstance::CGObjectInstance;
 
 	void onHeroVisit(const CGHeroInstance * h) const override;
-	void initObj(CRandomGenerator & rand) override;
+	void initObj(vstd::RNG & rand) override;
 
 	template <typename Handler> void serialize(Handler &h)
 	{

+ 5 - 4
lib/mapping/CDrawRoadsOperation.cpp

@@ -12,11 +12,12 @@
 #include "CDrawRoadsOperation.h"
 #include "CMap.h"
 
-#include "../CRandomGenerator.h"
 #include "../RoadHandler.h"
 #include "../RiverHandler.h"
 #include "../VCMI_Lib.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 const std::vector<CDrawLinesOperation::LinePattern> CDrawLinesOperation::patterns =
@@ -155,7 +156,7 @@ static bool ruleIsAny(const std::string & rule)
 #endif
 
 ///CDrawLinesOperation
-CDrawLinesOperation::CDrawLinesOperation(CMap * map, CTerrainSelection terrainSel, CRandomGenerator * gen):
+CDrawLinesOperation::CDrawLinesOperation(CMap * map, CTerrainSelection terrainSel, vstd::RNG * gen):
 	CMapOperation(map),
 	terrainSel(std::move(terrainSel)),
 	gen(gen)
@@ -163,14 +164,14 @@ CDrawLinesOperation::CDrawLinesOperation(CMap * map, CTerrainSelection terrainSe
 }
 
 ///CDrawRoadsOperation
-CDrawRoadsOperation::CDrawRoadsOperation(CMap * map, const CTerrainSelection & terrainSel, RoadId roadType, CRandomGenerator * gen):
+CDrawRoadsOperation::CDrawRoadsOperation(CMap * map, const CTerrainSelection & terrainSel, RoadId roadType, vstd::RNG * gen):
 	CDrawLinesOperation(map, terrainSel,gen),
 	roadType(roadType)
 {
 }
 
 ///CDrawRiversOperation
-CDrawRiversOperation::CDrawRiversOperation(CMap * map, const CTerrainSelection & terrainSel, RiverId riverType, CRandomGenerator * gen):
+CDrawRiversOperation::CDrawRiversOperation(CMap * map, const CTerrainSelection & terrainSel, RiverId riverType, vstd::RNG * gen):
 	CDrawLinesOperation(map, terrainSel, gen),
 	riverType(riverType)
 {

+ 4 - 4
lib/mapping/CDrawRoadsOperation.h

@@ -41,7 +41,7 @@ protected:
 		int flip;
 	};
 
-	CDrawLinesOperation(CMap * map, CTerrainSelection terrainSel, CRandomGenerator * gen);
+	CDrawLinesOperation(CMap * map, CTerrainSelection terrainSel, vstd::RNG * gen);
 
 	virtual void executeTile(TerrainTile & tile) = 0;
 	virtual bool canApplyPattern(const CDrawLinesOperation::LinePattern & pattern) const = 0;
@@ -58,13 +58,13 @@ protected:
 	ValidationResult validateTile(const LinePattern & pattern, const int3 & pos);
 	
 	CTerrainSelection terrainSel;
-	CRandomGenerator * gen;
+	vstd::RNG * gen;
 };
 
 class CDrawRoadsOperation : public CDrawLinesOperation
 {
 public:
-	CDrawRoadsOperation(CMap * map, const CTerrainSelection & terrainSel, RoadId roadType, CRandomGenerator * gen);
+	CDrawRoadsOperation(CMap * map, const CTerrainSelection & terrainSel, RoadId roadType, vstd::RNG * gen);
 	std::string getLabel() const override;
 	
 protected:
@@ -81,7 +81,7 @@ private:
 class CDrawRiversOperation : public CDrawLinesOperation
 {
 public:
-	CDrawRiversOperation(CMap * map, const CTerrainSelection & terrainSel, RiverId roadType, CRandomGenerator * gen);
+	CDrawRiversOperation(CMap * map, const CTerrainSelection & terrainSel, RiverId roadType, vstd::RNG * gen);
 	std::string getLabel() const override;
 	
 protected:

+ 2 - 0
lib/mapping/CMap.cpp

@@ -29,6 +29,8 @@
 #include "CMapOperation.h"
 #include "../serializer/JsonSerializeFormat.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 void Rumor::serializeJson(JsonSerializeFormat & handler)

+ 10 - 8
lib/mapping/CMapEditManager.cpp

@@ -15,6 +15,8 @@
 #include "CDrawRoadsOperation.h"
 #include "CMapOperation.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 CMapUndoManager::CMapUndoManager() :
@@ -121,26 +123,26 @@ CMap * CMapEditManager::getMap()
 	return map;
 }
 
-void CMapEditManager::clearTerrain(CRandomGenerator * gen)
+void CMapEditManager::clearTerrain(vstd::RNG * gen)
 {
-	execute(std::make_unique<CClearTerrainOperation>(map, gen ? gen : &(this->gen)));
+	execute(std::make_unique<CClearTerrainOperation>(map, gen ? gen : this->gen.get()));
 }
 
-void CMapEditManager::drawTerrain(TerrainId terType, int decorationsPercentage, CRandomGenerator * gen)
+void CMapEditManager::drawTerrain(TerrainId terType, int decorationsPercentage, vstd::RNG * gen)
 {
-	execute(std::make_unique<CDrawTerrainOperation>(map, terrainSel, terType, decorationsPercentage, gen ? gen : &(this->gen)));
+	execute(std::make_unique<CDrawTerrainOperation>(map, terrainSel, terType, decorationsPercentage, gen ? gen : this->gen.get()));
 	terrainSel.clearSelection();
 }
 
-void CMapEditManager::drawRoad(RoadId roadType, CRandomGenerator* gen)
+void CMapEditManager::drawRoad(RoadId roadType, vstd::RNG* gen)
 {
-	execute(std::make_unique<CDrawRoadsOperation>(map, terrainSel, roadType, gen ? gen : &(this->gen)));
+	execute(std::make_unique<CDrawRoadsOperation>(map, terrainSel, roadType, gen ? gen : this->gen.get()));
 	terrainSel.clearSelection();
 }
 
-void CMapEditManager::drawRiver(RiverId riverType, CRandomGenerator* gen)
+void CMapEditManager::drawRiver(RiverId riverType, vstd::RNG* gen)
 {
-	execute(std::make_unique<CDrawRiversOperation>(map, terrainSel, riverType, gen ? gen : &(this->gen)));
+	execute(std::make_unique<CDrawRiversOperation>(map, terrainSel, riverType, gen ? gen : this->gen.get()));
 	terrainSel.clearSelection();
 }
 

+ 10 - 6
lib/mapping/CMapEditManager.h

@@ -11,13 +11,17 @@
 #pragma once
 
 #include "../GameConstants.h"
-#include "../CRandomGenerator.h"
 #include "MapEditUtils.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 
 class CMapOperation;
 
+namespace vstd
+{
+class RNG;
+}
+
 /// The CMapUndoManager provides the functionality to save operations and undo/redo them.
 class DLL_LINKAGE CMapUndoManager : boost::noncopyable
 {
@@ -67,16 +71,16 @@ public:
 	CMap * getMap();
 
 	/// Clears the terrain. The free level is filled with water and the underground level with rock.
-	void clearTerrain(CRandomGenerator * gen = nullptr);
+	void clearTerrain(vstd::RNG * gen = nullptr);
 
 	/// Draws terrain at the current terrain selection. The selection will be cleared automatically.
-	void drawTerrain(TerrainId terType, int decorationsPercentage, CRandomGenerator * gen = nullptr);
+	void drawTerrain(TerrainId terType, int decorationsPercentage, vstd::RNG * gen = nullptr);
 
 	/// Draws roads at the current terrain selection. The selection will be cleared automatically.
-	void drawRoad(RoadId roadType, CRandomGenerator * gen = nullptr);
+	void drawRoad(RoadId roadType, vstd::RNG * gen = nullptr);
 	
 	/// Draws rivers at the current terrain selection. The selection will be cleared automatically.
-	void drawRiver(RiverId riverType, CRandomGenerator * gen = nullptr);
+	void drawRiver(RiverId riverType, vstd::RNG * gen = nullptr);
 
 	void insertObject(CGObjectInstance * obj);
 	void insertObjects(std::set<CGObjectInstance *> & objects);
@@ -94,7 +98,7 @@ private:
 
 	CMap * map;
 	CMapUndoManager undoManager;
-	CRandomGenerator gen;
+	std::unique_ptr<vstd::RNG> gen;
 	CTerrainSelection terrainSel;
 	CObjectSelection objectSel;
 };

+ 4 - 3
lib/mapping/CMapOperation.cpp

@@ -12,12 +12,13 @@
 #include "CMapOperation.h"
 
 #include "../VCMI_Lib.h"
-#include "../CRandomGenerator.h"
 #include "../TerrainHandler.h"
 #include "../mapObjects/CGObjectInstance.h"
 #include "CMap.h"
 #include "MapEditUtils.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 CMapOperation::CMapOperation(CMap* map) : map(map)
@@ -87,7 +88,7 @@ void CComposedOperation::addOperation(std::unique_ptr<CMapOperation>&& operation
 	operations.push_back(std::move(operation));
 }
 
-CDrawTerrainOperation::CDrawTerrainOperation(CMap * map, CTerrainSelection terrainSel, TerrainId terType, int decorationsPercentage, CRandomGenerator * gen):
+CDrawTerrainOperation::CDrawTerrainOperation(CMap * map, CTerrainSelection terrainSel, TerrainId terType, int decorationsPercentage, vstd::RNG * gen):
 	CMapOperation(map),
 	terrainSel(std::move(terrainSel)),
 	terType(terType),
@@ -560,7 +561,7 @@ CDrawTerrainOperation::ValidationResult::ValidationResult(bool result, std::stri
 
 }
 
-CClearTerrainOperation::CClearTerrainOperation(CMap* map, CRandomGenerator* gen) : CComposedOperation(map)
+CClearTerrainOperation::CClearTerrainOperation(CMap* map, vstd::RNG* gen) : CComposedOperation(map)
 {
 	CTerrainSelection terrainSel(map);
 	terrainSel.selectRange(MapRect(int3(0, 0, 0), map->width, map->height));

+ 8 - 4
lib/mapping/CMapOperation.h

@@ -17,7 +17,11 @@ VCMI_LIB_NAMESPACE_BEGIN
 
 class CGObjectInstance;
 class CMap;
-class CRandomGenerator;
+
+namespace vstd
+{
+class RNG;
+}
 
 /// The abstract base class CMapOperation defines an operation that can be executed, undone and redone.
 class DLL_LINKAGE CMapOperation : public boost::noncopyable
@@ -63,7 +67,7 @@ private:
 class CDrawTerrainOperation : public CMapOperation
 {
 public:
-	CDrawTerrainOperation(CMap * map, CTerrainSelection terrainSel, TerrainId terType, int decorationsPercentage, CRandomGenerator * gen);
+	CDrawTerrainOperation(CMap * map, CTerrainSelection terrainSel, TerrainId terType, int decorationsPercentage, vstd::RNG * gen);
 
 	void execute() override;
 	void undo() override;
@@ -103,7 +107,7 @@ private:
 	CTerrainSelection terrainSel;
 	TerrainId terType;
 	int decorationsPercentage;
-	CRandomGenerator* gen;
+	vstd::RNG* gen;
 	std::set<int3> invalidatedTerViews;
 };
 
@@ -111,7 +115,7 @@ private:
 class CClearTerrainOperation : public CComposedOperation
 {
 public:
-	CClearTerrainOperation(CMap * map, CRandomGenerator * gen);
+	CClearTerrainOperation(CMap * map, vstd::RNG * gen);
 
 	std::string getLabel() const override;
 };

+ 6 - 4
lib/mapping/ObstacleProxy.cpp

@@ -18,6 +18,8 @@
 #include "../mapObjects/ObstacleSetHandler.h"
 #include "../VCMI_Lib.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 void ObstacleProxy::collectPossibleObstacles(TerrainId terrain)
@@ -53,7 +55,7 @@ void ObstacleProxy::sortObstacles()
 	});
 }
 
-bool ObstacleProxy::prepareBiome(const ObstacleSetFilter & filter, CRandomGenerator & rand)
+bool ObstacleProxy::prepareBiome(const ObstacleSetFilter & filter, vstd::RNG & rand)
 {
 	possibleObstacles.clear();
 
@@ -228,7 +230,7 @@ bool ObstacleProxy::isProhibited(const rmg::Area& objArea) const
 	return false;
 };
 
-int ObstacleProxy::getWeightedObjects(const int3 & tile, CRandomGenerator & rand, IGameCallback * cb, std::list<rmg::Object> & allObjects, std::vector<std::pair<rmg::Object*, int3>> & weightedObjects)
+int ObstacleProxy::getWeightedObjects(const int3 & tile, vstd::RNG & rand, IGameCallback * cb, std::list<rmg::Object> & allObjects, std::vector<std::pair<rmg::Object*, int3>> & weightedObjects)
 {
 	int maxWeight = std::numeric_limits<int>::min();
 	for(auto & possibleObstacle : possibleObstacles)
@@ -309,7 +311,7 @@ int ObstacleProxy::getWeightedObjects(const int3 & tile, CRandomGenerator & rand
 	return maxWeight;
 }
 
-std::set<CGObjectInstance*> ObstacleProxy::createObstacles(CRandomGenerator & rand, IGameCallback * cb)
+std::set<CGObjectInstance*> ObstacleProxy::createObstacles(vstd::RNG & rand, IGameCallback * cb)
 {
 	//reverse order, since obstacles begin in bottom-right corner, while the map coordinates begin in top-left
 	auto blockedTiles = blockedArea.getTilesVector();
@@ -382,7 +384,7 @@ bool EditorObstaclePlacer::isInTheMap(const int3& tile)
 	return map->isInTheMap(tile);
 }
 
-std::set<CGObjectInstance*> EditorObstaclePlacer::placeObstacles(CRandomGenerator & rand)
+std::set<CGObjectInstance*> EditorObstaclePlacer::placeObstacles(vstd::RNG & rand)
 {
 	auto obstacles = createObstacles(rand, map->cb);
 	finalInsertion(map->getEditManager(), obstacles);

+ 4 - 5
lib/mapping/ObstacleProxy.h

@@ -18,7 +18,6 @@ VCMI_LIB_NAMESPACE_BEGIN
 class CMapEditManager;
 class CGObjectInstance;
 class ObjectTemplate;
-class CRandomGenerator;
 class IGameCallback;
 class ObstacleSetFilter;
 
@@ -30,7 +29,7 @@ public:
 	virtual ~ObstacleProxy() = default;
 
 	void collectPossibleObstacles(TerrainId terrain);
-	bool prepareBiome(const ObstacleSetFilter & filter, CRandomGenerator & rand);
+	bool prepareBiome(const ObstacleSetFilter & filter, vstd::RNG & rand);
 
 	void addBlockedTile(const int3 & tile);
 
@@ -44,7 +43,7 @@ public:
 
 	virtual void placeObject(rmg::Object & object, std::set<CGObjectInstance*> & instances);
 
-	virtual std::set<CGObjectInstance*> createObstacles(CRandomGenerator & rand, IGameCallback * cb);
+	virtual std::set<CGObjectInstance*> createObstacles(vstd::RNG & rand, IGameCallback * cb);
 
 	virtual bool isInTheMap(const int3& tile) = 0;
 	
@@ -53,7 +52,7 @@ public:
 	virtual void postProcess(const rmg::Object& object) {};
 
 protected:
-	int getWeightedObjects(const int3& tile, CRandomGenerator& rand, IGameCallback * cb, std::list<rmg::Object>& allObjects, std::vector<std::pair<rmg::Object*, int3>>& weightedObjects);
+	int getWeightedObjects(const int3& tile, vstd::RNG& rand, IGameCallback * cb, std::list<rmg::Object>& allObjects, std::vector<std::pair<rmg::Object*, int3>>& weightedObjects);
 	void sortObstacles();
 
 	rmg::Area blockedArea;
@@ -71,7 +70,7 @@ public:
 
 	bool isInTheMap(const int3& tile) override;
 
-	std::set<CGObjectInstance*> placeObstacles(CRandomGenerator& rand);
+	std::set<CGObjectInstance*> placeObstacles(vstd::RNG& rand);
 
 private:
 	CMap* map;

+ 1 - 0
lib/registerTypes/RegisterTypesLobbyPacks.h

@@ -17,6 +17,7 @@
 #include "../gameState/TavernHeroesPool.h"
 #include "../gameState/CGameStateCampaign.h"
 #include "../mapping/CMap.h"
+#include "../CRandomGenerator.h"
 #include "../TerrainHandler.h"
 #include "../RiverHandler.h"
 #include "../RoadHandler.h"

+ 9 - 8
lib/rewardable/Info.cpp

@@ -20,7 +20,8 @@
 #include "../json/JsonRandom.h"
 #include "../mapObjects/IObjectInterface.h"
 #include "../modding/IdentifierStorage.h"
-#include "../CRandomGenerator.h"
+
+#include <vstd/RNG.h>
 
 VCMI_LIB_NAMESPACE_BEGIN
 
@@ -106,7 +107,7 @@ void Rewardable::Info::init(const JsonNode & objectConfig, const std::string & o
 	loadString(parameters["onEmptyMessage"], TextIdentifier(objectName, "onEmpty"));
 }
 
-Rewardable::LimitersList Rewardable::Info::configureSublimiters(Rewardable::Configuration & object, CRandomGenerator & rng, IGameCallback * cb, const JsonNode & source) const
+Rewardable::LimitersList Rewardable::Info::configureSublimiters(Rewardable::Configuration & object, vstd::RNG & rng, IGameCallback * cb, const JsonNode & source) const
 {
 	Rewardable::LimitersList result;
 	for (const auto & input : source.Vector())
@@ -121,7 +122,7 @@ Rewardable::LimitersList Rewardable::Info::configureSublimiters(Rewardable::Conf
 	return result;
 }
 
-void Rewardable::Info::configureLimiter(Rewardable::Configuration & object, CRandomGenerator & rng, IGameCallback * cb, Rewardable::Limiter & limiter, const JsonNode & source) const
+void Rewardable::Info::configureLimiter(Rewardable::Configuration & object, vstd::RNG & rng, IGameCallback * cb, Rewardable::Limiter & limiter, const JsonNode & source) const
 {
 	auto const & variables = object.variables.values;
 	JsonRandom randomizer(cb);
@@ -153,7 +154,7 @@ void Rewardable::Info::configureLimiter(Rewardable::Configuration & object, CRan
 	limiter.noneOf = configureSublimiters(object, rng, cb, source["noneOf"] );
 }
 
-void Rewardable::Info::configureReward(Rewardable::Configuration & object, CRandomGenerator & rng, IGameCallback * cb, Rewardable::Reward & reward, const JsonNode & source) const
+void Rewardable::Info::configureReward(Rewardable::Configuration & object, vstd::RNG & rng, IGameCallback * cb, Rewardable::Reward & reward, const JsonNode & source) const
 {
 	auto const & variables = object.variables.values;
 	JsonRandom randomizer(cb);
@@ -210,14 +211,14 @@ void Rewardable::Info::configureReward(Rewardable::Configuration & object, CRand
 	}
 }
 
-void Rewardable::Info::configureResetInfo(Rewardable::Configuration & object, CRandomGenerator & rng, Rewardable::ResetInfo & resetParameters, const JsonNode & source) const
+void Rewardable::Info::configureResetInfo(Rewardable::Configuration & object, vstd::RNG & rng, Rewardable::ResetInfo & resetParameters, const JsonNode & source) const
 {
 	resetParameters.period   = static_cast<ui32>(source["period"].Float());
 	resetParameters.visitors = source["visitors"].Bool();
 	resetParameters.rewards  = source["rewards"].Bool();
 }
 
-void Rewardable::Info::configureVariables(Rewardable::Configuration & object, CRandomGenerator & rng, IGameCallback * cb, const JsonNode & source) const
+void Rewardable::Info::configureVariables(Rewardable::Configuration & object, vstd::RNG & rng, IGameCallback * cb, const JsonNode & source) const
 {
 	JsonRandom randomizer(cb);
 
@@ -277,7 +278,7 @@ void Rewardable::Info::replaceTextPlaceholders(MetaString & target, const Variab
 
 void Rewardable::Info::configureRewards(
 		Rewardable::Configuration & object,
-		CRandomGenerator & rng,
+		vstd::RNG & rng,
 		IGameCallback * cb,
 		const JsonNode & source,
 		Rewardable::EEventType event,
@@ -335,7 +336,7 @@ void Rewardable::Info::configureRewards(
 	}
 }
 
-void Rewardable::Info::configureObject(Rewardable::Configuration & object, CRandomGenerator & rng, IGameCallback * cb) const
+void Rewardable::Info::configureObject(Rewardable::Configuration & object, vstd::RNG & rng, IGameCallback * cb) const
 {
 	object.info.clear();
 

+ 12 - 9
lib/rewardable/Info.h

@@ -15,13 +15,16 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-class CRandomGenerator;
+namespace vstd
+{
+class RNG;
+}
+
 class MetaString;
 class IGameCallback;
 
 namespace Rewardable
 {
-
 struct Limiter;
 using LimitersList = std::vector<std::shared_ptr<Rewardable::Limiter>>;
 struct Reward;
@@ -39,14 +42,14 @@ class DLL_LINKAGE Info : public IObjectInfo
 	void replaceTextPlaceholders(MetaString & target, const Variables & variables) const;
 	void replaceTextPlaceholders(MetaString & target, const Variables & variables, const VisitInfo & info) const;
 
-	void configureVariables(Rewardable::Configuration & object, CRandomGenerator & rng, IGameCallback * cb, const JsonNode & source) const;
-	void configureRewards(Rewardable::Configuration & object, CRandomGenerator & rng, IGameCallback * cb, const JsonNode & source, Rewardable::EEventType mode, const std::string & textPrefix) const;
+	void configureVariables(Rewardable::Configuration & object, vstd::RNG & rng, IGameCallback * cb, const JsonNode & source) const;
+	void configureRewards(Rewardable::Configuration & object, vstd::RNG & rng, IGameCallback * cb, const JsonNode & source, Rewardable::EEventType mode, const std::string & textPrefix) const;
 
-	void configureLimiter(Rewardable::Configuration & object, CRandomGenerator & rng, IGameCallback * cb, Rewardable::Limiter & limiter, const JsonNode & source) const;
-	Rewardable::LimitersList configureSublimiters(Rewardable::Configuration & object, CRandomGenerator & rng, IGameCallback * cb, const JsonNode & source) const;
+	void configureLimiter(Rewardable::Configuration & object, vstd::RNG & rng, IGameCallback * cb, Rewardable::Limiter & limiter, const JsonNode & source) const;
+	Rewardable::LimitersList configureSublimiters(Rewardable::Configuration & object, vstd::RNG & rng, IGameCallback * cb, const JsonNode & source) const;
 
-	void configureReward(Rewardable::Configuration & object, CRandomGenerator & rng, IGameCallback * cb, Rewardable::Reward & info, const JsonNode & source) const;
-	void configureResetInfo(Rewardable::Configuration & object, CRandomGenerator & rng, Rewardable::ResetInfo & info, const JsonNode & source) const;
+	void configureReward(Rewardable::Configuration & object, vstd::RNG & rng, IGameCallback * cb, Rewardable::Reward & info, const JsonNode & source) const;
+	void configureResetInfo(Rewardable::Configuration & object, vstd::RNG & rng, Rewardable::ResetInfo & info, const JsonNode & source) const;
 public:
 	const JsonNode & getParameters() const;
 
@@ -65,7 +68,7 @@ public:
 
 	bool givesBonuses() const override;
 
-	void configureObject(Rewardable::Configuration & object, CRandomGenerator & rng, IGameCallback * cb) const;
+	void configureObject(Rewardable::Configuration & object, vstd::RNG & rng, IGameCallback * cb) const;
 
 	void init(const JsonNode & objectConfig, const std::string & objectTextID);
 

+ 5 - 5
lib/rmg/CMapGenOptions.cpp

@@ -14,11 +14,12 @@
 #include "../mapping/CMapHeader.h"
 #include "CRmgTemplateStorage.h"
 #include "CRmgTemplate.h"
-#include "CRandomGenerator.h"
 #include "../VCMI_Lib.h"
 #include "../CTownHandler.h"
 #include "serializer/JsonSerializeFormat.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 CMapGenOptions::CMapGenOptions()
@@ -487,7 +488,7 @@ void CMapGenOptions::setPlayerTeam(const PlayerColor & color, const TeamID & tea
 	customizedPlayers = true;
 }
 
-void CMapGenOptions::finalize(CRandomGenerator & rand)
+void CMapGenOptions::finalize(vstd::RNG & rand)
 {
 	logGlobal->info("RMG map: %dx%d, %s underground", getWidth(), getHeight(), getHasTwoLevels() ? "WITH" : "NO");
 	logGlobal->info("RMG settings: players %d, teams %d, computer players %d, computer teams %d, water %d, monsters %d",
@@ -690,8 +691,7 @@ bool CMapGenOptions::checkOptions() const
 	}
 	else
 	{
-		CRandomGenerator gen;
-		return getPossibleTemplate(gen) != nullptr;
+		return !getPossibleTemplates().empty();
 	}
 }
 
@@ -750,7 +750,7 @@ std::vector<const CRmgTemplate *> CMapGenOptions::getPossibleTemplates() const
 	return templates;
 }
 
-const CRmgTemplate * CMapGenOptions::getPossibleTemplate(CRandomGenerator & rand) const
+const CRmgTemplate * CMapGenOptions::getPossibleTemplate(vstd::RNG & rand) const
 {
 	auto templates = getPossibleTemplates();
 

+ 6 - 3
lib/rmg/CMapGenOptions.h

@@ -16,7 +16,10 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-class CRandomGenerator;
+namespace vstd
+{
+class RNG;
+}
 
 enum class EPlayerType
 {
@@ -148,7 +151,7 @@ public:
 	/// Finalizes the options. All random sizes for various properties will be overwritten by numbers from
 	/// a random number generator by keeping the options in a valid state. Check options should return true, otherwise
 	/// this function fails.
-	void finalize(CRandomGenerator & rand);
+	void finalize(vstd::RNG & rand);
 
 	/// Returns false if there is no template available which fits to the currently selected options.
 	bool checkOptions() const;
@@ -166,7 +169,7 @@ private:
 	PlayerColor getNextPlayerColor() const;
 	void updateCompOnlyPlayers();
 	void updatePlayers();
-	const CRmgTemplate * getPossibleTemplate(CRandomGenerator & rand) const;
+	const CRmgTemplate * getPossibleTemplate(vstd::RNG & rand) const;
 
 	si32 width;
 	si32 height;

+ 12 - 9
lib/rmg/CMapGenerator.cpp

@@ -14,6 +14,7 @@
 #include "../mapping/MapFormat.h"
 #include "../VCMI_Lib.h"
 #include "../CGeneralTextHandler.h"
+#include "../CRandomGenerator.h"
 #include "../mapObjectConstructors/AObjectTypeHandler.h"
 #include "../mapObjectConstructors/CObjectClassesHandler.h"
 #include "../mapping/CMapEditManager.h"
@@ -32,15 +33,17 @@
 #include "modificators/TreasurePlacer.h"
 #include "modificators/RoadPlacer.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 CMapGenerator::CMapGenerator(CMapGenOptions& mapGenOptions, IGameCallback * cb, int RandomSeed) :
 	mapGenOptions(mapGenOptions), randomSeed(RandomSeed),
-	monolithIndex(0)
+	monolithIndex(0),
+	rand(std::make_unique<CRandomGenerator>(RandomSeed))
 {
 	loadConfig();
-	rand.setSeed(this->randomSeed);
-	mapGenOptions.finalize(rand);
+	mapGenOptions.finalize(*rand);
 	map = std::make_unique<RmgMap>(mapGenOptions, cb);
 	placer = std::make_shared<CZonePlacer>(*map);
 }
@@ -116,7 +119,7 @@ std::unique_ptr<CMap> CMapGenerator::generate()
 	try
 	{
 		addHeaderInfo();
-		map->initTiles(*this, rand);
+		map->initTiles(*this, *rand);
 		Load::Progress::step();
 		initQuestArtsRemaining();
 		genZones();
@@ -286,7 +289,7 @@ void CMapGenerator::addPlayerInfo()
 					logGlobal->error("Not enough places in team for %s player", ((j == CPUONLY) ? "CPU" : "CPU or human"));
 					assert (teamNumbers[j].size());
 				}
-				auto itTeam = RandomGeneratorUtil::nextItem(teamNumbers[j], rand);
+				auto itTeam = RandomGeneratorUtil::nextItem(teamNumbers[j], *rand);
 				player.team = TeamID(*itTeam);
 				teamNumbers[j].erase(itTeam);
 			}
@@ -306,8 +309,8 @@ void CMapGenerator::addPlayerInfo()
 
 void CMapGenerator::genZones()
 {
-	placer->placeZones(&rand);
-	placer->assignZones(&rand);
+	placer->placeZones(rand.get());
+	placer->assignZones(rand.get());
 
 	logGlobal->info("Zones generated successfully");
 }
@@ -428,9 +431,9 @@ void CMapGenerator::fillZones()
 			if (it.second->getType() != ETemplateZoneType::WATER)
 				treasureZones.push_back(it.second);
 	}
-	auto grailZone = *RandomGeneratorUtil::nextItem(treasureZones, rand);
+	auto grailZone = *RandomGeneratorUtil::nextItem(treasureZones, *rand);
 
-	map->getMap(this).grailPos = *RandomGeneratorUtil::nextItem(grailZone->freePaths()->getTiles(), rand);
+	map->getMap(this).grailPos = *RandomGeneratorUtil::nextItem(grailZone->freePaths()->getTiles(), *rand);
 	map->getMap(this).reindexObjects();
 
 	logGlobal->info("Zones filled successfully");

+ 1 - 2
lib/rmg/CMapGenerator.h

@@ -11,7 +11,6 @@
 #pragma once
 
 #include "../GameConstants.h"
-#include "../CRandomGenerator.h"
 #include "CMapGenOptions.h"
 #include "../int3.h"
 #include "CRmgTemplate.h"
@@ -79,7 +78,7 @@ public:
 	int getRandomSeed() const;
 	
 private:
-	CRandomGenerator rand;
+	std::unique_ptr<vstd::RNG> rand;
 	int randomSeed;
 	CMapGenOptions& mapGenOptions;
 	Config config;

+ 11 - 12
lib/rmg/CZonePlacer.cpp

@@ -11,7 +11,6 @@
 #include "StdInc.h"
 #include "CZonePlacer.h"
 
-#include "../CRandomGenerator.h"
 #include "../CTownHandler.h"
 #include "../TerrainHandler.h"
 #include "../mapping/CMap.h"
@@ -23,12 +22,12 @@
 #include "Functions.h"
 #include "PenroseTiling.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 //#define ZONE_PLACEMENT_LOG true
 
-class CRandomGenerator;
-
 CZonePlacer::CZonePlacer(RmgMap & map)
 	: width(0), height(0), mapSize(0),
 	gravityConstant(1e-3f),
@@ -97,7 +96,7 @@ void CZonePlacer::findPathsBetweenZones()
 	}
 }
 
-void CZonePlacer::placeOnGrid(CRandomGenerator* rand)
+void CZonePlacer::placeOnGrid(vstd::RNG* rand)
 {
 	auto zones = map.getZones();
 	assert(zones.size());
@@ -118,7 +117,7 @@ void CZonePlacer::placeOnGrid(CRandomGenerator* rand)
 
 	auto getRandomEdge = [rand, gridSize](size_t& x, size_t& y)
 	{
-		switch (rand->nextInt() % 4)
+		switch (rand->nextInt(0, 3) % 4)
 		{
 		case 0:
 			x = 0;
@@ -150,7 +149,7 @@ void CZonePlacer::placeOnGrid(CRandomGenerator* rand)
 			else
 			{
 				//Random corner
-				if (rand->nextInt() % 2)
+				if (rand->nextInt(0, 1) == 1)
 				{
 					x = 0;
 				}
@@ -158,7 +157,7 @@ void CZonePlacer::placeOnGrid(CRandomGenerator* rand)
 				{
 					x = gridSize - 1;
 				}
-				if (rand->nextInt() % 2)
+				if (rand->nextInt(0, 1) == 1)
 				{
 					y = 0;
 				}
@@ -176,8 +175,8 @@ void CZonePlacer::placeOnGrid(CRandomGenerator* rand)
 			else
 			{
 				//One of 4 squares in the middle
-				x = (gridSize / 2) - 1 + rand->nextInt() % 2;
-				y = (gridSize / 2) - 1 + rand->nextInt() % 2;
+				x = (gridSize / 2) - 1 + rand->nextInt(0, 1);
+				y = (gridSize / 2) - 1 + rand->nextInt(0, 1);
 			}
 			break;
 		case ETemplateZoneType::JUNCTION:
@@ -308,7 +307,7 @@ float CZonePlacer::scaleForceBetweenZones(const std::shared_ptr<Zone> zoneA, con
 	}
 }
 
-void CZonePlacer::placeZones(CRandomGenerator * rand)
+void CZonePlacer::placeZones(vstd::RNG * rand)
 {
 	logGlobal->info("Starting zone placement");
 
@@ -432,7 +431,7 @@ void CZonePlacer::placeZones(CRandomGenerator * rand)
 	}
 }
 
-void CZonePlacer::prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const bool underground, CRandomGenerator * rand)
+void CZonePlacer::prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const bool underground, vstd::RNG * rand)
 {
 	std::vector<float> totalSize = { 0, 0 }; //make sure that sum of zone sizes on surface and uderground match size of the map
 
@@ -824,7 +823,7 @@ float CZonePlacer::metric (const int3 &A, const int3 &B) const
 
 }
 
-void CZonePlacer::assignZones(CRandomGenerator * rand)
+void CZonePlacer::assignZones(vstd::RNG * rand)
 {
 	logGlobal->info("Starting zone colouring");
 

+ 9 - 5
lib/rmg/CZonePlacer.h

@@ -16,9 +16,13 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
+namespace vstd
+{
+class RNG;
+}
+
 class CZoneGraph;
 class CMap;
-class CRandomGenerator;
 class RmgMap;
 class Zone;
 
@@ -37,16 +41,16 @@ public:
 	float getDistance(float distance) const; //additional scaling without 0 division
 	~CZonePlacer() = default;
 
-	void placeZones(CRandomGenerator * rand);
+	void placeZones(vstd::RNG * rand);
 	void findPathsBetweenZones();
-	void placeOnGrid(CRandomGenerator* rand);
+	void placeOnGrid(vstd::RNG* rand);
 	float scaleForceBetweenZones(const std::shared_ptr<Zone> zoneA, const std::shared_ptr<Zone> zoneB) const;
-	void assignZones(CRandomGenerator * rand);
+	void assignZones(vstd::RNG * rand);
 
 	const TDistanceMap & getDistanceMap();
 	
 private:
-	void prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const bool underground, CRandomGenerator * rand);
+	void prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const bool underground, vstd::RNG * rand);
 	void attractConnectedZones(TZoneMap & zones, TForceVector & forces, TDistanceVector & distances) const;
 	void separateOverlappingZones(TZoneMap &zones, TForceVector &forces, TDistanceVector &overlaps);
 	void moveOneZone(TZoneMap & zones, TForceVector & totalForces, TDistanceVector & distances, TDistanceVector & overlaps);

+ 3 - 1
lib/rmg/Functions.cpp

@@ -21,6 +21,8 @@
 #include "../mapObjectConstructors/CObjectClassesHandler.h"
 #include "../VCMI_Lib.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 rmg::Tileset collectDistantTiles(const Zone& zone, int distance)
@@ -34,7 +36,7 @@ rmg::Tileset collectDistantTiles(const Zone& zone, int distance)
 	return subarea.getTiles();
 }
 
-int chooseRandomAppearance(CRandomGenerator & generator, si32 ObjID, TerrainId terrain)
+int chooseRandomAppearance(vstd::RNG & generator, si32 ObjID, TerrainId terrain)
 {
 	auto factories = VLC->objtypeh->knownSubObjects(ObjID);
 	vstd::erase_if(factories, [ObjID, &terrain](si32 f)

+ 1 - 2
lib/rmg/Functions.h

@@ -19,7 +19,6 @@ class RmgMap;
 class ObjectManager;
 class ObjectTemplate;
 class CMapGenerator;
-class CRandomGenerator;
 
 class rmgException : public std::exception
 {
@@ -37,7 +36,7 @@ public:
 
 rmg::Tileset collectDistantTiles(const Zone & zone, int distance);
 
-int chooseRandomAppearance(CRandomGenerator & generator, si32 ObjID, TerrainId terrain);
+int chooseRandomAppearance(vstd::RNG & generator, si32 ObjID, TerrainId terrain);
 
 
 VCMI_LIB_NAMESPACE_END

+ 3 - 1
lib/rmg/PenroseTiling.cpp

@@ -13,6 +13,8 @@
 #include "StdInc.h"
 #include "PenroseTiling.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 
@@ -143,7 +145,7 @@ void PenroseTiling::split(Triangle& p, std::vector<Point2D>& points,
 	return;
 }
 
-std::set<Point2D> PenroseTiling::generatePenroseTiling(size_t numZones, CRandomGenerator * rand)
+std::set<Point2D> PenroseTiling::generatePenroseTiling(size_t numZones, vstd::RNG * rand)
 {
 	float scale = 173.2f / (numZones * 1.5f + 20);
 	float polyAngle = (2 * PI_CONSTANT) / POLY;

+ 7 - 3
lib/rmg/PenroseTiling.h

@@ -11,12 +11,16 @@
 #pragma once
 
 #include "../GameConstants.h"
-#include "../CRandomGenerator.h"
 #include <boost/geometry.hpp>
 #include <boost/geometry/geometries/point_xy.hpp>
 
 VCMI_LIB_NAMESPACE_BEGIN
 
+namespace vstd
+{
+class RNG;
+}
+
 using namespace boost::geometry;
 typedef std::array<uint32_t, 3> TIndices;
 
@@ -66,11 +70,11 @@ public:
 	
 	const bool P2 = false; // Tiling type
 
-	std::set<Point2D> generatePenroseTiling(size_t numZones, CRandomGenerator * rand);
+	std::set<Point2D> generatePenroseTiling(size_t numZones, vstd::RNG * rand);
 
 private:
 	void split(Triangle& p, std::vector<Point2D>& points, std::array<std::vector<uint32_t>, 5>& indices, uint32_t depth); 
 
 };
 
-VCMI_LIB_NAMESPACE_END
+VCMI_LIB_NAMESPACE_END

+ 1 - 1
lib/rmg/RmgMap.cpp

@@ -84,7 +84,7 @@ void RmgMap::foreachDiagonalNeighbour(const int3 & pos, const std::function<void
 	}
 }
 
-void RmgMap::initTiles(CMapGenerator & generator, CRandomGenerator & rand)
+void RmgMap::initTiles(CMapGenerator & generator, vstd::RNG & rand)
 {
 	mapInstance->initTerrain();
 	

+ 6 - 2
lib/rmg/RmgMap.h

@@ -17,7 +17,6 @@ VCMI_LIB_NAMESPACE_BEGIN
 
 class CMap;
 class CMapEditManager;
-class CRandomGenerator;
 class TileInfo;
 class CMapGenOptions;
 class Zone;
@@ -25,6 +24,11 @@ class CMapGenerator;
 class MapProxy;
 class playerInfo;
 
+namespace vstd
+{
+class RNG;
+}
+
 class RmgMap
 {
 public:
@@ -79,7 +83,7 @@ public:
 	void registerZone(FactionID faction);
 	ui32 getZoneCount(FactionID faction);
 	ui32 getTotalZoneCount() const;
-	void initTiles(CMapGenerator & generator, CRandomGenerator & rand);
+	void initTiles(CMapGenerator & generator, vstd::RNG & rand);
 	void addModificators();
 
 	bool isAllowedSpell(const SpellID & sid) const;

+ 7 - 5
lib/rmg/RmgObject.cpp

@@ -21,6 +21,8 @@
 #include "Functions.h"
 #include "../TerrainHandler.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 using namespace rmg;
@@ -111,7 +113,7 @@ void Object::Instance::setPositionRaw(const int3 & position)
 	dObject.pos = dPosition + dParent.getPosition();
 }
 
-void Object::Instance::setAnyTemplate(CRandomGenerator & rng)
+void Object::Instance::setAnyTemplate(vstd::RNG & rng)
 {
 	auto templates = dObject.getObjectHandler()->getTemplates();
 	if(templates.empty())
@@ -122,7 +124,7 @@ void Object::Instance::setAnyTemplate(CRandomGenerator & rng)
 	setPosition(getPosition(false));
 }
 
-void Object::Instance::setTemplate(TerrainId terrain, CRandomGenerator & rng)
+void Object::Instance::setTemplate(TerrainId terrain, vstd::RNG & rng)
 {
 	auto templates = dObject.getObjectHandler()->getMostSpecificTemplates(terrain);
 
@@ -366,7 +368,7 @@ void Object::setPosition(const int3 & position)
 		i.setPositionRaw(i.getPosition());
 }
 
-void Object::setTemplate(const TerrainId & terrain, CRandomGenerator & rng)
+void Object::setTemplate(const TerrainId & terrain, vstd::RNG & rng)
 {
 	for(auto& i : dInstances)
 		i.setTemplate(terrain, rng);
@@ -474,7 +476,7 @@ rmg::Area Object::Instance::getBorderAbove() const
 	return borderAbove;
 }
 
-void Object::Instance::finalize(RmgMap & map, CRandomGenerator & rng)
+void Object::Instance::finalize(RmgMap & map, vstd::RNG & rng)
 {
 	if(!map.isOnMap(getPosition(true)))
 		throw rmgException(boost::str(boost::format("Position of object %d at %s is outside the map") % dObject.id % getPosition(true).toString()));
@@ -511,7 +513,7 @@ void Object::Instance::finalize(RmgMap & map, CRandomGenerator & rng)
 	map.getMapProxy()->insertObject(&dObject);
 }
 
-void Object::finalize(RmgMap & map, CRandomGenerator & rng)
+void Object::finalize(RmgMap & map, vstd::RNG & rng)
 {
 	if(dInstances.empty())
 		throw rmgException("Cannot finalize object without instances");

+ 10 - 6
lib/rmg/RmgObject.h

@@ -16,8 +16,12 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
+namespace vstd
+{
+class RNG;
+}
+
 class CGObjectInstance;
-class CRandomGenerator;
 class RmgMap;
 
 namespace rmg {
@@ -39,8 +43,8 @@ public:
 		bool isRemovable() const;
 		const Area & getAccessibleArea() const;
 		Area getBorderAbove() const;
-		void setTemplate(TerrainId terrain, CRandomGenerator &); //cache invalidation
-		void setAnyTemplate(CRandomGenerator &); //cache invalidation
+		void setTemplate(TerrainId terrain, vstd::RNG &); //cache invalidation
+		void setAnyTemplate(vstd::RNG &); //cache invalidation
 		
 		int3 getTopTile() const;
 		int3 getPosition(bool isAbsolute = false) const;
@@ -49,7 +53,7 @@ public:
 		const CGObjectInstance & object() const;
 		CGObjectInstance & object();
 		
-		void finalize(RmgMap & map, CRandomGenerator &); //cache invalidation
+		void finalize(RmgMap & map, vstd::RNG &); //cache invalidation
 		void clear();
 		
 		std::function<void(CGObjectInstance *)> onCleared;
@@ -83,7 +87,7 @@ public:
 	
 	const int3 & getPosition() const;
 	void setPosition(const int3 & position);
-	void setTemplate(const TerrainId & terrain, CRandomGenerator &);
+	void setTemplate(const TerrainId & terrain, vstd::RNG &);
 	
 	const Area & getArea() const;  //lazy cache invalidation
 	const int3 getVisibleTop() const;
@@ -94,7 +98,7 @@ public:
 	void setValue(uint32_t value);
 	uint32_t getValue() const;
 	
-	void finalize(RmgMap & map, CRandomGenerator &);
+	void finalize(RmgMap & map, vstd::RNG &);
 	void clearCachedArea() const;
 	void clear();
 	

+ 10 - 4
lib/rmg/Zone.cpp

@@ -17,6 +17,10 @@
 #include "RmgPath.h"
 #include "modificators/ObjectManager.h"
 
+#include "../CRandomGenerator.h"
+
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 const std::function<bool(const int3 &)> AREA_NO_FILTER = [](const int3 & t)
@@ -24,16 +28,18 @@ const std::function<bool(const int3 &)> AREA_NO_FILTER = [](const int3 & t)
 	return true;
 };
 
-Zone::Zone(RmgMap & map, CMapGenerator & generator, CRandomGenerator & r)
+Zone::Zone(RmgMap & map, CMapGenerator & generator, vstd::RNG & r)
 	: finished(false)
 	, townType(ETownType::NEUTRAL)
 	, terrainType(ETerrainId::GRASS)
 	, map(map)
+	, rand(std::make_unique<CRandomGenerator>(r.nextInt()))
 	, generator(generator)
 {
-	rand.setSeed(r.nextInt());
 }
 
+Zone::~Zone() = default;
+
 bool Zone::isUnderground() const
 {
 	return getPos().z;
@@ -401,9 +407,9 @@ void Zone::initModificators()
 	}
 }
 
-CRandomGenerator& Zone::getRand()
+vstd::RNG& Zone::getRand()
 {
-	return rand;
+	return *rand;
 }
 
 VCMI_LIB_NAMESPACE_END

+ 4 - 5
lib/rmg/Zone.h

@@ -13,7 +13,6 @@
 #include "../GameConstants.h"
 #include "float3.h"
 #include "../int3.h"
-#include "../CRandomGenerator.h"
 #include "CRmgTemplate.h"
 #include "RmgArea.h"
 #include "RmgPath.h"
@@ -28,7 +27,6 @@ VCMI_LIB_NAMESPACE_BEGIN
 class RmgMap;
 class CMapGenerator;
 class Modificator;
-class CRandomGenerator;
 
 extern const std::function<bool(const int3 &)> AREA_NO_FILTER;
 
@@ -74,8 +72,9 @@ private:
 class Zone : public rmg::ZoneOptions
 {
 public:
-	Zone(RmgMap & map, CMapGenerator & generator, CRandomGenerator & rand);
+	Zone(RmgMap & map, CMapGenerator & generator, vstd::RNG & rand);
 	Zone(const Zone &) = delete;
+	~Zone();
 	
 	void setOptions(const rmg::ZoneOptions & options);
 	bool isUnderground() const;
@@ -127,14 +126,14 @@ public:
 	
 	void initModificators();
 	
-	CRandomGenerator & getRand();
+	vstd::RNG & getRand();
 public:
 	mutable boost::recursive_mutex areaMutex;
 	using Lock = boost::unique_lock<boost::recursive_mutex>;
 	
 protected:
 	CMapGenerator & generator;
-	CRandomGenerator rand;
+	std::unique_ptr<vstd::RNG> rand;
 	RmgMap & map;
 	TModificators modificators;
 	bool finished;

+ 2 - 0
lib/rmg/modificators/ConnectionsPlacer.cpp

@@ -26,6 +26,8 @@
 #include "WaterProxy.h"
 #include "TownPlacer.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 std::pair<Zone::Lock, Zone::Lock> ConnectionsPlacer::lockZones(std::shared_ptr<Zone> otherZone)

+ 2 - 0
lib/rmg/modificators/MinePlacer.cpp

@@ -22,6 +22,8 @@
 #include "WaterAdopter.h"
 #include "../TileInfo.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 void MinePlacer::process()

+ 2 - 0
lib/rmg/modificators/ObjectDistributor.cpp

@@ -25,6 +25,8 @@
 #include "../Functions.h"
 #include "../RmgObject.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 void ObjectDistributor::process()

+ 2 - 0
lib/rmg/modificators/ObjectManager.cpp

@@ -29,6 +29,8 @@
 #include "../Functions.h"
 #include "../RmgObject.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 void ObjectManager::process()

+ 0 - 1
lib/rmg/modificators/ObstaclePlacer.cpp

@@ -19,7 +19,6 @@
 #include "RiverPlacer.h"
 #include "../RmgMap.h"
 #include "../CMapGenerator.h"
-#include "../../CRandomGenerator.h"
 #include "../Functions.h"
 #include "../../mapping/CMapEditManager.h"
 #include "../../mapping/CMap.h"

+ 3 - 1
lib/rmg/modificators/PrisonHeroPlacer.cpp

@@ -17,7 +17,9 @@
 #include "../../VCMI_Lib.h"
 #include "../../mapObjectConstructors/AObjectTypeHandler.h"
 #include "../../mapObjectConstructors/CObjectClassesHandler.h"
-#include "../../mapObjects/MapObjects.h" 
+#include "../../mapObjects/MapObjects.h"
+
+#include <vstd/RNG.h>
 
 VCMI_LIB_NAMESPACE_BEGIN
 

+ 0 - 2
lib/rmg/modificators/PrisonHeroPlacer.h

@@ -15,8 +15,6 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-class CRandomGenerator;
-
 class PrisonHeroPlacer : public Modificator
 {
 public:

+ 4 - 2
lib/rmg/modificators/QuestArtifactPlacer.cpp

@@ -17,7 +17,9 @@
 #include "../../VCMI_Lib.h"
 #include "../../mapObjectConstructors/AObjectTypeHandler.h"
 #include "../../mapObjectConstructors/CObjectClassesHandler.h"
-#include "../../mapObjects/MapObjects.h" 
+#include "../../mapObjects/MapObjects.h"
+
+#include <vstd/RNG.h>
 
 VCMI_LIB_NAMESPACE_BEGIN
 
@@ -95,7 +97,7 @@ void QuestArtifactPlacer::findZonesForQuestArts()
 	logGlobal->trace("Number of nearby zones suitable for quest artifacts: %d", questArtZones.size());
 }
 
-void QuestArtifactPlacer::placeQuestArtifacts(CRandomGenerator & rand)
+void QuestArtifactPlacer::placeQuestArtifacts(vstd::RNG & rand)
 {
 	for (const auto & artifactToPlace : questArtifactsToPlace)
 	{

+ 2 - 4
lib/rmg/modificators/QuestArtifactPlacer.h

@@ -15,8 +15,6 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-class CRandomGenerator;
-
 class QuestArtifactPlacer : public Modificator
 {
 public:
@@ -33,7 +31,7 @@ public:
 	void rememberPotentialArtifactToReplace(CGObjectInstance* obj);
 	CGObjectInstance * drawObjectToReplace();
 	std::vector<CGObjectInstance*> getPossibleArtifactsToReplace() const;
-	void placeQuestArtifacts(CRandomGenerator & rand);
+	void placeQuestArtifacts(vstd::RNG & rand);
 	void dropReplacedArtifact(CGObjectInstance* obj);
 
 	size_t getMaxQuestArtifactCount() const;
@@ -50,4 +48,4 @@ protected:
 	std::vector<ArtifactID> questArtifacts;
 };
 
-VCMI_LIB_NAMESPACE_END
+VCMI_LIB_NAMESPACE_END

+ 2 - 0
lib/rmg/modificators/RiverPlacer.cpp

@@ -27,6 +27,8 @@
 #include "WaterProxy.h"
 #include "RoadPlacer.h"
 
+#include <vstd/RNG.h>
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 const int RIVER_DELTA_ID = 143;

+ 0 - 1
lib/rmg/modificators/RockFiller.cpp

@@ -19,7 +19,6 @@
 #include "../CMapGenerator.h"
 #include "../Functions.h"
 #include "../../TerrainHandler.h"
-#include "../../CRandomGenerator.h"
 #include "../lib/mapping/CMapEditManager.h"
 #include "../TileInfo.h"
 #include "../threadpool/MapProxy.h"

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است