mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-25 22:56:24 +00:00
feat(Core/Random): port random system from TrinityCore (#5454)
* feat(Core/Random): port random system from TrinityCore * lic * logic correct * MultimapErasePair move * whitespace 17:13:34 1. 'Containers.h'. Replace (1) 17:13:40 2. 'LootMgr.h'. Replace (1) 17:13:44 3. 'World.cpp'. Replace (1) 17:13:47 4. 'instance_scholomance.cpp'. Replace (1) * correct debug build
This commit is contained in:
229
src/common/Utilities/Containers.h
Normal file
229
src/common/Utilities/Containers.h
Normal file
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*/
|
||||
|
||||
#ifndef ACORE_CONTAINERS_H
|
||||
#define ACORE_CONTAINERS_H
|
||||
|
||||
#include "Define.h"
|
||||
#include "Random.h"
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace acore
|
||||
{
|
||||
template<class T>
|
||||
constexpr inline T* AddressOrSelf(T* ptr)
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
constexpr inline T* AddressOrSelf(T& not_ptr)
|
||||
{
|
||||
return std::addressof(not_ptr);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class CheckedBufferOutputIterator
|
||||
{
|
||||
public:
|
||||
using iterator_category = std::output_iterator_tag;
|
||||
using value_type = void;
|
||||
using pointer = T*;
|
||||
using reference = T&;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
CheckedBufferOutputIterator(T* buf, size_t n) : _buf(buf), _end(buf + n) {}
|
||||
|
||||
T& operator*() const { check(); return *_buf; }
|
||||
CheckedBufferOutputIterator& operator++() { check(); ++_buf; return *this; }
|
||||
CheckedBufferOutputIterator operator++(int) { CheckedBufferOutputIterator v = *this; operator++(); return v; }
|
||||
|
||||
[[nodiscard]] size_t remaining() const { return (_end - _buf); }
|
||||
|
||||
private:
|
||||
T* _buf;
|
||||
T* _end;
|
||||
|
||||
void check() const
|
||||
{
|
||||
if (!(_buf < _end))
|
||||
throw std::out_of_range("index");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace acore::Containers
|
||||
{
|
||||
// resizes <container> to have at most <requestedSize> elements
|
||||
// if it has more than <requestedSize> elements, the elements to keep are selected randomly
|
||||
template<class C>
|
||||
void RandomResize(C& container, std::size_t requestedSize)
|
||||
{
|
||||
static_assert(std::is_base_of<std::forward_iterator_tag, typename std::iterator_traits<typename C::iterator>::iterator_category>::value, "Invalid container passed to acore::Containers::RandomResize");
|
||||
|
||||
if (std::size(container) <= requestedSize)
|
||||
return;
|
||||
|
||||
auto keepIt = std::begin(container), curIt = std::begin(container);
|
||||
uint32 elementsToKeep = requestedSize, elementsToProcess = std::size(container);
|
||||
|
||||
while (elementsToProcess)
|
||||
{
|
||||
// this element has chance (elementsToKeep / elementsToProcess) of being kept
|
||||
if (urand(1, elementsToProcess) <= elementsToKeep)
|
||||
{
|
||||
if (keepIt != curIt)
|
||||
*keepIt = std::move(*curIt);
|
||||
|
||||
++keepIt;
|
||||
--elementsToKeep;
|
||||
}
|
||||
|
||||
++curIt;
|
||||
--elementsToProcess;
|
||||
}
|
||||
|
||||
container.erase(keepIt, std::end(container));
|
||||
}
|
||||
|
||||
template<class C, class Predicate>
|
||||
void RandomResize(C& container, Predicate&& predicate, std::size_t requestedSize)
|
||||
{
|
||||
//! First use predicate filter
|
||||
C containerCopy;
|
||||
std::copy_if(std::begin(container), std::end(container), std::inserter(containerCopy, std::end(containerCopy)), predicate);
|
||||
|
||||
if (requestedSize)
|
||||
RandomResize(containerCopy, requestedSize);
|
||||
|
||||
container = std::move(containerCopy);
|
||||
}
|
||||
|
||||
/*
|
||||
* Select a random element from a container.
|
||||
*
|
||||
* Note: container cannot be empty
|
||||
*/
|
||||
template<class C>
|
||||
inline auto SelectRandomContainerElement(C const& container) -> typename std::add_const<decltype(*std::begin(container))>::type&
|
||||
{
|
||||
auto it = std::begin(container);
|
||||
std::advance(it, urand(0, uint32(std::size(container)) - 1));
|
||||
return *it;
|
||||
}
|
||||
|
||||
/*
|
||||
* Select a random element from a container where each element has a different chance to be selected.
|
||||
*
|
||||
* @param container Container to select an element from
|
||||
* @param weights Chances of each element to be selected, must be in the same order as elements in container.
|
||||
* Caller is responsible for checking that sum of all weights is greater than 0.
|
||||
*
|
||||
* Note: container cannot be empty
|
||||
*/
|
||||
template<class C>
|
||||
inline auto SelectRandomWeightedContainerElement(C const& container, std::vector<double> weights) -> decltype(std::begin(container))
|
||||
{
|
||||
auto it = std::begin(container);
|
||||
std::advance(it, urandweighted(weights.size(), weights.data()));
|
||||
return it;
|
||||
}
|
||||
|
||||
/*
|
||||
* Select a random element from a container where each element has a different chance to be selected.
|
||||
*
|
||||
* @param container Container to select an element from
|
||||
* @param weightExtractor Function retrieving chance of each element in container, expected to take an element of the container and returning a double
|
||||
*
|
||||
* Note: container cannot be empty
|
||||
*/
|
||||
template<class C, class Fn>
|
||||
auto SelectRandomWeightedContainerElement(C const& container, Fn weightExtractor) -> decltype(std::begin(container))
|
||||
{
|
||||
std::vector<double> weights;
|
||||
weights.reserve(std::size(container));
|
||||
double weightSum = 0.0;
|
||||
|
||||
for (auto& val : container)
|
||||
{
|
||||
double weight = weightExtractor(val);
|
||||
weights.push_back(weight);
|
||||
weightSum += weight;
|
||||
}
|
||||
|
||||
if (weightSum <= 0.0)
|
||||
weights.assign(std::size(container), 1.0);
|
||||
|
||||
return SelectRandomWeightedContainerElement(container, weights);
|
||||
}
|
||||
|
||||
/*
|
||||
* @fn void acore::Containers::RandomShuffle(C& container)
|
||||
*
|
||||
* @brief Reorder the elements of the container randomly.
|
||||
*
|
||||
* @param container Container to reorder
|
||||
*/
|
||||
template<class C>
|
||||
inline void RandomShuffle(C& container)
|
||||
{
|
||||
std::shuffle(std::begin(container), std::end(container), RandomEngine::Instance());
|
||||
}
|
||||
|
||||
template<class K, class V, template<class, class, class...> class M, class... Rest>
|
||||
void MultimapErasePair(M<K, V, Rest...>& multimap, K const& key, V const& value)
|
||||
{
|
||||
auto range = multimap.equal_range(key);
|
||||
for (auto itr = range.first; itr != range.second;)
|
||||
{
|
||||
if (itr->second == value)
|
||||
itr = multimap.erase(itr);
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Container, typename Predicate>
|
||||
std::enable_if_t<std::is_move_assignable_v<decltype(*std::declval<Container>().begin())>, void> EraseIf(Container& c, Predicate p)
|
||||
{
|
||||
auto wpos = c.begin();
|
||||
for (auto rpos = c.begin(), end = c.end(); rpos != end; ++rpos)
|
||||
{
|
||||
if (!p(*rpos))
|
||||
{
|
||||
if (rpos != wpos)
|
||||
{
|
||||
std::swap(*rpos, *wpos);
|
||||
}
|
||||
++wpos;
|
||||
}
|
||||
}
|
||||
c.erase(wpos, c.end());
|
||||
}
|
||||
|
||||
template <typename Container, typename Predicate>
|
||||
std::enable_if_t<!std::is_move_assignable_v<decltype(*std::declval<Container>().begin())>, void> EraseIf(Container& c, Predicate p)
|
||||
{
|
||||
for (auto it = c.begin(); it != c.end();)
|
||||
{
|
||||
if (p(*it))
|
||||
{
|
||||
it = c.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif //! #ifdef ACORE_CONTAINERS_H
|
||||
84
src/common/Utilities/Random.cpp
Normal file
84
src/common/Utilities/Random.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||
* Copyright (C) 2008-2021 TrinityCore <http://www.trinitycore.org/>
|
||||
*/
|
||||
|
||||
#include "Random.h"
|
||||
#include "Errors.h"
|
||||
#include "SFMTRand.h"
|
||||
#include <memory>
|
||||
#include <random>
|
||||
|
||||
static thread_local std::unique_ptr<SFMTRand> sfmtRand;
|
||||
static RandomEngine engine;
|
||||
|
||||
static SFMTRand* GetRng()
|
||||
{
|
||||
if (!sfmtRand)
|
||||
sfmtRand = std::make_unique<SFMTRand>();
|
||||
|
||||
return sfmtRand.get();
|
||||
}
|
||||
|
||||
int32 irand(int32 min, int32 max)
|
||||
{
|
||||
ASSERT(max >= min);
|
||||
std::uniform_int_distribution<int32> uid(min, max);
|
||||
return uid(engine);
|
||||
}
|
||||
|
||||
uint32 urand(uint32 min, uint32 max)
|
||||
{
|
||||
ASSERT(max >= min);
|
||||
std::uniform_int_distribution<uint32> uid(min, max);
|
||||
return uid(engine);
|
||||
}
|
||||
|
||||
uint32 urandms(uint32 min, uint32 max)
|
||||
{
|
||||
ASSERT(std::numeric_limits<uint32>::max() / Milliseconds::period::den >= max);
|
||||
return urand(min * Milliseconds::period::den, max * Milliseconds::period::den);
|
||||
}
|
||||
|
||||
float frand(float min, float max)
|
||||
{
|
||||
ASSERT(max >= min);
|
||||
std::uniform_real_distribution<float> urd(min, max);
|
||||
return urd(engine);
|
||||
}
|
||||
|
||||
Milliseconds randtime(Milliseconds min, Milliseconds max)
|
||||
{
|
||||
long long diff = max.count() - min.count();
|
||||
ASSERT(diff >= 0);
|
||||
ASSERT(diff <= (uint32)-1);
|
||||
return min + Milliseconds(urand(0, diff));
|
||||
}
|
||||
|
||||
uint32 rand32()
|
||||
{
|
||||
return GetRng()->RandomUInt32();
|
||||
}
|
||||
|
||||
double rand_norm()
|
||||
{
|
||||
std::uniform_real_distribution<double> urd;
|
||||
return urd(engine);
|
||||
}
|
||||
|
||||
double rand_chance()
|
||||
{
|
||||
std::uniform_real_distribution<double> urd(0.0, 100.0);
|
||||
return urd(engine);
|
||||
}
|
||||
|
||||
uint32 urandweighted(size_t count, double const* chances)
|
||||
{
|
||||
std::discrete_distribution<uint32> dd(chances, chances + count);
|
||||
return dd(engine);
|
||||
}
|
||||
|
||||
RandomEngine& RandomEngine::Instance()
|
||||
{
|
||||
return engine;
|
||||
}
|
||||
67
src/common/Utilities/Random.h
Normal file
67
src/common/Utilities/Random.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||
* Copyright (C) 2008-2021 TrinityCore <http://www.trinitycore.org/>
|
||||
*/
|
||||
|
||||
#ifndef Random_h__
|
||||
#define Random_h__
|
||||
|
||||
#include "Define.h"
|
||||
#include "Duration.h"
|
||||
#include <limits>
|
||||
|
||||
/* Return a random number in the range min..max. */
|
||||
AC_COMMON_API int32 irand(int32 min, int32 max);
|
||||
|
||||
/* Return a random number in the range min..max (inclusive). */
|
||||
AC_COMMON_API uint32 urand(uint32 min, uint32 max);
|
||||
|
||||
/* Return a random millisecond value between min and max seconds. Functionally equivalent to urand(min*IN_MILLISECONDS, max*IN_MILLISECONDS). */
|
||||
AC_COMMON_API uint32 urandms(uint32 min, uint32 max);
|
||||
|
||||
/* Return a random number in the range 0 .. UINT32_MAX. */
|
||||
AC_COMMON_API uint32 rand32();
|
||||
|
||||
/* Return a random time in the range min..max (up to millisecond precision). Only works for values where millisecond difference is a valid uint32. */
|
||||
AC_COMMON_API Milliseconds randtime(Milliseconds min, Milliseconds max);
|
||||
|
||||
/* Return a random number in the range min..max */
|
||||
AC_COMMON_API float frand(float min, float max);
|
||||
|
||||
/* Return a random double from 0.0 to 1.0 (exclusive). */
|
||||
AC_COMMON_API double rand_norm();
|
||||
|
||||
/* Return a random double from 0.0 to 100.0 (exclusive). */
|
||||
AC_COMMON_API double rand_chance();
|
||||
|
||||
/* Return a random number in the range 0..count (exclusive) with each value having a different chance of happening */
|
||||
AC_COMMON_API uint32 urandweighted(size_t count, double const* chances);
|
||||
|
||||
/* Return true if a random roll fits in the specified chance (range 0-100). */
|
||||
inline bool roll_chance_f(float chance)
|
||||
{
|
||||
return chance > rand_chance();
|
||||
}
|
||||
|
||||
/* Return true if a random roll fits in the specified chance (range 0-100). */
|
||||
inline bool roll_chance_i(int chance)
|
||||
{
|
||||
return chance > irand(0, 99);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper satisfying UniformRandomNumberGenerator concept for use in <random> algorithms
|
||||
*/
|
||||
class AC_COMMON_API RandomEngine
|
||||
{
|
||||
public:
|
||||
typedef uint32 result_type;
|
||||
|
||||
static constexpr result_type min() { return std::numeric_limits<result_type>::min(); }
|
||||
static constexpr result_type max() { return std::numeric_limits<result_type>::max(); }
|
||||
result_type operator()() const { return rand32(); }
|
||||
|
||||
static RandomEngine& Instance();
|
||||
};
|
||||
|
||||
#endif // Random_h__
|
||||
108
src/common/Utilities/SFMTRand.cpp
Normal file
108
src/common/Utilities/SFMTRand.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||
* Copyright (C) 2008-2021 TrinityCore <http://www.trinitycore.org/>
|
||||
*/
|
||||
|
||||
#include "SFMTRand.h"
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <random>
|
||||
#include <ctime>
|
||||
|
||||
#if defined(__aarch64__)
|
||||
#if defined(__clang__)
|
||||
#include <mm_malloc.h>
|
||||
#elif defined(__GNUC__)
|
||||
static __inline__ void *__attribute__((__always_inline__, __nodebug__, __malloc__))
|
||||
_mm_malloc(size_t __size, size_t __align)
|
||||
{
|
||||
if (__align == 1)
|
||||
{
|
||||
return malloc(__size);
|
||||
}
|
||||
|
||||
if (!(__align & (__align - 1)) && __align < sizeof(void *))
|
||||
__align = sizeof(void *);
|
||||
|
||||
void *__mallocedMemory;
|
||||
|
||||
if (posix_memalign(&__mallocedMemory, __align, __size))
|
||||
return NULL;
|
||||
|
||||
return __mallocedMemory;
|
||||
}
|
||||
|
||||
static __inline__ void __attribute__((__always_inline__, __nodebug__))
|
||||
_mm_free(void *__p)
|
||||
{
|
||||
free(__p);
|
||||
}
|
||||
#else
|
||||
#error aarch64 only on clang and gcc
|
||||
#endif
|
||||
#else
|
||||
#include <emmintrin.h>
|
||||
#endif
|
||||
|
||||
SFMTRand::SFMTRand()
|
||||
{
|
||||
std::random_device dev;
|
||||
|
||||
if (dev.entropy() > 0)
|
||||
{
|
||||
std::array<uint32, SFMT_N32> seed;
|
||||
std::generate(seed.begin(), seed.end(), std::ref(dev));
|
||||
|
||||
sfmt_init_by_array(&_state, seed.data(), seed.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
sfmt_init_gen_rand(&_state, uint32(time(nullptr)));
|
||||
}
|
||||
}
|
||||
|
||||
uint32 SFMTRand::RandomUInt32() // Output random bits
|
||||
{
|
||||
return sfmt_genrand_uint32(&_state);
|
||||
}
|
||||
|
||||
void* SFMTRand::operator new(size_t size, std::nothrow_t const&)
|
||||
{
|
||||
return _mm_malloc(size, 16);
|
||||
}
|
||||
|
||||
void SFMTRand::operator delete(void* ptr, std::nothrow_t const&)
|
||||
{
|
||||
_mm_free(ptr);
|
||||
}
|
||||
|
||||
void* SFMTRand::operator new(size_t size)
|
||||
{
|
||||
return _mm_malloc(size, 16);
|
||||
}
|
||||
|
||||
void SFMTRand::operator delete(void* ptr)
|
||||
{
|
||||
_mm_free(ptr);
|
||||
}
|
||||
|
||||
void* SFMTRand::operator new[](size_t size, std::nothrow_t const&)
|
||||
{
|
||||
return _mm_malloc(size, 16);
|
||||
}
|
||||
|
||||
void SFMTRand::operator delete[](void* ptr, std::nothrow_t const&)
|
||||
{
|
||||
_mm_free(ptr);
|
||||
}
|
||||
|
||||
void* SFMTRand::operator new[](size_t size)
|
||||
{
|
||||
return _mm_malloc(size, 16);
|
||||
}
|
||||
|
||||
void SFMTRand::operator delete[](void* ptr)
|
||||
{
|
||||
_mm_free(ptr);
|
||||
}
|
||||
33
src/common/Utilities/SFMTRand.h
Normal file
33
src/common/Utilities/SFMTRand.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||
* Copyright (C) 2008-2021 TrinityCore <http://www.trinitycore.org/>
|
||||
*/
|
||||
|
||||
#ifndef SFMTRand_h__
|
||||
#define SFMTRand_h__
|
||||
|
||||
#include "Define.h"
|
||||
#include <SFMT.h>
|
||||
#include <new>
|
||||
|
||||
/*
|
||||
* C++ Wrapper for SFMT
|
||||
*/
|
||||
class SFMTRand
|
||||
{
|
||||
public:
|
||||
SFMTRand();
|
||||
uint32 RandomUInt32(); // Output random bits
|
||||
void* operator new(size_t size, std::nothrow_t const&);
|
||||
void operator delete(void* ptr, std::nothrow_t const&);
|
||||
void* operator new(size_t size);
|
||||
void operator delete(void* ptr);
|
||||
void* operator new[](size_t size, std::nothrow_t const&);
|
||||
void operator delete[](void* ptr, std::nothrow_t const&);
|
||||
void* operator new[](size_t size);
|
||||
void operator delete[](void* ptr);
|
||||
private:
|
||||
sfmt_t _state;
|
||||
};
|
||||
|
||||
#endif // SFMTRand_h__
|
||||
@@ -10,62 +10,11 @@
|
||||
#include "Log.h"
|
||||
#include "Errors.h"
|
||||
#include "TypeList.h"
|
||||
#include <ace/Task.h>
|
||||
#include "SFMT.h"
|
||||
#include "Errors.h" // for ASSERT
|
||||
#include <ace/TSS_T.h>
|
||||
#include <array>
|
||||
#include <cwchar>
|
||||
#include <string>
|
||||
#include <random>
|
||||
|
||||
typedef ACE_TSS<SFMTRand> SFMTRandTSS;
|
||||
static SFMTRandTSS sfmtRand;
|
||||
static SFMTEngine engine;
|
||||
|
||||
int32 irand(int32 min, int32 max)
|
||||
{
|
||||
ASSERT(max >= min);
|
||||
return int32(sfmtRand->IRandom(min, max));
|
||||
}
|
||||
|
||||
uint32 urand(uint32 min, uint32 max)
|
||||
{
|
||||
ASSERT(max >= min);
|
||||
return sfmtRand->URandom(min, max);
|
||||
}
|
||||
|
||||
float frand(float min, float max)
|
||||
{
|
||||
ASSERT(max >= min);
|
||||
return float(sfmtRand->Random() * (max - min) + min);
|
||||
}
|
||||
|
||||
uint32 rand32()
|
||||
{
|
||||
return int32(sfmtRand->BRandom());
|
||||
}
|
||||
|
||||
double rand_norm()
|
||||
{
|
||||
return sfmtRand->Random();
|
||||
}
|
||||
|
||||
double rand_chance()
|
||||
{
|
||||
return sfmtRand->Random() * 100.0;
|
||||
}
|
||||
|
||||
uint32 urandweighted(size_t count, double const* chances)
|
||||
{
|
||||
std::discrete_distribution<uint32> dd(chances, chances + count);
|
||||
return dd(SFMTEngine::Instance());
|
||||
}
|
||||
|
||||
SFMTEngine& SFMTEngine::Instance()
|
||||
{
|
||||
return engine;
|
||||
}
|
||||
#include <ace/Default_Constants.h>
|
||||
|
||||
Tokenizer::Tokenizer(const std::string& src, const char sep, uint32 vectorReserve)
|
||||
{
|
||||
|
||||
@@ -71,38 +71,6 @@ uint32 TimeStringToSecs(const std::string& timestring);
|
||||
std::string TimeToTimestampStr(time_t t);
|
||||
std::string TimeToHumanReadable(time_t t);
|
||||
|
||||
/* Return a random number in the range min..max. */
|
||||
int32 irand(int32 min, int32 max);
|
||||
|
||||
/* Return a random number in the range min..max (inclusive). */
|
||||
uint32 urand(uint32 min, uint32 max);
|
||||
|
||||
/* Return a random number in the range 0 .. UINT32_MAX. */
|
||||
uint32 rand32();
|
||||
|
||||
/* Return a random number in the range min..max */
|
||||
float frand(float min, float max);
|
||||
|
||||
/* Return a random double from 0.0 to 1.0 (exclusive). */
|
||||
double rand_norm();
|
||||
|
||||
/* Return a random double from 0.0 to 100.0 (exclusive). */
|
||||
double rand_chance();
|
||||
|
||||
uint32 urandweighted(size_t count, double const* chances);
|
||||
|
||||
/* Return true if a random roll fits in the specified chance (range 0-100). */
|
||||
inline bool roll_chance_f(float chance)
|
||||
{
|
||||
return chance > rand_chance();
|
||||
}
|
||||
|
||||
/* Return true if a random roll fits in the specified chance (range 0-100). */
|
||||
inline bool roll_chance_i(int32 chance)
|
||||
{
|
||||
return chance > irand(0, 99);
|
||||
}
|
||||
|
||||
inline void ApplyPercentModFloatVar(float& var, float val, bool apply)
|
||||
{
|
||||
if (val == -100.0f) // prevent set var to zero
|
||||
@@ -582,21 +550,6 @@ bool CompareValues(ComparisionType type, T val1, T val2)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SFMT wrapper satisfying UniformRandomNumberGenerator concept for use in <random> algorithms
|
||||
*/
|
||||
class SFMTEngine
|
||||
{
|
||||
public:
|
||||
typedef uint32 result_type;
|
||||
|
||||
static constexpr result_type min() { return std::numeric_limits<result_type>::min(); }
|
||||
static constexpr result_type max() { return std::numeric_limits<result_type>::max(); }
|
||||
result_type operator()() const { return rand32(); }
|
||||
|
||||
static SFMTEngine& Instance();
|
||||
};
|
||||
|
||||
class EventMap
|
||||
{
|
||||
typedef std::multimap<uint32, uint32> EventStore;
|
||||
|
||||
Reference in New Issue
Block a user