Merge remote-tracking branch 'upstream/master' into spaupdate03

This commit is contained in:
KayenEQ
2021-07-30 13:51:16 -04:00
28 changed files with 591 additions and 84 deletions
+1
View File
@@ -451,6 +451,7 @@ SET(repositories
)
SET(common_headers
additive_lagged_fibonacci_engine.h
any.h
base_packet.h
base_data.h
+147
View File
@@ -0,0 +1,147 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2021 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#pragma once
#include <cstdint>
#include <limits>
#include <type_traits>
#include <algorithm>
#include <iostream>
/*
* This is an additive lagged fibonacci generator as seen in The Art of Computer Programming, Vol. 2
* This should roughly match the implementation that EQ's client uses and be compatible with our Random class
*
* EQ's rand looks like it was from an example implementation that as posted on pscode.com
*
* You might also want to consider defining BIASED_INT_DIST as well to more closely match EQ
*/
namespace EQ {
template<typename UIntType, size_t w, size_t j, size_t k>
class additive_lagged_fibonacci_engine {
static_assert(std::is_unsigned<UIntType>::value, "result_type must be an unsigned integral type");
static_assert(0u < j && j < k, "0 < j < k");
static_assert(0u < w && w <= std::numeric_limits<UIntType>::digits,
"template argument substituting w out of bounds");
public:
using result_type = UIntType;
static constexpr size_t word_size = w;
static constexpr size_t short_lag = j;
static constexpr size_t long_lag = k;
static constexpr result_type default_seed = 19780503u; // default for subtract_with_carry_engine
additive_lagged_fibonacci_engine() : additive_lagged_fibonacci_engine(default_seed) {}
explicit additive_lagged_fibonacci_engine(result_type sd) { seed(sd); }
void seed(result_type seed = default_seed)
{
state1 = long_lag - long_lag;
state2 = long_lag - short_lag;
state[0] = static_cast<int>(seed) & ((1u << word_size) - 1);
state[1] = 1;
for (int i = 2; i < long_lag; ++i)
state[i] = (state[i - 1] + state[i - 2]) & ((1u << word_size) - 1);
return;
}
// TODO: seed via seed_seq
static constexpr result_type min() { return 0; }
static constexpr result_type max() { return ((1u << word_size) - 1) >> 6; }
void discard(unsigned long long z) {
for (; z != 0ULL; --z)
(*this)();
}
result_type operator()() {
result_type rand = (state[state1] + state[state2]) & ((1u << word_size) - 1);
state[state1] = rand;
if (++state1 == long_lag)
state1 = 0;
if (++state2 == long_lag)
state2 = 0;
return rand >> 6;
}
private:
result_type state1;
result_type state2;
result_type state[long_lag];
public:
template<typename UInt, size_t W, size_t J, size_t K>
friend bool operator==(const additive_lagged_fibonacci_engine<UInt, W, J, K> &x,
const additive_lagged_fibonacci_engine<UInt, W, J, K> &y)
{
return std::equal(x.state, x.state + long_lag, y.state) && x.state1 == y.state1 &&
x.state2 == y.state2;
}
template<typename UInt, size_t W, size_t J, size_t K>
friend bool operator!=(const additive_lagged_fibonacci_engine<UInt, W, J, K> &x,
const additive_lagged_fibonacci_engine<UInt, W, J, K> &y)
{ return !(x == y); }
template<typename UInt, size_t W, size_t J, size_t K, typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits> &
operator<<(std::basic_istream<CharT, Traits> &os, additive_lagged_fibonacci_engine<UInt, W, J, K> &x)
{
using ios_base = typename std::basic_istream<CharT, Traits>::ios_base;
const typename ios_base::fmtflags flags = os.flags();
const CharT fill = os.fill();
const CharT space = os.widen(' ');
os.flags(ios_base::dec | ios_base::fixed | ios_base::left);
os.fill(space);
for (size_t i = 0; i < long_lag; ++i)
os << x.state[i] << space;
os << x.state1 << space << x.state2;
os.flags(flags);
os.fill(fill);
return os;
}
template<typename UInt, size_t W, size_t J, size_t K, typename CharT, typename Traits>
friend std::basic_istream<CharT, Traits> &
operator>>(std::basic_istream<CharT, Traits> &is, additive_lagged_fibonacci_engine<UInt, W, J, K> &x)
{
using ios_base = typename std::basic_istream<CharT, Traits>::ios_base;
const typename ios_base::fmtflags flags = is.flags();
is.flags(ios_base::dec | ios_base::skipws);
for (size_t i = 0; i < long_lag; ++i)
is >> x.state[i];
is >> x.state1;
is >> x.state2;
is.flags(flags);
return is;
}
};
using EQRand = additive_lagged_fibonacci_engine<uint32_t, 30, 24, 55>;
};
+39 -7
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
Copyright (C) 2001-2021 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -25,10 +25,24 @@
#include <iterator>
#include <type_traits>
/* This uses mt19937 seeded with the std::random_device
* The idea is to have this be included as a member of another class
* so mocking out for testing is easier
* If you need to reseed random.Reseed()
#ifdef USE_SFMT19937
// only GCC supports, so lets turn it off
#ifndef __GNUC__
#undef USE_SFMT19937
#endif
#ifdef __clang__
#undef USE_SFMT19937
#endif
#endif
#ifdef USE_ADDITIVE_LFIB_PRNG
#include "additive_lagged_fibonacci_engine.h"
#elif defined(USE_SFMT19937)
#include <ext/random>
#endif
/* This uses mt19937 (or other compatible engine) seeded with the std::random_device. The idea is to have this be
* included as a member of another class so mocking out for testing is easier If you need to reseed random.Reseed()
* Eventually this should be derived from an abstract base class
*/
@@ -40,7 +54,12 @@ namespace EQ {
{
if (low > high)
std::swap(low, high);
// EQ uses biased int distribution, so I guess we can support it :P
#ifdef BIASED_INT_DIST
return low + m_gen() % (high - low + 1);
#else
return int_dist(m_gen, int_param_t(low, high)); // [low, high]
#endif
}
// AKA old MakeRandomFloat
@@ -98,11 +117,24 @@ namespace EQ {
}
private:
#ifndef BIASED_INT_DIST
typedef std::uniform_int_distribution<int>::param_type int_param_t;
typedef std::uniform_real_distribution<double>::param_type real_param_t;
std::mt19937 m_gen;
std::uniform_int_distribution<int> int_dist;
#endif
typedef std::uniform_real_distribution<double>::param_type real_param_t;
std::uniform_real_distribution<double> real_dist;
// define USE_CUSTOM_PRNG_ENGINE to any supported random engine like:
// #define USE_CUSTOM_PRNG_ENGINE std::default_random_engine
#ifdef USE_ADDITIVE_LFIB_PRNG
EQRand
#elif defined(USE_SFMT19937)
__gnu_cxx::sfmt19937
#elif defined(USE_CUSTOM_PRNG_ENGINE)
USE_CUSTOM_PRNG_ENGINE
#else
std::mt19937
#endif
m_gen;
};
}
+9 -4
View File
@@ -609,7 +609,7 @@ typedef enum {
#define SE_TradeSkillMastery 263 // implemented - lets you raise more than one tradeskill above master.
#define SE_HastenedAASkill 264 // implemented
#define SE_MasteryofPast 265 // implemented[AA] - Spells less than effect values level can not be fizzled
#define SE_ExtraAttackChance 266 // implemented - increase chance to score an extra attack with a 2-Handed Weapon.
#define SE_ExtraAttackChance 266 // implemented, @OffBonus, gives your double attacks a percent chance to perform an extra attack with 2-handed primary weapon, base: chance, limit: amt attacks, max: none
#define SE_AddPetCommand 267 // implemented - sets command base2 to base1
#define SE_ReduceTradeskillFail 268 // implemented - reduces chance to fail with given tradeskill by a percent chance
#define SE_MaxBindWound 269 // implemented[AA] - Increase max HP you can bind wound.
@@ -825,11 +825,16 @@ typedef enum {
#define SE_Ff_Value_Min 479 // implemented, @Ff, Minimum base value of a spell that can be focused, base: spells to be focused base1 value
#define SE_Ff_Value_Max 480 // implemented, @Ff, Max base value of a spell that can be focused, base: spells to be focused base1 value
#define SE_Fc_Cast_Spell_On_Land 481 // implemented, @Fc, On Target, cast spell if hit by spell, base: chance pct, limit: spellid
//#define SE_Skill_Base_Damage_Mod 482 //
#define SE_Fc_Spell_Damage_Pct_IncomingPC 483 // implemented, @Fc, On Target, spell damage taken mod pct, base: min pct, limit: max pct
#define SE_Fc_Spell_Damage_Amt_IncomingPC 484 // implemented, @Fc, On Target, damage taken flat amt, base: amt
#define SE_Ff_CasterClass 485 // implemented, @Ff, Caster of spell on target with a focus effect that is checked by incoming spells must be specified class(es). base1: class(es), Note: Set multiple classes same as would for items
#define SE_Ff_Same_Caster 486 // implemented, @Ff, Caster of spell on target with a focus effect that is checked by incoming spells, base1: 0=Must be different caster 1=Must be same caster
#define SE_Fc_Cast_Spell_On_Land 481 // Implemented - [FOCUS] Spells cast on target with this Focus Effect will have chance to cause a Spell to be cast if limits met.
#define SE_Skill_Base_Damage_Mod 482 // implemented, @OffBonus, modify base melee damage by percent, base: pct, limit: skill(-1=ALL), max: none
#define SE_Fc_Spell_Damage_Pct_IncomingPC 483 // Implemented - [FOCUS] modifies incoming spell damage by percent
#define SE_Fc_Spell_Damage_Amt_IncomingPC 484 // Implemented - [FOCUS] modifies incoming spell damage by flat amount. Typically adds damage to incoming spells.
#define SE_Ff_CasterClass 485 // Implemented - [FOCUS LIMIT] Caster of spell on target with a focus effect that is checked by incoming spells must be specified class.
#define SE_Ff_Same_Caster 486 // Implemented - [FOCUS LIMIT] Caster of spell on target with a focus effect that is checked by incoming spells 0=Must be different caster 1=Must be same caster
//#define SE_Extend_Tradeskill_Cap 487 //
//#define SE_Defender_Melee_Force_Pct_PC 488 //
//#define SE_Worn_Endurance_Regen_Cap 489 //
@@ -841,8 +846,8 @@ typedef enum {
#define SE_Ff_DurationMax 495 // implemented, @Ff, Max duration of spell that can be focused, base: tics
#define SE_Critical_Melee_Damage_Mod_Max 496 // implemented - increase or decrease by percent critical damage (not stackable)
//#define SE_Ff_FocusCastProcNoBypass 497 //
//#define SE_AddExtraAttackPct_1h_Primary 498 //
//#define SE_AddExtraAttackPct_1h_Secondary 499 //
#define SE_AddExtraAttackPct_1h_Primary 498 // implemented, @OffBonus, gives your double attacks a percent chance to perform an extra attack with 1-handed primary weapon, base: chance, limit: amt attacks, max: none
#define SE_AddExtraAttackPct_1h_Secondary 499 //implemented, @OffBonus, gives your double attacks a percent chance to perform an extra attack with 1-handed secondary weapon, base: chance, limit: amt attacks, max: none
#define SE_Fc_CastTimeMod2 500 // implemented, @Fc, On Caster, cast time mod pct, base: pct, Note: Can reduce to instant cast
#define SE_Fc_CastTimeAmt 501 // implemented, @Fc, On Caster, cast time mod flat amt, base: milliseconds, Note: Can reduce to instant cast
#define SE_Fearstun 502 // implemented - Stun with a max level limit. Normal stun restrictions don't apply.