Core/Misc: Partial merge of 3.3.5-dbedit:

- Added SmartEnum.h for enum iteration, stringification, and more, courtesy of krabicezpapundeklu/smart_enum
- Moved a bunch of enums in SharedDefines.h to the new system
- Miscellaneous utility methods ported
This commit is contained in:
Treeston
2018-10-26 14:43:22 +02:00
parent 0a0312b705
commit 338e8ba0fe
14 changed files with 1002 additions and 342 deletions

1
.gitignore vendored
View File

@@ -22,3 +22,4 @@ nbproject/*
.vscode .vscode
cmake-build-*/ cmake-build-*/
.vs .vs
*.user

View File

@@ -10,7 +10,7 @@
add_subdirectory(threads) add_subdirectory(threads)
if(SERVERS OR TOOLS) if (SERVERS OR TOOLS)
add_subdirectory(boost) add_subdirectory(boost)
add_subdirectory(process) add_subdirectory(process)
add_subdirectory(zlib) add_subdirectory(zlib)
@@ -22,16 +22,17 @@ if(SERVERS OR TOOLS)
add_subdirectory(valgrind) add_subdirectory(valgrind)
add_subdirectory(openssl) add_subdirectory(openssl)
add_subdirectory(jemalloc) add_subdirectory(jemalloc)
add_subdirectory(smart_enum)
endif() endif()
if(SERVERS) if (SERVERS)
add_subdirectory(mysql) add_subdirectory(mysql)
add_subdirectory(readline) add_subdirectory(readline)
add_subdirectory(gsoap) add_subdirectory(gsoap)
add_subdirectory(efsw) add_subdirectory(efsw)
endif() endif()
if(TOOLS) if (TOOLS)
add_subdirectory(bzip2) add_subdirectory(bzip2)
add_subdirectory(libmpq) add_subdirectory(libmpq)
endif() endif()

View File

@@ -0,0 +1,15 @@
# Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
add_library(smart_enum INTERFACE)
target_include_directories(smart_enum
INTERFACE
${CMAKE_CURRENT_SOURCE_DIR})

View File

@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,485 @@
// Copyright Jarda Flieger 2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef SMART_ENUM_HEADER_INCLUDED
#define SMART_ENUM_HEADER_INCLUDED
#include <cstring>
#include <stdexcept>
#include <tuple>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/logical/not.hpp>
#include <boost/preprocessor/punctuation/remove_parens.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/tuple/push_back.hpp>
#define SMART_ENUM(...) \
SMART_ENUM_IMPL(, __VA_ARGS__)
#define SMART_ENUM_CLASS(...) \
SMART_ENUM_IMPL(class, __VA_ARGS__)
#ifdef _MSC_VER
#define SMART_ENUM_IMPL(CLASS, ...) \
BOOST_PP_CAT \
( \
BOOST_PP_OVERLOAD(SMART_ENUM_IMPL_, __VA_ARGS__)(CLASS, __VA_ARGS__), \
BOOST_PP_EMPTY() \
)
#else
#define SMART_ENUM_IMPL(CLASS, ...) \
BOOST_PP_OVERLOAD(SMART_ENUM_IMPL_, __VA_ARGS__)(CLASS, __VA_ARGS__)
#endif
#define SMART_ENUM_IMPL_2(CLASS, NAME, MEMBERS) \
SMART_ENUM_IMPL_DEFINITION(CLASS, _, NAME, MEMBERS)
#define SMART_ENUM_IMPL_3(CLASS, NAMESPACES, NAME, MEMBERS) \
SMART_ENUM_IMPL_DEFINITION(CLASS, SMART_ENUM_IMPL_ARG_TO_TUPLE(NAMESPACES), NAME, MEMBERS)
#define SMART_ENUM_IMPL_DEFINITION(CLASS, NAMESPACES, NAME, MEMBERS) \
SMART_ENUM_IMPL_DEFINITION_1 \
( \
CLASS, NAMESPACES, SMART_ENUM_IMPL_ARG_TO_TUPLE(NAME), (SMART_ENUM_IMPL_ARGS_TO_TUPLES(MEMBERS)) \
)
#define SMART_ENUM_IMPL_DEFINITION_1(CLASS, NAMESPACES, NAME, MEMBERS) \
SMART_ENUM_IMPL_REPEAT(NAMESPACE_START, NAMESPACES) \
enum CLASS SMART_ENUM_IMPL_NAME_SIZE(NAME) \
{ \
SMART_ENUM_IMPL_MEMBER_DEFINITIONS(MEMBERS) \
}; \
SMART_ENUM_IMPL_REPEAT(NAMESPACE_END, NAMESPACES) \
\
SMART_ENUM_IMPL_TRAITS(NAMESPACES, BOOST_PP_TUPLE_ELEM(0, NAME), MEMBERS)
#define SMART_ENUM_IMPL_NAME_SIZE(NAME_SIZE) \
BOOST_PP_TUPLE_ELEM(0, NAME_SIZE) \
BOOST_PP_IF \
( \
BOOST_PP_DEC(BOOST_PP_TUPLE_SIZE(NAME_SIZE)), \
SMART_ENUM_IMPL_NAME_SIZE_1, BOOST_PP_TUPLE_EAT(1) \
) \
NAME_SIZE
#define SMART_ENUM_IMPL_NAME_SIZE_1(NAME, SIZE) \
: SIZE
// traits
#define SMART_ENUM_IMPL_TRAITS(NAMESPACES, NAME, MEMBERS) \
SMART_ENUM_IMPL_TRAITS_1 \
( \
SMART_ENUM_IMPL_FULL_NAME(NAMESPACES, NAME), \
SMART_ENUM_IMPL_FULL_NAME_STRING(NAMESPACES, NAME), \
NAME, \
MEMBERS \
)
#define SMART_ENUM_IMPL_TRAITS_1(FULL_NAME, FULL_NAME_STRING, NAME, MEMBERS) \
namespace smart_enum \
{ \
template<> struct enum_traits<FULL_NAME> : detail::enum_traits_base<FULL_NAME> \
{ \
using type = FULL_NAME; \
using data_type = SMART_ENUM_IMPL_DATA_TYPE(BOOST_PP_TUPLE_ELEM(0, MEMBERS)); \
\
static constexpr const char *name = BOOST_PP_STRINGIZE(NAME); \
static constexpr const char *full_name = FULL_NAME_STRING; \
\
static constexpr std::size_t count = BOOST_PP_TUPLE_SIZE(MEMBERS); \
\
SMART_ENUM_IMPL_DATA(FULL_NAME, MEMBERS) \
SMART_ENUM_IMPL_FROM_STRING(FULL_NAME, MEMBERS) \
SMART_ENUM_IMPL_INDEX_OF(FULL_NAME, MEMBERS) \
SMART_ENUM_IMPL_TO_STRING(FULL_NAME, MEMBERS) \
SMART_ENUM_IMPL_VALUE_OF(FULL_NAME, MEMBERS) \
}; \
}
// full name
#define SMART_ENUM_IMPL_FULL_NAME(NAMESPACES, NAME) \
SMART_ENUM_IMPL_REPEAT(FULL_NAME_1, NAMESPACES) NAME
#define SMART_ENUM_IMPL_FULL_NAME_1(NAMESPACE) \
NAMESPACE ::
#define SMART_ENUM_IMPL_FULL_NAME_STRING(NAMESPACES, NAME) \
SMART_ENUM_IMPL_REPEAT(FULL_NAME_STRING_1, NAMESPACES) BOOST_PP_STRINGIZE(NAME)
#define SMART_ENUM_IMPL_FULL_NAME_STRING_1(NAMESPACE) \
BOOST_PP_STRINGIZE(NAMESPACE) "::"
// data
#define SMART_ENUM_IMPL_DATA(PREFIX, MEMBERS) \
static constexpr data_type data(PREFIX value) \
{ \
switch(value) \
{ \
SMART_ENUM_IMPL_REPEAT_MEMBERS(PREFIX, MEMBERS, MEMBER_DATA) \
} \
\
return {}; \
}
#define SMART_ENUM_IMPL_MEMBER_DATA(PREFIX, NAME, MEMBER, INDEX) \
case PREFIX :: NAME: \
return EnumText \
SMART_ENUM_IMPL_MEMBER_DATA_1 \
( \
SMART_ENUM_IMPL_TUPLE_LAST_ELEMENT(MEMBER) \
) \
;
#define SMART_ENUM_IMPL_MEMBER_DATA_1(DATA) \
BOOST_PP_IIF \
( \
BOOST_PP_IS_BEGIN_PARENS(DATA), DATA, () \
)
#define SMART_ENUM_IMPL_DATA_TYPE(MEMBER) \
EnumText
// member definitions
#define SMART_ENUM_IMPL_MEMBER_DEFINITIONS(MEMBERS) \
SMART_ENUM_IMPL_ENUM_MEMBERS(_, MEMBERS, MEMBER_DEFINITION)
#define SMART_ENUM_IMPL_MEMBER_DEFINITION(PREFIX, NAME, MEMBER, INDEX) \
NAME \
SMART_ENUM_IMPL_MEMBER_DEFINITION_1 \
( \
BOOST_PP_TUPLE_ELEM(1, BOOST_PP_TUPLE_PUSH_BACK(MEMBER, ())) \
)
#define SMART_ENUM_IMPL_MEMBER_DEFINITION_1(VALUE) \
BOOST_PP_EXPR_IIF \
( \
BOOST_PP_NOT(BOOST_PP_IS_BEGIN_PARENS(VALUE)), = VALUE \
)
// from_string
#define SMART_ENUM_IMPL_FROM_STRING(PREFIX, MEMBERS) \
static PREFIX from_string(const char *s) \
{ \
return SMART_ENUM_IMPL_REPEAT_MEMBERS(PREFIX, MEMBERS, MEMBER_FROM_STRING) throw std::invalid_argument("s"); \
}
#define SMART_ENUM_IMPL_MEMBER_FROM_STRING(PREFIX, NAME, MEMBER, INDEX) \
!std::strcmp(s, BOOST_PP_STRINGIZE(NAME)) ? PREFIX :: NAME :
// index_of
#define SMART_ENUM_IMPL_INDEX_OF(PREFIX, MEMBERS) \
static constexpr std::size_t index_of(PREFIX value) \
{ \
return SMART_ENUM_IMPL_REPEAT_MEMBERS(PREFIX, MEMBERS, MEMBER_INDEX_OF) throw std::invalid_argument("value"); \
}
#define SMART_ENUM_IMPL_MEMBER_INDEX_OF(PREFIX, NAME, MEMBER, INDEX) \
value == PREFIX :: NAME ? INDEX ## u :
// to_string
#define SMART_ENUM_IMPL_TO_STRING(PREFIX, MEMBERS) \
static constexpr const char *to_string(PREFIX value) \
{ \
switch(value) \
{ \
SMART_ENUM_IMPL_REPEAT_MEMBERS(PREFIX, MEMBERS, MEMBER_TO_STRING) \
} \
\
throw std::invalid_argument("value"); \
}
#define SMART_ENUM_IMPL_MEMBER_TO_STRING(PREFIX, NAME, MEMBER, INDEX) \
case PREFIX :: NAME: \
return BOOST_PP_STRINGIZE(NAME);
// value_of
#define SMART_ENUM_IMPL_VALUE_OF(PREFIX, MEMBERS) \
static constexpr PREFIX value_of(std::size_t index) \
{ \
return SMART_ENUM_IMPL_REPEAT_MEMBERS(PREFIX, MEMBERS, MEMBER_VALUE_OF) throw std::invalid_argument("index"); \
}
#define SMART_ENUM_IMPL_MEMBER_VALUE_OF(PREFIX, NAME, MEMBER, INDEX) \
index == INDEX ? PREFIX :: NAME :
// namespaces
#define SMART_ENUM_IMPL_NAMESPACE_END(_) \
}
#define SMART_ENUM_IMPL_NAMESPACE_START(NAMESPACE) \
namespace NAMESPACE {
// utils
#define SMART_ENUM_IMPL_ARG_TO_TUPLE(ARG) \
(BOOST_PP_REMOVE_PARENS(ARG))
#define SMART_ENUM_IMPL_ARGS_TO_TUPLES(ARGS) \
BOOST_PP_ENUM(BOOST_PP_TUPLE_SIZE(ARGS), SMART_ENUM_IMPL_ARGS_TO_TUPLES_1, ARGS)
#define SMART_ENUM_IMPL_ARGS_TO_TUPLES_1(_, INDEX, ARGS) \
SMART_ENUM_IMPL_ARG_TO_TUPLE(BOOST_PP_TUPLE_ELEM(INDEX, ARGS))
#define SMART_ENUM_IMPL_REPEAT(MACRO, TUPLE) \
BOOST_PP_EXPR_IIF \
( \
BOOST_PP_IS_BEGIN_PARENS(TUPLE), \
BOOST_PP_REPEAT(BOOST_PP_TUPLE_SIZE(TUPLE), SMART_ENUM_IMPL_REPEAT_1, (TUPLE, MACRO)) \
)
#define SMART_ENUM_IMPL_REPEAT_1(_, INDEX, TUPLE_MACRO) \
BOOST_PP_CAT(SMART_ENUM_IMPL_, BOOST_PP_TUPLE_ELEM(1, TUPLE_MACRO)) \
(BOOST_PP_TUPLE_ELEM(INDEX, BOOST_PP_TUPLE_ELEM(0, TUPLE_MACRO)))
#define SMART_ENUM_IMPL_ENUM_MEMBERS(PREFIX, MEMBERS, MACRO) \
BOOST_PP_ENUM(BOOST_PP_TUPLE_SIZE(MEMBERS), SMART_ENUM_IMPL_PROCESS_MEMBERS_1, (PREFIX, MEMBERS, MACRO))
#define SMART_ENUM_IMPL_REPEAT_MEMBERS(PREFIX, MEMBERS, MACRO) \
BOOST_PP_REPEAT(BOOST_PP_TUPLE_SIZE(MEMBERS), SMART_ENUM_IMPL_PROCESS_MEMBERS_1, (PREFIX, MEMBERS, MACRO))
#define SMART_ENUM_IMPL_PROCESS_MEMBERS_1(_, INDEX, PREFIX_MEMBERS_MACRO) \
SMART_ENUM_IMPL_PROCESS_MEMBERS_2 \
( \
BOOST_PP_TUPLE_ELEM(0, PREFIX_MEMBERS_MACRO), \
BOOST_PP_TUPLE_ELEM(INDEX, BOOST_PP_TUPLE_ELEM(1, PREFIX_MEMBERS_MACRO)), \
BOOST_PP_TUPLE_ELEM(2, PREFIX_MEMBERS_MACRO), \
INDEX \
)
#define SMART_ENUM_IMPL_PROCESS_MEMBERS_2(PREFIX, MEMBER, MACRO, INDEX) \
BOOST_PP_CAT(SMART_ENUM_IMPL_, MACRO)(PREFIX, BOOST_PP_TUPLE_ELEM(0, MEMBER), MEMBER, INDEX)
#define SMART_ENUM_IMPL_TUPLE_LAST_ELEMENT(TUPLE) \
BOOST_PP_TUPLE_ELEM(BOOST_PP_DEC(BOOST_PP_TUPLE_SIZE(TUPLE)), TUPLE)
namespace smart_enum
{
template
<
typename Enum
>
class enum_iterator;
template
<
typename Enum
>
struct enum_range;
namespace detail
{
template
<
typename Enum
>
struct enum_traits_base
{
static constexpr bool is_enum_class =
std::integral_constant
<
bool, std::is_enum<Enum>::value && !std::is_convertible<Enum, int>::value
>
::value;
};
}
template
<
typename Enum
>
struct enum_traits {};
template
<
typename Enum
>
constexpr enum_iterator<Enum> begin()
{
return enum_iterator<Enum>{enum_traits<Enum>::value_of(0)};
}
template
<
typename Enum
>
typename enum_traits<Enum>::data_type data(Enum value)
{
return enum_traits<Enum>::data(value);
}
template
<
typename Enum
>
constexpr enum_iterator<Enum> end()
{
return {};
}
template
<
typename Enum
>
constexpr std::size_t count()
{
return enum_traits<Enum>::count;
}
template
<
typename Enum
>
Enum from_string(const char *s)
{
return enum_traits<Enum>::from_string(s);
}
template
<
typename Enum
>
constexpr const char *full_name()
{
return enum_traits<Enum>::full_name;
}
template
<
typename Enum
>
constexpr std::size_t index_of(Enum value)
{
return enum_traits<Enum>::index_of(value);
}
template
<
typename Enum
>
constexpr bool is_enum_class()
{
return enum_traits<Enum>::is_enum_class;
}
template
<
typename Enum
>
constexpr const char *name()
{
return enum_traits<Enum>::name;
}
template
<
typename Enum
>
constexpr enum_range<Enum> range()
{
return {};
}
template
<
typename Enum
>
constexpr const char *to_string(Enum value)
{
return enum_traits<Enum>::to_string(value);
}
template
<
typename Enum
>
constexpr Enum value_of(std::size_t index)
{
return enum_traits<Enum>::value_of(index);
}
template
<
typename Enum
>
class enum_iterator : public boost::iterator_facade
<
enum_iterator<Enum>, Enum, boost::random_access_traversal_tag, Enum
>
{
public:
constexpr enum_iterator()
: index_{ count<Enum>() }
{
}
constexpr explicit enum_iterator(Enum value)
: index_{ index_of(value) }
{
}
constexpr bool operator!=(const enum_iterator& other) const
{
return other.index_ != index_;
}
private:
std::size_t index_;
void advance(std::ptrdiff_t n)
{
index_ += n;
}
void decrement()
{
--index_;
}
constexpr Enum dereference() const
{
return value_of<Enum>(index_);
}
constexpr std::ptrdiff_t distance_to(const enum_iterator &other) const
{
return other.index_ - index_;
}
constexpr bool equal(const enum_iterator &other) const
{
return other.index_ == index_;
}
void increment()
{
++index_;
}
friend class boost::iterator_core_access;
};
template
<
typename Enum
>
struct enum_range
{
constexpr enum_iterator<Enum> begin() const
{
return smart_enum::begin<Enum>();
}
constexpr enum_iterator<Enum> end() const
{
return smart_enum::end<Enum>();
}
};
}
#endif

View File

@@ -72,7 +72,8 @@ target_link_libraries(common
openssl openssl
valgrind valgrind
threads threads
jemalloc) jemalloc
smart_enum)
add_dependencies(common revision_data.h) add_dependencies(common revision_data.h)

