| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 | /* * GameRandomizer.h, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * * License: GNU General Public License v2.0 or later * Full text of license available in license.txt file, in main folder * */#pragma once#include "callback/IGameRandomizer.h"#include "CRandomGenerator.h"VCMI_LIB_NAMESPACE_BEGINenum class EGameSettings;class CGHeroInstance;class DLL_LINKAGE RandomizationBias{	int32_t accumulatedBias = 0;public:	/// Performs coin flip with specified success chance	/// Returns true with probability successChance percents, and false with probability totalWeight-successChance percents	bool roll(vstd::RNG & generator, int successChance, int totalWeight, int biasValue);	template<typename Handler>	void serialize(Handler & h)	{		h & accumulatedBias;	}};/// Biased randomizer that has following properties:/// - at bias value of 0 it acts as statistical random generator, just like vstd::RNG/// - at bias value of 100 it guarantees that it will take at most 100/chance rolls till succesfull roll/// - at bias value between 1..99 similar guarantee is also provided, but with larger number of rolls/// No matter what bias is, statistical probability on large number of rolls remains the same/// Its goal is to simulate human expectations of random distributions and reduce frustration from "bad" rollsclass DLL_LINKAGE RandomGeneratorWithBias{	CRandomGenerator generator;	RandomizationBias bias;public:	explicit RandomGeneratorWithBias(int seed = 0);	/// Performs coin flip with specified success chance	/// Returns true with probability successChance percents, and false with probability 100-successChance percents	bool roll(int successChance, int totalWeight, int biasValue);	template<typename Handler>	void serialize(Handler & h)	{		h & generator;		h & bias;	}};class DLL_LINKAGE GameRandomizer final : public IGameRandomizer{	struct HeroSkillRandomizer	{		explicit HeroSkillRandomizer(int seed = 0)			: seed(seed)		{}		CRandomGenerator seed;		int8_t magicSchoolCounter = 1;		int8_t wisdomCounter = 1;		template<typename Handler>		void serialize(Handler & h)		{			h & seed;			h & magicSchoolCounter;			h & wisdomCounter;		}	};	const IGameInfoCallback & gameInfo;	/// Global RNG, for use when there is no specialized instance	CRandomGenerator globalRandomNumberGenerator;	/// Stores number of times each artifact was placed on map via randomization	std::map<ArtifactID, int> allocatedArtifacts;	std::map<HeroTypeID, HeroSkillRandomizer> heroSkillSeed;	std::map<ObjectInstanceID, RandomGeneratorWithBias> goodMoraleSeed;	std::map<ObjectInstanceID, RandomGeneratorWithBias> badMoraleSeed;	std::map<ObjectInstanceID, RandomGeneratorWithBias> goodLuckSeed;	std::map<ObjectInstanceID, RandomGeneratorWithBias> badLuckSeed;	std::map<ObjectInstanceID, RandomGeneratorWithBias> combatAbilitySeed;	bool rollMoraleLuck(std::map<ObjectInstanceID, RandomGeneratorWithBias> & seeds, ObjectInstanceID actor, int moraleLuckValue, EGameSettings biasValue, EGameSettings diceSize, EGameSettings diceWeights);public:	explicit GameRandomizer(const IGameInfoCallback & gameInfo);	~GameRandomizer();	PrimarySkill rollPrimarySkillForLevelup(const CGHeroInstance * hero) override;	SecondarySkill rollSecondarySkillForLevelup(const CGHeroInstance * hero, const std::set<SecondarySkill> & candidates) override;	bool rollGoodMorale(ObjectInstanceID actor, int moraleValue);	bool rollBadMorale(ObjectInstanceID actor, int moraleValue);	bool rollGoodLuck(ObjectInstanceID actor, int luckValue);	bool rollBadLuck(ObjectInstanceID actor, int luckValue);	bool rollCombatAbility(ObjectInstanceID actor, int percentageChance);	CreatureID rollCreature() override;	CreatureID rollCreature(int tier) override;	ArtifactID rollArtifact() override;	ArtifactID rollArtifact(EArtifactClass type) override;	ArtifactID rollArtifact(std::set<ArtifactID> filtered) override;	std::vector<ArtifactID> rollMarketArtifactSet() override;	vstd::RNG & getDefault() override;	void setSeed(int newSeed);	template<typename Handler>	void serialize(Handler & h)	{		h & globalRandomNumberGenerator;		if (h.hasFeature(Handler::Version::RANDOMIZATION_REWORK))		{			h & allocatedArtifacts;			h & heroSkillSeed;			h & goodMoraleSeed;			h & badMoraleSeed;			h & goodLuckSeed;			h & badLuckSeed;			h & combatAbilitySeed;		}	}};VCMI_LIB_NAMESPACE_END
 |