mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 07:23:54 +00:00
Merge branch 'prng-fixes' into 'master'
More determinism See merge request OpenMW/openmw!1874
This commit is contained in:
commit
b9b8cefb4d
9 changed files with 24 additions and 15 deletions
|
@ -359,7 +359,10 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
// findRandomPointAroundCircle uses wanderDistance as limit for random and not as exact distance
|
// findRandomPointAroundCircle uses wanderDistance as limit for random and not as exact distance
|
||||||
if (const auto destination = DetourNavigator::findRandomPointAroundCircle(*navigator, halfExtents,
|
if (const auto destination = DetourNavigator::findRandomPointAroundCircle(*navigator, halfExtents,
|
||||||
mInitialActorPosition, wanderDistance, navigatorFlags))
|
mInitialActorPosition, wanderDistance, navigatorFlags, []() {
|
||||||
|
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
|
||||||
|
return Misc::Rng::rollProbability(prng);
|
||||||
|
}))
|
||||||
mDestination = *destination;
|
mDestination = *destination;
|
||||||
else
|
else
|
||||||
mDestination = getRandomPointAround(mInitialActorPosition, wanderRadius);
|
mDestination = getRandomPointAround(mInitialActorPosition, wanderRadius);
|
||||||
|
|
|
@ -142,7 +142,8 @@ void HeadAnimationTime::setEnabled(bool enabled)
|
||||||
|
|
||||||
void HeadAnimationTime::resetBlinkTimer()
|
void HeadAnimationTime::resetBlinkTimer()
|
||||||
{
|
{
|
||||||
mBlinkTimer = -(2.0f + Misc::Rng::rollDice(6));
|
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
|
||||||
|
mBlinkTimer = -(2.0f + Misc::Rng::rollDice(6, prng));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HeadAnimationTime::update(float dt)
|
void HeadAnimationTime::update(float dt)
|
||||||
|
|
|
@ -226,8 +226,8 @@ namespace MWWorld
|
||||||
if(transitionRatio >= mThunderThreshold && mThunderFrequency > 0.0f)
|
if(transitionRatio >= mThunderThreshold && mThunderFrequency > 0.0f)
|
||||||
{
|
{
|
||||||
flashDecrement(elapsedSeconds);
|
flashDecrement(elapsedSeconds);
|
||||||
|
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
|
||||||
if(Misc::Rng::rollProbability() <= thunderChance(transitionRatio, elapsedSeconds))
|
if(Misc::Rng::rollProbability(prng) <= thunderChance(transitionRatio, elapsedSeconds))
|
||||||
{
|
{
|
||||||
lightningAndThunder();
|
lightningAndThunder();
|
||||||
}
|
}
|
||||||
|
@ -265,7 +265,8 @@ namespace MWWorld
|
||||||
// They appear to go from 0 (brightest, closest) to 3 (faintest, farthest). The value of 0.25 per distance
|
// They appear to go from 0 (brightest, closest) to 3 (faintest, farthest). The value of 0.25 per distance
|
||||||
// was derived by setting the Flash Decrement to 0.1 and measuring how long each value took to decay to 0.
|
// was derived by setting the Flash Decrement to 0.1 and measuring how long each value took to decay to 0.
|
||||||
// TODO: Determine the distribution of each distance to see if it's evenly weighted.
|
// TODO: Determine the distribution of each distance to see if it's evenly weighted.
|
||||||
unsigned int distance = Misc::Rng::rollDice(4);
|
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
|
||||||
|
unsigned int distance = Misc::Rng::rollDice(4, prng);
|
||||||
// Flash brightness appears additive, since if multiple strikes occur, it takes longer for it to decay to 0.
|
// Flash brightness appears additive, since if multiple strikes occur, it takes longer for it to decay to 0.
|
||||||
mFlashBrightness += 1 - (distance * 0.25f);
|
mFlashBrightness += 1 - (distance * 0.25f);
|
||||||
MWBase::Environment::get().getSoundManager()->playSound(mThunderSoundID[distance], 1.0, 1.0);
|
MWBase::Environment::get().getSoundManager()->playSound(mThunderSoundID[distance], 1.0, 1.0);
|
||||||
|
@ -348,7 +349,8 @@ namespace MWWorld
|
||||||
// All probabilities must add to 100 (responsibility of the user).
|
// All probabilities must add to 100 (responsibility of the user).
|
||||||
// If chances A and B has values 30 and 70 then by generating 100 numbers 1..100, 30% will be lesser or equal 30
|
// If chances A and B has values 30 and 70 then by generating 100 numbers 1..100, 30% will be lesser or equal 30
|
||||||
// and 70% will be greater than 30 (in theory).
|
// and 70% will be greater than 30 (in theory).
|
||||||
int chance = Misc::Rng::rollDice(100) + 1; // 1..100
|
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
|
||||||
|
int chance = Misc::Rng::rollDice(100, prng) + 1; // 1..100
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(; static_cast<size_t>(i) < mChances.size(); ++i)
|
for(; static_cast<size_t>(i) < mChances.size(); ++i)
|
||||||
|
@ -685,7 +687,8 @@ namespace MWWorld
|
||||||
currentSpeed = targetSpeed;
|
currentSpeed = targetSpeed;
|
||||||
|
|
||||||
float multiplier = mWeatherSettings[weatherId].mRainEffect.empty() ? 1.f : 0.5f;
|
float multiplier = mWeatherSettings[weatherId].mRainEffect.empty() ? 1.f : 0.5f;
|
||||||
float updatedSpeed = (Misc::Rng::rollClosedProbability() - 0.5f) * multiplier * targetSpeed + currentSpeed;
|
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
|
||||||
|
float updatedSpeed = (Misc::Rng::rollClosedProbability(prng) - 0.5f) * multiplier * targetSpeed + currentSpeed;
|
||||||
|
|
||||||
if (updatedSpeed > 0.5f * targetSpeed && updatedSpeed < 2.f * targetSpeed)
|
if (updatedSpeed > 0.5f * targetSpeed && updatedSpeed < 2.f * targetSpeed)
|
||||||
currentSpeed = updatedSpeed;
|
currentSpeed = updatedSpeed;
|
||||||
|
|
|
@ -3697,7 +3697,7 @@ namespace MWWorld
|
||||||
const ESM::CreatureLevList* list = mStore.get<ESM::CreatureLevList>().find(creatureList);
|
const ESM::CreatureLevList* list = mStore.get<ESM::CreatureLevList>().find(creatureList);
|
||||||
|
|
||||||
static int iNumberCreatures = mStore.get<ESM::GameSetting>().find("iNumberCreatures")->mValue.getInteger();
|
static int iNumberCreatures = mStore.get<ESM::GameSetting>().find("iNumberCreatures")->mValue.getInteger();
|
||||||
int numCreatures = 1 + Misc::Rng::rollDice(iNumberCreatures); // [1, iNumberCreatures]
|
int numCreatures = 1 + Misc::Rng::rollDice(iNumberCreatures, mPrng); // [1, iNumberCreatures]
|
||||||
|
|
||||||
for (int i=0; i<numCreatures; ++i)
|
for (int i=0; i<numCreatures; ++i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -819,7 +819,8 @@ namespace
|
||||||
|
|
||||||
Misc::Rng::init(42);
|
Misc::Rng::init(42);
|
||||||
|
|
||||||
const auto result = findRandomPointAroundCircle(*mNavigator, mAgentHalfExtents, mStart, 100.0, Flag_walk);
|
const auto result = findRandomPointAroundCircle(*mNavigator, mAgentHalfExtents, mStart, 100.0, Flag_walk,
|
||||||
|
[]() { return Misc::Rng::rollClosedProbability(); });
|
||||||
|
|
||||||
ASSERT_THAT(result, Optional(Vec3fEq(70.35845947265625, 335.592041015625, -2.6667339801788330078125)))
|
ASSERT_THAT(result, Optional(Vec3fEq(70.35845947265625, 335.592041015625, -2.6667339801788330078125)))
|
||||||
<< (result ? *result : osg::Vec3f());
|
<< (result ? *result : osg::Vec3f());
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
namespace DetourNavigator
|
namespace DetourNavigator
|
||||||
{
|
{
|
||||||
std::optional<osg::Vec3f> findRandomPointAroundCircle(const dtNavMesh& navMesh, const osg::Vec3f& halfExtents,
|
std::optional<osg::Vec3f> findRandomPointAroundCircle(const dtNavMesh& navMesh, const osg::Vec3f& halfExtents,
|
||||||
const osg::Vec3f& start, const float maxRadius, const Flags includeFlags, const DetourSettings& settings)
|
const osg::Vec3f& start, const float maxRadius, const Flags includeFlags, const DetourSettings& settings, float(*prng)())
|
||||||
{
|
{
|
||||||
dtNavMeshQuery navMeshQuery;
|
dtNavMeshQuery navMeshQuery;
|
||||||
if (!initNavMeshQuery(navMeshQuery, navMesh, settings.mMaxNavMeshQueryNodes))
|
if (!initNavMeshQuery(navMeshQuery, navMesh, settings.mMaxNavMeshQueryNodes))
|
||||||
|
@ -25,8 +25,9 @@ namespace DetourNavigator
|
||||||
|
|
||||||
dtPolyRef resultRef = 0;
|
dtPolyRef resultRef = 0;
|
||||||
osg::Vec3f resultPosition;
|
osg::Vec3f resultPosition;
|
||||||
|
|
||||||
navMeshQuery.findRandomPointAroundCircle(startRef, start.ptr(), maxRadius, &queryFilter,
|
navMeshQuery.findRandomPointAroundCircle(startRef, start.ptr(), maxRadius, &queryFilter,
|
||||||
[]() { return Misc::Rng::rollProbability(); }, &resultRef, resultPosition.ptr());
|
prng, &resultRef, resultPosition.ptr());
|
||||||
|
|
||||||
if (resultRef == 0)
|
if (resultRef == 0)
|
||||||
return std::optional<osg::Vec3f>();
|
return std::optional<osg::Vec3f>();
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace DetourNavigator
|
||||||
struct DetourSettings;
|
struct DetourSettings;
|
||||||
|
|
||||||
std::optional<osg::Vec3f> findRandomPointAroundCircle(const dtNavMesh& navMesh, const osg::Vec3f& halfExtents,
|
std::optional<osg::Vec3f> findRandomPointAroundCircle(const dtNavMesh& navMesh, const osg::Vec3f& halfExtents,
|
||||||
const osg::Vec3f& start, const float maxRadius, const Flags includeFlags, const DetourSettings& settings);
|
const osg::Vec3f& start, const float maxRadius, const Flags includeFlags, const DetourSettings& settings, float(*prng)());
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
namespace DetourNavigator
|
namespace DetourNavigator
|
||||||
{
|
{
|
||||||
std::optional<osg::Vec3f> findRandomPointAroundCircle(const Navigator& navigator, const osg::Vec3f& agentHalfExtents,
|
std::optional<osg::Vec3f> findRandomPointAroundCircle(const Navigator& navigator, const osg::Vec3f& agentHalfExtents,
|
||||||
const osg::Vec3f& start, const float maxRadius, const Flags includeFlags)
|
const osg::Vec3f& start, const float maxRadius, const Flags includeFlags, float(*prng)())
|
||||||
{
|
{
|
||||||
const auto navMesh = navigator.getNavMesh(agentHalfExtents);
|
const auto navMesh = navigator.getNavMesh(agentHalfExtents);
|
||||||
if (!navMesh)
|
if (!navMesh)
|
||||||
|
@ -14,7 +14,7 @@ namespace DetourNavigator
|
||||||
const auto& settings = navigator.getSettings();
|
const auto& settings = navigator.getSettings();
|
||||||
const auto result = DetourNavigator::findRandomPointAroundCircle(navMesh->lockConst()->getImpl(),
|
const auto result = DetourNavigator::findRandomPointAroundCircle(navMesh->lockConst()->getImpl(),
|
||||||
toNavMeshCoordinates(settings.mRecast, agentHalfExtents), toNavMeshCoordinates(settings.mRecast, start),
|
toNavMeshCoordinates(settings.mRecast, agentHalfExtents), toNavMeshCoordinates(settings.mRecast, start),
|
||||||
toNavMeshCoordinates(settings.mRecast, maxRadius), includeFlags, settings.mDetour);
|
toNavMeshCoordinates(settings.mRecast, maxRadius), includeFlags, settings.mDetour, prng);
|
||||||
if (!result)
|
if (!result)
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
return std::optional<osg::Vec3f>(fromNavMeshCoordinates(settings.mRecast, *result));
|
return std::optional<osg::Vec3f>(fromNavMeshCoordinates(settings.mRecast, *result));
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace DetourNavigator
|
||||||
* @return not empty optional with position if point is found and empty optional if point is not found.
|
* @return not empty optional with position if point is found and empty optional if point is not found.
|
||||||
*/
|
*/
|
||||||
std::optional<osg::Vec3f> findRandomPointAroundCircle(const Navigator& navigator, const osg::Vec3f& agentHalfExtents,
|
std::optional<osg::Vec3f> findRandomPointAroundCircle(const Navigator& navigator, const osg::Vec3f& agentHalfExtents,
|
||||||
const osg::Vec3f& start, const float maxRadius, const Flags includeFlags);
|
const osg::Vec3f& start, const float maxRadius, const Flags includeFlags, float(*prng)());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief raycast finds farest navmesh point from start on a line from start to end that has path from start.
|
* @brief raycast finds farest navmesh point from start on a line from start to end that has path from start.
|
||||||
|
|
Loading…
Reference in a new issue