View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
*
* 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; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef TRINITY_FUZZYFIND_H
#define TRINITY_FUZZYFIND_H
namespace Trinity
{
namespace Containers
{
template <typename Container, typename NeedleContainer, typename ContainsOperator = bool(std::string const&, std::string const&), typename T = void>
auto FuzzyFindIn(Container const& container, NeedleContainer const& needles, ContainsOperator const& contains = StringContainsStringI, int(*bonus)(decltype((*std::begin(std::declval<Container>())))) = nullptr)
{
using IteratorResult = decltype((*std::begin(container)));
using MappedType = std::conditional_t<advstd::is_reference_v<IteratorResult>, std::reference_wrapper<std::remove_reference_t<IteratorResult>>, IteratorResult>;
std::multimap<size_t, MappedType, std::greater<size_t>> results;
for (auto outerIt = std::begin(container), outerEnd = std::end(container); outerIt != outerEnd; ++outerIt)
{
size_t count = 0;
for (auto innerIt = std::begin(needles), innerEnd = std::end(needles); innerIt != innerEnd; ++innerIt)
if (contains(*outerIt, *innerIt))
++count;
if (!count)
continue;
if (bonus)
count += bonus(*outerIt);
results.emplace(count, *outerIt);
}
return results;
}
}
}
#endif

View File

@@ -0,0 +1,61 @@
/*
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
*
* 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; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef TRINITY_SMARTENUM_H
#define TRINITY_SMARTENUM_H
#include "smart_enum.hpp"
struct EnumText
{
EnumText(char const* t = nullptr, char const* d = nullptr) : Title(t), Description(d ? d : t) {}
// Human-readable title of the value
char const* const Title;
// Human-readable description of the value
char const* const Description;
protected:
EnumText(char const* n, EnumText e) : Title(e.Title ? e.Title : n), Description(e.Description ? e.Description : Title) {}
};
struct FullEnumText : public EnumText
{
FullEnumText(char const* constant, EnumText e) : EnumText(constant, e), Constant(constant) {}
// Enum constant of the value
char const* const Constant;
};
template <typename E>
class EnumUtils
{
public:
static constexpr auto Begin() { return smart_enum::begin<E>(); }
static constexpr auto End() { return smart_enum::end<E>(); }
static constexpr auto Iterate() { return smart_enum::range<E>(); }
static constexpr FullEnumText ToString(E value)
{
return { smart_enum::to_string<E>(value), smart_enum::data<E>(value) };
}
static constexpr char const* ToConstant(E value) { return ToString(value).Constant; }
static constexpr char const* ToTitle(E value) { return ToString(value).Title; }
static constexpr char const* ToDescription(E value) { return ToString(value).Description; }
};
#define SMART_ENUM_BOUND(type, name) static constexpr type name = type(smart_enum::value_of<type>(smart_enum::count<type>()-1)+1);
#define SMART_ENUM_BOUND_AFTER(type, name, entry) static constexpr type name = type(entry + 1);
#endif

View File

@@ -24,6 +24,7 @@
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <utility>
#include <vector> #include <vector>
class TC_COMMON_API Tokenizer class TC_COMMON_API Tokenizer
@@ -299,6 +300,11 @@ TC_COMMON_API void HexStrToByteArray(std::string const& str, uint8* out, bool re
TC_COMMON_API bool StringToBool(std::string const& str); TC_COMMON_API bool StringToBool(std::string const& str);
TC_COMMON_API bool StringContainsStringI(std::string const& haystack, std::string const& needle); TC_COMMON_API bool StringContainsStringI(std::string const& haystack, std::string const& needle);
template <typename T>
inline bool ValueContainsStringI(std::pair<T, std::string> const& haystack, std::string const& needle)
{
return StringContainsStringI(haystack.second, needle);
}
// simple class for not-modifyable list // simple class for not-modifyable list
template <typename T> template <typename T>

View File

@@ -73,6 +73,12 @@ namespace advstd
// C++17 std::tuple_size_v // C++17 std::tuple_size_v
forward_1v(tuple_size, size_t); forward_1v(tuple_size, size_t);
// C++17 std::is_enum_v
forward_1v(is_enum, bool);
// C++17 std::is_arithmetic_v
forward_1v(is_arithmetic, bool);
#undef forward_1v #undef forward_1v
#undef forward_2v #undef forward_2v

View File

@@ -345,7 +345,7 @@ enum MapFlags
MAP_FLAG_DYNAMIC_DIFFICULTY = 0x100 MAP_FLAG_DYNAMIC_DIFFICULTY = 0x100
}; };
enum AbilytyLearnType enum AbilityLearnType
{ {
SKILL_LINE_ABILITY_LEARNED_ON_SKILL_VALUE = 1, // Spell state will update depending on skill value SKILL_LINE_ABILITY_LEARNED_ON_SKILL_VALUE = 1, // Spell state will update depending on skill value
SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN = 2 // Spell will be learned/removed together with entire skill SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN = 2 // Spell will be learned/removed together with entire skill

View File

@@ -18,14 +18,13 @@
#include "DBCStore.h" #include "DBCStore.h"
#include "DBCDatabaseLoader.h" #include "DBCDatabaseLoader.h"
DBCStorageBase::DBCStorageBase(char const* fmt) : _fieldCount(0), _fileFormat(fmt), _dataTable(nullptr), _dataTableEx(nullptr), _indexTableSize(0) DBCStorageBase::DBCStorageBase(char const* fmt) : _fieldCount(0), _fileFormat(fmt), _dataTable(nullptr), _indexTableSize(0)
{ {
} }
DBCStorageBase::~DBCStorageBase() DBCStorageBase::~DBCStorageBase()
{ {
delete[] _dataTable; delete[] _dataTable;
delete[] _dataTableEx;
for (char* strings : _stringPool) for (char* strings : _stringPool)
delete[] strings; delete[] strings;
} }
@@ -72,5 +71,5 @@ bool DBCStorageBase::LoadStringsFrom(char const* path, char** indexTable)
void DBCStorageBase::LoadFromDB(char const* table, char const* format, char const* index, char**& indexTable) void DBCStorageBase::LoadFromDB(char const* table, char const* format, char const* index, char**& indexTable)
{ {
_dataTableEx = DBCDatabaseLoader(table, format, index, _fileFormat, _stringPool).Load(_indexTableSize, indexTable); _stringPool.push_back(DBCDatabaseLoader(table, format, index, _fileFormat, _stringPool).Load(_indexTableSize, indexTable));
} }

View File

@@ -45,7 +45,6 @@ class TC_SHARED_API DBCStorageBase
uint32 _fieldCount; uint32 _fieldCount;
char const* _fileFormat; char const* _fileFormat;
char* _dataTable; char* _dataTable;
char* _dataTableEx;
std::vector<char*> _stringPool; std::vector<char*> _stringPool;
uint32 _indexTableSize; uint32 _indexTableSize;
}; };

View File

@@ -21,6 +21,7 @@
#include "Define.h" #include "Define.h"
#include "DetourNavMesh.h" #include "DetourNavMesh.h"
#include "SmartEnum.h"
float const GROUND_HEIGHT_TOLERANCE = 0.05f; // Extra tolerance to z position to check if it is in air or on ground. float const GROUND_HEIGHT_TOLERANCE = 0.05f; // Extra tolerance to z position to check if it is in air or on ground.
@@ -260,31 +261,32 @@ enum Stats
#define MAX_STATS 5 #define MAX_STATS 5
enum Powers SMART_ENUM((Powers, int8),
{ (
POWER_MANA = 0, (POWER_HEALTH, -2, ("Health")),
POWER_RAGE = 1, (POWER_ALL, 127, ("All powers")),
POWER_FOCUS = 2, (POWER_MANA, 0, ("Mana")),
POWER_ENERGY = 3, (POWER_RAGE, 1, ("Rage")),
POWER_HAPPINESS = 4, (POWER_FOCUS, 2, ("Focus")),
POWER_RUNE = 5, (POWER_ENERGY, 3, ("Energy")),
POWER_RUNIC_POWER = 6, (POWER_HAPPINESS, 4, ("Happiness")),
MAX_POWERS = 7, (POWER_RUNE, 5, ("Runes")),
POWER_ALL = 127, // default for class? (POWER_RUNIC_POWER, 6, ("Runic Power"))
POWER_HEALTH = 0xFFFFFFFE // (-2 as signed value) ));
}; SMART_ENUM_BOUND(Powers, MAX_POWERS);
enum SpellSchools
{ SMART_ENUM(SpellSchools,
SPELL_SCHOOL_NORMAL = 0, (
SPELL_SCHOOL_HOLY = 1, (SPELL_SCHOOL_NORMAL, 0, ("Physical")),
SPELL_SCHOOL_FIRE = 2, (SPELL_SCHOOL_HOLY, 1, ("Holy")),
SPELL_SCHOOL_NATURE = 3, (SPELL_SCHOOL_FIRE, 2, ("Fire")),
SPELL_SCHOOL_FROST = 4, (SPELL_SCHOOL_NATURE, 3, ("Nature")),
SPELL_SCHOOL_SHADOW = 5, (SPELL_SCHOOL_FROST, 4, ("Frost")),
SPELL_SCHOOL_ARCANE = 6, (SPELL_SCHOOL_SHADOW, 5, ("Shadow")),
MAX_SPELL_SCHOOL = 7 (SPELL_SCHOOL_ARCANE, 6, ("Arcane"))
}; ));
SMART_ENUM_BOUND(SpellSchools, MAX_SPELL_SCHOOL);
enum SpellSchoolMask : uint32 enum SpellSchoolMask : uint32
{ {
@@ -310,11 +312,16 @@ enum SpellSchoolMask : uint32
SPELL_SCHOOL_MASK_ALL = (SPELL_SCHOOL_MASK_NORMAL | SPELL_SCHOOL_MASK_MAGIC) SPELL_SCHOOL_MASK_ALL = (SPELL_SCHOOL_MASK_NORMAL | SPELL_SCHOOL_MASK_MAGIC)
}; };
inline SpellSchools GetFirstSchoolInMask(SpellSchoolMask mask) inline constexpr SpellSchoolMask GetMaskForSchool(SpellSchools school)
{ {
for (int i = 0; i < MAX_SPELL_SCHOOL; ++i) return SpellSchoolMask(1 << school);
if (mask & (1 << i)) }
return SpellSchools(i);
inline constexpr SpellSchools GetFirstSchoolInMask(SpellSchoolMask mask)
{
for (SpellSchools school : EnumUtils<SpellSchools>::Iterate())
if (mask & GetMaskForSchool(school))
return school;
return SPELL_SCHOOL_NORMAL; return SPELL_SCHOOL_NORMAL;
} }
@@ -369,293 +376,294 @@ uint32 constexpr QuestDifficultyColors[MAX_QUEST_DIFFICULTY] = {
// Spell Attributes definitions // Spell Attributes definitions
// *********************************** // ***********************************
enum SpellAttr0 SMART_ENUM((SpellAttr0, uint32),
{ (
SPELL_ATTR0_UNK0 = 0x00000001, // 0 (SPELL_ATTR0_UNK0, 0x00000001),
SPELL_ATTR0_REQ_AMMO = 0x00000002, // 1 on next ranged (SPELL_ATTR0_REQ_AMMO, 0x00000002, ("1 on next ranged")),
SPELL_ATTR0_ON_NEXT_SWING = 0x00000004, // 2 (SPELL_ATTR0_ON_NEXT_SWING, 0x00000004),
SPELL_ATTR0_IS_REPLENISHMENT = 0x00000008, // 3 not set in 3.0.3 (SPELL_ATTR0_IS_REPLENISHMENT, 0x00000008, ("3 not set in 3.0.3")),
SPELL_ATTR0_ABILITY = 0x00000010, // 4 client puts 'ability' instead of 'spell' in game strings for these spells (SPELL_ATTR0_ABILITY, 0x00000010, ("4 client puts 'ability' instead of 'spell' in game strings for these spells")),
SPELL_ATTR0_TRADESPELL = 0x00000020, // 5 trade spells (recipes), will be added by client to a sublist of profession spell (SPELL_ATTR0_TRADESPELL, 0x00000020, ("5 trade spells (recipes), will be added by client to a sublist of profession spell")),
SPELL_ATTR0_PASSIVE = 0x00000040, // 6 Passive spell (SPELL_ATTR0_PASSIVE, 0x00000040, ("6 Passive spell")),
SPELL_ATTR0_HIDDEN_CLIENTSIDE = 0x00000080, // 7 Spells with this attribute are not visible in spellbook or aura bar (SPELL_ATTR0_HIDDEN_CLIENTSIDE, 0x00000080, ("7 Spells with this attribute are not visible in spellbook or aura bar")),
SPELL_ATTR0_HIDE_IN_COMBAT_LOG = 0x00000100, // 8 This attribite controls whether spell appears in combat logs (SPELL_ATTR0_HIDE_IN_COMBAT_LOG, 0x00000100, ("8 This attribite controls whether spell appears in combat logs")),
SPELL_ATTR0_TARGET_MAINHAND_ITEM = 0x00000200, // 9 Client automatically selects item from mainhand slot as a cast target (SPELL_ATTR0_TARGET_MAINHAND_ITEM, 0x00000200, ("9 Client automatically selects item from mainhand slot as a cast target")),
SPELL_ATTR0_ON_NEXT_SWING_2 = 0x00000400, // 10 (SPELL_ATTR0_ON_NEXT_SWING_2, 0x00000400, ""),
SPELL_ATTR0_UNK11 = 0x00000800, // 11 (SPELL_ATTR0_UNK11, 0x00000800, ""),
SPELL_ATTR0_DAYTIME_ONLY = 0x00001000, // 12 only useable at daytime, not set in 2.4.2 (SPELL_ATTR0_DAYTIME_ONLY, 0x00001000, ("12 only useable at daytime, not set in 2.4.2")),
SPELL_ATTR0_NIGHT_ONLY = 0x00002000, // 13 only useable at night, not set in 2.4.2 (SPELL_ATTR0_NIGHT_ONLY, 0x00002000, ("13 only useable at night, not set in 2.4.2")),
SPELL_ATTR0_INDOORS_ONLY = 0x00004000, // 14 only useable indoors, not set in 2.4.2 (SPELL_ATTR0_INDOORS_ONLY, 0x00004000, ("14 only useable indoors, not set in 2.4.2")),
SPELL_ATTR0_OUTDOORS_ONLY = 0x00008000, // 15 Only useable outdoors. (SPELL_ATTR0_OUTDOORS_ONLY, 0x00008000, ("15 Only useable outdoors.")),
SPELL_ATTR0_NOT_SHAPESHIFT = 0x00010000, // 16 Not while shapeshifted (SPELL_ATTR0_NOT_SHAPESHIFT, 0x00010000, ("16 Not while shapeshifted")),
SPELL_ATTR0_ONLY_STEALTHED = 0x00020000, // 17 Must be in stealth (SPELL_ATTR0_ONLY_STEALTHED, 0x00020000, ("17 Must be in stealth")),
SPELL_ATTR0_DONT_AFFECT_SHEATH_STATE = 0x00040000, // 18 client won't hide unit weapons in sheath on cast/channel (SPELL_ATTR0_DONT_AFFECT_SHEATH_STATE, 0x00040000, ("18 client won't hide unit weapons in sheath on cast/channel")),
SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION = 0x00080000, // 19 spelldamage depends on caster level (SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION, 0x00080000, ("19 spelldamage depends on caster level")),
SPELL_ATTR0_STOP_ATTACK_TARGET = 0x00100000, // 20 Stop attack after use this spell (and not begin attack if use) (SPELL_ATTR0_STOP_ATTACK_TARGET, 0x00100000, ("20 Stop attack after use this spell (and not begin attack if use)")),
SPELL_ATTR0_IMPOSSIBLE_DODGE_PARRY_BLOCK = 0x00200000, // 21 Cannot be dodged/parried/blocked (SPELL_ATTR0_IMPOSSIBLE_DODGE_PARRY_BLOCK, 0x00200000, ("21 Cannot be dodged/parried/blocked")),
SPELL_ATTR0_CAST_TRACK_TARGET = 0x00400000, // 22 Client automatically forces player to face target when casting (SPELL_ATTR0_CAST_TRACK_TARGET, 0x00400000, ("22 Client automatically forces player to face target when casting")),
SPELL_ATTR0_CASTABLE_WHILE_DEAD = 0x00800000, // 23 castable while dead? (SPELL_ATTR0_CASTABLE_WHILE_DEAD, 0x00800000, ("23 castable while dead?")),
SPELL_ATTR0_CASTABLE_WHILE_MOUNTED = 0x01000000, // 24 castable while mounted (SPELL_ATTR0_CASTABLE_WHILE_MOUNTED, 0x01000000, ("24 castable while mounted")),
SPELL_ATTR0_DISABLED_WHILE_ACTIVE = 0x02000000, // 25 Activate and start cooldown after aura fade or remove summoned creature or go (SPELL_ATTR0_DISABLED_WHILE_ACTIVE, 0x02000000, ("25 Activate and start cooldown after aura fade or remove summoned creature or go")),
SPELL_ATTR0_NEGATIVE_1 = 0x04000000, // 26 Many negative spells have this attr (SPELL_ATTR0_NEGATIVE_1, 0x04000000, ("26 Many negative spells have this attr")),
SPELL_ATTR0_CASTABLE_WHILE_SITTING = 0x08000000, // 27 castable while sitting (SPELL_ATTR0_CASTABLE_WHILE_SITTING, 0x08000000, ("27 castable while sitting")),
SPELL_ATTR0_CANT_USED_IN_COMBAT = 0x10000000, // 28 Cannot be used in combat (SPELL_ATTR0_CANT_USED_IN_COMBAT, 0x10000000, ("28 Cannot be used in combat")),
SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY = 0x20000000, // 29 unaffected by invulnerability (hmm possible not...) (SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY, 0x20000000, ("29 unaffected by invulnerability (hmm possible not...)")),
SPELL_ATTR0_HEARTBEAT_RESIST_CHECK = 0x40000000, // 30 random chance the effect will end TODO: implement core support (SPELL_ATTR0_HEARTBEAT_RESIST_CHECK, 0x40000000, ("30 random chance the effect will end TODO: implement core support")),
SPELL_ATTR0_CANT_CANCEL = 0x80000000 // 31 positive aura can't be canceled (SPELL_ATTR0_CANT_CANCEL, 0x80000000, ("31 positive aura can't be canceled"))
}; )
);
enum SpellAttr1 SMART_ENUM((SpellAttr1, uint32),
{ (
SPELL_ATTR1_DISMISS_PET = 0x00000001, // 0 for spells without this flag client doesn't allow to summon pet if caster has a pet (SPELL_ATTR1_DISMISS_PET, 0x00000001, ("0 for spells without this flag client doesn't allow to summon pet if caster has a pet")),
SPELL_ATTR1_DRAIN_ALL_POWER = 0x00000002, // 1 use all power (Only paladin Lay of Hands and Bunyanize) (SPELL_ATTR1_DRAIN_ALL_POWER, 0x00000002, ("1 use all power (Only paladin Lay of Hands and Bunyanize)")),
SPELL_ATTR1_CHANNELED_1 = 0x00000004, // 2 clientside checked? cancelable? (SPELL_ATTR1_CHANNELED_1, 0x00000004, ("2 clientside checked? cancelable?")),
SPELL_ATTR1_CANT_BE_REDIRECTED = 0x00000008, // 3 (SPELL_ATTR1_CANT_BE_REDIRECTED, 0x00000008, ("3")),
SPELL_ATTR1_UNK4 = 0x00000010, // 4 stealth and whirlwind (SPELL_ATTR1_UNK4, 0x00000010, ("4 stealth and whirlwind")),
SPELL_ATTR1_NOT_BREAK_STEALTH = 0x00000020, // 5 Not break stealth (SPELL_ATTR1_NOT_BREAK_STEALTH, 0x00000020, ("5 Not break stealth")),
SPELL_ATTR1_CHANNELED_2 = 0x00000040, // 6 (SPELL_ATTR1_CHANNELED_2, 0x00000040, ("6")),
SPELL_ATTR1_CANT_BE_REFLECTED = 0x00000080, // 7 (SPELL_ATTR1_CANT_BE_REFLECTED, 0x00000080, ("7")),
SPELL_ATTR1_CANT_TARGET_IN_COMBAT = 0x00000100, // 8 can target only out of combat units (SPELL_ATTR1_CANT_TARGET_IN_COMBAT, 0x00000100, ("8 can target only out of combat units")),
SPELL_ATTR1_MELEE_COMBAT_START = 0x00000200, // 9 player starts melee combat after this spell is cast (SPELL_ATTR1_MELEE_COMBAT_START, 0x00000200, ("9 player starts melee combat after this spell is cast")),
SPELL_ATTR1_NO_THREAT = 0x00000400, // 10 no generates threat on cast 100% (old NO_INITIAL_AGGRO) (SPELL_ATTR1_NO_THREAT, 0x00000400, ("10 no generates threat on cast 100% (old NO_INITIAL_AGGRO)")),
SPELL_ATTR1_UNK11 = 0x00000800, // 11 aura (SPELL_ATTR1_UNK11, 0x00000800, ("11 aura")),
SPELL_ATTR1_IS_PICKPOCKET = 0x00001000, // 12 Pickpocket (SPELL_ATTR1_IS_PICKPOCKET, 0x00001000, ("12 Pickpocket")),
SPELL_ATTR1_FARSIGHT = 0x00002000, // 13 Client removes farsight on aura loss (SPELL_ATTR1_FARSIGHT, 0x00002000, ("13 Client removes farsight on aura loss")),
SPELL_ATTR1_CHANNEL_TRACK_TARGET = 0x00004000, // 14 Client automatically forces player to face target when channeling (SPELL_ATTR1_CHANNEL_TRACK_TARGET, 0x00004000, ("14 Client automatically forces player to face target when channeling")),
SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY = 0x00008000, // 15 remove auras on immunity (SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY, 0x00008000, ("15 remove auras on immunity")),
SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE = 0x00010000, // 16 on immuniy (SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE, 0x00010000, ("16 on immuniy")),
SPELL_ATTR1_UNAUTOCASTABLE_BY_PET = 0x00020000, // 17 (SPELL_ATTR1_UNAUTOCASTABLE_BY_PET, 0x00020000, ("17")),
SPELL_ATTR1_UNK18 = 0x00040000, // 18 stun, polymorph, daze, hex (SPELL_ATTR1_UNK18, 0x00040000, ("18 stun, polymorph, daze, hex")),
SPELL_ATTR1_CANT_TARGET_SELF = 0x00080000, // 19 (SPELL_ATTR1_CANT_TARGET_SELF, 0x00080000, ("19")),
SPELL_ATTR1_REQ_COMBO_POINTS1 = 0x00100000, // 20 Req combo points on target (SPELL_ATTR1_REQ_COMBO_POINTS1, 0x00100000, ("20 Req combo points on target")),
SPELL_ATTR1_UNK21 = 0x00200000, // 21 (SPELL_ATTR1_UNK21, 0x00200000, ("21")),
SPELL_ATTR1_REQ_COMBO_POINTS2 = 0x00400000, // 22 Req combo points on target (SPELL_ATTR1_REQ_COMBO_POINTS2, 0x00400000, ("22 Req combo points on target")),
SPELL_ATTR1_UNK23 = 0x00800000, // 23 (SPELL_ATTR1_UNK23, 0x00800000, ("23")),
SPELL_ATTR1_IS_FISHING = 0x01000000, // 24 only fishing spells (SPELL_ATTR1_IS_FISHING, 0x01000000, ("24 only fishing spells")),
SPELL_ATTR1_UNK25 = 0x02000000, // 25 (SPELL_ATTR1_UNK25, 0x02000000, ("25")),
SPELL_ATTR1_UNK26 = 0x04000000, // 26 works correctly with [target=focus] and [target=mouseover] macros? (SPELL_ATTR1_UNK26, 0x04000000, ("26 works correctly with [target=focus] and [target=mouseover] macros?")),
SPELL_ATTR1_UNK27 = 0x08000000, // 27 melee spell? (SPELL_ATTR1_UNK27, 0x08000000, ("27 melee spell?")),
SPELL_ATTR1_DONT_DISPLAY_IN_AURA_BAR = 0x10000000, // 28 client doesn't display these spells in aura bar (SPELL_ATTR1_DONT_DISPLAY_IN_AURA_BAR, 0x10000000, ("28 client doesn't display these spells in aura bar")),
SPELL_ATTR1_CHANNEL_DISPLAY_SPELL_NAME = 0x20000000, // 29 spell name is displayed in cast bar instead of 'channeling' text (SPELL_ATTR1_CHANNEL_DISPLAY_SPELL_NAME, 0x20000000, ("29 spell name is displayed in cast bar instead of 'channeling' text")),
SPELL_ATTR1_ENABLE_AT_DODGE = 0x40000000, // 30 Overpower (SPELL_ATTR1_ENABLE_AT_DODGE, 0x40000000, ("30 Overpower")),
SPELL_ATTR1_UNK31 = 0x80000000 // 31 (SPELL_ATTR1_UNK31, 0x80000000, ("31"))
}; ));
enum SpellAttr2 SMART_ENUM((SpellAttr2, uint32),
{ (
SPELL_ATTR2_CAN_TARGET_DEAD = 0x00000001, // 0 can target dead unit or corpse (SPELL_ATTR2_CAN_TARGET_DEAD, 0x00000001, ("0 can target dead unit or corpse")),
SPELL_ATTR2_UNK1 = 0x00000002, // 1 vanish, shadowform, Ghost Wolf and other (SPELL_ATTR2_UNK1, 0x00000002, ("1 vanish, shadowform, Ghost Wolf and other")),
SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS = 0x00000004, // 2 26368 4.0.1 dbc change (SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS, 0x00000004, ("2 26368 4.0.1 dbc change")),
SPELL_ATTR2_UNK3 = 0x00000008, // 3 (SPELL_ATTR2_UNK3, 0x00000008, ("3")),
SPELL_ATTR2_DISPLAY_IN_STANCE_BAR = 0x00000010, // 4 client displays icon in stance bar when learned, even if not shapeshift (SPELL_ATTR2_DISPLAY_IN_STANCE_BAR, 0x00000010, ("4 client displays icon in stance bar when learned, even if not shapeshift")),
SPELL_ATTR2_AUTOREPEAT_FLAG = 0x00000020, // 5 (SPELL_ATTR2_AUTOREPEAT_FLAG, 0x00000020, ("5")),
SPELL_ATTR2_CANT_TARGET_TAPPED = 0x00000040, // 6 target must be tapped by caster (SPELL_ATTR2_CANT_TARGET_TAPPED, 0x00000040, ("6 target must be tapped by caster")),
SPELL_ATTR2_UNK7 = 0x00000080, // 7 (SPELL_ATTR2_UNK7, 0x00000080, ("7")),
SPELL_ATTR2_UNK8 = 0x00000100, // 8 not set in 3.0.3 (SPELL_ATTR2_UNK8, 0x00000100, ("8 not set in 3.0.3")),
SPELL_ATTR2_UNK9 = 0x00000200, // 9 (SPELL_ATTR2_UNK9, 0x00000200, ("9")),
SPELL_ATTR2_UNK10 = 0x00000400, // 10 related to tame (SPELL_ATTR2_UNK10, 0x00000400, ("10 related to tame")),
SPELL_ATTR2_HEALTH_FUNNEL = 0x00000800, // 11 (SPELL_ATTR2_HEALTH_FUNNEL, 0x00000800, ("11")),
SPELL_ATTR2_UNK12 = 0x00001000, // 12 Cleave, Heart Strike, Maul, Sunder Armor, Swipe (SPELL_ATTR2_UNK12, 0x00001000, ("12 Cleave, Heart Strike, Maul, Sunder Armor, Swipe")),
SPELL_ATTR2_PRESERVE_ENCHANT_IN_ARENA = 0x00002000, // 13 Items enchanted by spells with this flag preserve the enchant to arenas (SPELL_ATTR2_PRESERVE_ENCHANT_IN_ARENA, 0x00002000, ("13 Items enchanted by spells with this flag preserve the enchant to arenas")),
SPELL_ATTR2_UNK14 = 0x00004000, // 14 (SPELL_ATTR2_UNK14, 0x00004000, ("14")),
SPELL_ATTR2_UNK15 = 0x00008000, // 15 not set in 3.0.3 (SPELL_ATTR2_UNK15, 0x00008000, ("15 not set in 3.0.3")),
SPELL_ATTR2_TAME_BEAST = 0x00010000, // 16 (SPELL_ATTR2_TAME_BEAST, 0x00010000, ("16")),
SPELL_ATTR2_NOT_RESET_AUTO_ACTIONS = 0x00020000, // 17 don't reset timers for melee autoattacks (swings) or ranged autoattacks (autoshoots) (SPELL_ATTR2_NOT_RESET_AUTO_ACTIONS, 0x00020000, ("17 don't reset timers for melee autoattacks (swings) or ranged autoattacks (autoshoots)")),
SPELL_ATTR2_REQ_DEAD_PET = 0x00040000, // 18 Only Revive pet and Heart of the Pheonix (SPELL_ATTR2_REQ_DEAD_PET, 0x00040000, ("18 Only Revive pet and Heart of the Pheonix")),
SPELL_ATTR2_NOT_NEED_SHAPESHIFT = 0x00080000, // 19 does not necessarly need shapeshift (SPELL_ATTR2_NOT_NEED_SHAPESHIFT, 0x00080000, ("19 does not necessarly need shapeshift")),
SPELL_ATTR2_UNK20 = 0x00100000, // 20 (SPELL_ATTR2_UNK20, 0x00100000, ("20")),
SPELL_ATTR2_DAMAGE_REDUCED_SHIELD = 0x00200000, // 21 for ice blocks, pala immunity buffs, priest absorb shields, but used also for other spells -> not sure! (SPELL_ATTR2_DAMAGE_REDUCED_SHIELD, 0x00200000, ("21 for ice blocks, pala immunity buffs, priest absorb shields, but used also for other spells -> not sure!")),
SPELL_ATTR2_UNK22 = 0x00400000, // 22 Ambush, Backstab, Cheap Shot, Death Grip, Garrote, Judgements, Mutilate, Pounce, Ravage, Shiv, Shred (SPELL_ATTR2_UNK22, 0x00400000, ("22 Ambush, Backstab, Cheap Shot, Death Grip, Garrote, Judgements, Mutilate, Pounce, Ravage, Shiv, Shred")),
SPELL_ATTR2_IS_ARCANE_CONCENTRATION = 0x00800000, // 23 Only mage Arcane Concentration have this flag (SPELL_ATTR2_IS_ARCANE_CONCENTRATION, 0x00800000, ("23 Only mage Arcane Concentration have this flag")),
SPELL_ATTR2_UNK24 = 0x01000000, // 24 (SPELL_ATTR2_UNK24, 0x01000000, ("24")),
SPELL_ATTR2_UNK25 = 0x02000000, // 25 (SPELL_ATTR2_UNK25, 0x02000000, ("25")),
SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE = 0x04000000, // 26 unaffected by school immunity (SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE, 0x04000000, ("26 unaffected by school immunity")),
SPELL_ATTR2_UNK27 = 0x08000000, // 27 (SPELL_ATTR2_UNK27, 0x08000000, ("27")),
SPELL_ATTR2_UNK28 = 0x10000000, // 28 (SPELL_ATTR2_UNK28, 0x10000000, ("28")),
SPELL_ATTR2_CANT_CRIT = 0x20000000, // 29 Spell can't crit (SPELL_ATTR2_CANT_CRIT, 0x20000000, ("29 Spell can't crit")),
SPELL_ATTR2_TRIGGERED_CAN_TRIGGER_PROC = 0x40000000, // 30 spell can trigger even if triggered (SPELL_ATTR2_TRIGGERED_CAN_TRIGGER_PROC, 0x40000000, ("30 spell can trigger even if triggered")),
SPELL_ATTR2_FOOD_BUFF = 0x80000000 // 31 Food or Drink Buff (like Well Fed) (SPELL_ATTR2_FOOD_BUFF, 0x80000000, ("31 Food or Drink Buff (like Well Fed)"))
}; ));
enum SpellAttr3 SMART_ENUM((SpellAttr3, uint32),
{ (
SPELL_ATTR3_UNK0 = 0x00000001, // 0 (SPELL_ATTR3_UNK0, 0x00000001, ("0")),
SPELL_ATTR3_IGNORE_PROC_SUBCLASS_MASK = 0x00000002, // 1 Ignores subclass mask check when checking proc (SPELL_ATTR3_IGNORE_PROC_SUBCLASS_MASK, 0x00000002, ("1 Ignores subclass mask check when checking proc")),
SPELL_ATTR3_UNK2 = 0x00000004, // 2 (SPELL_ATTR3_UNK2, 0x00000004, ("2")),
SPELL_ATTR3_BLOCKABLE_SPELL = 0x00000008, // 3 Only dmg class melee in 3.1.3 (SPELL_ATTR3_BLOCKABLE_SPELL, 0x00000008, ("3 Only dmg class melee in 3.1.3")),
SPELL_ATTR3_IGNORE_RESURRECTION_TIMER = 0x00000010, // 4 you don't have to wait to be resurrected with these spells (SPELL_ATTR3_IGNORE_RESURRECTION_TIMER, 0x00000010, ("4 you don't have to wait to be resurrected with these spells")),
SPELL_ATTR3_UNK5 = 0x00000020, // 5 (SPELL_ATTR3_UNK5, 0x00000020, ("5")),
SPELL_ATTR3_UNK6 = 0x00000040, // 6 (SPELL_ATTR3_UNK6, 0x00000040, ("6")),
SPELL_ATTR3_STACK_FOR_DIFF_CASTERS = 0x00000080, // 7 separate stack for every caster (SPELL_ATTR3_STACK_FOR_DIFF_CASTERS, 0x00000080, ("7 separate stack for every caster")),
SPELL_ATTR3_ONLY_TARGET_PLAYERS = 0x00000100, // 8 can only target players (SPELL_ATTR3_ONLY_TARGET_PLAYERS, 0x00000100, ("8 can only target players")),
SPELL_ATTR3_TRIGGERED_CAN_TRIGGER_PROC_2 = 0x00000200, // 9 triggered from effect? (SPELL_ATTR3_TRIGGERED_CAN_TRIGGER_PROC_2, 0x00000200, ("9 triggered from effect?")),
SPELL_ATTR3_MAIN_HAND = 0x00000400, // 10 Main hand weapon required (SPELL_ATTR3_MAIN_HAND, 0x00000400, ("10 Main hand weapon required")),
SPELL_ATTR3_BATTLEGROUND = 0x00000800, // 11 Can only be cast in battleground (SPELL_ATTR3_BATTLEGROUND, 0x00000800, ("11 Can only be cast in battleground")),
SPELL_ATTR3_ONLY_TARGET_GHOSTS = 0x00001000, // 12 (SPELL_ATTR3_ONLY_TARGET_GHOSTS, 0x00001000, ("12")),
SPELL_ATTR3_DONT_DISPLAY_CHANNEL_BAR = 0x00002000, // 13 Clientside attribute - will not display channeling bar (SPELL_ATTR3_DONT_DISPLAY_CHANNEL_BAR, 0x00002000, ("13 Clientside attribute - will not display channeling bar")),
SPELL_ATTR3_IS_HONORLESS_TARGET = 0x00004000, // 14 "Honorless Target" only this spells have this flag (SPELL_ATTR3_IS_HONORLESS_TARGET, 0x00004000, ("14 'Honorless Target' only this spells have this flag")),
SPELL_ATTR3_UNK15 = 0x00008000, // 15 Auto Shoot, Shoot, Throw, - this is autoshot flag (SPELL_ATTR3_UNK15, 0x00008000, ("15 Auto Shoot, Shoot, Throw, - this is autoshot flag")),
SPELL_ATTR3_CANT_TRIGGER_PROC = 0x00010000, // 16 confirmed with many patchnotes (SPELL_ATTR3_CANT_TRIGGER_PROC, 0x00010000, ("16 confirmed with many patchnotes")),
SPELL_ATTR3_NO_INITIAL_AGGRO = 0x00020000, // 17 Soothe Animal, 39758, Mind Soothe (SPELL_ATTR3_NO_INITIAL_AGGRO, 0x00020000, ("17 Soothe Animal, 39758, Mind Soothe")),
SPELL_ATTR3_IGNORE_HIT_RESULT = 0x00040000, // 18 Spell should always hit its target (SPELL_ATTR3_IGNORE_HIT_RESULT, 0x00040000, ("18 Spell should always hit its target")),
SPELL_ATTR3_DISABLE_PROC = 0x00080000, // 19 during aura proc no spells can trigger (20178, 20375) (SPELL_ATTR3_DISABLE_PROC, 0x00080000, ("19 during aura proc no spells can trigger (20178, 20375)")),
SPELL_ATTR3_DEATH_PERSISTENT = 0x00100000, // 20 Death persistent spells (SPELL_ATTR3_DEATH_PERSISTENT, 0x00100000, ("20 Death persistent spells")),
SPELL_ATTR3_UNK21 = 0x00200000, // 21 unused (SPELL_ATTR3_UNK21, 0x00200000, ("21 unused")),
SPELL_ATTR3_REQ_WAND = 0x00400000, // 22 Req wand (SPELL_ATTR3_REQ_WAND, 0x00400000, ("22 Req wand")),
SPELL_ATTR3_UNK23 = 0x00800000, // 23 (SPELL_ATTR3_UNK23, 0x00800000, ("23")),
SPELL_ATTR3_REQ_OFFHAND = 0x01000000, // 24 Req offhand weapon (SPELL_ATTR3_REQ_OFFHAND, 0x01000000, ("24 Req offhand weapon")),
SPELL_ATTR3_TREAT_AS_PERIODIC = 0x02000000, // 25 Makes the spell appear as periodic in client combat logs - used by spells that trigger another spell on each tick (SPELL_ATTR3_TREAT_AS_PERIODIC, 0x02000000, ("25 Makes the spell appear as periodic in client combat logs - used by spells that trigger another spell on each tick")),
SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED = 0x04000000, // 26 auras with this attribute can proc from triggered spell casts with SPELL_ATTR3_TRIGGERED_CAN_TRIGGER_PROC_2 (67736 + 52999) (SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED, 0x04000000, ("26 auras with this attribute can proc from triggered spell casts with SPELL_ATTR3_TRIGGERED_CAN_TRIGGER_PROC_2 (67736 + 52999)")),
SPELL_ATTR3_DRAIN_SOUL = 0x08000000, // 27 only drain soul has this flag (SPELL_ATTR3_DRAIN_SOUL, 0x08000000, ("27 only drain soul has this flag")),
SPELL_ATTR3_UNK28 = 0x10000000, // 28 (SPELL_ATTR3_UNK28, 0x10000000, ("28")),
SPELL_ATTR3_NO_DONE_BONUS = 0x20000000, // 29 Ignore caster spellpower and done damage mods? client doesn't apply spellmods for those spells (SPELL_ATTR3_NO_DONE_BONUS, 0x20000000, ("29 Ignore caster spellpower and done damage mods? client doesn't apply spellmods for those spells")),
SPELL_ATTR3_DONT_DISPLAY_RANGE = 0x40000000, // 30 client doesn't display range in tooltip for those spells (SPELL_ATTR3_DONT_DISPLAY_RANGE, 0x40000000, ("30 client doesn't display range in tooltip for those spells")),
SPELL_ATTR3_UNK31 = 0x80000000 // 31 (SPELL_ATTR3_UNK31, 0x80000000, ("31"))
}; ));
enum SpellAttr4 SMART_ENUM((SpellAttr4, uint32),
{ (
SPELL_ATTR4_IGNORE_RESISTANCES = 0x00000001, // 0 spells with this attribute will completely ignore the target's resistance (these spells can't be resisted) (SPELL_ATTR4_IGNORE_RESISTANCES, 0x00000001, ("0 spells with this attribute will completely ignore the target's resistance (these spells can't be resisted)")),
SPELL_ATTR4_PROC_ONLY_ON_CASTER = 0x00000002, // 1 proc only on effects with TARGET_UNIT_CASTER? (SPELL_ATTR4_PROC_ONLY_ON_CASTER, 0x00000002, ("1 proc only on effects with TARGET_UNIT_CASTER?")),
SPELL_ATTR4_FADES_WHILE_LOGGED_OUT = 0x00000004, // 2 duration is removed from aura while player is logged out (SPELL_ATTR4_FADES_WHILE_LOGGED_OUT, 0x00000004, ("2 duration is removed from aura while player is logged out")),
SPELL_ATTR4_UNK3 = 0x00000008, // 3 (SPELL_ATTR4_UNK3, 0x00000008, ("3")),
SPELL_ATTR4_UNK4 = 0x00000010, // 4 This will no longer cause guards to attack on use?? (SPELL_ATTR4_UNK4, 0x00000010, ("4 This will no longer cause guards to attack on use??")),
SPELL_ATTR4_UNK5 = 0x00000020, // 5 (SPELL_ATTR4_UNK5, 0x00000020, ("5")),
SPELL_ATTR4_NOT_STEALABLE = 0x00000040, // 6 although such auras might be dispellable, they cannot be stolen (SPELL_ATTR4_NOT_STEALABLE, 0x00000040, ("6 although such auras might be dispellable, they cannot be stolen")),
SPELL_ATTR4_CAN_CAST_WHILE_CASTING = 0x00000080, // 7 Can be cast while another cast is in progress - see CanCastWhileCasting(SpellRec const*,CGUnit_C *,int &) (SPELL_ATTR4_CAN_CAST_WHILE_CASTING, 0x00000080, ("7 Can be cast while another cast is in progress - see CanCastWhileCasting(SpellRec const*,CGUnit_C *,int &)")),
SPELL_ATTR4_FIXED_DAMAGE = 0x00000100, // 8 Ignores resilience and any (except mechanic related) damage or % damage taken auras on target. (SPELL_ATTR4_FIXED_DAMAGE, 0x00000100, ("8 Ignores resilience and any (except mechanic related) damage or % damage taken auras on target.")),
SPELL_ATTR4_TRIGGER_ACTIVATE = 0x00000200, // 9 initially disabled / trigger activate from event (Execute, Riposte, Deep Freeze end other) (SPELL_ATTR4_TRIGGER_ACTIVATE, 0x00000200, ("9 initially disabled / trigger activate from event (Execute, Riposte, Deep Freeze end other)")),
SPELL_ATTR4_SPELL_VS_EXTEND_COST = 0x00000400, // 10 Rogue Shiv have this flag (SPELL_ATTR4_SPELL_VS_EXTEND_COST, 0x00000400, ("10 Rogue Shiv have this flag")),
SPELL_ATTR4_UNK11 = 0x00000800, // 11 (SPELL_ATTR4_UNK11, 0x00000800, ("11")),
SPELL_ATTR4_UNK12 = 0x00001000, // 12 (SPELL_ATTR4_UNK12, 0x00001000, ("12")),
SPELL_ATTR4_UNK13 = 0x00002000, // 13 (SPELL_ATTR4_UNK13, 0x00002000, ("13")),
SPELL_ATTR4_DAMAGE_DOESNT_BREAK_AURAS = 0x00004000, // 14 doesn't break auras by damage from these spells (SPELL_ATTR4_DAMAGE_DOESNT_BREAK_AURAS, 0x00004000, ("14 doesn't break auras by damage from these spells")),
SPELL_ATTR4_UNK15 = 0x00008000, // 15 (SPELL_ATTR4_UNK15, 0x00008000, ("15")),
SPELL_ATTR4_NOT_USABLE_IN_ARENA = 0x00010000, // 16 (SPELL_ATTR4_NOT_USABLE_IN_ARENA, 0x00010000, ("16")),
SPELL_ATTR4_USABLE_IN_ARENA = 0x00020000, // 17 (SPELL_ATTR4_USABLE_IN_ARENA, 0x00020000, ("17")),
SPELL_ATTR4_AREA_TARGET_CHAIN = 0x00040000, // 18 (NYI)hits area targets one after another instead of all at once (SPELL_ATTR4_AREA_TARGET_CHAIN, 0x00040000, ("18 (NYI)hits area targets one after another instead of all at once")),
SPELL_ATTR4_UNK19 = 0x00080000, // 19 proc dalayed, after damage or don't proc on absorb? (SPELL_ATTR4_UNK19, 0x00080000, ("19 proc dalayed, after damage or don't proc on absorb?")),
SPELL_ATTR4_NOT_CHECK_SELFCAST_POWER = 0x00100000, // 20 supersedes message "More powerful spell applied" for self casts. (SPELL_ATTR4_NOT_CHECK_SELFCAST_POWER, 0x00100000, ("20 supersedes message 'More powerful spell applied' for self casts.")),
SPELL_ATTR4_UNK21 = 0x00200000, // 21 Pally aura, dk presence, dudu form, warrior stance, shadowform, hunter track (SPELL_ATTR4_UNK21, 0x00200000, ("21 Pally aura, dk presence, dudu form, warrior stance, shadowform, hunter track")),
SPELL_ATTR4_UNK22 = 0x00400000, // 22 Seal of Command (42058, 57770) and Gymer's Smash 55426 (SPELL_ATTR4_UNK22, 0x00400000, ("22 Seal of Command (42058, 57770) and Gymer's Smash 55426")),
SPELL_ATTR4_CANT_TRIGGER_ITEM_SPELLS = 0x00800000, // 23 spells with this flag should not trigger item spells / enchants (mostly in conjunction with SPELL_ATTR0_STOP_ATTACK_TARGET) (SPELL_ATTR4_CANT_TRIGGER_ITEM_SPELLS, 0x00800000, ("23 spells with this flag should not trigger item spells / enchants (mostly in conjunction with SPELL_ATTR0_STOP_ATTACK_TARGET)")),
SPELL_ATTR4_UNK24 = 0x01000000, // 24 some shoot spell (SPELL_ATTR4_UNK24, 0x01000000, ("24 some shoot spell")),
SPELL_ATTR4_IS_PET_SCALING = 0x02000000, // 25 pet scaling auras (SPELL_ATTR4_IS_PET_SCALING, 0x02000000, ("25 pet scaling auras")),
SPELL_ATTR4_CAST_ONLY_IN_OUTLAND = 0x04000000, // 26 Can only be used in Outland. (SPELL_ATTR4_CAST_ONLY_IN_OUTLAND, 0x04000000, ("26 Can only be used in Outland.")),
SPELL_ATTR4_INHERIT_CRIT_FROM_AURA = 0x08000000, // 27 Volley, Arcane Missiles, Penance -> related to critical on channeled periodical damage spell (SPELL_ATTR4_INHERIT_CRIT_FROM_AURA, 0x08000000, ("27 Volley, Arcane Missiles, Penance -> related to critical on channeled periodical damage spell")),
SPELL_ATTR4_UNK28 = 0x10000000, // 28 Aimed Shot (SPELL_ATTR4_UNK28, 0x10000000, ("28 Aimed Shot")),
SPELL_ATTR4_UNK29 = 0x20000000, // 29 (SPELL_ATTR4_UNK29, 0x20000000, ("29")),
SPELL_ATTR4_UNK30 = 0x40000000, // 30 (SPELL_ATTR4_UNK30, 0x40000000, ("30")),
SPELL_ATTR4_UNK31 = 0x80000000 // 31 Polymorph (chicken) 228 and Sonic Boom (38052, 38488) (SPELL_ATTR4_UNK31, 0x80000000, ("31 Polymorph (chicken) 228 and Sonic Boom (38052, 38488)"))
}; ));
enum SpellAttr5 SMART_ENUM((SpellAttr5, uint32),
{ (
SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING = 0x00000001, // 0 available casting channel spell when moving (SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING, 0x00000001, ("0 available casting channel spell when moving")),
SPELL_ATTR5_NO_REAGENT_WHILE_PREP = 0x00000002, // 1 not need reagents if UNIT_FLAG_PREPARATION (SPELL_ATTR5_NO_REAGENT_WHILE_PREP, 0x00000002, ("1 not need reagents if UNIT_FLAG_PREPARATION")),
SPELL_ATTR5_REMOVE_ON_ARENA_ENTER = 0x00000004, // 2 remove this aura on arena enter (SPELL_ATTR5_REMOVE_ON_ARENA_ENTER, 0x00000004, ("2 remove this aura on arena enter")),
SPELL_ATTR5_USABLE_WHILE_STUNNED = 0x00000008, // 3 usable while stunned (SPELL_ATTR5_USABLE_WHILE_STUNNED, 0x00000008, ("3 usable while stunned")),
SPELL_ATTR5_UNK4 = 0x00000010, // 4 (SPELL_ATTR5_UNK4, 0x00000010, ("4")),
SPELL_ATTR5_SINGLE_TARGET_SPELL = 0x00000020, // 5 Only one target can be apply at a time (SPELL_ATTR5_SINGLE_TARGET_SPELL, 0x00000020, ("5 Only one target can be apply at a time")),
SPELL_ATTR5_UNK6 = 0x00000040, // 6 (SPELL_ATTR5_UNK6, 0x00000040, ("6")),
SPELL_ATTR5_UNK7 = 0x00000080, // 7 (SPELL_ATTR5_UNK7, 0x00000080, ("7")),
SPELL_ATTR5_UNK8 = 0x00000100, // 8 (SPELL_ATTR5_UNK8, 0x00000100, ("8")),
SPELL_ATTR5_START_PERIODIC_AT_APPLY = 0x00000200, // 9 begin periodic tick at aura apply (SPELL_ATTR5_START_PERIODIC_AT_APPLY, 0x00000200, ("9 begin periodic tick at aura apply")),
SPELL_ATTR5_HIDE_DURATION = 0x00000400, // 10 do not send duration to client (SPELL_ATTR5_HIDE_DURATION, 0x00000400, ("10 do not send duration to client")),
SPELL_ATTR5_ALLOW_TARGET_OF_TARGET_AS_TARGET = 0x00000800, // 11 (NYI) uses target's target as target if original target not valid (intervene for example) (SPELL_ATTR5_ALLOW_TARGET_OF_TARGET_AS_TARGET, 0x00000800, ("11 (NYI) uses target's target as target if original target not valid (intervene for example)")),
SPELL_ATTR5_UNK12 = 0x00001000, // 12 Cleave related? (SPELL_ATTR5_UNK12, 0x00001000, ("12 Cleave related?")),
SPELL_ATTR5_HASTE_AFFECT_DURATION = 0x00002000, // 13 haste effects decrease duration of this (SPELL_ATTR5_HASTE_AFFECT_DURATION, 0x00002000, ("13 haste effects decrease duration of this")),
SPELL_ATTR5_UNK14 = 0x00004000, // 14 (SPELL_ATTR5_UNK14, 0x00004000, ("14")),
SPELL_ATTR5_UNK15 = 0x00008000, // 15 Inflits on multiple targets? (SPELL_ATTR5_UNK15, 0x00008000, ("15 Inflits on multiple targets?")),
SPELL_ATTR5_UNK16 = 0x00010000, // 16 (SPELL_ATTR5_UNK16, 0x00010000, ("16")),
SPELL_ATTR5_USABLE_WHILE_FEARED = 0x00020000, // 17 usable while feared (SPELL_ATTR5_USABLE_WHILE_FEARED, 0x00020000, ("17 usable while feared")),
SPELL_ATTR5_USABLE_WHILE_CONFUSED = 0x00040000, // 18 usable while confused (SPELL_ATTR5_USABLE_WHILE_CONFUSED, 0x00040000, ("18 usable while confused")),
SPELL_ATTR5_DONT_TURN_DURING_CAST = 0x00080000, // 19 Blocks caster's turning when casting (client does not automatically turn caster's model to face UNIT_FIELD_TARGET) (SPELL_ATTR5_DONT_TURN_DURING_CAST, 0x00080000, ("19 Blocks caster's turning when casting (client does not automatically turn caster's model to face UNIT_FIELD_TARGET)")),
SPELL_ATTR5_UNK20 = 0x00100000, // 20 (SPELL_ATTR5_UNK20, 0x00100000, ("20")),
SPELL_ATTR5_UNK21 = 0x00200000, // 21 (SPELL_ATTR5_UNK21, 0x00200000, ("21")),
SPELL_ATTR5_UNK22 = 0x00400000, // 22 (SPELL_ATTR5_UNK22, 0x00400000, ("22")),
SPELL_ATTR5_UNK23 = 0x00800000, // 23 (SPELL_ATTR5_UNK23, 0x00800000, ("23")),
SPELL_ATTR5_UNK24 = 0x01000000, // 24 (SPELL_ATTR5_UNK24, 0x01000000, ("24")),
SPELL_ATTR5_UNK25 = 0x02000000, // 25 (SPELL_ATTR5_UNK25, 0x02000000, ("25")),
SPELL_ATTR5_SKIP_CHECKCAST_LOS_CHECK = 0x04000000, // 26 aoe related - Boulder, Cannon, Corpse Explosion, Fire Nova, Flames, Frost Bomb, Living Bomb, Seed of Corruption, Starfall, Thunder Clap, Volley (SPELL_ATTR5_SKIP_CHECKCAST_LOS_CHECK, 0x04000000, ("26 aoe related - Boulder, Cannon, Corpse Explosion, Fire Nova, Flames, Frost Bomb, Living Bomb, Seed of Corruption, Starfall, Thunder Clap, Volley")),
SPELL_ATTR5_DONT_SHOW_AURA_IF_SELF_CAST = 0x08000000, // 27 Auras with this attribute are not visible on units that are the caster (SPELL_ATTR5_DONT_SHOW_AURA_IF_SELF_CAST, 0x08000000, ("27 Auras with this attribute are not visible on units that are the caster")),
SPELL_ATTR5_DONT_SHOW_AURA_IF_NOT_SELF_CAST = 0x10000000, // 28 Auras with this attribute are not visible on units that are not the caster (SPELL_ATTR5_DONT_SHOW_AURA_IF_NOT_SELF_CAST, 0x10000000, ("28 Auras with this attribute are not visible on units that are not the caster")),
SPELL_ATTR5_UNK29 = 0x20000000, // 29 (SPELL_ATTR5_UNK29, 0x20000000, ("29")),
SPELL_ATTR5_UNK30 = 0x40000000, // 30 (SPELL_ATTR5_UNK30, 0x40000000, ("30")),
SPELL_ATTR5_UNK31 = 0x80000000 // 31 Forces all nearby enemies to focus attacks caster (SPELL_ATTR5_UNK31, 0x80000000, ("31 Forces all nearby enemies to focus attacks caster"))
}; ));
enum SpellAttr6 SMART_ENUM((SpellAttr6, uint32),
{ (
SPELL_ATTR6_DONT_DISPLAY_COOLDOWN = 0x00000001, // 0 client doesn't display cooldown in tooltip for these spells (SPELL_ATTR6_DONT_DISPLAY_COOLDOWN, 0x00000001, ("0 client doesn't display cooldown in tooltip for these spells")),
SPELL_ATTR6_ONLY_IN_ARENA = 0x00000002, // 1 only usable in arena (SPELL_ATTR6_ONLY_IN_ARENA, 0x00000002, ("1 only usable in arena")),
SPELL_ATTR6_IGNORE_CASTER_AURAS = 0x00000004, // 2 (SPELL_ATTR6_IGNORE_CASTER_AURAS, 0x00000004, ("2")),
SPELL_ATTR6_ASSIST_IGNORE_IMMUNE_FLAG = 0x00000008, // 3 skips checking UNIT_FLAG_IMMUNE_TO_PC and UNIT_FLAG_IMMUNE_TO_NPC flags on assist (SPELL_ATTR6_ASSIST_IGNORE_IMMUNE_FLAG, 0x00000008, ("3 skips checking UNIT_FLAG_IMMUNE_TO_PC and UNIT_FLAG_IMMUNE_TO_NPC flags on assist")),
SPELL_ATTR6_UNK4 = 0x00000010, // 4 (SPELL_ATTR6_UNK4, 0x00000010, ("4")),
SPELL_ATTR6_DONT_CONSUME_PROC_CHARGES = 0x00000020, // 5 dont consume proc charges (SPELL_ATTR6_DONT_CONSUME_PROC_CHARGES, 0x00000020, ("5 dont consume proc charges")),
SPELL_ATTR6_USE_SPELL_CAST_EVENT = 0x00000040, // 6 Auras with this attribute trigger SPELL_CAST combat log event instead of SPELL_AURA_START (clientside attribute) (SPELL_ATTR6_USE_SPELL_CAST_EVENT, 0x00000040, ("6 Auras with this attribute trigger SPELL_CAST combat log event instead of SPELL_AURA_START (clientside attribute)")),
SPELL_ATTR6_UNK7 = 0x00000080, // 7 (SPELL_ATTR6_UNK7, 0x00000080, ("7")),
SPELL_ATTR6_CANT_TARGET_CROWD_CONTROLLED = 0x00000100, // 8 (SPELL_ATTR6_CANT_TARGET_CROWD_CONTROLLED, 0x00000100, ("8")),
SPELL_ATTR6_UNK9 = 0x00000200, // 9 (SPELL_ATTR6_UNK9, 0x00000200, ("9")),
SPELL_ATTR6_CAN_TARGET_POSSESSED_FRIENDS = 0x00000400, // 10 NYI! (SPELL_ATTR6_CAN_TARGET_POSSESSED_FRIENDS, 0x00000400, ("10 NYI!")),
SPELL_ATTR6_NOT_IN_RAID_INSTANCE = 0x00000800, // 11 not usable in raid instance (SPELL_ATTR6_NOT_IN_RAID_INSTANCE, 0x00000800, ("11 not usable in raid instance")),
SPELL_ATTR6_CASTABLE_WHILE_ON_VEHICLE = 0x00001000, // 12 castable while caster is on vehicle (SPELL_ATTR6_CASTABLE_WHILE_ON_VEHICLE, 0x00001000, ("12 castable while caster is on vehicle")),
SPELL_ATTR6_CAN_TARGET_INVISIBLE = 0x00002000, // 13 ignore visibility requirement for spell target (phases, invisibility, etc.) (SPELL_ATTR6_CAN_TARGET_INVISIBLE, 0x00002000, ("13 ignore visibility requirement for spell target (phases, invisibility, etc.)")),
SPELL_ATTR6_UNK14 = 0x00004000, // 14 (SPELL_ATTR6_UNK14, 0x00004000, ("14")),
SPELL_ATTR6_UNK15 = 0x00008000, // 15 only 54368, 67892 (SPELL_ATTR6_UNK15, 0x00008000, ("15 only 54368, 67892")),
SPELL_ATTR6_UNK16 = 0x00010000, // 16 (SPELL_ATTR6_UNK16, 0x00010000, ("16")),
SPELL_ATTR6_UNK17 = 0x00020000, // 17 Mount spell (SPELL_ATTR6_UNK17, 0x00020000, ("17 Mount spell")),
SPELL_ATTR6_CAST_BY_CHARMER = 0x00040000, // 18 client won't allow to cast these spells when unit is not possessed && charmer of caster will be original caster (SPELL_ATTR6_CAST_BY_CHARMER, 0x00040000, ("18 client won't allow to cast these spells when unit is not possessed && charmer of caster will be original caster")),
SPELL_ATTR6_UNK19 = 0x00080000, // 19 only 47488, 50782 (SPELL_ATTR6_UNK19, 0x00080000, ("19 only 47488, 50782")),
SPELL_ATTR6_ONLY_VISIBLE_TO_CASTER = 0x00100000, // 20 Auras with this attribute are only visible to their caster (or pet's owner) (SPELL_ATTR6_ONLY_VISIBLE_TO_CASTER, 0x00100000, ("20 Auras with this attribute are only visible to their caster (or pet's owner)")),
SPELL_ATTR6_CLIENT_UI_TARGET_EFFECTS = 0x00200000, // 21 it's only client-side attribute (SPELL_ATTR6_CLIENT_UI_TARGET_EFFECTS, 0x00200000, ("21 it's only client-side attribute")),
SPELL_ATTR6_UNK22 = 0x00400000, // 22 only 72054 (SPELL_ATTR6_UNK22, 0x00400000, ("22 only 72054")),
SPELL_ATTR6_UNK23 = 0x00800000, // 23 (SPELL_ATTR6_UNK23, 0x00800000, ("23")),
SPELL_ATTR6_CAN_TARGET_UNTARGETABLE = 0x01000000, // 24 (SPELL_ATTR6_CAN_TARGET_UNTARGETABLE, 0x01000000, ("24")),
SPELL_ATTR6_NOT_RESET_SWING_IF_INSTANT = 0x02000000, // 25 Exorcism, Flash of Light (SPELL_ATTR6_NOT_RESET_SWING_IF_INSTANT, 0x02000000, ("25 Exorcism, Flash of Light")),
SPELL_ATTR6_UNK26 = 0x04000000, // 26 related to player castable positive buff (SPELL_ATTR6_UNK26, 0x04000000, ("26 related to player castable positive buff")),
SPELL_ATTR6_LIMIT_PCT_HEALING_MODS = 0x08000000, // 27 some custom rules - complicated (SPELL_ATTR6_LIMIT_PCT_HEALING_MODS, 0x08000000, ("27 some custom rules - complicated")),
SPELL_ATTR6_UNK28 = 0x10000000, // 28 Death Grip (SPELL_ATTR6_UNK28, 0x10000000, ("28 Death Grip")),
SPELL_ATTR6_LIMIT_PCT_DAMAGE_MODS = 0x20000000, // 29 ignores done percent damage mods? some custom rules - complicated (SPELL_ATTR6_LIMIT_PCT_DAMAGE_MODS, 0x20000000, ("29 ignores done percent damage mods? some custom rules - complicated")),
SPELL_ATTR6_UNK30 = 0x40000000, // 30 (SPELL_ATTR6_UNK30, 0x40000000, ("30")),
SPELL_ATTR6_IGNORE_CATEGORY_COOLDOWN_MODS = 0x80000000 // 31 Spells with this attribute skip applying modifiers to category cooldowns (SPELL_ATTR6_IGNORE_CATEGORY_COOLDOWN_MODS, 0x80000000, ("31 Spells with this attribute skip applying modifiers to category cooldowns"))
}; ));
enum SpellAttr7 SMART_ENUM((SpellAttr7, uint32),
{ (
SPELL_ATTR7_UNK0 = 0x00000001, // 0 Shaman's new spells (Call of the ...), Feign Death. (SPELL_ATTR7_UNK0, 0x00000001, ("0 Shaman's new spells (Call of the ...), Feign Death.")),
SPELL_ATTR7_IGNORE_DURATION_MODS = 0x00000002, // 1 Duration is not affected by duration modifiers (SPELL_ATTR7_IGNORE_DURATION_MODS, 0x00000002, ("1 Duration is not affected by duration modifiers")),
SPELL_ATTR7_REACTIVATE_AT_RESURRECT = 0x00000004, // 2 Paladin's auras and 65607 only. (SPELL_ATTR7_REACTIVATE_AT_RESURRECT, 0x00000004, ("2 Paladin's auras and 65607 only.")),
SPELL_ATTR7_IS_CHEAT_SPELL = 0x00000008, // 3 Cannot cast if caster doesn't have UnitFlag2 & UNIT_FLAG2_ALLOW_CHEAT_SPELLS (SPELL_ATTR7_IS_CHEAT_SPELL, 0x00000008, ("3 Cannot cast if caster doesn't have UnitFlag2 & UNIT_FLAG2_ALLOW_CHEAT_SPELLS")),
SPELL_ATTR7_UNK4 = 0x00000010, // 4 Only 47883 (Soulstone Resurrection) and test spell. (SPELL_ATTR7_UNK4, 0x00000010, ("4 Only 47883 (Soulstone Resurrection) and test spell.")),
SPELL_ATTR7_SUMMON_PLAYER_TOTEM = 0x00000020, // 5 Only Shaman player totems. (SPELL_ATTR7_SUMMON_PLAYER_TOTEM, 0x00000020, ("5 Only Shaman player totems.")),
SPELL_ATTR7_NO_PUSHBACK_ON_DAMAGE = 0x00000040, // 6 Does not cause spell pushback on damage (SPELL_ATTR7_NO_PUSHBACK_ON_DAMAGE, 0x00000040, ("6 Does not cause spell pushback on damage")),
SPELL_ATTR7_UNK7 = 0x00000080, // 7 66218 (Launch) spell. (SPELL_ATTR7_UNK7, 0x00000080, ("7 66218 (Launch) spell.")),
SPELL_ATTR7_HORDE_ONLY = 0x00000100, // 8 Teleports, mounts and other spells. (SPELL_ATTR7_HORDE_ONLY, 0x00000100, ("8 Teleports, mounts and other spells.")),
SPELL_ATTR7_ALLIANCE_ONLY = 0x00000200, // 9 Teleports, mounts and other spells. (SPELL_ATTR7_ALLIANCE_ONLY, 0x00000200, ("9 Teleports, mounts and other spells.")),
SPELL_ATTR7_DISPEL_CHARGES = 0x00000400, // 10 Dispel and Spellsteal individual charges instead of whole aura. (SPELL_ATTR7_DISPEL_CHARGES, 0x00000400, ("10 Dispel and Spellsteal individual charges instead of whole aura.")),
SPELL_ATTR7_INTERRUPT_ONLY_NONPLAYER = 0x00000800, // 11 Only non-player casts interrupt, though Feral Charge - Bear has it. (SPELL_ATTR7_INTERRUPT_ONLY_NONPLAYER, 0x00000800, ("11 Only non-player casts interrupt, though Feral Charge - Bear has it.")),
SPELL_ATTR7_UNK12 = 0x00001000, // 12 Not set in 3.2.2a. (SPELL_ATTR7_UNK12, 0x00001000, ("12 Not set in 3.2.2a.")),
SPELL_ATTR7_UNK13 = 0x00002000, // 13 Not set in 3.2.2a. (SPELL_ATTR7_UNK13, 0x00002000, ("13 Not set in 3.2.2a.")),
SPELL_ATTR7_UNK14 = 0x00004000, // 14 Only 52150 (Raise Dead - Pet) spell. (SPELL_ATTR7_UNK14, 0x00004000, ("14 Only 52150 (Raise Dead - Pet) spell.")),
SPELL_ATTR7_UNK15 = 0x00008000, // 15 Exorcism. Usable on players? 100% crit chance on undead and demons? (SPELL_ATTR7_UNK15, 0x00008000, ("15 Exorcism. Usable on players? 100% crit chance on undead and demons?")),
SPELL_ATTR7_CAN_RESTORE_SECONDARY_POWER = 0x00010000, // 16 These spells can replenish a powertype, which is not the current powertype. (SPELL_ATTR7_CAN_RESTORE_SECONDARY_POWER, 0x00010000, ("16 These spells can replenish a powertype, which is not the current powertype.")),
SPELL_ATTR7_UNK17 = 0x00020000, // 17 Only 27965 (Suicide) spell. (SPELL_ATTR7_UNK17, 0x00020000, ("17 Only 27965 (Suicide) spell.")),
SPELL_ATTR7_HAS_CHARGE_EFFECT = 0x00040000, // 18 Only spells that have Charge among effects. (SPELL_ATTR7_HAS_CHARGE_EFFECT, 0x00040000, ("18 Only spells that have Charge among effects.")),
SPELL_ATTR7_ZONE_TELEPORT = 0x00080000, // 19 Teleports to specific zones. (SPELL_ATTR7_ZONE_TELEPORT, 0x00080000, ("19 Teleports to specific zones.")),
SPELL_ATTR7_UNK20 = 0x00100000, // 20 Blink, Divine Shield, Ice Block (SPELL_ATTR7_UNK20, 0x00100000, ("20 Blink, Divine Shield, Ice Block")),
SPELL_ATTR7_UNK21 = 0x00200000, // 21 Not set (SPELL_ATTR7_UNK21, 0x00200000, ("21 Not set")),
SPELL_ATTR7_IGNORE_COLD_WEATHER_FLYING = 0x00400000, // 22 Loaned Gryphon, Loaned Wind Rider (SPELL_ATTR7_IGNORE_COLD_WEATHER_FLYING, 0x00400000, ("22 Loaned Gryphon, Loaned Wind Rider")),
SPELL_ATTR7_UNK23 = 0x00800000, // 23 Motivate, Mutilate, Shattering Throw (SPELL_ATTR7_UNK23, 0x00800000, ("23 Motivate, Mutilate, Shattering Throw")),
SPELL_ATTR7_UNK24 = 0x01000000, // 24 Motivate, Mutilate, Perform Speech, Shattering Throw (SPELL_ATTR7_UNK24, 0x01000000, ("24 Motivate, Mutilate, Perform Speech, Shattering Throw")),
SPELL_ATTR7_UNK25 = 0x02000000, // 25 (SPELL_ATTR7_UNK25, 0x02000000, ("25")),
SPELL_ATTR7_UNK26 = 0x04000000, // 26 (SPELL_ATTR7_UNK26, 0x04000000, ("26")),
SPELL_ATTR7_UNK27 = 0x08000000, // 27 Not set (SPELL_ATTR7_UNK27, 0x08000000, ("27 Not set")),
SPELL_ATTR7_CONSOLIDATED_RAID_BUFF = 0x10000000, // 28 May be collapsed in raid buff frame (clientside attribute) (SPELL_ATTR7_CONSOLIDATED_RAID_BUFF, 0x10000000, ("28 May be collapsed in raid buff frame (clientside attribute)")),
SPELL_ATTR7_UNK29 = 0x20000000, // 29 only 69028, 71237 (SPELL_ATTR7_UNK29, 0x20000000, ("29 only 69028, 71237")),
SPELL_ATTR7_UNK30 = 0x40000000, // 30 Burning Determination, Divine Sacrifice, Earth Shield, Prayer of Mending (SPELL_ATTR7_UNK30, 0x40000000, ("30 Burning Determination, Divine Sacrifice, Earth Shield, Prayer of Mending")),
SPELL_ATTR7_CLIENT_INDICATOR = 0x80000000 (SPELL_ATTR7_CLIENT_INDICATOR, 0x80000000, (""))
}; ));
#define MIN_TALENT_SPEC 0 #define MIN_TALENT_SPEC 0
#define MAX_TALENT_SPEC 1 #define MAX_TALENT_SPEC 1
@@ -1524,13 +1532,14 @@ enum SpellHitType
SPELL_HIT_TYPE_ATTACK_TABLE_DEBUG = 0x20 SPELL_HIT_TYPE_ATTACK_TABLE_DEBUG = 0x20
}; };
enum SpellDmgClass SMART_ENUM(SpellDmgClass,
{ (
SPELL_DAMAGE_CLASS_NONE = 0, (SPELL_DAMAGE_CLASS_NONE, 0, ("None")),
SPELL_DAMAGE_CLASS_MAGIC = 1, (SPELL_DAMAGE_CLASS_MAGIC, 1, ("Magic")),
SPELL_DAMAGE_CLASS_MELEE = 2, (SPELL_DAMAGE_CLASS_MELEE, 2, ("Melee")),
SPELL_DAMAGE_CLASS_RANGED = 3 (SPELL_DAMAGE_CLASS_RANGED, 3, ("Ranged"))
}; ));
SMART_ENUM_BOUND(SpellDmgClass, MAX_SPELL_DAMAGE_CLASS);
enum SpellPreventionType enum SpellPreventionType
{ {
@@ -3491,27 +3500,28 @@ enum MailResponseResult
MAIL_ERR_ITEM_HAS_EXPIRED = 21 MAIL_ERR_ITEM_HAS_EXPIRED = 21
}; };
enum SpellFamilyNames SMART_ENUM(SpellFamilyNames,
{ (
SPELLFAMILY_GENERIC = 0, (SPELLFAMILY_GENERIC, 0, ("Generic")),
SPELLFAMILY_UNK1 = 1, // events, holidays (SPELLFAMILY_UNK1, 1, ("Unk1", "Unk1 (Events, Holidays...)")),
// 2 - unused // 2 - unused
SPELLFAMILY_MAGE = 3, (SPELLFAMILY_MAGE, 3, ("Mage")),
SPELLFAMILY_WARRIOR = 4, (SPELLFAMILY_WARRIOR, 4, ("Warrior")),
SPELLFAMILY_WARLOCK = 5, (SPELLFAMILY_WARLOCK, 5, ("Warlock")),
SPELLFAMILY_PRIEST = 6, (SPELLFAMILY_PRIEST, 6, ("Priest")),
SPELLFAMILY_DRUID = 7, (SPELLFAMILY_DRUID, 7, ("Druid")),
SPELLFAMILY_ROGUE = 8, (SPELLFAMILY_ROGUE, 8, ("Rogue")),
SPELLFAMILY_HUNTER = 9, (SPELLFAMILY_HUNTER, 9, ("Hunter")),
SPELLFAMILY_PALADIN = 10, (SPELLFAMILY_PALADIN, 10, ("Paladin")),
SPELLFAMILY_SHAMAN = 11, (SPELLFAMILY_SHAMAN, 11, ("Shaman")),
SPELLFAMILY_UNK2 = 12, // 2 spells (silence resistance) (SPELLFAMILY_UNK2, 12, ("Unk2", "Unk2 (Silence resistance?)")),
SPELLFAMILY_POTION = 13, (SPELLFAMILY_POTION, 13, ("Potion")),
// 14 - unused // 14 - unused
SPELLFAMILY_DEATHKNIGHT = 15, (SPELLFAMILY_DEATHKNIGHT, 15, ("Death Knight")),
// 16 - unused // 16 - unused
SPELLFAMILY_PET = 17 (SPELLFAMILY_PET, 17, ("Pet"))
}; ));
SMART_ENUM_BOUND(SpellFamilyNames, MAX_SPELL_FAMILY);
enum TradeStatus enum TradeStatus
{ {