diff options
159 files changed, 6994 insertions, 2504 deletions
diff --git a/cmake/macros/ConfigureBoost.cmake b/cmake/macros/ConfigureBoost.cmake index 022d84246ef..b3a71b8a682 100644 --- a/cmake/macros/ConfigureBoost.cmake +++ b/cmake/macros/ConfigureBoost.cmake @@ -1,13 +1,3 @@ -macro(get_WIN32_WINNT version) - if (WIN32 AND CMAKE_SYSTEM_VERSION) - set(ver ${CMAKE_SYSTEM_VERSION}) - string(REPLACE "." "" ver ${ver}) - string(REGEX REPLACE "([0-9])" "0\\1" ver ${ver}) - - set(${version} "0x${ver}") - endif() -endmacro() - if(WIN32) set(BOOST_DEBUG ON) if(DEFINED ENV{BOOST_ROOT}) @@ -25,8 +15,7 @@ if(WIN32) set(Boost_USE_MULTITHREADED ON) set(Boost_USE_STATIC_RUNTIME OFF) - get_WIN32_WINNT(ver) - add_definitions(-D_WIN32_WINNT=${ver}) + add_definitions(-D_WIN32_WINNT=0x0601) endif() find_package(Boost 1.49 REQUIRED system filesystem thread program_options iostreams regex) diff --git a/dep/CMakeLists.txt b/dep/CMakeLists.txt index 2b3796fb2fa..f829956b7bf 100644 --- a/dep/CMakeLists.txt +++ b/dep/CMakeLists.txt @@ -32,10 +32,10 @@ endif() if(SERVERS OR TOOLS) add_subdirectory(g3dlite) add_subdirectory(recastnavigation) + add_subdirectory(cppformat) endif() if(SERVERS) - add_subdirectory(cppformat) add_subdirectory(gsoap) endif() diff --git a/dep/PackageList.txt b/dep/PackageList.txt index 65533192da9..e84fef8d3b2 100644 --- a/dep/PackageList.txt +++ b/dep/PackageList.txt @@ -14,7 +14,7 @@ bzip2 (a freely available, patent free, high-quality data compressor) cppformat (type safe format library) https://github.com/cppformat/cppformat - Version: 7859f8123311c1b8f69856d3c5e1b8501fbdae11 + Version: 5c76d107cbaf5e851bd66b6c563e4fc7c90be7ad G3D (a commercial-grade C++ 3D engine available as Open Source (BSD License) http://g3d.sourceforge.net/ diff --git a/dep/SFMT/SFMT-hotfix1.diff b/dep/SFMT/SFMT-hotfix1.diff new file mode 100644 index 00000000000..ba7810dc100 --- /dev/null +++ b/dep/SFMT/SFMT-hotfix1.diff @@ -0,0 +1,14 @@ +diff --git a/dep/SFMT/SFMT.h b/dep/SFMT/SFMT.h +index 3d15d65..ccf21ce 100644 +--- a/dep/SFMT/SFMT.h ++++ b/dep/SFMT/SFMT.h +@@ -173,7 +173,8 @@ public: + uint32_t statesize = SFMT_N*4; // Size of state vector + + // Fill state vector with random numbers from seed +- ((uint32_t*)state)[0] = y; ++ uint32_t* s = (uint32_t*)&state; ++ s[0] = y; + const uint32_t factor = 1812433253U;// Multiplication factor + + for (i = 1; i < statesize; i++) { diff --git a/dep/SFMT/SFMT.h b/dep/SFMT/SFMT.h index 3d15d651e5b..ccf21cecd5f 100644 --- a/dep/SFMT/SFMT.h +++ b/dep/SFMT/SFMT.h @@ -173,7 +173,8 @@ public: uint32_t statesize = SFMT_N*4; // Size of state vector // Fill state vector with random numbers from seed - ((uint32_t*)state)[0] = y; + uint32_t* s = (uint32_t*)&state; + s[0] = y; const uint32_t factor = 1812433253U;// Multiplication factor for (i = 1; i < statesize; i++) { diff --git a/dep/cppformat/ChangeLog.rst b/dep/cppformat/ChangeLog.rst index 89d5af8e9c7..d2a77f8712f 100644 --- a/dep/cppformat/ChangeLog.rst +++ b/dep/cppformat/ChangeLog.rst @@ -1,3 +1,356 @@ +2.0.0 - 2015-12-01 +------------------ + +General +~~~~~~~ + +* [Breaking] Named arguments + (`#169 <https://github.com/cppformat/cppformat/pull/169>`_, + `#173 <https://github.com/cppformat/cppformat/pull/173>`_, + `#174 <https://github.com/cppformat/cppformat/pull/174>`_): + + .. code:: c++ + + fmt::print("The answer is {answer}.", fmt::arg("answer", 42)); + + Thanks to `@jamboree <https://github.com/jamboree>`_. + +* [Experimental] User-defined literals for format and named arguments + (`#204 <https://github.com/cppformat/cppformat/pull/204>`_, + `#206 <https://github.com/cppformat/cppformat/pull/206>`_, + `#207 <https://github.com/cppformat/cppformat/pull/207>`_): + + .. code:: c++ + + using namespace fmt::literals; + fmt::print("The answer is {answer}.", "answer"_a=42); + + Thanks to `@dean0x7d (Dean Moldovan) <https://github.com/dean0x7d>`_. + +* [Breaking] Formatting of more than 16 arguments is now supported when using + variadic templates + (`#141 <https://github.com/cppformat/cppformat/issues/141>`_). + Thanks to `@Shauren <https://github.com/Shauren>`_. + +* Runtime width specification + (`#168 <https://github.com/cppformat/cppformat/pull/168>`_): + + .. code:: c++ + + fmt::format("{0:{1}}", 42, 5); // gives " 42" + + Thanks to `@jamboree <https://github.com/jamboree>`_. + +* [Breaking] Enums are now formatted with an overloaded ``std::ostream`` insertion + operator (``operator<<``) if available + (`#232 <https://github.com/cppformat/cppformat/issues/232>`_). + +* [Breaking] Changed default ``bool`` format to textual, "true" or "false" + (`#170 <https://github.com/cppformat/cppformat/issues/170>`_): + + .. code:: c++ + + fmt::print("{}", true); // prints "true" + + To print ``bool`` as a number use numeric format specifier such as ``d``: + + .. code:: c++ + + fmt::print("{:d}", true); // prints "1" + +* ``fmt::printf`` and ``fmt::sprintf`` now support formatting of ``bool`` with the + ``%s`` specifier giving textual output, "true" or "false" + (`#223 <https://github.com/cppformat/cppformat/pull/223>`_): + + .. code:: c++ + + fmt::printf("%s", true); // prints "true" + + Thanks to `@LarsGullik <https://github.com/LarsGullik>`_. + +* [Breaking] ``signed char`` and ``unsigned char`` are now formatted as integers by default + (`#217 <https://github.com/cppformat/cppformat/pull/217>`_). + +* [Breaking] Pointers to C strings can now be formatted with the ``p`` specifier + (`#223 <https://github.com/cppformat/cppformat/pull/223>`_): + + .. code:: c++ + + fmt::print("{:p}", "test"); // prints pointer value + + Thanks to `@LarsGullik <https://github.com/LarsGullik>`_. + +* [Breaking] ``fmt::printf`` and ``fmt::sprintf`` now print null pointers as ``(nil)`` + and null strings as ``(null)`` for consistency with glibc + (`#226 <https://github.com/cppformat/cppformat/pull/226>`_). + Thanks to `@LarsGullik <https://github.com/LarsGullik>`_. + +* [Breaking] ``fmt::(s)printf`` now supports formatting of objects of user-defined types + that provide an overloaded ``std::ostream`` insertion operator (``operator<<``) + (`#201 <https://github.com/cppformat/cppformat/issues/201>`_): + + .. code:: c++ + + fmt::printf("The date is %s", Date(2012, 12, 9)); + +* [Breaking] The ``Buffer`` template is now part of the public API and can be used + to implement custom memory buffers + (`#140 <https://github.com/cppformat/cppformat/issues/140>`_). + Thanks to `@polyvertex (Jean-Charles Lefebvre) <https://github.com/polyvertex>`_. + +* [Breaking] Improved compatibility between ``BasicStringRef`` and + `std::experimental::basic_string_view + <http://en.cppreference.com/w/cpp/experimental/basic_string_view>`_ + (`#100 <https://github.com/cppformat/cppformat/issues/100>`_, + `#159 <https://github.com/cppformat/cppformat/issues/159>`_, + `#183 <https://github.com/cppformat/cppformat/issues/183>`_): + + - Comparison operators now compare string content, not pointers + - ``BasicStringRef::c_str`` replaced by ``BasicStringRef::data`` + - ``BasicStringRef`` is no longer assumed to be null-terminated + + References to null-terminated strings are now represented by a new class, + ``BasicCStringRef``. + +* Dependency on pthreads introduced by Google Test is now optional + (`#185 <https://github.com/cppformat/cppformat/issues/185>`_). + +* New CMake options ``FMT_DOC``, ``FMT_INSTALL`` and ``FMT_TEST`` to control + generation of ``doc``, ``install`` and ``test`` targets respectively, on by default + (`#197 <https://github.com/cppformat/cppformat/issues/197>`_, + `#198 <https://github.com/cppformat/cppformat/issues/198>`_, + `#200 <https://github.com/cppformat/cppformat/issues/200>`_). + Thanks to `@maddinat0r (Alex Martin) <https://github.com/maddinat0r>`_. + +* ``noexcept`` is now used when compiling with MSVC2015 + (`#215 <https://github.com/cppformat/cppformat/pull/215>`_). + Thanks to `@dmkrepo (Dmitriy) <https://github.com/dmkrepo>`_. + +* Added an option to disable use of ``windows.h`` when ``FMT_USE_WINDOWS_H`` + is defined as 0 before including ``format.h`` + (`#171 <https://github.com/cppformat/cppformat/issues/171>`_). + Thanks to `@alfps (Alf P. Steinbach) <https://github.com/alfps>`_. + +* [Breaking] ``windows.h`` is now included with ``NOMINMAX`` unless + ``FMT_WIN_MINMAX`` is defined. This is done to prevent breaking code using + ``std::min`` and ``std::max`` and only affects the header-only configuration + (`#152 <https://github.com/cppformat/cppformat/issues/152>`_, + `#153 <https://github.com/cppformat/cppformat/pull/153>`_, + `#154 <https://github.com/cppformat/cppformat/pull/154>`_). + Thanks to `@DevO2012 <https://github.com/DevO2012>`_. + +* Improved support for custom character types + (`#171 <https://github.com/cppformat/cppformat/issues/171>`_). + Thanks to `@alfps (Alf P. Steinbach) <https://github.com/alfps>`_. + +* Added an option to disable use of IOStreams when ``FMT_USE_IOSTREAMS`` + is defined as 0 before including ``format.h`` + (`#205 <https://github.com/cppformat/cppformat/issues/205>`_, + `#208 <https://github.com/cppformat/cppformat/pull/208>`_). + Thanks to `@JodiTheTigger <https://github.com/JodiTheTigger>`_. + +* Improved detection of ``isnan``, ``isinf`` and ``signbit``. + +Optimization +~~~~~~~~~~~~ + +* Made formatting of user-defined types more efficient with a custom stream buffer + (`#92 <https://github.com/cppformat/cppformat/issues/92>`_, + `#230 <https://github.com/cppformat/cppformat/pull/230>`_). + Thanks to `@NotImplemented <https://github.com/NotImplemented>`_. + +* Further improved performance of ``fmt::Writer`` on integer formatting + and fixed a minor regression. Now it is ~7% faster than ``karma::generate`` + on Karma's benchmark + (`#186 <https://github.com/cppformat/cppformat/issues/186>`_). + +* [Breaking] Reduced `compiled code size + <https://github.com/cppformat/cppformat#compile-time-and-code-bloat>`_ + (`#143 <https://github.com/cppformat/cppformat/issues/143>`_, + `#149 <https://github.com/cppformat/cppformat/pull/149>`_). + +Distribution +~~~~~~~~~~~~ + +* [Breaking] Headers are now installed in + ``${CMAKE_INSTALL_PREFIX}/include/cppformat`` + (`#178 <https://github.com/cppformat/cppformat/issues/178>`_). + Thanks to `@jackyf (Eugene V. Lyubimkin) <https://github.com/jackyf>`_. + +* [Breaking] Changed the library name from ``format`` to ``cppformat`` + for consistency with the project name and to avoid potential conflicts + (`#178 <https://github.com/cppformat/cppformat/issues/178>`_). + Thanks to `@jackyf (Eugene V. Lyubimkin) <https://github.com/jackyf>`_. + +* C++ Format is now available in `Debian <https://www.debian.org/>`_ GNU/Linux + (`stretch <https://packages.debian.org/source/stretch/cppformat>`_, + `sid <https://packages.debian.org/source/sid/cppformat>`_) and + derived distributions such as + `Ubuntu <https://launchpad.net/ubuntu/+source/cppformat>`_ 15.10 and later + (`#155 <https://github.com/cppformat/cppformat/issues/155>`_):: + + $ sudo apt-get install libcppformat1-dev + + Thanks to `@jackyf (Eugene V. Lyubimkin) <https://github.com/jackyf>`_. + +* `Packages for Fedora and RHEL <https://admin.fedoraproject.org/pkgdb/package/cppformat/>`_ + are now available. Thanks to Dave Johansen. + +* C++ Format can now be installed via `Homebrew <http://brew.sh/>`_ on OS X + (`#157 <https://github.com/cppformat/cppformat/issues/157>`_):: + + $ brew install cppformat + + Thanks to `@ortho <https://github.com/ortho>`_, Anatoliy Bulukin. + +Documentation +~~~~~~~~~~~~~ + +* Migrated from ReadTheDocs to GitHub Pages for better responsiveness + and reliability + (`#128 <https://github.com/cppformat/cppformat/issues/128>`_). + New documentation address is http://cppformat.github.io/. + + +* Added `Building the documentation + <http://cppformat.github.io/dev/usage.html#building-the-documentation>`_ + section to the documentation. + +* Documentation build script is now compatible with Python 3 and newer pip versions. + (`#189 <https://github.com/cppformat/cppformat/pull/189>`_, + `#209 <https://github.com/cppformat/cppformat/issues/209>`_). + Thanks to `@JodiTheTigger <https://github.com/JodiTheTigger>`_ and + `@xentec <https://github.com/xentec>`_. + +* Documentation fixes and improvements + (`#36 <https://github.com/cppformat/cppformat/issues/36>`_, + `#75 <https://github.com/cppformat/cppformat/issues/75>`_, + `#125 <https://github.com/cppformat/cppformat/issues/125>`_, + `#160 <https://github.com/cppformat/cppformat/pull/160>`_, + `#161 <https://github.com/cppformat/cppformat/pull/161>`_, + `#162 <https://github.com/cppformat/cppformat/issues/162>`_, + `#165 <https://github.com/cppformat/cppformat/issues/165>`_, + `#210 <https://github.com/cppformat/cppformat/issues/210>`_). + Thanks to `@syohex (Syohei YOSHIDA) <https://github.com/syohex>`_ and + bug reporters. + +* Fixed out-of-tree documentation build + (`#177 <https://github.com/cppformat/cppformat/issues/177>`_). + Thanks to `@jackyf (Eugene V. Lyubimkin) <https://github.com/jackyf>`_. + +Fixes +~~~~~ + +* Fixed ``initializer_list`` detection + (`#136 <https://github.com/cppformat/cppformat/issues/136>`_). + Thanks to `@Gachapen (Magnus Bjerke Vik) <https://github.com/Gachapen>`_. + +* [Breaking] Fixed formatting of enums with numeric format specifiers in + ``fmt::(s)printf`` + (`#131 <https://github.com/cppformat/cppformat/issues/131>`_, + `#139 <https://github.com/cppformat/cppformat/issues/139>`_): + + .. code:: c++ + + enum { ANSWER = 42 }; + fmt::printf("%d", ANSWER); + + Thanks to `@Naios <https://github.com/Naios>`_. + +* Improved compatibility with old versions of MinGW + (`#129 <https://github.com/cppformat/cppformat/issues/129>`_, + `#130 <https://github.com/cppformat/cppformat/pull/130>`_, + `#132 <https://github.com/cppformat/cppformat/issues/132>`_). + Thanks to `@cstamford (Christopher Stamford) <https://github.com/cstamford>`_. + +* Fixed a compile error on MSVC with disabled exceptions + (`#144 <https://github.com/cppformat/cppformat/issues/144>`_). + +* Added a workaround for broken implementation of variadic templates in MSVC2012 + (`#148 <https://github.com/cppformat/cppformat/issues/148>`_). + +* Placed the anonymous namespace within ``fmt`` namespace for the header-only + configuration + (`#171 <https://github.com/cppformat/cppformat/issues/171>`_). + Thanks to `@alfps (Alf P. Steinbach) <https://github.com/alfps>`_. + +* Fixed issues reported by Coverity Scan + (`#187 <https://github.com/cppformat/cppformat/issues/187>`_, + `#192 <https://github.com/cppformat/cppformat/issues/192>`_). + +* Implemented a workaround for a name lookup bug in MSVC2010 + (`#188 <https://github.com/cppformat/cppformat/issues/188>`_). + +* Fixed compiler warnings + (`#95 <https://github.com/cppformat/cppformat/issues/95>`_, + `#96 <https://github.com/cppformat/cppformat/issues/96>`_, + `#114 <https://github.com/cppformat/cppformat/pull/114>`_, + `#135 <https://github.com/cppformat/cppformat/issues/135>`_, + `#142 <https://github.com/cppformat/cppformat/issues/142>`_, + `#145 <https://github.com/cppformat/cppformat/issues/145>`_, + `#146 <https://github.com/cppformat/cppformat/issues/146>`_, + `#158 <https://github.com/cppformat/cppformat/issues/158>`_, + `#163 <https://github.com/cppformat/cppformat/issues/163>`_, + `#175 <https://github.com/cppformat/cppformat/issues/175>`_, + `#190 <https://github.com/cppformat/cppformat/issues/190>`_, + `#191 <https://github.com/cppformat/cppformat/pull/191>`_, + `#194 <https://github.com/cppformat/cppformat/issues/194>`_, + `#196 <https://github.com/cppformat/cppformat/pull/196>`_, + `#216 <https://github.com/cppformat/cppformat/issues/216>`_, + `#218 <https://github.com/cppformat/cppformat/pull/218>`_, + `#220 <https://github.com/cppformat/cppformat/pull/220>`_, + `#229 <https://github.com/cppformat/cppformat/pull/229>`_, + `#233 <https://github.com/cppformat/cppformat/issues/233>`_, + `#234 <https://github.com/cppformat/cppformat/issues/234>`_, + `#236 <https://github.com/cppformat/cppformat/pull/236>`_). + Thanks to `@seanmiddleditch (Sean Middleditch) <https://github.com/seanmiddleditch>`_, + `@dixlorenz (Dix Lorenz) <https://github.com/dixlorenz>`_, + `@CarterLi (李通洲) <https://github.com/CarterLi>`_, + `@Naios <https://github.com/Naios>`_, + `@fmatthew5876 (Matthew Fioravante) <https://github.com/fmatthew5876>`_, + `@LevskiWeng (Levski Weng) <https://github.com/LevskiWeng>`_, + `@rpopescu <https://github.com/rpopescu>`_, + `@gabime (Gabi Melman) <https://github.com/gabime>`_, + `@cubicool (Jeremy Moles) <https://github.com/cubicool>`_, + `@jkflying (Julian Kent) <https://github.com/jkflying>`_, + `@LogicalKnight (Sean L) <https://github.com/LogicalKnight>`_, + `@inguin (Ingo van Lil) <https://github.com/inguin>`_ and + `@Jopie64 (Johan) <https://github.com/Jopie64>`_. + +* Fixed portability issues (mostly causing test failures) on ARM, ppc64, ppc64le, + s390x and SunOS 5.11 i386 ( + `#138 <https://github.com/cppformat/cppformat/issues/138>`_, + `#179 <https://github.com/cppformat/cppformat/issues/179>`_, + `#180 <https://github.com/cppformat/cppformat/issues/180>`_, + `#202 <https://github.com/cppformat/cppformat/issues/202>`_, + `#225 <https://github.com/cppformat/cppformat/issues/225>`_, + `Red Hat Bugzilla Bug 1260297 <https://bugzilla.redhat.com/show_bug.cgi?id=1260297>`_). + Thanks to `@Naios <https://github.com/Naios>`_, + `@jackyf (Eugene V. Lyubimkin) <https://github.com/jackyf>`_ and Dave Johansen. + +* Fixed a name conflict with macro ``free`` defined in + ``crtdbg.h`` when ``_CRTDBG_MAP_ALLOC`` is set + (`#211 <https://github.com/cppformat/cppformat/issues/211>`_). + +* Fixed shared library build on OS X + (`#212 <https://github.com/cppformat/cppformat/pull/212>`_). + Thanks to `@dean0x7d (Dean Moldovan) <https://github.com/dean0x7d>`_. + +* Fixed an overload conflict on MSVC when ``/Zc:wchar_t-`` option is specified + (`#214 <https://github.com/cppformat/cppformat/pull/214>`_). + Thanks to `@slavanap (Vyacheslav Napadovsky) <https://github.com/slavanap>`_. + +* Improved compatibility with MSVC 2008 + (`#236 <https://github.com/cppformat/cppformat/pull/236>`_). + Thanks to `@Jopie64 (Johan) <https://github.com/Jopie64>`_. + +* Improved compatibility with bcc32 + (`#227 <https://github.com/cppformat/cppformat/issues/227>`_). + +* Fixed ``static_assert`` detection on Clang + (`#228 <https://github.com/cppformat/cppformat/pull/228>`_). + Thanks to `@dean0x7d (Dean Moldovan) <https://github.com/dean0x7d>`_. + 1.1.0 - 2015-03-06 ------------------ @@ -66,11 +419,6 @@ * Fixed packaging issues (`#94 <https://github.com/cppformat/cppformat/issues/94>`_). -* Fixed warnings in GCC, MSVC and Xcode/Clang - (`#95 <https://github.com/cppformat/cppformat/issues/95>`_, - `#96 <https://github.com/cppformat/cppformat/issues/96>`_ and - `#114 <https://github.com/cppformat/cppformat/pull/114>`_). - * Added `changelog <https://github.com/cppformat/cppformat/blob/master/ChangeLog.rst>`_ (`#103 <https://github.com/cppformat/cppformat/issues/103>`_). diff --git a/dep/cppformat/README.rst b/dep/cppformat/README.rst index 29f433480f3..fb4399f0af4 100644 --- a/dep/cppformat/README.rst +++ b/dep/cppformat/README.rst @@ -7,9 +7,6 @@ C++ Format .. image:: https://ci.appveyor.com/api/projects/status/qk0bhyhqp1ekpat8 :target: https://ci.appveyor.com/project/vitaut/cppformat -.. image:: https://webapi.biicode.com/v1/badges/vitaut/vitaut/cppformat/master?dummy - :target: https://www.biicode.com/vitaut/cppformat - .. image:: https://badges.gitter.im/Join%20Chat.svg :alt: Join the chat at https://gitter.im/cppformat/cppformat :target: https://gitter.im/cppformat/cppformat?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge @@ -149,6 +146,8 @@ Projects using this library * `readpe <https://bitbucket.org/sys_dev/readpe>`_: Read Portable Executable +* `redis-cerberus <https://github.com/HunanTV/redis-cerberus>`_: A Redis cluster proxy + * `Saddy <https://code.google.com/p/saddy/>`_: Small crossplatform 2D graphic engine @@ -157,6 +156,10 @@ Projects using this library * `spdlog <https://github.com/gabime/spdlog>`_: Super fast C++ logging library +* `Stellar <https://www.stellar.org/>`_: Financial platform + +* `Touch Surgery <https://www.touchsurgery.com/>`_: Surgery simulator + * `TrinityCore <https://github.com/TrinityCore/TrinityCore>`_: Open-source MMORPG framework `More... <https://github.com/search?q=cppformat&type=Code>`_ diff --git a/dep/cppformat/format.cc b/dep/cppformat/format.cc index 86b86c741b5..1970d53c500 100644 --- a/dep/cppformat/format.cc +++ b/dep/cppformat/format.cc @@ -34,6 +34,7 @@ #include <climits> #include <cmath> #include <cstdarg> +#include <cstddef> // for std::ptrdiff_t #if defined(_WIN32) && defined(__MINGW32__) # include <cstring> @@ -51,17 +52,6 @@ using fmt::internal::Arg; -// Check if exceptions are disabled. -#if __GNUC__ && !__EXCEPTIONS -# define FMT_EXCEPTIONS 0 -#endif -#if _MSC_VER && !_HAS_EXCEPTIONS -# define FMT_EXCEPTIONS 0 -#endif -#ifndef FMT_EXCEPTIONS -# define FMT_EXCEPTIONS 1 -#endif - #if FMT_EXCEPTIONS # define FMT_TRY try # define FMT_CATCH(x) catch (x) @@ -70,21 +60,13 @@ using fmt::internal::Arg; # define FMT_CATCH(x) if (false) #endif -#ifndef FMT_THROW -# if FMT_EXCEPTIONS -# define FMT_THROW(x) throw x -# else -# define FMT_THROW(x) assert(false) -# endif -#endif - #ifdef FMT_HEADER_ONLY # define FMT_FUNC inline #else # define FMT_FUNC #endif -#if _MSC_VER +#ifdef _MSC_VER # pragma warning(push) # pragma warning(disable: 4127) // conditional expression is constant # pragma warning(disable: 4702) // unreachable code @@ -95,11 +77,11 @@ using fmt::internal::Arg; // Dummy implementations of strerror_r and strerror_s called if corresponding // system functions are not available. -static inline fmt::internal::None<> strerror_r(int, char *, ...) { - return fmt::internal::None<>(); +static inline fmt::internal::Null<> strerror_r(int, char *, ...) { + return fmt::internal::Null<>(); } -static inline fmt::internal::None<> strerror_s(char *, std::size_t, ...) { - return fmt::internal::None<>(); +static inline fmt::internal::Null<> strerror_s(char *, std::size_t, ...) { + return fmt::internal::Null<>(); } namespace fmt { @@ -133,6 +115,7 @@ struct IntChecker { unsigned max = INT_MAX; return value <= max; } + static bool fits_in_int(bool) { return true; } }; template <> @@ -141,6 +124,7 @@ struct IntChecker<true> { static bool fits_in_int(T value) { return value >= INT_MIN && value <= INT_MAX; } + static bool fits_in_int(int) { return true; } }; const char RESET_COLOR[] = "\x1b[0m"; @@ -185,7 +169,7 @@ int safe_strerror( } // Handle the case when strerror_r is not available. - int handle(fmt::internal::None<>) { + int handle(fmt::internal::Null<>) { return fallback(strerror_s(buffer_, buffer_size_, error_code_)); } @@ -197,15 +181,15 @@ int safe_strerror( } // Fallback to strerror if strerror_r and strerror_s are not available. - int fallback(fmt::internal::None<>) { + int fallback(fmt::internal::Null<>) { errno = 0; buffer_ = strerror(error_code_); return errno; } public: - StrError(int error_code, char *&buffer, std::size_t buffer_size) - : error_code_(error_code), buffer_(buffer), buffer_size_(buffer_size) {} + StrError(int err_code, char *&buf, std::size_t buf_size) + : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {} int run() { strerror_r(0, 0, ""); // Suppress a warning about unused strerror_r. @@ -250,50 +234,6 @@ class IsZeroInt : public fmt::internal::ArgVisitor<IsZeroInt, bool> { bool visit_any_int(T value) { return value == 0; } }; -// Parses an unsigned integer advancing s to the end of the parsed input. -// This function assumes that the first character of s is a digit. -template <typename Char> -int parse_nonnegative_int(const Char *&s) { - assert('0' <= *s && *s <= '9'); - unsigned value = 0; - do { - unsigned new_value = value * 10 + (*s++ - '0'); - // Check if value wrapped around. - if (new_value < value) { - value = UINT_MAX; - break; - } - value = new_value; - } while ('0' <= *s && *s <= '9'); - if (value > INT_MAX) - FMT_THROW(fmt::FormatError("number is too big")); - return value; -} - -template <typename Char> -inline bool is_name_start(Char c) { - return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c; -} - -inline void require_numeric_argument(const Arg &arg, char spec) { - if (arg.type > Arg::LAST_NUMERIC_TYPE) { - std::string message = - fmt::format("format specifier '{}' requires numeric argument", spec); - FMT_THROW(fmt::FormatError(message)); - } -} - -template <typename Char> -void check_sign(const Char *&s, const Arg &arg) { - char sign = static_cast<char>(*s); - require_numeric_argument(arg, sign); - if (arg.type == Arg::UINT || arg.type == Arg::ULONG_LONG) { - FMT_THROW(fmt::FormatError(fmt::format( - "format specifier '{}' requires signed argument", sign))); - } - ++s; -} - // Checks if an argument is a valid printf width specifier and sets // left alignment if it is negative. class WidthHandler : public fmt::internal::ArgVisitor<WidthHandler, unsigned> { @@ -351,6 +291,11 @@ class ArgConverter : public fmt::internal::ArgVisitor<ArgConverter<T>, void> { ArgConverter(fmt::internal::Arg &arg, wchar_t type) : arg_(arg), type_(type) {} + void visit_bool(bool value) { + if (type_ != 's') + visit_any_int(value); + } + template <typename U> void visit_any_int(U value) { bool is_signed = type_ == 'd' || type_ == 'i'; @@ -399,128 +344,72 @@ class CharConverter : public fmt::internal::ArgVisitor<CharConverter, void> { namespace internal { -template <typename Impl, typename Char> -class BasicArgFormatter : public ArgVisitor<Impl, void> { - private: - BasicWriter<Char> &writer_; - FormatSpec &spec_; +template <typename Char> +class PrintfArgFormatter : + public ArgFormatterBase<PrintfArgFormatter<Char>, Char> { - FMT_DISALLOW_COPY_AND_ASSIGN(BasicArgFormatter); + void write_null_pointer() { + this->spec().type_ = 0; + this->write("(nil)"); + } - protected: - BasicWriter<Char> &writer() { return writer_; } - const FormatSpec &spec() const { return spec_; } + typedef ArgFormatterBase<PrintfArgFormatter<Char>, Char> Base; public: - BasicArgFormatter(BasicWriter<Char> &w, FormatSpec &s) - : writer_(w), spec_(s) {} - - template <typename T> - void visit_any_int(T value) { writer_.write_int(value, spec_); } - - template <typename T> - void visit_any_double(T value) { writer_.write_double(value, spec_); } + PrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s) + : ArgFormatterBase<PrintfArgFormatter<Char>, Char>(w, s) {} void visit_bool(bool value) { - if (spec_.type_) { - writer_.write_int(value, spec_); - return; - } - const char *str_value = value ? "true" : "false"; - Arg::StringValue<char> str = { str_value, strlen(str_value) }; - writer_.write_str(str, spec_); + FormatSpec &fmt_spec = this->spec(); + if (fmt_spec.type_ != 's') + return this->visit_any_int(value); + fmt_spec.type_ = 0; + this->write(value); } void visit_char(int value) { - if (spec_.type_ && spec_.type_ != 'c') { - spec_.flags_ |= CHAR_FLAG; - writer_.write_int(value, spec_); - return; - } - if (spec_.align_ == ALIGN_NUMERIC || spec_.flags_ != 0) - FMT_THROW(FormatError("invalid format specifier for char")); + const FormatSpec &fmt_spec = this->spec(); + BasicWriter<Char> &w = this->writer(); + if (fmt_spec.type_ && fmt_spec.type_ != 'c') + w.write_int(value, fmt_spec); typedef typename BasicWriter<Char>::CharPtr CharPtr; - Char fill = internal::CharTraits<Char>::cast(spec_.fill()); CharPtr out = CharPtr(); - if (spec_.width_ > 1) { - out = writer_.grow_buffer(spec_.width_); - if (spec_.align_ == ALIGN_RIGHT) { - std::fill_n(out, spec_.width_ - 1, fill); - out += spec_.width_ - 1; - } else if (spec_.align_ == ALIGN_CENTER) { - out = writer_.fill_padding(out, spec_.width_, 1, fill); + if (fmt_spec.width_ > 1) { + Char fill = ' '; + out = w.grow_buffer(fmt_spec.width_); + if (fmt_spec.align_ != ALIGN_LEFT) { + std::fill_n(out, fmt_spec.width_ - 1, fill); + out += fmt_spec.width_ - 1; } else { - std::fill_n(out + 1, spec_.width_ - 1, fill); + std::fill_n(out + 1, fmt_spec.width_ - 1, fill); } } else { - out = writer_.grow_buffer(1); + out = w.grow_buffer(1); } - *out = internal::CharTraits<Char>::cast(value); - } - - void visit_string(Arg::StringValue<char> value) { - writer_.write_str(value, spec_); + *out = static_cast<Char>(value); } - using ArgVisitor<Impl, void>::visit_wstring; - - void visit_wstring(Arg::StringValue<Char> value) { - writer_.write_str(value, spec_); + void visit_cstring(const char *value) { + if (value) + Base::visit_cstring(value); + else if (this->spec().type_ == 'p') + write_null_pointer(); + else + this->write("(null)"); } void visit_pointer(const void *value) { - if (spec_.type_ && spec_.type_ != 'p') - report_unknown_type(spec_.type_, "pointer"); - spec_.flags_ = HASH_FLAG; - spec_.type_ = 'x'; - writer_.write_int(reinterpret_cast<uintptr_t>(value), spec_); + if (value) + return Base::visit_pointer(value); + this->spec().type_ = 0; + write_null_pointer(); } -}; - -// An argument formatter. -template <typename Char> -class ArgFormatter : public BasicArgFormatter<ArgFormatter<Char>, Char> { - private: - BasicFormatter<Char> &formatter_; - const Char *format_; - - public: - ArgFormatter(BasicFormatter<Char> &f, FormatSpec &s, const Char *fmt) - : BasicArgFormatter<ArgFormatter<Char>, Char>(f.writer(), s), - formatter_(f), format_(fmt) {} void visit_custom(Arg::CustomValue c) { - c.format(&formatter_, c.value, &format_); - } -}; - -template <typename Char> -class PrintfArgFormatter : - public BasicArgFormatter<PrintfArgFormatter<Char>, Char> { - public: - PrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s) - : BasicArgFormatter<PrintfArgFormatter<Char>, Char>(w, s) {} - - void visit_char(int value) { - const FormatSpec &spec = this->spec(); - BasicWriter<Char> &writer = this->writer(); - if (spec.type_ && spec.type_ != 'c') - writer.write_int(value, spec); - typedef typename BasicWriter<Char>::CharPtr CharPtr; - CharPtr out = CharPtr(); - if (spec.width_ > 1) { - Char fill = ' '; - out = writer.grow_buffer(spec.width_); - if (spec.align_ != ALIGN_LEFT) { - std::fill_n(out, spec.width_ - 1, fill); - out += spec.width_ - 1; - } else { - std::fill_n(out + 1, spec.width_ - 1, fill); - } - } else { - out = writer.grow_buffer(1); - } - *out = static_cast<Char>(value); + BasicFormatter<Char> formatter(ArgList(), this->writer()); + const Char format_str[] = {'}', 0}; + const Char *format = format_str; + c.format(&formatter, c.value, &format); } }; } // namespace internal @@ -611,14 +500,17 @@ FMT_FUNC void fmt::internal::report_unknown_type(char code, const char *type) { #if FMT_USE_WINDOWS_H FMT_FUNC fmt::internal::UTF8ToUTF16::UTF8ToUTF16(fmt::StringRef s) { - int length = MultiByteToWideChar( - CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s.size(), 0, 0); static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16"; + if (s.size() > INT_MAX) + FMT_THROW(WindowsError(ERROR_INVALID_PARAMETER, ERROR_MSG)); + int s_size = static_cast<int>(s.size()); + int length = MultiByteToWideChar( + CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, 0, 0); if (length == 0) FMT_THROW(WindowsError(GetLastError(), ERROR_MSG)); buffer_.resize(length + 1); length = MultiByteToWideChar( - CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s.size(), &buffer_[0], length); + CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, &buffer_[0], length); if (length == 0) FMT_THROW(WindowsError(GetLastError(), ERROR_MSG)); buffer_[length] = 0; @@ -632,12 +524,15 @@ FMT_FUNC fmt::internal::UTF16ToUTF8::UTF16ToUTF8(fmt::WStringRef s) { } FMT_FUNC int fmt::internal::UTF16ToUTF8::convert(fmt::WStringRef s) { - int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s.size(), 0, 0, 0, 0); + if (s.size() > INT_MAX) + return ERROR_INVALID_PARAMETER; + int s_size = static_cast<int>(s.size()); + int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, 0, 0, 0, 0); if (length == 0) return GetLastError(); buffer_.resize(length + 1); length = WideCharToMultiByte( - CP_UTF8, 0, s.data(), s.size(), &buffer_[0], length, 0, 0); + CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, 0, 0); if (length == 0) return GetLastError(); buffer_[length] = 0; @@ -679,7 +574,7 @@ FMT_FUNC void fmt::internal::format_windows_error( } } } FMT_CATCH(...) {} - format_error_code(out, error_code, message); + fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32. } #endif // FMT_USE_WINDOWS_H @@ -702,7 +597,7 @@ FMT_FUNC void fmt::internal::format_system_error( buffer.resize(buffer.size() * 2); } } FMT_CATCH(...) {} - format_error_code(out, error_code, message); + fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32. } template <typename Char> @@ -755,68 +650,6 @@ void fmt::internal::FixedBuffer<Char>::grow(std::size_t) { FMT_THROW(std::runtime_error("buffer overflow")); } -template <typename Char> -template <typename StrChar> -void fmt::BasicWriter<Char>::write_str( - const Arg::StringValue<StrChar> &s, const FormatSpec &spec) { - // Check if StrChar is convertible to Char. - internal::CharTraits<Char>::convert(StrChar()); - if (spec.type_ && spec.type_ != 's') - internal::report_unknown_type(spec.type_, "string"); - const StrChar *str_value = s.value; - std::size_t str_size = s.size; - if (str_size == 0) { - if (!str_value) - FMT_THROW(FormatError("string pointer is null")); - if (*str_value) - str_size = std::char_traits<StrChar>::length(str_value); - } - std::size_t precision = spec.precision_; - if (spec.precision_ >= 0 && precision < str_size) - str_size = spec.precision_; - write_str(str_value, str_size, spec); -} - -template <typename Char> -inline Arg fmt::BasicFormatter<Char>::get_arg( - BasicStringRef<Char> arg_name, const char *&error) { - if (check_no_auto_index(error)) { - map_.init(args()); - const Arg *arg = map_.find(arg_name); - if (arg) - return *arg; - error = "argument not found"; - } - return Arg(); -} - -template <typename Char> -inline Arg fmt::BasicFormatter<Char>::parse_arg_index(const Char *&s) { - const char *error = 0; - Arg arg = *s < '0' || *s > '9' ? - next_arg(error) : get_arg(parse_nonnegative_int(s), error); - if (error) { - FMT_THROW(FormatError( - *s != '}' && *s != ':' ? "invalid format string" : error)); - } - return arg; -} - -template <typename Char> -inline Arg fmt::BasicFormatter<Char>::parse_arg_name(const Char *&s) { - assert(is_name_start(*s)); - const Char *start = s; - Char c; - do { - c = *++s; - } while (is_name_start(c) || ('0' <= c && c <= '9')); - const char *error = 0; - Arg arg = get_arg(fmt::BasicStringRef<Char>(start, s - start), error); - if (error) - FMT_THROW(fmt::FormatError(error)); - return arg; -} - FMT_FUNC Arg fmt::internal::FormatterBase::do_get_arg( unsigned arg_index, const char *&error) { Arg arg = args_[arg_index]; @@ -832,28 +665,6 @@ FMT_FUNC Arg fmt::internal::FormatterBase::do_get_arg( return arg; } -inline Arg fmt::internal::FormatterBase::next_arg(const char *&error) { - if (next_arg_index_ >= 0) - return do_get_arg(next_arg_index_++, error); - error = "cannot switch from manual to automatic argument indexing"; - return Arg(); -} - -inline bool fmt::internal::FormatterBase::check_no_auto_index( - const char *&error) { - if (next_arg_index_ > 0) { - error = "cannot switch from automatic to manual argument indexing"; - return false; - } - next_arg_index_ = -1; - return true; -} - -inline Arg fmt::internal::FormatterBase::get_arg( - unsigned arg_index, const char *&error) { - return check_no_auto_index(error) ? do_get_arg(arg_index, error) : Arg(); -} - template <typename Char> void fmt::internal::PrintfFormatter<Char>::parse_flags( FormatSpec &spec, const Char *&s) { @@ -929,10 +740,8 @@ unsigned fmt::internal::PrintfFormatter<Char>::parse_header( template <typename Char> void fmt::internal::PrintfFormatter<Char>::format( - BasicWriter<Char> &writer, BasicCStringRef<Char> format_str, - const ArgList &args) { + BasicWriter<Char> &writer, BasicCStringRef<Char> format_str) { const Char *start = format_str.c_str(); - set_args(args); const Char *s = start; while (*s) { Char c = *s++; @@ -989,10 +798,10 @@ void fmt::internal::PrintfFormatter<Char>::format( ArgConverter<intmax_t>(arg, *s).visit(arg); break; case 'z': - ArgConverter<size_t>(arg, *s).visit(arg); + ArgConverter<std::size_t>(arg, *s).visit(arg); break; case 't': - ArgConverter<ptrdiff_t>(arg, *s).visit(arg); + ArgConverter<std::ptrdiff_t>(arg, *s).visit(arg); break; case 'L': // printf produces garbage when 'L' is omitted for long double, no @@ -1028,207 +837,17 @@ void fmt::internal::PrintfFormatter<Char>::format( write(writer, start, s); } -template <typename Char> -const Char *fmt::BasicFormatter<Char>::format( - const Char *&format_str, const Arg &arg) { - const Char *s = format_str; - FormatSpec spec; - if (*s == ':') { - if (arg.type == Arg::CUSTOM) { - arg.custom.format(this, arg.custom.value, &s); - return s; - } - ++s; - // Parse fill and alignment. - if (Char c = *s) { - const Char *p = s + 1; - spec.align_ = ALIGN_DEFAULT; - do { - switch (*p) { - case '<': - spec.align_ = ALIGN_LEFT; - break; - case '>': - spec.align_ = ALIGN_RIGHT; - break; - case '=': - spec.align_ = ALIGN_NUMERIC; - break; - case '^': - spec.align_ = ALIGN_CENTER; - break; - } - if (spec.align_ != ALIGN_DEFAULT) { - if (p != s) { - if (c == '}') break; - if (c == '{') - FMT_THROW(FormatError("invalid fill character '{'")); - s += 2; - spec.fill_ = c; - } else ++s; - if (spec.align_ == ALIGN_NUMERIC) - require_numeric_argument(arg, '='); - break; - } - } while (--p >= s); - } - - // Parse sign. - switch (*s) { - case '+': - check_sign(s, arg); - spec.flags_ |= SIGN_FLAG | PLUS_FLAG; - break; - case '-': - check_sign(s, arg); - spec.flags_ |= MINUS_FLAG; - break; - case ' ': - check_sign(s, arg); - spec.flags_ |= SIGN_FLAG; - break; - } - - if (*s == '#') { - require_numeric_argument(arg, '#'); - spec.flags_ |= HASH_FLAG; - ++s; - } - - // Parse zero flag. - if (*s == '0') { - require_numeric_argument(arg, '0'); - spec.align_ = ALIGN_NUMERIC; - spec.fill_ = '0'; - ++s; - } - - // Parse width. - if ('0' <= *s && *s <= '9') { - spec.width_ = parse_nonnegative_int(s); - } else if (*s == '{') { - ++s; - Arg width_arg = is_name_start(*s) ? - parse_arg_name(s) : parse_arg_index(s); - if (*s++ != '}') - FMT_THROW(FormatError("invalid format string")); - ULongLong value = 0; - switch (width_arg.type) { - case Arg::INT: - if (width_arg.int_value < 0) - FMT_THROW(FormatError("negative width")); - value = width_arg.int_value; - break; - case Arg::UINT: - value = width_arg.uint_value; - break; - case Arg::LONG_LONG: - if (width_arg.long_long_value < 0) - FMT_THROW(FormatError("negative width")); - value = width_arg.long_long_value; - break; - case Arg::ULONG_LONG: - value = width_arg.ulong_long_value; - break; - default: - FMT_THROW(FormatError("width is not integer")); - } - if (value > INT_MAX) - FMT_THROW(FormatError("number is too big")); - spec.width_ = static_cast<int>(value); - } - - // Parse precision. - if (*s == '.') { - ++s; - spec.precision_ = 0; - if ('0' <= *s && *s <= '9') { - spec.precision_ = parse_nonnegative_int(s); - } else if (*s == '{') { - ++s; - Arg precision_arg = - is_name_start(*s) ? parse_arg_name(s) : parse_arg_index(s); - if (*s++ != '}') - FMT_THROW(FormatError("invalid format string")); - ULongLong value = 0; - switch (precision_arg.type) { - case Arg::INT: - if (precision_arg.int_value < 0) - FMT_THROW(FormatError("negative precision")); - value = precision_arg.int_value; - break; - case Arg::UINT: - value = precision_arg.uint_value; - break; - case Arg::LONG_LONG: - if (precision_arg.long_long_value < 0) - FMT_THROW(FormatError("negative precision")); - value = precision_arg.long_long_value; - break; - case Arg::ULONG_LONG: - value = precision_arg.ulong_long_value; - break; - default: - FMT_THROW(FormatError("precision is not integer")); - } - if (value > INT_MAX) - FMT_THROW(FormatError("number is too big")); - spec.precision_ = static_cast<int>(value); - } else { - FMT_THROW(FormatError("missing precision specifier")); - } - if (arg.type <= Arg::LAST_INTEGER_TYPE || arg.type == Arg::POINTER) { - FMT_THROW(FormatError( - fmt::format("precision not allowed in {} format specifier", - arg.type == Arg::POINTER ? "pointer" : "integer"))); - } - } - - // Parse type. - if (*s != '}' && *s) - spec.type_ = static_cast<char>(*s++); - } - - if (*s++ != '}') - FMT_THROW(FormatError("missing '}' in format string")); - start_ = s; - - // Format argument. - internal::ArgFormatter<Char>(*this, spec, s - 1).visit(arg); - return s; -} - -template <typename Char> -void fmt::BasicFormatter<Char>::format( - BasicCStringRef<Char> format_str, const ArgList &args) { - const Char *s = start_ = format_str.c_str(); - set_args(args); - while (*s) { - Char c = *s++; - if (c != '{' && c != '}') continue; - if (*s == c) { - write(writer_, start_, s); - start_ = ++s; - continue; - } - if (c == '}') - FMT_THROW(FormatError("unmatched '}' in format string")); - write(writer_, start_, s - 1); - Arg arg = is_name_start(*s) ? parse_arg_name(s) : parse_arg_index(s); - s = format(s, arg); - } - write(writer_, start_, s); -} - FMT_FUNC void fmt::report_system_error( int error_code, fmt::StringRef message) FMT_NOEXCEPT { - report_error(internal::format_system_error, error_code, message); + // 'fmt::' is for bcc32. + fmt::report_error(internal::format_system_error, error_code, message); } #if FMT_USE_WINDOWS_H FMT_FUNC void fmt::report_windows_error( int error_code, fmt::StringRef message) FMT_NOEXCEPT { - report_error(internal::format_windows_error, error_code, message); + // 'fmt::' is for bcc32. + fmt::report_error(internal::format_windows_error, error_code, message); } #endif @@ -1250,7 +869,7 @@ FMT_FUNC void fmt::print(std::ostream &os, CStringRef format_str, ArgList args) FMT_FUNC void fmt::print_colored(Color c, CStringRef format, ArgList args) { char escape[] = "\x1b[30m"; - escape[3] = '0' + static_cast<char>(c); + escape[3] = static_cast<char>('0' + c); std::fputs(escape, stdout); print(format, args); std::fputs(RESET_COLOR, stdout); @@ -1271,14 +890,10 @@ template struct fmt::internal::BasicData<void>; template void fmt::internal::FixedBuffer<char>::grow(std::size_t); -template const char *fmt::BasicFormatter<char>::format( - const char *&format_str, const fmt::internal::Arg &arg); - -template void fmt::BasicFormatter<char>::format( - CStringRef format, const ArgList &args); +template void fmt::internal::ArgMap<char>::init(const fmt::ArgList &args); template void fmt::internal::PrintfFormatter<char>::format( - BasicWriter<char> &writer, CStringRef format, const ArgList &args); + BasicWriter<char> &writer, CStringRef format); template int fmt::internal::CharTraits<char>::format_float( char *buffer, std::size_t size, const char *format, @@ -1292,15 +907,10 @@ template int fmt::internal::CharTraits<char>::format_float( template void fmt::internal::FixedBuffer<wchar_t>::grow(std::size_t); -template const wchar_t *fmt::BasicFormatter<wchar_t>::format( - const wchar_t *&format_str, const fmt::internal::Arg &arg); - -template void fmt::BasicFormatter<wchar_t>::format( - BasicCStringRef<wchar_t> format, const ArgList &args); +template void fmt::internal::ArgMap<wchar_t>::init(const fmt::ArgList &args); template void fmt::internal::PrintfFormatter<wchar_t>::format( - BasicWriter<wchar_t> &writer, WCStringRef format, - const ArgList &args); + BasicWriter<wchar_t> &writer, WCStringRef format); template int fmt::internal::CharTraits<wchar_t>::format_float( wchar_t *buffer, std::size_t size, const wchar_t *format, @@ -1312,6 +922,6 @@ template int fmt::internal::CharTraits<wchar_t>::format_float( #endif // FMT_HEADER_ONLY -#if _MSC_VER +#ifdef _MSC_VER # pragma warning(pop) #endif diff --git a/dep/cppformat/format.h b/dep/cppformat/format.h index dfe95a77931..a98a166091b 100644 --- a/dep/cppformat/format.h +++ b/dep/cppformat/format.h @@ -28,20 +28,39 @@ #ifndef FMT_FORMAT_H_ #define FMT_FORMAT_H_ +#if defined _MSC_VER && _MSC_VER <= 1500 +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; +typedef long long intmax_t; +#else #include <stdint.h> +#endif #include <cassert> #include <cmath> -#include <cstddef> // for std::ptrdiff_t #include <cstdio> -#include <algorithm> +#include <cstring> #include <limits> +#include <memory> #include <stdexcept> #include <string> -#include <sstream> #include <map> -#if _SECURE_SCL +#ifndef FMT_USE_IOSTREAMS +# define FMT_USE_IOSTREAMS 1 +#endif + +#if FMT_USE_IOSTREAMS +# include <ostream> +#endif + +#ifdef _SECURE_SCL +# define FMT_SECURE_SCL _SECURE_SCL +#else +# define FMT_SECURE_SCL 0 +#endif + +#if FMT_SECURE_SCL # include <iterator> #endif @@ -92,6 +111,9 @@ inline uint32_t clzll(uint64_t x) { // Disable the warning about declaration shadowing because it affects too // many valid cases. # pragma GCC diagnostic ignored "-Wshadow" +// Disable the warning about implicit conversions that may change the sign of +// an integer; silencing it otherwise would require many explicit casts. +# pragma GCC diagnostic ignored "-Wsign-conversion" # endif # if __cplusplus >= 201103L || defined __GXX_EXPERIMENTAL_CXX0X__ # define FMT_HAS_GXX_CXX11 1 @@ -100,7 +122,7 @@ inline uint32_t clzll(uint64_t x) { # define FMT_GCC_EXTENSION #endif -#ifdef __clang__ +#if defined(__clang__) && !defined(__INTEL_COMPILER) # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wdocumentation" #endif @@ -153,17 +175,45 @@ inline uint32_t clzll(uint64_t x) { #endif // Define FMT_USE_NOEXCEPT to make C++ Format use noexcept (C++11 feature). +#ifndef FMT_USE_NOEXCEPT +# define FMT_USE_NOEXCEPT 0 +#endif + #ifndef FMT_NOEXCEPT # if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \ - (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) + (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \ + _MSC_VER >= 1900 # define FMT_NOEXCEPT noexcept # else # define FMT_NOEXCEPT throw() # endif #endif +// Check if exceptions are disabled. +#if defined(__GNUC__) && !defined(__EXCEPTIONS) +# define FMT_EXCEPTIONS 0 +#endif +#if defined(_MSC_VER) && !_HAS_EXCEPTIONS +# define FMT_EXCEPTIONS 0 +#endif +#ifndef FMT_EXCEPTIONS +# define FMT_EXCEPTIONS 1 +#endif + +#ifndef FMT_THROW +# if FMT_EXCEPTIONS +# define FMT_THROW(x) throw x +# else +# define FMT_THROW(x) assert(false) +# endif +#endif + // A macro to disallow the copy constructor and operator= functions // This should be used in the private: declarations for a class +#ifndef FMT_USE_DELETED_FUNCTIONS +# define FMT_USE_DELETED_FUNCTIONS 0 +#endif + #if FMT_USE_DELETED_FUNCTIONS || FMT_HAS_FEATURE(cxx_deleted_functions) || \ (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1800 # define FMT_DELETED_OR_UNDEFINED = delete @@ -177,11 +227,93 @@ inline uint32_t clzll(uint64_t x) { TypeName& operator=(const TypeName&) #endif +#ifndef FMT_USE_USER_DEFINED_LITERALS +// All compilers which support UDLs also support variadic templates. This +// makes the fmt::literals implementation easier. However, an explicit check +// for variadic templates is added here just in case. +# define FMT_USE_USER_DEFINED_LITERALS \ + FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES && \ + (FMT_HAS_FEATURE(cxx_user_literals) || \ + (FMT_GCC_VERSION >= 407 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1900) +#endif + #ifndef FMT_ASSERT # define FMT_ASSERT(condition, message) assert((condition) && message) #endif namespace fmt { +namespace internal { +struct DummyInt { + int data[2]; + operator int() const { return 0; } +}; +typedef std::numeric_limits<fmt::internal::DummyInt> FPUtil; + +// Dummy implementations of system functions such as signbit and ecvt called +// if the latter are not available. +inline DummyInt signbit(...) { return DummyInt(); } +inline DummyInt _ecvt_s(...) { return DummyInt(); } +inline DummyInt isinf(...) { return DummyInt(); } +inline DummyInt _finite(...) { return DummyInt(); } +inline DummyInt isnan(...) { return DummyInt(); } +inline DummyInt _isnan(...) { return DummyInt(); } + +// A helper function to suppress bogus "conditional expression is constant" +// warnings. +template <typename T> +inline T check(T value) { return value; } +} +} // namespace fmt + +namespace std { +// Standard permits specialization of std::numeric_limits. This specialization +// is used to resolve ambiguity between isinf and std::isinf in glibc: +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48891 +// and the same for isnan and signbit. +template <> +class numeric_limits<fmt::internal::DummyInt> : + public std::numeric_limits<int> { + public: + // Portable version of isinf. + template <typename T> + static bool isinfinity(T x) { + using namespace fmt::internal; + // The resolution "priority" is: + // isinf macro > std::isinf > ::isinf > fmt::internal::isinf + if (check(sizeof(isinf(x)) == sizeof(bool) || + sizeof(isinf(x)) == sizeof(int))) { + return isinf(x) != 0; + } + return !_finite(static_cast<double>(x)); + } + + // Portable version of isnan. + template <typename T> + static bool isnotanumber(T x) { + using namespace fmt::internal; + if (check(sizeof(isnan(x)) == sizeof(bool) || + sizeof(isnan(x)) == sizeof(int))) { + return isnan(x) != 0; + } + return _isnan(static_cast<double>(x)) != 0; + } + + // Portable version of signbit. + static bool isnegative(double x) { + using namespace fmt::internal; + if (check(sizeof(signbit(x)) == sizeof(int))) + return signbit(x) != 0; + if (x < 0) return true; + if (!isnotanumber(x)) return false; + int dec = 0, sign = 0; + char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail. + _ecvt_s(buffer, sizeof(buffer), x, 0, &dec, &sign); + return sign != 0; + } +}; +} // namespace std + +namespace fmt { // Fix the warning about long long on older versions of GCC // that don't support the diagnostic pragma. @@ -207,7 +339,7 @@ void format(BasicFormatter<Char> &f, const Char *&format_str, const T &value); /** \rst A string reference. It can be constructed from a C string or ``std::string``. - + You can use one of the following typedefs for common character types: +------------+-------------------------+ @@ -270,22 +402,38 @@ class BasicStringRef { /** Returns the string size. */ std::size_t size() const { return size_; } + // Lexicographically compare this string reference to other. + int compare(BasicStringRef other) const { + std::size_t size = size_ < other.size_ ? size_ : other.size_; + int result = std::char_traits<Char>::compare(data_, other.data_, size); + if (result == 0) + result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1); + return result; + } + friend bool operator==(BasicStringRef lhs, BasicStringRef rhs) { - return lhs.data_ == rhs.data_; + return lhs.compare(rhs) == 0; } friend bool operator!=(BasicStringRef lhs, BasicStringRef rhs) { - return lhs.data_ != rhs.data_; + return lhs.compare(rhs) != 0; } friend bool operator<(BasicStringRef lhs, BasicStringRef rhs) { - return std::lexicographical_compare( - lhs.data_, lhs.data_ + lhs.size_, rhs.data_, rhs.data_ + rhs.size_); + return lhs.compare(rhs) < 0; + } + friend bool operator<=(BasicStringRef lhs, BasicStringRef rhs) { + return lhs.compare(rhs) <= 0; + } + friend bool operator>(BasicStringRef lhs, BasicStringRef rhs) { + return lhs.compare(rhs) > 0; + } + friend bool operator>=(BasicStringRef lhs, BasicStringRef rhs) { + return lhs.compare(rhs) >= 0; } }; typedef BasicStringRef<char> StringRef; typedef BasicStringRef<wchar_t> WStringRef; - /** \rst A reference to a null terminated string. It can be constructed from a C @@ -348,7 +496,7 @@ namespace internal { // to avoid dynamic memory allocation. enum { INLINE_BUFFER_SIZE = 500 }; -#if _SECURE_SCL +#if FMT_SECURE_SCL // Use checked iterator to avoid warnings on MSVC. template <typename T> inline stdext::checked_array_iterator<T*> make_ptr(T *ptr, std::size_t size) { @@ -433,11 +581,13 @@ class Buffer { template <typename T> template <typename U> void Buffer<T>::append(const U *begin, const U *end) { - std::ptrdiff_t num_elements = end - begin; - if (size_ + num_elements > capacity_) - grow(size_ + num_elements); - std::copy(begin, end, internal::make_ptr(ptr_, capacity_) + size_); - size_ += num_elements; + assert(begin <= end); + std::size_t new_size = size_ + (end - begin); + if (new_size > capacity_) + grow(new_size); + std::uninitialized_copy(begin, end, + internal::make_ptr(ptr_, capacity_) + size_); + size_ = new_size; } namespace internal { @@ -449,9 +599,9 @@ class MemoryBuffer : private Allocator, public Buffer<T> { private: T data_[SIZE]; - // Free memory allocated by the buffer. - void free() { - if (this->ptr_ != data_) this->deallocate(this->ptr_, this->capacity_); + // Deallocate memory allocated by the buffer. + void deallocate() { + if (this->ptr_ != data_) Allocator::deallocate(this->ptr_, this->capacity_); } protected: @@ -460,7 +610,7 @@ class MemoryBuffer : private Allocator, public Buffer<T> { public: explicit MemoryBuffer(const Allocator &alloc = Allocator()) : Allocator(alloc), Buffer<T>(data_, SIZE) {} - ~MemoryBuffer() { free(); } + ~MemoryBuffer() { deallocate(); } #if FMT_USE_RVALUE_REFERENCES private: @@ -472,12 +622,12 @@ class MemoryBuffer : private Allocator, public Buffer<T> { this->capacity_ = other.capacity_; if (other.ptr_ == other.data_) { this->ptr_ = data_; - std::copy(other.data_, - other.data_ + this->size_, make_ptr(data_, this->capacity_)); + std::uninitialized_copy(other.data_, other.data_ + this->size_, + make_ptr(data_, this->capacity_)); } else { this->ptr_ = other.ptr_; // Set pointer to the inline array so that delete is not called - // when freeing. + // when deallocating. other.ptr_ = other.data_; } } @@ -489,7 +639,7 @@ class MemoryBuffer : private Allocator, public Buffer<T> { MemoryBuffer &operator=(MemoryBuffer &&other) { assert(this != &other); - free(); + deallocate(); move(other); return *this; } @@ -501,12 +651,13 @@ class MemoryBuffer : private Allocator, public Buffer<T> { template <typename T, std::size_t SIZE, typename Allocator> void MemoryBuffer<T, SIZE, Allocator>::grow(std::size_t size) { - std::size_t new_capacity = - (std::max)(size, this->capacity_ + this->capacity_ / 2); + std::size_t new_capacity = this->capacity_ + this->capacity_ / 2; + if (size > new_capacity) + new_capacity = size; T *new_ptr = this->allocate(new_capacity); // The following code doesn't throw, so the raw pointer above doesn't leak. - std::copy(this->ptr_, - this->ptr_ + this->size_, make_ptr(new_ptr, new_capacity)); + std::uninitialized_copy(this->ptr_, this->ptr_ + this->size_, + make_ptr(new_ptr, new_capacity)); std::size_t old_capacity = this->capacity_; T *old_ptr = this->ptr_; this->capacity_ = new_capacity; @@ -515,7 +666,7 @@ void MemoryBuffer<T, SIZE, Allocator>::grow(std::size_t size) { // the buffer already uses the new storage and will deallocate it in case // of exception. if (old_ptr != data_) - this->deallocate(old_ptr, old_capacity); + Allocator::deallocate(old_ptr, old_capacity); } // A fixed-size buffer. @@ -528,50 +679,15 @@ class FixedBuffer : public fmt::Buffer<Char> { void grow(std::size_t size); }; -#ifndef _MSC_VER -// Portable version of signbit. -inline int getsign(double x) { - // When compiled in C++11 mode signbit is no longer a macro but a function - // defined in namespace std and the macro is undefined. -# ifdef signbit - return signbit(x); -# else - return std::signbit(x); -# endif -} - -// Portable version of isinf. -# ifdef isinf -inline int isinfinity(double x) { return isinf(x); } -inline int isinfinity(long double x) { return isinf(x); } -# else -inline int isinfinity(double x) { return std::isinf(x); } -inline int isinfinity(long double x) { return std::isinf(x); } -# endif -#else -inline int getsign(double value) { - if (value < 0) return 1; - if (value == value) return 0; - int dec = 0, sign = 0; - char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail. - _ecvt_s(buffer, sizeof(buffer), value, 0, &dec, &sign); - return sign; -} -inline int isinfinity(double x) { return !_finite(x); } -inline int isinfinity(long double x) { - return !_finite(static_cast<double>(x)); -} -#endif - template <typename Char> class BasicCharTraits { public: -#if _SECURE_SCL +#if FMT_SECURE_SCL typedef stdext::checked_array_iterator<Char*> CharPtr; #else typedef Char *CharPtr; #endif - static Char cast(wchar_t value) { return static_cast<Char>(value); } + static Char cast(int value) { return static_cast<Char>(value); } }; template <typename Char> @@ -712,24 +828,23 @@ inline unsigned count_digits(uint32_t n) { // Formats a decimal unsigned integer value writing into buffer. template <typename UInt, typename Char> inline void format_decimal(Char *buffer, UInt value, unsigned num_digits) { - --num_digits; + buffer += num_digits; while (value >= 100) { // Integer division is slow so do it for a group of two digits instead // of for every digit. The idea comes from the talk by Alexandrescu // "Three Optimization Tips for C++". See speed-test for a comparison. - unsigned index = (value % 100) * 2; + unsigned index = static_cast<unsigned>((value % 100) * 2); value /= 100; - buffer[num_digits] = Data::DIGITS[index + 1]; - buffer[num_digits - 1] = Data::DIGITS[index]; - num_digits -= 2; + *--buffer = Data::DIGITS[index + 1]; + *--buffer = Data::DIGITS[index]; } if (value < 10) { - *buffer = static_cast<char>('0' + value); + *--buffer = static_cast<char>('0' + value); return; } unsigned index = static_cast<unsigned>(value * 2); - buffer[1] = Data::DIGITS[index + 1]; - buffer[0] = Data::DIGITS[index]; + *--buffer = Data::DIGITS[index + 1]; + *--buffer = Data::DIGITS[index]; } #ifndef _WIN32 @@ -833,48 +948,80 @@ template <typename Char> struct NamedArg; template <typename T = void> -struct None {}; +struct Null {}; // A helper class template to enable or disable overloads taking wide // characters and strings in MakeValue. template <typename T, typename Char> struct WCharHelper { - typedef None<T> Supported; + typedef Null<T> Supported; typedef T Unsupported; }; template <typename T> struct WCharHelper<T, wchar_t> { typedef T Supported; - typedef None<T> Unsupported; + typedef Null<T> Unsupported; }; +typedef char Yes[1]; +typedef char No[2]; + +// These are non-members to workaround an overload resolution bug in bcc32. +Yes &convert(fmt::ULongLong); +Yes &convert(std::ostream &); +No &convert(...); + template <typename T> -class IsConvertibleToInt { - private: - typedef char yes[1]; - typedef char no[2]; +T &get(); + +struct DummyStream : std::ostream { + // Hide all operator<< overloads from std::ostream. + void operator<<(Null<>); +}; - static const T &get(); +No &operator<<(std::ostream &, int); - static yes &check(fmt::ULongLong); - static no &check(...); - - public: - enum { value = (sizeof(check(get())) == sizeof(yes)) }; +template<typename T, bool ENABLE_CONVERSION> +struct ConvertToIntImpl { + enum { value = false }; +}; + +template<typename T> +struct ConvertToIntImpl<T, true> { + // Convert to int only if T doesn't have an overloaded operator<<. + enum { + value = sizeof(convert(get<DummyStream>() << get<T>())) == sizeof(No) + }; +}; + +template<typename T, bool ENABLE_CONVERSION> +struct ConvertToIntImpl2 { + enum { value = false }; }; -#define FMT_CONVERTIBLE_TO_INT(Type) \ +template<typename T> +struct ConvertToIntImpl2<T, true> { + enum { + // Don't convert numeric types. + value = ConvertToIntImpl<T, !std::numeric_limits<T>::is_specialized>::value + }; +}; + +template<typename T> +struct ConvertToInt { + enum { enable_conversion = sizeof(convert(get<T>())) == sizeof(Yes) }; + enum { value = ConvertToIntImpl2<T, enable_conversion>::value }; +}; + +#define FMT_DISABLE_CONVERSION_TO_INT(Type) \ template <> \ - class IsConvertibleToInt<Type> { \ - public: \ - enum { value = 1 }; \ - } + struct ConvertToInt<Type> { enum { value = 0 }; } // Silence warnings about convering float to int. -FMT_CONVERTIBLE_TO_INT(float); -FMT_CONVERTIBLE_TO_INT(double); -FMT_CONVERTIBLE_TO_INT(long double); +FMT_DISABLE_CONVERSION_TO_INT(float); +FMT_DISABLE_CONVERSION_TO_INT(double); +FMT_DISABLE_CONVERSION_TO_INT(long double); template<bool B, class T = void> struct EnableIf {}; @@ -888,13 +1035,19 @@ struct Conditional { typedef T type; }; template<class T, class F> struct Conditional<false, T, F> { typedef F type; }; -// A helper function to suppress bogus "conditional expression is constant" -// warnings. -inline bool check(bool value) { return value; } +// For bcc32 which doesn't understand ! in template arguments. +template<bool> +struct Not { enum { value = 0 }; }; + +template<> +struct Not<false> { enum { value = 1 }; }; // Makes an Arg object from any type. -template <typename Char> +template <typename Formatter> class MakeValue : public Arg { + public: + typedef typename Formatter::Char Char; + private: // The following two methods are private to disallow formatting of // arbitrary pointers. If you want to output a pointer cast it to @@ -910,7 +1063,9 @@ class MakeValue : public Arg { // characters and strings into narrow strings as in // fmt::format("{}", L"test"); // To fix this, use a wide format string: fmt::format(L"{}", L"test"). +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) MakeValue(typename WCharHelper<wchar_t, Char>::Unsupported); +#endif MakeValue(typename WCharHelper<wchar_t *, Char>::Unsupported); MakeValue(typename WCharHelper<const wchar_t *, Char>::Unsupported); MakeValue(typename WCharHelper<const std::wstring &, Char>::Unsupported); @@ -930,7 +1085,7 @@ class MakeValue : public Arg { template <typename T> static void format_custom_arg( void *formatter, const void *arg, void *format_str_ptr) { - format(*static_cast<BasicFormatter<Char>*>(formatter), + format(*static_cast<Formatter*>(formatter), *static_cast<const Char**>(format_str_ptr), *static_cast<const T*>(arg)); } @@ -979,14 +1134,16 @@ class MakeValue : public Arg { FMT_MAKE_VALUE(float, double_value, DOUBLE) FMT_MAKE_VALUE(double, double_value, DOUBLE) FMT_MAKE_VALUE(long double, long_double_value, LONG_DOUBLE) - FMT_MAKE_VALUE(signed char, int_value, CHAR) - FMT_MAKE_VALUE(unsigned char, int_value, CHAR) + FMT_MAKE_VALUE(signed char, int_value, INT) + FMT_MAKE_VALUE(unsigned char, uint_value, UINT) FMT_MAKE_VALUE(char, int_value, CHAR) +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) MakeValue(typename WCharHelper<wchar_t, Char>::Supported value) { int_value = value; } static uint64_t type(wchar_t) { return Arg::CHAR; } +#endif #define FMT_MAKE_STR_VALUE(Type, TYPE) \ MakeValue(Type value) { set_string(value); } \ @@ -1016,24 +1173,25 @@ class MakeValue : public Arg { template <typename T> MakeValue(const T &value, - typename EnableIf<!IsConvertibleToInt<T>::value, int>::type = 0) { + typename EnableIf<Not< + ConvertToInt<T>::value>::value, int>::type = 0) { custom.value = &value; custom.format = &format_custom_arg<T>; } template <typename T> MakeValue(const T &value, - typename EnableIf<IsConvertibleToInt<T>::value, int>::type = 0) { + typename EnableIf<ConvertToInt<T>::value, int>::type = 0) { int_value = value; } template <typename T> static uint64_t type(const T &) { - return IsConvertibleToInt<T>::value ? Arg::INT : Arg::CUSTOM; + return ConvertToInt<T>::value ? Arg::INT : Arg::CUSTOM; } // Additional template param `Char_` is needed here because make_type always - // uses MakeValue<char>. + // uses char. template <typename Char_> MakeValue(const NamedArg<Char_> &value) { pointer = &value; } @@ -1045,10 +1203,12 @@ template <typename Char> struct NamedArg : Arg { BasicStringRef<Char> name; + typedef internal::MakeValue< BasicFormatter<Char> > MakeValue; + template <typename T> - NamedArg(BasicStringRef<Char> name, const T &value) - : name(name), Arg(MakeValue<Char>(value)) { - type = static_cast<internal::Arg::Type>(MakeValue<Char>::type(value)); + NamedArg(BasicStringRef<Char> argname, const T &value) + : Arg(MakeValue(value)), name(argname) { + type = static_cast<Arg::Type>(MakeValue::type(value)); } }; @@ -1118,6 +1278,9 @@ class ArgVisitor { return FMT_DISPATCH(visit_unhandled_arg()); } + Result visit_cstring(const char *) { + return FMT_DISPATCH(visit_unhandled_arg()); + } Result visit_string(Arg::StringValue<char>) { return FMT_DISPATCH(visit_unhandled_arg()); } @@ -1145,18 +1308,15 @@ class ArgVisitor { case Arg::ULONG_LONG: return FMT_DISPATCH(visit_ulong_long(arg.ulong_long_value)); case Arg::BOOL: - return FMT_DISPATCH(visit_bool(arg.int_value)); + return FMT_DISPATCH(visit_bool(arg.int_value != 0)); case Arg::CHAR: return FMT_DISPATCH(visit_char(arg.int_value)); case Arg::DOUBLE: return FMT_DISPATCH(visit_double(arg.double_value)); case Arg::LONG_DOUBLE: return FMT_DISPATCH(visit_long_double(arg.long_double_value)); - case Arg::CSTRING: { - Arg::StringValue<char> str = arg.string; - str.size = 0; - return FMT_DISPATCH(visit_string(str)); - } + case Arg::CSTRING: + return FMT_DISPATCH(visit_cstring(arg.string.value)); case Arg::STRING: return FMT_DISPATCH(visit_string(arg.string)); case Arg::WSTRING: @@ -1174,9 +1334,6 @@ class RuntimeError : public std::runtime_error { RuntimeError() : std::runtime_error("") {} }; -template <typename Impl, typename Char> -class BasicArgFormatter; - template <typename Char> class PrintfArgFormatter; @@ -1248,111 +1405,6 @@ class ArgList { } }; -struct FormatSpec; - -namespace internal { - -template <typename Char> -class ArgMap { - private: - typedef std::map<fmt::BasicStringRef<Char>, internal::Arg> MapType; - typedef typename MapType::value_type Pair; - - MapType map_; - - public: - void init(const ArgList &args); - - const internal::Arg* find(const fmt::BasicStringRef<Char> &name) const { - typename MapType::const_iterator it = map_.find(name); - return it != map_.end() ? &it->second : 0; - } -}; - -class FormatterBase { - private: - ArgList args_; - int next_arg_index_; - - // Returns the argument with specified index. - Arg do_get_arg(unsigned arg_index, const char *&error); - - protected: - const ArgList &args() const { return args_; } - - void set_args(const ArgList &args) { - args_ = args; - next_arg_index_ = 0; - } - - // Returns the next argument. - Arg next_arg(const char *&error); - - // Checks if manual indexing is used and returns the argument with - // specified index. - Arg get_arg(unsigned arg_index, const char *&error); - - bool check_no_auto_index(const char *&error); - - template <typename Char> - void write(BasicWriter<Char> &w, const Char *start, const Char *end) { - if (start != end) - w << BasicStringRef<Char>(start, end - start); - } -}; - -// A printf formatter. -template <typename Char> -class PrintfFormatter : private FormatterBase { - private: - void parse_flags(FormatSpec &spec, const Char *&s); - - // Returns the argument with specified index or, if arg_index is equal - // to the maximum unsigned value, the next argument. - Arg get_arg(const Char *s, - unsigned arg_index = (std::numeric_limits<unsigned>::max)()); - - // Parses argument index, flags and width and returns the argument index. - unsigned parse_header(const Char *&s, FormatSpec &spec); - - public: - void format(BasicWriter<Char> &writer, - BasicCStringRef<Char> format_str, const ArgList &args); -}; -} // namespace internal - -// A formatter. -template <typename Char> -class BasicFormatter : private internal::FormatterBase { - private: - BasicWriter<Char> &writer_; - const Char *start_; - internal::ArgMap<Char> map_; - - FMT_DISALLOW_COPY_AND_ASSIGN(BasicFormatter); - - using FormatterBase::get_arg; - - // Checks if manual indexing is used and returns the argument with - // specified name. - internal::Arg get_arg(BasicStringRef<Char> arg_name, const char *&error); - - // Parses argument index and returns corresponding argument. - internal::Arg parse_arg_index(const Char *&s); - - // Parses argument name and returns corresponding argument. - internal::Arg parse_arg_name(const Char *&s); - - public: - explicit BasicFormatter(BasicWriter<Char> &w) : writer_(w) {} - - BasicWriter<Char> &writer() { return writer_; } - - void format(BasicCStringRef<Char> format_str, const ArgList &args); - - const Char *format(const Char *&format_str, const internal::Arg &arg); -}; - enum Alignment { ALIGN_DEFAULT, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER, ALIGN_NUMERIC }; @@ -1574,6 +1626,242 @@ inline StrFormatSpec<wchar_t> pad( return StrFormatSpec<wchar_t>(str, width, fill); } +namespace internal { + +template <typename Char> +class ArgMap { + private: + typedef std::map<fmt::BasicStringRef<Char>, internal::Arg> MapType; + typedef typename MapType::value_type Pair; + + MapType map_; + + public: + void init(const ArgList &args); + + const internal::Arg* find(const fmt::BasicStringRef<Char> &name) const { + typename MapType::const_iterator it = map_.find(name); + return it != map_.end() ? &it->second : 0; + } +}; + +template <typename Impl, typename Char> +class ArgFormatterBase : public ArgVisitor<Impl, void> { + private: + BasicWriter<Char> &writer_; + FormatSpec &spec_; + + FMT_DISALLOW_COPY_AND_ASSIGN(ArgFormatterBase); + + void write_pointer(const void *p) { + spec_.flags_ = HASH_FLAG; + spec_.type_ = 'x'; + writer_.write_int(reinterpret_cast<uintptr_t>(p), spec_); + } + + protected: + BasicWriter<Char> &writer() { return writer_; } + FormatSpec &spec() { return spec_; } + + void write(bool value) { + const char *str_value = value ? "true" : "false"; + Arg::StringValue<char> str = { str_value, std::strlen(str_value) }; + writer_.write_str(str, spec_); + } + + void write(const char *value) { + Arg::StringValue<char> str = {value, value != 0 ? std::strlen(value) : 0}; + writer_.write_str(str, spec_); + } + + public: + ArgFormatterBase(BasicWriter<Char> &w, FormatSpec &s) + : writer_(w), spec_(s) {} + + template <typename T> + void visit_any_int(T value) { writer_.write_int(value, spec_); } + + template <typename T> + void visit_any_double(T value) { writer_.write_double(value, spec_); } + + void visit_bool(bool value) { + if (spec_.type_) + return visit_any_int(value); + write(value); + } + + void visit_char(int value) { + if (spec_.type_ && spec_.type_ != 'c') { + spec_.flags_ |= CHAR_FLAG; + writer_.write_int(value, spec_); + return; + } + if (spec_.align_ == ALIGN_NUMERIC || spec_.flags_ != 0) + FMT_THROW(FormatError("invalid format specifier for char")); + typedef typename BasicWriter<Char>::CharPtr CharPtr; + Char fill = internal::CharTraits<Char>::cast(spec_.fill()); + CharPtr out = CharPtr(); + const unsigned CHAR_WIDTH = 1; + if (spec_.width_ > CHAR_WIDTH) { + out = writer_.grow_buffer(spec_.width_); + if (spec_.align_ == ALIGN_RIGHT) { + std::uninitialized_fill_n(out, spec_.width_ - CHAR_WIDTH, fill); + out += spec_.width_ - CHAR_WIDTH; + } else if (spec_.align_ == ALIGN_CENTER) { + out = writer_.fill_padding(out, spec_.width_, + internal::check(CHAR_WIDTH), fill); + } else { + std::uninitialized_fill_n(out + CHAR_WIDTH, + spec_.width_ - CHAR_WIDTH, fill); + } + } else { + out = writer_.grow_buffer(CHAR_WIDTH); + } + *out = internal::CharTraits<Char>::cast(value); + } + + void visit_cstring(const char *value) { + if (spec_.type_ == 'p') + return write_pointer(value); + write(value); + } + + void visit_string(Arg::StringValue<char> value) { + writer_.write_str(value, spec_); + } + + using ArgVisitor<Impl, void>::visit_wstring; + + void visit_wstring(Arg::StringValue<Char> value) { + writer_.write_str(value, spec_); + } + + void visit_pointer(const void *value) { + if (spec_.type_ && spec_.type_ != 'p') + report_unknown_type(spec_.type_, "pointer"); + write_pointer(value); + } +}; + +// An argument formatter. +template <typename Char> +class BasicArgFormatter : + public ArgFormatterBase<BasicArgFormatter<Char>, Char> { + private: + BasicFormatter<Char> &formatter_; + const Char *format_; + + public: + BasicArgFormatter(BasicFormatter<Char> &f, FormatSpec &s, const Char *fmt) + : ArgFormatterBase<BasicArgFormatter<Char>, Char>(f.writer(), s), + formatter_(f), format_(fmt) {} + + void visit_custom(Arg::CustomValue c) { + c.format(&formatter_, c.value, &format_); + } +}; + +class FormatterBase { + private: + ArgList args_; + int next_arg_index_; + + // Returns the argument with specified index. + Arg do_get_arg(unsigned arg_index, const char *&error); + + protected: + const ArgList &args() const { return args_; } + + explicit FormatterBase(const ArgList &args) { + args_ = args; + next_arg_index_ = 0; + } + + // Returns the next argument. + Arg next_arg(const char *&error) { + if (next_arg_index_ >= 0) + return do_get_arg(next_arg_index_++, error); + error = "cannot switch from manual to automatic argument indexing"; + return Arg(); + } + + // Checks if manual indexing is used and returns the argument with + // specified index. + Arg get_arg(unsigned arg_index, const char *&error) { + return check_no_auto_index(error) ? do_get_arg(arg_index, error) : Arg(); + } + + bool check_no_auto_index(const char *&error) { + if (next_arg_index_ > 0) { + error = "cannot switch from automatic to manual argument indexing"; + return false; + } + next_arg_index_ = -1; + return true; + } + + template <typename Char> + void write(BasicWriter<Char> &w, const Char *start, const Char *end) { + if (start != end) + w << BasicStringRef<Char>(start, end - start); + } +}; + +// A printf formatter. +template <typename Char> +class PrintfFormatter : private FormatterBase { + private: + void parse_flags(FormatSpec &spec, const Char *&s); + + // Returns the argument with specified index or, if arg_index is equal + // to the maximum unsigned value, the next argument. + Arg get_arg(const Char *s, + unsigned arg_index = (std::numeric_limits<unsigned>::max)()); + + // Parses argument index, flags and width and returns the argument index. + unsigned parse_header(const Char *&s, FormatSpec &spec); + + public: + explicit PrintfFormatter(const ArgList &args) : FormatterBase(args) {} + void format(BasicWriter<Char> &writer, BasicCStringRef<Char> format_str); +}; +} // namespace internal + +// A formatter. +template <typename CharType> +class BasicFormatter : private internal::FormatterBase { + public: + typedef CharType Char; + + private: + BasicWriter<Char> &writer_; + internal::ArgMap<Char> map_; + + FMT_DISALLOW_COPY_AND_ASSIGN(BasicFormatter); + + using internal::FormatterBase::get_arg; + + // Checks if manual indexing is used and returns the argument with + // specified name. + internal::Arg get_arg(BasicStringRef<Char> arg_name, const char *&error); + + // Parses argument index and returns corresponding argument. + internal::Arg parse_arg_index(const Char *&s); + + // Parses argument name and returns corresponding argument. + internal::Arg parse_arg_name(const Char *&s); + + public: + BasicFormatter(const ArgList &args, BasicWriter<Char> &w) + : internal::FormatterBase(args), writer_(w) {} + + BasicWriter<Char> &writer() { return writer_; } + + void format(BasicCStringRef<Char> format_str); + + const Char *format(const Char *&format_str, const internal::Arg &arg); +}; + // Generates a comma-separated list with results of applying f to // numbers 0..n-1. # define FMT_GEN(n, f) FMT_GEN##n(f) @@ -1597,7 +1885,9 @@ namespace internal { inline uint64_t make_type() { return 0; } template <typename T> -inline uint64_t make_type(const T &arg) { return MakeValue<char>::type(arg); } +inline uint64_t make_type(const T &arg) { + return MakeValue< BasicFormatter<char> >::type(arg); +} template <unsigned N> struct ArgArray { @@ -1621,7 +1911,8 @@ inline void do_set_types(Arg *) {} template <typename T, typename... Args> inline void do_set_types(Arg *args, const T &arg, const Args & ... tail) { - args->type = static_cast<Arg::Type>(MakeValue<T>::type(arg)); + args->type = static_cast<Arg::Type>( + MakeValue< BasicFormatter<char> >::type(arg)); do_set_types(args + 1, tail...); } @@ -1637,24 +1928,24 @@ inline void set_types(Value *, const Args & ...) { // Do nothing as types are passed separately from values. } -template <typename Char, typename Value> +template <typename Formatter, typename Value> inline void store_args(Value *) {} -template <typename Char, typename Arg, typename T, typename... Args> +template <typename Formatter, typename Arg, typename T, typename... Args> inline void store_args(Arg *args, const T &arg, const Args & ... tail) { // Assign only the Value subobject of Arg and don't overwrite type (if any) // that is assigned by set_types. Value &value = *args; - value = MakeValue<Char>(arg); - store_args<Char>(args + 1, tail...); + value = MakeValue<Formatter>(arg); + store_args<Formatter>(args + 1, tail...); } -template <typename Char, typename... Args> +template <typename Formatter, typename... Args> ArgList make_arg_list(typename ArgArray<sizeof...(Args)>::Type array, const Args & ... args) { if (check(sizeof...(Args) >= ArgList::MAX_PACKED_ARGS)) set_types(array, args...); - store_args<Char>(array, args...); + store_args<Formatter>(array, args...); return ArgList(make_type(args...), array); } #else @@ -1677,13 +1968,47 @@ inline uint64_t make_type(FMT_GEN15(FMT_ARG_TYPE_DEFAULT)) { (t12.type << 48) | (t13.type << 52) | (t14.type << 56); } #endif + +template <class Char> +class FormatBuf : public std::basic_streambuf<Char> { + private: + typedef typename std::basic_streambuf<Char>::int_type int_type; + typedef typename std::basic_streambuf<Char>::traits_type traits_type; + + Buffer<Char> &buffer_; + Char *start_; + + public: + FormatBuf(Buffer<Char> &buffer) : buffer_(buffer), start_(&buffer[0]) { + this->setp(start_, start_ + buffer_.capacity()); + } + + int_type overflow(int_type ch = traits_type::eof()) { + if (!traits_type::eq_int_type(ch, traits_type::eof())) { + size_t size = this->pptr() - start_; + buffer_.resize(size); + buffer_.reserve(size * 2); + + start_ = &buffer_[0]; + start_[size] = traits_type::to_char_type(ch); + this->setp(start_+ size + 1, start_ + size * 2); + } + return ch; + } + + size_t size() const { + return this->pptr() - start_; + } +}; } // namespace internal # define FMT_MAKE_TEMPLATE_ARG(n) typename T##n # define FMT_MAKE_ARG_TYPE(n) T##n # define FMT_MAKE_ARG(n) const T##n &v##n -# define FMT_MAKE_REF_char(n) fmt::internal::MakeValue<char>(v##n) -# define FMT_MAKE_REF_wchar_t(n) fmt::internal::MakeValue<wchar_t>(v##n) +# define FMT_ASSIGN_char(n) \ + arr[n] = fmt::internal::MakeValue< fmt::BasicFormatter<char> >(v##n) +# define FMT_ASSIGN_wchar_t(n) \ + arr[n] = fmt::internal::MakeValue< fmt::BasicFormatter<wchar_t> >(v##n) #if FMT_USE_VARIADIC_TEMPLATES // Defines a variadic function returning void. @@ -1691,7 +2016,8 @@ inline uint64_t make_type(FMT_GEN15(FMT_ARG_TYPE_DEFAULT)) { template <typename... Args> \ void func(arg_type arg0, const Args & ... args) { \ typename fmt::internal::ArgArray<sizeof...(Args)>::Type array; \ - func(arg0, fmt::internal::make_arg_list<Char>(array, args...)); \ + func(arg0, fmt::internal::make_arg_list< \ + fmt::BasicFormatter<Char> >(array, args...)); \ } // Defines a variadic constructor. @@ -1699,12 +2025,14 @@ inline uint64_t make_type(FMT_GEN15(FMT_ARG_TYPE_DEFAULT)) { template <typename... Args> \ ctor(arg0_type arg0, arg1_type arg1, const Args & ... args) { \ typename fmt::internal::ArgArray<sizeof...(Args)>::Type array; \ - func(arg0, arg1, fmt::internal::make_arg_list<Char>(array, args...)); \ + func(arg0, arg1, fmt::internal::make_arg_list< \ + fmt::BasicFormatter<Char> >(array, args...)); \ } #else -# define FMT_MAKE_REF(n) fmt::internal::MakeValue<Char>(v##n) +# define FMT_MAKE_REF(n) \ + fmt::internal::MakeValue< fmt::BasicFormatter<Char> >(v##n) # define FMT_MAKE_REF2(n) v##n // Defines a wrapper for a function taking one argument of type arg_type @@ -1799,7 +2127,7 @@ class SystemError : public internal::RuntimeError { *error_code* is a system error code as given by ``errno``. If *error_code* is not a valid error code such as -1, the system message may look like "Unknown error -1" and is platform-dependent. - + **Example**:: // This throws a SystemError with the description @@ -1847,7 +2175,7 @@ class BasicWriter { typedef typename internal::CharTraits<Char>::CharPtr CharPtr; -#if _SECURE_SCL +#if FMT_SECURE_SCL // Returns pointer value. static Char *get(CharPtr p) { return p.base(); } #else @@ -1867,12 +2195,33 @@ class BasicWriter { return internal::make_ptr(&buffer_[size], n); } + // Writes an unsigned decimal integer. + template <typename UInt> + Char *write_unsigned_decimal(UInt value, unsigned prefix_size = 0) { + unsigned num_digits = internal::count_digits(value); + Char *ptr = get(grow_buffer(prefix_size + num_digits)); + internal::format_decimal(ptr + prefix_size, value, num_digits); + return ptr; + } + + // Writes a decimal integer. + template <typename Int> + void write_decimal(Int value) { + typename internal::IntTraits<Int>::MainType abs_value = value; + if (internal::is_negative(value)) { + abs_value = 0 - abs_value; + *write_unsigned_decimal(abs_value, 1) = '-'; + } else { + write_unsigned_decimal(abs_value, 0); + } + } + // Prepare a buffer for integer formatting. CharPtr prepare_int_buffer(unsigned num_digits, const EmptySpec &, const char *prefix, unsigned prefix_size) { unsigned size = prefix_size + num_digits; CharPtr p = grow_buffer(size); - std::copy(prefix, prefix + prefix_size, p); + std::uninitialized_copy(prefix, prefix + prefix_size, p); return p + size - 1; } @@ -1890,12 +2239,11 @@ class BasicWriter { // Writes a formatted string. template <typename StrChar> - CharPtr write_str( - const StrChar *s, std::size_t size, const AlignSpec &spec); + CharPtr write_str(const StrChar *s, std::size_t size, const AlignSpec &spec); template <typename StrChar> - void write_str( - const internal::Arg::StringValue<StrChar> &str, const FormatSpec &spec); + void write_str(const internal::Arg::StringValue<StrChar> &str, + const FormatSpec &spec); // This following methods are private to disallow writing wide characters // and strings to a char stream. If you want to print a wide string as a @@ -1915,7 +2263,7 @@ class BasicWriter { void append_float_length(Char *&, T) {} template <typename Impl, typename Char_> - friend class internal::BasicArgFormatter; + friend class internal::ArgFormatterBase; friend class internal::PrintfArgFormatter<Char>; @@ -1967,7 +2315,7 @@ class BasicWriter { /** \rst Writes formatted data. - + *args* is an argument list representing arbitrary arguments. **Example**:: @@ -1990,24 +2338,27 @@ class BasicWriter { \endrst */ void write(BasicCStringRef<Char> format, ArgList args) { - BasicFormatter<Char>(*this).format(format, args); + BasicFormatter<Char>(args, *this).format(format); } FMT_VARIADIC_VOID(write, BasicCStringRef<Char>) BasicWriter &operator<<(int value) { - return *this << IntFormatSpec<int>(value); + write_decimal(value); + return *this; } BasicWriter &operator<<(unsigned value) { return *this << IntFormatSpec<unsigned>(value); } BasicWriter &operator<<(long value) { - return *this << IntFormatSpec<long>(value); + write_decimal(value); + return *this; } BasicWriter &operator<<(unsigned long value) { return *this << IntFormatSpec<unsigned long>(value); } BasicWriter &operator<<(LongLong value) { - return *this << IntFormatSpec<LongLong>(value); + write_decimal(value); + return *this; } /** @@ -2093,21 +2444,43 @@ typename BasicWriter<Char>::CharPtr BasicWriter<Char>::write_str( out = grow_buffer(spec.width()); Char fill = internal::CharTraits<Char>::cast(spec.fill()); if (spec.align() == ALIGN_RIGHT) { - std::fill_n(out, spec.width() - size, fill); + std::uninitialized_fill_n(out, spec.width() - size, fill); out += spec.width() - size; } else if (spec.align() == ALIGN_CENTER) { out = fill_padding(out, spec.width(), size, fill); } else { - std::fill_n(out + size, spec.width() - size, fill); + std::uninitialized_fill_n(out + size, spec.width() - size, fill); } } else { out = grow_buffer(size); } - std::copy(s, s + size, out); + std::uninitialized_copy(s, s + size, out); return out; } template <typename Char> +template <typename StrChar> +void BasicWriter<Char>::write_str( + const internal::Arg::StringValue<StrChar> &s, const FormatSpec &spec) { + // Check if StrChar is convertible to Char. + internal::CharTraits<Char>::convert(StrChar()); + if (spec.type_ && spec.type_ != 's') + internal::report_unknown_type(spec.type_, "string"); + const StrChar *str_value = s.value; + std::size_t str_size = s.size; + if (str_size == 0) { + if (!str_value) { + FMT_THROW(FormatError("string pointer is null")); + return; + } + } + std::size_t precision = spec.precision_; + if (spec.precision_ >= 0 && precision < str_size) + str_size = spec.precision_; + write_str(str_value, str_size, spec); +} + +template <typename Char> typename BasicWriter<Char>::CharPtr BasicWriter<Char>::fill_padding( CharPtr buffer, unsigned total_size, @@ -2115,10 +2488,11 @@ typename BasicWriter<Char>::CharPtr std::size_t padding = total_size - content_size; std::size_t left_padding = padding / 2; Char fill_char = internal::CharTraits<Char>::cast(fill); - std::fill_n(buffer, left_padding, fill_char); + std::uninitialized_fill_n(buffer, left_padding, fill_char); buffer += left_padding; CharPtr content = buffer; - std::fill_n(buffer + content_size, padding - left_padding, fill_char); + std::uninitialized_fill_n(buffer + content_size, + padding - left_padding, fill_char); return content; } @@ -2144,42 +2518,42 @@ typename BasicWriter<Char>::CharPtr unsigned fill_size = width - number_size; if (align != ALIGN_LEFT) { CharPtr p = grow_buffer(fill_size); - std::fill(p, p + fill_size, fill); + std::uninitialized_fill(p, p + fill_size, fill); } CharPtr result = prepare_int_buffer( num_digits, subspec, prefix, prefix_size); if (align == ALIGN_LEFT) { CharPtr p = grow_buffer(fill_size); - std::fill(p, p + fill_size, fill); + std::uninitialized_fill(p, p + fill_size, fill); } return result; } unsigned size = prefix_size + num_digits; if (width <= size) { CharPtr p = grow_buffer(size); - std::copy(prefix, prefix + prefix_size, p); + std::uninitialized_copy(prefix, prefix + prefix_size, p); return p + size - 1; } CharPtr p = grow_buffer(width); CharPtr end = p + width; if (align == ALIGN_LEFT) { - std::copy(prefix, prefix + prefix_size, p); + std::uninitialized_copy(prefix, prefix + prefix_size, p); p += size; - std::fill(p, end, fill); + std::uninitialized_fill(p, end, fill); } else if (align == ALIGN_CENTER) { p = fill_padding(p, width, size, fill); - std::copy(prefix, prefix + prefix_size, p); + std::uninitialized_copy(prefix, prefix + prefix_size, p); p += size; } else { if (align == ALIGN_NUMERIC) { if (prefix_size != 0) { - p = std::copy(prefix, prefix + prefix_size, p); + p = std::uninitialized_copy(prefix, prefix + prefix_size, p); size -= prefix_size; } } else { - std::copy(prefix, prefix + prefix_size, end - size); + std::uninitialized_copy(prefix, prefix + prefix_size, end - size); } - std::fill(p, end - size, fill); + std::uninitialized_fill(p, end - size, fill); p = end; } return p - 1; @@ -2241,7 +2615,7 @@ void BasicWriter<Char>::write_int(T value, Spec spec) { Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size)); n = abs_value; do { - *p-- = '0' + (n & 1); + *p-- = static_cast<Char>('0' + (n & 1)); } while ((n >>= 1) != 0); break; } @@ -2256,7 +2630,7 @@ void BasicWriter<Char>::write_int(T value, Spec spec) { Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size)); n = abs_value; do { - *p-- = '0' + (n & 7); + *p-- = static_cast<Char>('0' + (n & 7)); } while ((n >>= 3) != 0); break; } @@ -2295,16 +2669,16 @@ void BasicWriter<Char>::write_double( } char sign = 0; - // Use getsign instead of value < 0 because the latter is always + // Use isnegative instead of value < 0 because the latter is always // false for NaN. - if (internal::getsign(static_cast<double>(value))) { + if (internal::FPUtil::isnegative(static_cast<double>(value))) { sign = '-'; value = -value; } else if (spec.flag(SIGN_FLAG)) { sign = spec.flag(PLUS_FLAG) ? '+' : ' '; } - if (value != value) { + if (internal::FPUtil::isnotanumber(value)) { // Format NaN ourselves because sprintf's output is not consistent // across platforms. std::size_t nan_size = 4; @@ -2319,7 +2693,7 @@ void BasicWriter<Char>::write_double( return; } - if (internal::isinfinity(value)) { + if (internal::FPUtil::isinfinity(value)) { // Format infinity ourselves because sprintf's output is not consistent // across platforms. std::size_t inf_size = 4; @@ -2337,7 +2711,7 @@ void BasicWriter<Char>::write_double( std::size_t offset = buffer_.size(); unsigned width = spec.width(); if (sign) { - buffer_.reserve(buffer_.size() + (std::max)(width, 1u)); + buffer_.reserve(buffer_.size() + (width > 1u ? width : 1u)); if (width > 0) --width; ++offset; @@ -2372,7 +2746,7 @@ void BasicWriter<Char>::write_double( Char fill = internal::CharTraits<Char>::cast(spec.fill()); for (;;) { std::size_t buffer_size = buffer_.capacity() - offset; -#if _MSC_VER +#ifdef _MSC_VER // MSVC's vsnprintf_s doesn't work with zero size, so reserve // space for at least one extra character to make the size non-zero. // Note that the buffer's capacity will increase by more than 1. @@ -2399,7 +2773,7 @@ void BasicWriter<Char>::write_double( spec.width() > static_cast<unsigned>(n)) { width = spec.width(); CharPtr p = grow_buffer(width); - std::copy(p, p + n, p + (width - n) / 2); + std::memmove(get(p) + (width - n) / 2, get(p), n * sizeof(Char)); fill_padding(p, spec.width(), n, fill); return; } @@ -2492,7 +2866,7 @@ typedef BasicMemoryWriter<wchar_t> WMemoryWriter; This class template provides operations for formatting and writing data into a fixed-size array. For writing into a dynamically growing buffer use :class:`fmt::BasicMemoryWriter`. - + Any write method will throw ``std::runtime_error`` if the output doesn't fit into the array. @@ -2539,12 +2913,16 @@ typedef BasicArrayWriter<wchar_t> WArrayWriter; // Formats a value. template <typename Char, typename T> void format(BasicFormatter<Char> &f, const Char *&format_str, const T &value) { - std::basic_ostringstream<Char> os; - os << value; - std::basic_string<Char> str = os.str(); - internal::Arg arg = internal::MakeValue<Char>(str); - arg.type = static_cast<internal::Arg::Type>( - internal::MakeValue<Char>::type(str)); + internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer; + + internal::FormatBuf<Char> format_buf(buffer); + std::basic_ostream<Char> output(&format_buf); + output << value; + + BasicStringRef<Char> str(&buffer[0], format_buf.size()); + typedef internal::MakeValue< BasicFormatter<Char> > MakeValue; + internal::Arg arg = MakeValue(str); + arg.type = static_cast<internal::Arg::Type>(MakeValue::type(str)); format_str = f.format(format_str, arg); } @@ -2606,7 +2984,7 @@ enum Color { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE }; Formats a string and prints it to stdout using ANSI escape sequences to specify color (experimental). Example: - PrintColored(fmt::RED, "Elapsed time: {0:.2f} seconds") << 1.23; + print_colored(fmt::RED, "Elapsed time: {0:.2f} seconds", 1.23); */ void print_colored(Color c, CStringRef format, ArgList args); @@ -2653,20 +3031,9 @@ void print(std::FILE *f, CStringRef format_str, ArgList args); */ void print(CStringRef format_str, ArgList args); -/** - \rst - Prints formatted data to the stream *os*. - - **Example**:: - - print(cerr, "Don't {}!", "panic"); - \endrst - */ -void print(std::ostream &os, CStringRef format_str, ArgList args); - template <typename Char> void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args) { - internal::PrintfFormatter<Char>().format(w, format, args); + internal::PrintfFormatter<Char>(args).format(w, format); } /** @@ -2684,6 +3051,12 @@ inline std::string sprintf(CStringRef format, ArgList args) { return w.str(); } +inline std::wstring sprintf(WCStringRef format, ArgList args) { + WMemoryWriter w; + printf(w, format, args); + return w.str(); +} + /** \rst Prints formatted data to the file *f*. @@ -2726,7 +3099,7 @@ class FormatInt { // Integer division is slow so do it for a group of two digits instead // of for every digit. The idea comes from the talk by Alexandrescu // "Three Optimization Tips for C++". See speed-test for a comparison. - unsigned index = (value % 100) * 2; + unsigned index = static_cast<unsigned>((value % 100) * 2); value /= 100; *--buffer_end = internal::Data::DIGITS[index + 1]; *--buffer_end = internal::Data::DIGITS[index]; @@ -2874,7 +3247,8 @@ void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED; const Args & ... args) { \ typename fmt::internal::ArgArray<sizeof...(Args)>::Type array; \ call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \ - fmt::internal::make_arg_list<Char>(array, args...)); \ + fmt::internal::make_arg_list< \ + fmt::BasicFormatter<Char> >(array, args...)); \ } #else // Defines a wrapper for a function taking __VA_ARGS__ arguments @@ -2883,7 +3257,8 @@ void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED; template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \ inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \ FMT_GEN(n, FMT_MAKE_ARG)) { \ - fmt::internal::ArgArray<n>::Type arr = {FMT_GEN(n, FMT_MAKE_REF_##Char)}; \ + fmt::internal::ArgArray<n>::Type arr; \ + FMT_GEN(n, FMT_ASSIGN_##Char); \ call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList( \ fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), arr)); \ } @@ -2969,19 +3344,378 @@ FMT_VARIADIC(std::string, format, CStringRef) FMT_VARIADIC_W(std::wstring, format, WCStringRef) FMT_VARIADIC(void, print, CStringRef) FMT_VARIADIC(void, print, std::FILE *, CStringRef) -FMT_VARIADIC(void, print, std::ostream &, CStringRef) + FMT_VARIADIC(void, print_colored, Color, CStringRef) FMT_VARIADIC(std::string, sprintf, CStringRef) +FMT_VARIADIC_W(std::wstring, sprintf, WCStringRef) FMT_VARIADIC(int, printf, CStringRef) FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef) + +#if FMT_USE_IOSTREAMS +/** + \rst + Prints formatted data to the stream *os*. + + **Example**:: + + print(cerr, "Don't {}!", "panic"); + \endrst + */ +void print(std::ostream &os, CStringRef format_str, ArgList args); +FMT_VARIADIC(void, print, std::ostream &, CStringRef) +#endif + +namespace internal { +template <typename Char> +inline bool is_name_start(Char c) { + return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c; +} + +// Parses an unsigned integer advancing s to the end of the parsed input. +// This function assumes that the first character of s is a digit. +template <typename Char> +int parse_nonnegative_int(const Char *&s) { + assert('0' <= *s && *s <= '9'); + unsigned value = 0; + do { + unsigned new_value = value * 10 + (*s++ - '0'); + // Check if value wrapped around. + if (new_value < value) { + value = (std::numeric_limits<unsigned>::max)(); + break; + } + value = new_value; + } while ('0' <= *s && *s <= '9'); + // Convert to unsigned to prevent a warning. + unsigned max_int = (std::numeric_limits<int>::max)(); + if (value > max_int) + FMT_THROW(FormatError("number is too big")); + return value; +} + +inline void require_numeric_argument(const Arg &arg, char spec) { + if (arg.type > Arg::LAST_NUMERIC_TYPE) { + std::string message = + fmt::format("format specifier '{}' requires numeric argument", spec); + FMT_THROW(fmt::FormatError(message)); + } +} + +template <typename Char> +void check_sign(const Char *&s, const Arg &arg) { + char sign = static_cast<char>(*s); + require_numeric_argument(arg, sign); + if (arg.type == Arg::UINT || arg.type == Arg::ULONG_LONG) { + FMT_THROW(FormatError(fmt::format( + "format specifier '{}' requires signed argument", sign))); + } + ++s; +} +} // namespace internal + +template <typename Char> +inline internal::Arg BasicFormatter<Char>::get_arg( + BasicStringRef<Char> arg_name, const char *&error) { + if (check_no_auto_index(error)) { + map_.init(args()); + const internal::Arg *arg = map_.find(arg_name); + if (arg) + return *arg; + error = "argument not found"; + } + return internal::Arg(); +} + +template <typename Char> +inline internal::Arg BasicFormatter<Char>::parse_arg_index(const Char *&s) { + const char *error = 0; + internal::Arg arg = *s < '0' || *s > '9' ? + next_arg(error) : get_arg(internal::parse_nonnegative_int(s), error); + if (error) { + FMT_THROW(FormatError( + *s != '}' && *s != ':' ? "invalid format string" : error)); + } + return arg; +} + +template <typename Char> +inline internal::Arg BasicFormatter<Char>::parse_arg_name(const Char *&s) { + assert(internal::is_name_start(*s)); + const Char *start = s; + Char c; + do { + c = *++s; + } while (internal::is_name_start(c) || ('0' <= c && c <= '9')); + const char *error = 0; + internal::Arg arg = get_arg(BasicStringRef<Char>(start, s - start), error); + if (error) + FMT_THROW(FormatError(error)); + return arg; +} + +// Should be after FormatSpec +template <typename Char> +const Char *BasicFormatter<Char>::format( + const Char *&format_str, const internal::Arg &arg) { + using internal::Arg; + const Char *s = format_str; + FormatSpec spec; + if (*s == ':') { + if (arg.type == Arg::CUSTOM) { + arg.custom.format(this, arg.custom.value, &s); + return s; + } + ++s; + // Parse fill and alignment. + if (Char c = *s) { + const Char *p = s + 1; + spec.align_ = ALIGN_DEFAULT; + do { + switch (*p) { + case '<': + spec.align_ = ALIGN_LEFT; + break; + case '>': + spec.align_ = ALIGN_RIGHT; + break; + case '=': + spec.align_ = ALIGN_NUMERIC; + break; + case '^': + spec.align_ = ALIGN_CENTER; + break; + } + if (spec.align_ != ALIGN_DEFAULT) { + if (p != s) { + if (c == '}') break; + if (c == '{') + FMT_THROW(FormatError("invalid fill character '{'")); + s += 2; + spec.fill_ = c; + } else ++s; + if (spec.align_ == ALIGN_NUMERIC) + require_numeric_argument(arg, '='); + break; + } + } while (--p >= s); + } + + // Parse sign. + switch (*s) { + case '+': + check_sign(s, arg); + spec.flags_ |= SIGN_FLAG | PLUS_FLAG; + break; + case '-': + check_sign(s, arg); + spec.flags_ |= MINUS_FLAG; + break; + case ' ': + check_sign(s, arg); + spec.flags_ |= SIGN_FLAG; + break; + } + + if (*s == '#') { + require_numeric_argument(arg, '#'); + spec.flags_ |= HASH_FLAG; + ++s; + } + + // Parse zero flag. + if (*s == '0') { + require_numeric_argument(arg, '0'); + spec.align_ = ALIGN_NUMERIC; + spec.fill_ = '0'; + ++s; + } + + // Parse width. + if ('0' <= *s && *s <= '9') { + spec.width_ = internal::parse_nonnegative_int(s); + } else if (*s == '{') { + ++s; + Arg width_arg = internal::is_name_start(*s) ? + parse_arg_name(s) : parse_arg_index(s); + if (*s++ != '}') + FMT_THROW(FormatError("invalid format string")); + ULongLong value = 0; + switch (width_arg.type) { + case Arg::INT: + if (width_arg.int_value < 0) + FMT_THROW(FormatError("negative width")); + value = width_arg.int_value; + break; + case Arg::UINT: + value = width_arg.uint_value; + break; + case Arg::LONG_LONG: + if (width_arg.long_long_value < 0) + FMT_THROW(FormatError("negative width")); + value = width_arg.long_long_value; + break; + case Arg::ULONG_LONG: + value = width_arg.ulong_long_value; + break; + default: + FMT_THROW(FormatError("width is not integer")); + } + if (value > (std::numeric_limits<int>::max)()) + FMT_THROW(FormatError("number is too big")); + spec.width_ = static_cast<int>(value); + } + + // Parse precision. + if (*s == '.') { + ++s; + spec.precision_ = 0; + if ('0' <= *s && *s <= '9') { + spec.precision_ = internal::parse_nonnegative_int(s); + } else if (*s == '{') { + ++s; + Arg precision_arg = internal::is_name_start(*s) ? + parse_arg_name(s) : parse_arg_index(s); + if (*s++ != '}') + FMT_THROW(FormatError("invalid format string")); + ULongLong value = 0; + switch (precision_arg.type) { + case Arg::INT: + if (precision_arg.int_value < 0) + FMT_THROW(FormatError("negative precision")); + value = precision_arg.int_value; + break; + case Arg::UINT: + value = precision_arg.uint_value; + break; + case Arg::LONG_LONG: + if (precision_arg.long_long_value < 0) + FMT_THROW(FormatError("negative precision")); + value = precision_arg.long_long_value; + break; + case Arg::ULONG_LONG: + value = precision_arg.ulong_long_value; + break; + default: + FMT_THROW(FormatError("precision is not integer")); + } + if (value > (std::numeric_limits<int>::max)()) + FMT_THROW(FormatError("number is too big")); + spec.precision_ = static_cast<int>(value); + } else { + FMT_THROW(FormatError("missing precision specifier")); + } + if (arg.type <= Arg::LAST_INTEGER_TYPE || arg.type == Arg::POINTER) { + FMT_THROW(FormatError( + fmt::format("precision not allowed in {} format specifier", + arg.type == Arg::POINTER ? "pointer" : "integer"))); + } + } + + // Parse type. + if (*s != '}' && *s) + spec.type_ = static_cast<char>(*s++); + } + + if (*s++ != '}') + FMT_THROW(FormatError("missing '}' in format string")); + + // Format argument. + internal::BasicArgFormatter<Char>(*this, spec, s - 1).visit(arg); + return s; } +template <typename Char> +void BasicFormatter<Char>::format(BasicCStringRef<Char> format_str) { + const Char *s = format_str.c_str(); + const Char *start = s; + while (*s) { + Char c = *s++; + if (c != '{' && c != '}') continue; + if (*s == c) { + write(writer_, start, s); + start = ++s; + continue; + } + if (c == '}') + FMT_THROW(FormatError("unmatched '}' in format string")); + write(writer_, start, s - 1); + internal::Arg arg = internal::is_name_start(*s) ? + parse_arg_name(s) : parse_arg_index(s); + start = s = format(s, arg); + } + write(writer_, start, s); +} +} // namespace fmt + +#if FMT_USE_USER_DEFINED_LITERALS +namespace fmt { +namespace internal { + +template <typename Char> +struct UdlFormat { + const Char *str; + + template <typename... Args> + auto operator()(Args && ... args) const + -> decltype(format(str, std::forward<Args>(args)...)) { + return format(str, std::forward<Args>(args)...); + } +}; + +template <typename Char> +struct UdlArg { + const Char *str; + + template <typename T> + NamedArg<Char> operator=(T &&value) const { + return {str, std::forward<T>(value)}; + } +}; + +} // namespace internal + +inline namespace literals { + +/** + \rst + C++11 literal equivalent of :func:`fmt::format`. + + **Example**:: + + using namespace fmt::literals; + std::string message = "The answer is {}"_format(42); + \endrst + */ +inline internal::UdlFormat<char> +operator"" _format(const char *s, std::size_t) { return {s}; } +inline internal::UdlFormat<wchar_t> +operator"" _format(const wchar_t *s, std::size_t) { return {s}; } + +/** + \rst + C++11 literal equivalent of :func:`fmt::arg`. + + **Example**:: + + using namespace fmt::literals; + print("Elapsed time: {s:.2f} seconds", "s"_a=1.23); + \endrst + */ +inline internal::UdlArg<char> +operator"" _a(const char *s, std::size_t) { return {s}; } +inline internal::UdlArg<wchar_t> +operator"" _a(const wchar_t *s, std::size_t) { return {s}; } + +} // inline namespace literals +} // namespace fmt +#endif // FMT_USE_USER_DEFINED_LITERALS + // Restore warnings. #if FMT_GCC_VERSION >= 406 # pragma GCC diagnostic pop #endif -#ifdef __clang__ +#if defined(__clang__) && !defined(__INTEL_COMPILER) # pragma clang diagnostic pop #endif diff --git a/dep/cppformat/posix.cc b/dep/cppformat/posix.cc index d36871f43a3..756281a0ebd 100644 --- a/dep/cppformat/posix.cc +++ b/dep/cppformat/posix.cc @@ -55,11 +55,14 @@ # ifdef __MINGW32__ # define _SH_DENYNO 0x40 -# undef fileno # endif #endif // _WIN32 +#ifdef fileno +# undef fileno +#endif + namespace { #ifdef _WIN32 // Return type of read and write functions. diff --git a/dep/cppformat/posix.h b/dep/cppformat/posix.h index 722690a8b33..88bcb4f557b 100644 --- a/dep/cppformat/posix.h +++ b/dep/cppformat/posix.h @@ -69,7 +69,11 @@ # define FMT_UNUSED #endif -#if FMT_USE_STATIC_ASSERT || FMT_HAS_CPP_ATTRIBUTE(cxx_static_assert) || \ +#ifndef FMT_USE_STATIC_ASSERT +# define FMT_USE_STATIC_ASSERT 0 +#endif + +#if FMT_USE_STATIC_ASSERT || FMT_HAS_FEATURE(cxx_static_assert) || \ (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1600 # define FMT_STATIC_ASSERT(cond, message) static_assert(cond, message) #else diff --git a/doc/UnixInstall.txt b/doc/UnixInstall.txt index 7c27e431495..a97fdd2bd31 100644 --- a/doc/UnixInstall.txt +++ b/doc/UnixInstall.txt @@ -6,10 +6,10 @@ WARNING: THIS DOCUMENTATION IS NOT ALWAYS UP TO DATE. FOR MORE UP-TO-DATE INFORMATION, CHECK THE TRINITY WIKI. ========================================================= -CHECK http://www.trinitycore.info/How-to:Linux FOR FURTHER HELP +CHECK http://www.trinitycore.info/ FOR FURTHER HELP These are instructions for installation in a Linux environment, if you are -using Windows refer to http://www.trinitycore.info/How-to:Win +using Windows refer to http://www.trinitycore.info/ Installing TrinityCore is fairly simple on a Linux machine, assuming you have all required applications @@ -25,7 +25,7 @@ you created a dir named build ad want to have your finalcompiled product installed in /home/trinity/server, an example sequence of commands can be : - cmake ../ -DPREFIX=/home/trinity/server -DTOOLS=1 -DWITH_WARNINGS=1 + cmake ../ -DCMAKE_INSTALL_PREFIX=/home/trinity/server -DTOOLS=1 -DWITH_WARNINGS=1 make make install @@ -34,24 +34,24 @@ than where to install using flags built into our cmake files. Just open up CMakeLists.txt in the main folder and take a look at some of the flags like - SERVERS Build worldserver and authserver - SCRIPTS Build core with scripts included - TOOLS Build map/vmap extraction/assembler tools - USE_SCRIPTPCH Use precompiled headers when compiling scripts - USE_COREPCH Use precompiled headers when compiling servers - WITH_WARNINGS Show all warnings during compile - WITH_COREDEBUG Include additional debug-code in core - PREFIX Set installation directory - NOJEM Do not build with jemalloc (advanced users only) - CONF_DIR Set path as default configuration directory - LIBSDIR Set path as default library directory - CMAKE_C_FLAGS Set C_FLAGS for compile (advanced users only) - CMAKE_CXX_FLAGS Set CXX_FLAGS for compile (advanced users only) - CMAKE_BUILD_TYPE Set buildtype - the supported modes are : - Release, MinSizeRel, RelWithDebInfo, Debug - -Of course, replace the paths in PREFIX, CONF_DIR and LIBSDIR with the -directories you wish to install TrinityCore to. The datadir is where maps, + SERVERS Build worldserver and authserver + SCRIPTS Build core with scripts included + TOOLS Build map/mmaps/vmap extraction/assembler tools + USE_SCRIPTPCH Use precompiled headers when compiling scripts + USE_COREPCH Use precompiled headers when compiling servers + WITH_WARNINGS Show all warnings during compile + WITH_COREDEBUG Include additional debug-code in core + CMAKE_INSTALL_PREFIX Set installation directory + NOJEM Do not build with jemalloc (advanced users only) + CONF_DIR Set path as default configuration directory + LIBSDIR Set path as default library directory + CMAKE_C_FLAGS Set C_FLAGS for compile (advanced users only) + CMAKE_CXX_FLAGS Set CXX_FLAGS for compile (advanced users only) + CMAKE_BUILD_TYPE Set buildtype - the supported modes are : + Release, MinSizeRel, RelWithDebInfo, Debug + +Of course, replace the paths in CMAKE_INSTALL_PREFIX with the +directory you wish to install TrinityCore to. The datadir is where maps, DBCs, and SQLs are stored. The sysconfdir is where configuration files are stored. Once TrinityCore is installed you will need to apply database updates diff --git a/sql/updates/world/2015_11_12_00_world.sql b/sql/updates/world/2015_11_12_00_world.sql new file mode 100644 index 00000000000..79c2461e5ff --- /dev/null +++ b/sql/updates/world/2015_11_12_00_world.sql @@ -0,0 +1,1739 @@ +SET @OGUID:=81188; +DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+2471; + +SET @OGUID:=81188; +INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES +(@OGUID+0 , 180405, 571, 1, 1, 5235.096, -1315.231, 242.0927, 1.832595, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 66) +(@OGUID+1 , 180405, 571, 1, 1, 5216.018, -1290.845, 243.406, 3.368496, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 66) +(@OGUID+2 , 180405, 571, 1, 1, 5221.816, -1337.178, 241.8734, 1.082103, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 66) +(@OGUID+3 , 180405, 571, 1, 1, 5190.064, -1301.23, 245.2663, 4.468043, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 66) +(@OGUID+4 , 180405, 571, 1, 1, 5201.61, -1335.664, 242.9156, 6.265733, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 66) +(@OGUID+5 , 180405, 571, 1, 1, 5136.854, -2186.576, 236.5713, 1.483528, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+6 , 180405, 571, 1, 1, 5180.994, -2197.26, 238.9063, 4.799657, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+7 , 180405, 571, 1, 1, 5154.888, -2212.581, 237.812, 3.700105, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+8 , 180405, 571, 1, 1, 5122.884, -2229.666, 241.3221, 3.228859, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4317) +(@OGUID+9 , 180405, 571, 1, 1, 5359.893, -2664.229, 301.0435, 5.794494, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+10 , 180405, 571, 1, 1, 5433.402, -2615.731, 312.4956, 1.082103, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4275) +(@OGUID+11 , 180405, 571, 1, 1, 5467.35, -2650.341, 312.4956, 4.153885, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4275) +(@OGUID+12 , 180405, 571, 1, 1, 5526.185, -2673.551, 303.9539, 4.921829, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4275) +(@OGUID+13 , 180405, 571, 1, 1, 5536.588, -2625.326, 303.6935, 1.850049, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4275) +(@OGUID+14 , 180405, 571, 1, 1, 5449.43, -2564.951, 308.4314, 3.47321, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4275) +(@OGUID+15 , 180405, 571, 1, 1, 5763.002, -3528.326, 388.487, 3.717554, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+16 , 180405, 571, 1, 1, 5786.963, -3540.992, 387.882, 5.93412, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+17 , 180405, 571, 1, 1, 5754.921, -3608.51, 386.4638, 3.036838, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4323) +(@OGUID+18 , 180405, 571, 1, 1, 3858.005, -4565.136, 215.9988, 1.221729, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+19 , 180405, 571, 1, 1, 3888.583, -4554.612, 217.6464, 0.06981169, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+20 , 180405, 571, 1, 1, 3830.209, -4542.06, 214.4055, 2.635444, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+21 , 180405, 571, 1, 1, 3846.518, -4514.354, 213.1539, 0.8726639, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+22 , 180405, 571, 1, 1, 3861.908, -4495.958, 214.0141, 0.6981314, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4211) +(@OGUID+23 , 180405, 571, 1, 1, 4571.689, -4261.007, 182.1285, 0.087266, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4159) +(@OGUID+24 , 180405, 571, 1, 1, 4532.587, -4188.319, 173.4792, 1.623156, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4159) +(@OGUID+25 , 180405, 571, 1, 1, 4526.884, -4148.059, 172.4744, 4.450591, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4159) +(@OGUID+26 , 180405, 571, 1, 1, 4589.202, -4206.561, 178.8516, 0.1919852, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4159) +(@OGUID+27 , 180405, 571, 1, 1, 4567.845, -4178.61, 175.7076, 5.183629, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4159) +(@OGUID+28 , 180405, 571, 1, 1, 3404.216, -2841.716, 201.0336, 1.012289, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+29 , 180405, 571, 1, 1, 3455.106, -2785.783, 201.4688, 2.199115, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+30 , 180405, 571, 1, 1, 3393.907, -2804.209, 227.3434, 5.654869, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+31 , 180405, 571, 1, 1, 3390.204, -2797.654, 200.4411, 5.759588, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+32 , 180405, 571, 1, 1, 3415.27, -2746.156, 199.3946, 0.2617982, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4204) +(@OGUID+33 , 180405, 571, 1, 1, 3268.182, -2366.07, 122.9121, 3.996807, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4217) +(@OGUID+34 , 180405, 571, 1, 1, 3231.953, -2368.505, 132.1824, 2.862335, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4217) +(@OGUID+35 , 180405, 571, 1, 1, 3213.3, -2336.478, 122.9258, 2.111848, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4206) +(@OGUID+36 , 180405, 571, 1, 1, 3264.644, -2297.473, 121.0501, 2.949595, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4206) +(@OGUID+37 , 180405, 571, 1, 1, 3267.19, -2260.863, 114.0805, 3.508117, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4248) +(@OGUID+38 , 180405, 571, 1, 1, 3231.138, -2257.735, 114.4141, 3.525572, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4248) +(@OGUID+39 , 180405, 571, 1, 1, 3252.991, -2215.066, 117.3726, 2.775069, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4206) +(@OGUID+40 , 180405, 571, 1, 1, 3270.524, -2221.896, 117.3726, 3.228859, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4206) +(@OGUID+41 , 180405, 571, 1, 1, 3165.017, -2261.948, 121.5571, 5.218536, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4206) +(@OGUID+42 , 180405, 571, 1, 1, 3267.909, -2244.548, 121.1477, 6.021387, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4206) +(@OGUID+43 , 180405, 571, 1, 1, 3373.89, -2216.506, 124.3674, 2.705255, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4206) +(@OGUID+44 , 180405, 571, 1, 1, 2671.809, -4329.921, 293.616, 2.879789, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4065) +(@OGUID+45 , 180405, 571, 1, 1, 2622.076, -4352.586, 283.4205, 5.096362, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4065) +(@OGUID+46 , 180405, 571, 1, 1, 2645.095, -4365.969, 279.2655, 3.438303, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4065) +(@OGUID+47 , 180405, 571, 1, 1, 2621.35, -4382.056, 282.7698, 5.270896, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4065) +(@OGUID+48 , 180405, 571, 1, 1, 2720.132, -4365.484, 281.1786, 0.9948372, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4065) +(@OGUID+49 , 180405, 571, 1, 1, 2660.348, -4411.663, 290.1755, 3.351047, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4018) +(@OGUID+50 , 180405, 571, 1, 1, 2389.726, -4986.201, 258.8515, 3.717554, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+51 , 180405, 571, 1, 1, 2365.341, -5054.367, 254.0189, 3.543024, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+52 , 180405, 571, 1, 1, 2397.013, -5053.728, 254.2539, 4.363324, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+53 , 180405, 571, 1, 1, 1860.306, -6006.499, 9.963303, 4.537859, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4060) +(@OGUID+54 , 180405, 571, 1, 1, 1949.557, -6101.297, 30.84152, 4.380776, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4060) +(@OGUID+55 , 180405, 571, 1, 1, 1874.136, -6124.242, 27.42142, 5.009095, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4060) +(@OGUID+56 , 180405, 571, 1, 1, 1919.801, -6125.821, 27.42174, 4.590216, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4060) +(@OGUID+57 , 180405, 571, 1, 1, 1932.311, -6147.982, 26.77648, 0.8552105, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4000) +(@OGUID+58 , 180405, 571, 1, 1, 1896.94, -6176.019, 23.88414, 3.001947, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4000) +(@OGUID+59 , 180405, 571, 1, 1, 500.0282, -4625.844, 249.6229, 1.937312, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+60 , 180405, 571, 1, 1, 448.2436, -4689.455, 248.3156, 0.3490652, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+61 , 180405, 571, 1, 1, 400.814, -4664.87, 248.9721, 4.66003, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3991) +(@OGUID+62 , 180405, 571, 1, 1, 437.1691, -4547.266, 245.5937, 5.619962, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3991) +(@OGUID+63 , 180405, 571, 1, 1, 498.3495, -4543.512, 249.0318, 2.321287, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3991) +(@OGUID+64 , 180405, 571, 1, 1, 383.7737, -4704.653, 246.4204, 1.06465, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3991) +(@OGUID+65 , 180405, 571, 1, 1, 341.7077, -4663.656, 252.0559, 5.183629, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3991) +(@OGUID+66 , 180405, 571, 1, 1, 324.1059, -4619.823, 236.087, 4.991644, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3991) +(@OGUID+67 , 180405, 571, 1, 1, 400.9474, -4492.049, 233.8787, 2.705255, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3991) +(@OGUID+68 , 180405, 571, 1, 1, 401.9044, -4511.179, 250.6629, 1.099556, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3991) +(@OGUID+69 , 180405, 571, 1, 1, 360.6213, -4478.643, 242.9844, 2.705255, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3991) +(@OGUID+70 , 180405, 571, 1, 1, 454.7388, -4499.015, 248.8951, 3.490667, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3991) +(@OGUID+71 , 180405, 571, 1, 1, 734.592, -2933.09, 7.260227, 2.024579, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3987) +(@OGUID+72 , 180405, 571, 1, 1, 797.5989, -2948.066, 6.855769, 3.543024, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3987) +(@OGUID+73 , 180405, 571, 1, 1, 803.2014, -2915.014, 7.161566, 0, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3987) +(@OGUID+74 , 180405, 571, 1, 1, 786.0313, -2859.193, 4.484391, 5.462882, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3988) +(@OGUID+75 , 180405, 571, 1, 1, 1360.858, -3212.248, 186.6853, 0.8726639, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+76 , 180405, 571, 1, 1, 1369.589, -3177.692, 164.0921, 5.67232, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+77 , 180405, 571, 1, 1, 1371.091, -3219.997, 164.9762, 0.8901166, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3998) +(@OGUID+78 , 180405, 571, 1, 1, 1458.077, -3181.131, 170.4188, 5.811947, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3998) +(@OGUID+79 , 180405, 571, 1, 1, 1427.257, -3256.968, 165.5387, 4.485497, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3998) +(@OGUID+80 , 180405, 571, 1, 1, 1344.667, -3284.161, 174.4178, 6.003934, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3998) +(@OGUID+81 , 180405, 571, 1, 1, 1426.128, -3314.11, 168.664, 3.961899, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3998) +(@OGUID+82 , 180405, 571, 1, 1, 651.1013, -5033.48, 8.628246, 4.363324, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3981) +(@OGUID+83 , 180405, 571, 1, 1, 601.5671, -5000.274, 8.872829, 2.635444, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3981) +(@OGUID+84 , 180405, 571, 1, 1, 597.5203, -5013.503, 3.252731, 1.640607, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3981) +(@OGUID+85 , 180405, 571, 1, 1, 571.9734, -4937.067, 17.71497, 5.375615, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3981) +(@OGUID+86 , 180405, 571, 1, 1, 522.7151, -4947.288, 32.97911, 1.378809, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3981) +(@OGUID+87 , 180405, 571, 1, 1, 570.3427, -5099.132, 8.790771, 2.548179, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 3981) +(@OGUID+88 , 180405, 571, 1, 1, 2475.441, -5066.366, 305.6736, 5.846854, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4003) +(@OGUID+89 , 180405, 571, 1, 1, 2432.477, -5157.805, 281.0374, 0.6457717, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4003) +(@OGUID+90 , 180405, 571, 1, 1, 2424.413, -5138.231, 281.4278, 3.787367, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4003) +(@OGUID+91 , 180405, 571, 1, 1, 2494.666, -5065.818, 284.7478, 0.01745246, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4003) +(@OGUID+92 , 180405, 571, 1, 1, 2513.709, -5000.823, 286.0405, 2.792518, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4003) +(@OGUID+93 , 180405, 571, 1, 1, 3241.704, -654.431, 166.4061, 3.68265, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+94 , 180405, 571, 1, 1, 3227.741, -670.722, 167.4637, 2.321287, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+95 , 180405, 571, 1, 1, 3254.793, -668.5916, 174.1517, 5.759588, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+96 , 180405, 571, 1, 1, 3217.112, -730.1161, 173.5844, 4.32842, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4186) +(@OGUID+97 , 180405, 571, 1, 1, 3281.125, -720.5612, 175.8869, 5.916668, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4186) +(@OGUID+98 , 180405, 571, 1, 1, 3247.021, -717.0428, 167.3728, 3.57793, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4186) +(@OGUID+99 , 180405, 571, 1, 1, 3261.009, -755.8375, 174.2986, 2.949595, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4186) +(@OGUID+100 , 180405, 571, 1, 1, 2566.921, -1911.748, 3.159494, 1.97222, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4242) +(@OGUID+101 , 180405, 571, 1, 1, 2513.8, -1885.403, 12.88906, 4.468043, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4242) +(@OGUID+102 , 180405, 571, 1, 1, 2424.383, -1848.096, 3.90364, 2.129301, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4242) +(@OGUID+103 , 180405, 571, 1, 1, 2495.073, -1815.667, 11.99702, 0.4188786, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4242) +(@OGUID+104 , 180405, 571, 1, 1, 2601.156, -1804.928, 12.57094, 2.530723, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4242) +(@OGUID+105 , 180405, 571, 1, 1, 3694.363, -742.5368, 213.9544, 3.543024, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4177) +(@OGUID+106 , 180405, 571, 1, 1, 3843.085, -705.7463, 225.1528, 1.658062, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4177) +(@OGUID+107 , 180405, 571, 1, 1, 3880.034, -784.3032, 221.0895, 3.735006, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4177) +(@OGUID+108 , 180405, 571, 1, 1, 3666.556, -707.39, 228.8305, 1.832595, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4177) +(@OGUID+109 , 180405, 571, 1, 1, 3649.726, -701.9913, 215.0304, 1.204277, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4177) +(@OGUID+110 , 180405, 571, 1, 1, 3542.812, 202.7465, 52.22747, 1.204277, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4254) +(@OGUID+111 , 180405, 571, 1, 1, 3538.371, 244.3045, 47.28843, 3.159062, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4161) +(@OGUID+112 , 180405, 571, 1, 1, 3575.413, 264.5829, 47.28846, 4.747296, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4161) +(@OGUID+113 , 180405, 571, 1, 1, 3564.399, 258.56, 122.2979, 1.274088, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4161) +(@OGUID+114 , 180405, 571, 1, 1, 3544.587, 296.3797, 122.2979, 3.560473, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4161) +(@OGUID+115 , 180405, 571, 1, 1, 3480.402, 254.7602, 52.25331, 4.537859, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4161) +(@OGUID+116 , 180405, 571, 1, 1, 3524.332, 270.6145, 122.2979, 5.201083, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4161) +(@OGUID+117 , 180405, 571, 1, 1, 3532.921, 299.8601, 47.28838, 0.8377575, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4161) +(@OGUID+118 , 180405, 571, 1, 1, 3529.778, 341.6897, 52.22746, 2.740162, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4161) +(@OGUID+119 , 180405, 571, 1, 1, 2802.93, 889.9564, 12.99052, 0.5934101, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4152) +(@OGUID+120 , 180405, 571, 1, 1, 2766.088, 896.6517, 10.43985, 5.969027, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4152) +(@OGUID+121 , 180405, 571, 1, 1, 2780.375, 916.6542, 22.35928, 1.762782, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4152) +(@OGUID+122 , 180405, 571, 1, 1, 2782.104, 959.6036, 22.56974, 0.9424766, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4152) +(@OGUID+123 , 180405, 571, 1, 1, 2713.333, 904.954, 4.644395, 4.921829, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4152) +(@OGUID+124 , 180405, 571, 1, 1, 3459.519, 1994.401, 64.16402, 4.694937, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4158) +(@OGUID+125 , 180405, 571, 1, 1, 3487.954, 1962.221, 64.86233, 5.742135, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4158) +(@OGUID+126 , 180405, 571, 1, 1, 3488.449, 2022.323, 64.86241, 4.206246, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4158) +(@OGUID+127 , 180405, 571, 1, 1, 3526.152, 1989.084, 65.00359, 1.256636, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4158) +(@OGUID+128 , 180405, 571, 1, 1, 3543.308, 2012.801, 67.83711, 2.809975, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4158) +(@OGUID+129 , 180405, 571, 1, 1, 8478.809, -335.0501, 905.8823, 4.81711, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4436) +(@OGUID+130 , 180405, 571, 1, 1, 8442.125, -343.2864, 906.6075, 4.258607, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4484) +(@OGUID+131 , 180405, 571, 1, 1, 8439.769, -360.4051, 910.7804, 4.450591, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4484) +(@OGUID+132 , 180405, 571, 1, 1, 8431.716, -369.2213, 910.7804, 4.310966, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4484) +(@OGUID+133 , 180405, 571, 1, 1, 7857.659, -740.2723, 1178.374, 1.97222, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+134 , 180405, 571, 1, 1, 7783.667, -2801.49, 1220.847, 5.427975, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+135 , 180405, 571, 1, 1, 7807.762, -2817.106, 1222.603, 4.782203, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+136 , 180405, 571, 1, 1, 7816.426, -2858.509, 1228.606, 5.393069, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4441) +(@OGUID+137 , 180405, 571, 1, 1, 7868.84, -2788.675, 1143.72, 1.221729, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4441) +(@OGUID+138 , 180405, 571, 1, 1, 7817.629, -2897.441, 1246.089, 5.567601, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4441) +(@OGUID+139 , 180405, 571, 1, 1, 7809.628, -2931.258, 1257.037, 4.468043, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4441) +(@OGUID+140 , 180405, 571, 1, 1, 7809.809, -2961.031, 1257.285, 3.33359, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4441) +(@OGUID+141 , 180405, 571, 1, 1, 7841.398, -2981.669, 1266.466, 4.485497, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4441) +(@OGUID+142 , 180405, 571, 1, 1, 6200.735, -1057.431, 417.0221, 5.044002, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4419) +(@OGUID+143 , 180405, 571, 1, 1, 6124.892, -1075.259, 411.6781, 3.630291, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4419) +(@OGUID+144 , 180405, 571, 1, 1, 6138.141, -1046.391, 412.701, 5.724681, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4419) +(@OGUID+145 , 180405, 571, 1, 1, 6107.655, -1084.122, 413.654, 3.211419, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4419) +(@OGUID+146 , 180405, 571, 1, 1, 6112.512, -1025.256, 414.1365, 3.246347, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4419) +(@OGUID+147 , 180405, 571, 1, 1, 6664.644, -251.6691, 962.2526, 5.724681, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4428) +(@OGUID+148 , 180405, 571, 1, 1, 6679.855, -261.4221, 961.9869, 5.148723, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4428) +(@OGUID+149 , 180405, 571, 1, 1, 6683.386, -201.5864, 951.2874, 6.108654, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4428) +(@OGUID+150 , 180405, 571, 1, 1, 5560.767, 5743.191, -75.39922, 3.106652, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4285) +(@OGUID+151 , 180405, 571, 1, 1, 5521.055, 5775.581, -77.84254, 4.293513, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4285) +(@OGUID+152 , 180405, 571, 1, 1, 5587.409, 5831.001, -67.94295, 1.780234, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4285) +(@OGUID+153 , 180405, 571, 1, 1, 5495.171, 4739.647, -195.2901, 5.93412, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4290) +(@OGUID+154 , 180405, 571, 1, 1, 5522.425, 4744.925, -188.8901, 4.956738, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4290) +(@OGUID+155 , 180405, 571, 1, 1, 4472.997, 5697.727, 84.70158, 6.073746, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4123) +(@OGUID+156 , 180405, 571, 1, 1, 4519.887, 5708.41, 84.29858, 4.590216, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4122) +(@OGUID+157 , 180405, 571, 1, 1, 4128.227, 5302.944, 30.827, 3.543024, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4108) +(@OGUID+158 , 180405, 571, 1, 1, 4064.082, 5254.847, 27.40729, 3.176533, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4108) +(@OGUID+159 , 180405, 571, 1, 1, 4052.241, 5303.074, 27.85353, 3.647741, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4108) +(@OGUID+160 , 180405, 571, 1, 1, 2899.752, 6243.547, 208.8471, 5.93412, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4020) +(@OGUID+161 , 180405, 571, 1, 1, 2825.619, 6186.017, 124.1293, 0.2268925, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4129) +(@OGUID+162 , 180405, 571, 1, 1, 2806.39, 6171.232, 91.58034, 5.846854, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4129) +(@OGUID+163 , 180405, 571, 1, 1, 2777.328, 6130.342, 97.58146, 2.652894, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4129) +(@OGUID+164 , 180405, 571, 1, 1, 2248.339, 5206.908, 14.71353, 1.53589, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4032) +(@OGUID+165 , 180405, 571, 1, 1, 2262.972, 5191.829, 13.71622, 4.34587, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4032) +(@OGUID+166 , 180405, 571, 1, 1, 2238.288, 5169.116, 14.44349, 1.326448, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4032) +(@OGUID+167 , 180405, 571, 1, 1, 2266.964, 5169.439, 11.26108, 3.141593, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4032) +(@OGUID+168 , 180405, 571, 1, 1, 2242.774, 5143.132, 6.842498, 4.398232, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4032) +(@OGUID+169 , 180405, 571, 1, 1, 3014.273, 4067.549, 26.34313, 3.595379, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4113) +(@OGUID+170 , 180405, 571, 1, 1, 2998.225, 4050.244, 26.61139, 2.042035, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4113) +(@OGUID+171 , 180405, 571, 1, 1, 2922.996, 4039.652, 1.847561, 3.560473, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4113) +(@OGUID+172 , 180405, 571, 1, 1, 2873.578, 4044.563, 5.168859, 2.024579, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4113) +(@OGUID+173 , 180405, 571, 1, 1, 3382.788, 4113.637, 29.84352, 5.689774, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+174 , 180405, 571, 1, 1, 3392.099, 4155.976, 30.3478, 3.68265, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 0) +(@OGUID+175 , 180405, 571, 1, 1, 3459.185, 4145.886, 17.19302, 0.8726639, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4043) +(@OGUID+176 , 180405, 571, 1, 1, 3444.382, 4152.429, 31.86185, 0.2268925, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4043) +(@OGUID+177 , 180405, 571, 1, 1, 3435.074, 4077.38, 27.98145, 0.5410506, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4043) +(@OGUID+178 , 180405, 571, 1, 1, 3476.852, 4086.253, 28.05615, 0.2443456, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4043) +(@OGUID+179 , 180405, 571, 1, 1, 3494.191, 4124.338, 29.75336, 2.460913, 0, 0, 0, 1, 120, 255, 1), -- 180405 (Area: 4043) +(@OGUID+180 , 180406, 571, 1, 1, 5233.11, -1303.505, 242.6981, 2.408554, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 66) +(@OGUID+181 , 180406, 571, 1, 1, 5223.288, -1292.884, 242.986, 3.019413, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 66) +(@OGUID+182 , 180406, 571, 1, 1, 5235.496, -1320.318, 242.1528, 1.902409, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 66) +(@OGUID+183 , 180406, 571, 1, 1, 5217.619, -1336.551, 242.0803, 0.3141584, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 66) +(@OGUID+184 , 180406, 571, 1, 1, 5204.664, -1302.282, 243.929, 0.7330382, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 66) +(@OGUID+185 , 180406, 571, 1, 1, 5186.655, -1315.126, 244.0308, 5.096362, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 66) +(@OGUID+186 , 180406, 571, 1, 1, 5197.557, -1293.151, 245.1381, 3.909541, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 66) +(@OGUID+187 , 180406, 571, 1, 1, 5167.86, -2163.789, 244.9229, 0.1047193, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+188 , 180406, 571, 1, 1, 5118.464, -2229.395, 241.3221, 2.775069, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4317) +(@OGUID+189 , 180406, 571, 1, 1, 5200.777, -2213.902, 241.7638, 4.537859, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4317) +(@OGUID+190 , 180406, 571, 1, 1, 5209.903, -2206.08, 240.9178, 3.68265, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4317) +(@OGUID+191 , 180406, 571, 1, 1, 5381.495, -2622.062, 303.9539, 1.832595, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+192 , 180406, 571, 1, 1, 5432.385, -2649.816, 312.4956, 2.82743, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4275) +(@OGUID+193 , 180406, 571, 1, 1, 5380.949, -2686.028, 301.1252, 5.759588, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4275) +(@OGUID+194 , 180406, 571, 1, 1, 5492.693, -2604.736, 304.7423, 1.815142, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4275) +(@OGUID+195 , 180406, 571, 1, 1, 5528.45, -2651.096, 303.9539, 4.97419, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4275) +(@OGUID+196 , 180406, 571, 1, 1, 5750.874, -3530.618, 388.8118, 3.508117, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+197 , 180406, 571, 1, 1, 5780.643, -3626.452, 387.7118, 5.427975, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4323) +(@OGUID+198 , 180406, 571, 1, 1, 5784.183, -3601.332, 387.882, 4.363324, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4323) +(@OGUID+199 , 180406, 571, 1, 1, 4586.705, -4265.697, 182.0961, 0.122173, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+200 , 180406, 571, 1, 1, 3867.676, -4566.178, 215.357, 1.221729, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+201 , 180406, 571, 1, 1, 3832.829, -4549.958, 215.4487, 2.687807, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+202 , 180406, 571, 1, 1, 3840.872, -4517.668, 216.5039, 1.274088, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+203 , 180406, 571, 1, 1, 3854.774, -4497.302, 214.1549, 4.76475, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4211) +(@OGUID+204 , 180406, 571, 1, 1, 4507.235, -4229.571, 167.2504, 4.415683, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+205 , 180406, 571, 1, 1, 4543.993, -4219.068, 170.553, 5.166176, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+206 , 180406, 571, 1, 1, 4576.085, -4253.777, 182.2079, 2.792518, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4159) +(@OGUID+207 , 180406, 571, 1, 1, 3443.539, -2828.223, 202.6841, 6.265733, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+208 , 180406, 571, 1, 1, 3440.909, -2781.021, 200.6416, 2.495818, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+209 , 180406, 571, 1, 1, 3399.112, -2788.302, 211.2246, 1.797689, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+210 , 180406, 571, 1, 1, 3484.97, -2776.988, 199.2997, 1.762782, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+211 , 180406, 571, 1, 1, 3429.496, -2767.099, 200.3861, 3.316144, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4204) +(@OGUID+212 , 180406, 571, 1, 1, 3452.409, -2756.081, 199.3898, 5.044002, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4204) +(@OGUID+213 , 180406, 571, 1, 1, 3229.066, -2337.311, 95.43889, 2.426008, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4217) +(@OGUID+214 , 180406, 571, 1, 1, 3219.195, -2355.696, 129.1687, 2.216565, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4217) +(@OGUID+215 , 180406, 571, 1, 1, 3275.07, -2303.272, 120.9754, 2.879789, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4206) +(@OGUID+216 , 180406, 571, 1, 1, 3195.742, -2285.431, 110.5097, 1.954769, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4248) +(@OGUID+217 , 180406, 571, 1, 1, 3305.993, -2292.779, 115.1555, 4.450591, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4248) +(@OGUID+218 , 180406, 571, 1, 1, 3162.851, -2230.15, 121.904, 5.148723, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4206) +(@OGUID+219 , 180406, 571, 1, 1, 3320.307, -2237.068, 124.4572, 4.118979, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4206) +(@OGUID+220 , 180406, 571, 1, 1, 2666.803, -4317.568, 293.4839, 2.199115, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4065) +(@OGUID+221 , 180406, 571, 1, 1, 2693.682, -4363.086, 279.9544, 3.38594, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4065) +(@OGUID+222 , 180406, 571, 1, 1, 2618.073, -4361.412, 283.4159, 4.956738, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4065) +(@OGUID+223 , 180406, 571, 1, 1, 2726.429, -4358.761, 281.7853, 1.134463, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4065) +(@OGUID+224 , 180406, 571, 1, 1, 2700.32, -4374.62, 280.271, 0.9599299, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4065) +(@OGUID+225 , 180406, 571, 1, 1, 2649.371, -4408.653, 290.186, 3.263772, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4018) +(@OGUID+226 , 180406, 571, 1, 1, 2376.891, -4990.313, 257.6985, 3.630291, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+227 , 180406, 571, 1, 1, 2377.773, -5054.615, 254.4842, 3.455756, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+228 , 180406, 571, 1, 1, 1854.089, -6015.621, 10.07462, 4.590216, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4060) +(@OGUID+229 , 180406, 571, 1, 1, 1934.119, -6111.237, 27.48708, 1.431168, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4060) +(@OGUID+230 , 180406, 571, 1, 1, 1835.864, -6089.984, 11.71504, 3.822273, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4060) +(@OGUID+231 , 180406, 571, 1, 1, 1917.503, -6158.714, 26.71446, 0.9773831, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4000) +(@OGUID+232 , 180406, 571, 1, 1, 1914.023, -6154.183, 26.71475, 4.101525, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4000) +(@OGUID+233 , 180406, 571, 1, 1, 1890.54, -6173.179, 23.86584, 2.792518, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4000) +(@OGUID+234 , 180406, 571, 1, 1, 496.4844, -4643.306, 253.2072, 1.343901, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+235 , 180406, 571, 1, 1, 424.201, -4690.684, 248.2388, 0.6283169, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3991) +(@OGUID+236 , 180406, 571, 1, 1, 499.7206, -4566.931, 248.0764, 1.727875, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3991) +(@OGUID+237 , 180406, 571, 1, 1, 411.8591, -4705.089, 229.9662, 1.413715, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3991) +(@OGUID+238 , 180406, 571, 1, 1, 440.6808, -4553.362, 245.5923, 5.67232, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3991) +(@OGUID+239 , 180406, 571, 1, 1, 367.8212, -4687.587, 250.9387, 5.707228, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3991) +(@OGUID+240 , 180406, 571, 1, 1, 337.9065, -4640.5, 252.0777, 5.096362, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3991) +(@OGUID+241 , 180406, 571, 1, 1, 322.0139, -4605.215, 237.0853, 5.393069, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3991) +(@OGUID+242 , 180406, 571, 1, 1, 393.0851, -4532.665, 250.5189, 0.2094394, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3991) +(@OGUID+243 , 180406, 571, 1, 1, 376.1369, -4496.113, 243.0968, 2.809975, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3991) +(@OGUID+244 , 180406, 571, 1, 1, 476.5408, -4503.842, 248.7666, 2.652894, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3991) +(@OGUID+245 , 180406, 571, 1, 1, 749.118, -2942.905, 14.74626, 3.263772, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3987) +(@OGUID+246 , 180406, 571, 1, 1, 809.5295, -2922.639, 7.219683, 5.131269, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3987) +(@OGUID+247 , 180406, 571, 1, 1, 737.8038, -2880.736, 12.96916, 1.169369, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3987) +(@OGUID+248 , 180406, 571, 1, 1, 773.0608, -2857.431, 4.171994, 1.361356, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3988) +(@OGUID+249 , 180406, 571, 1, 1, 1350.321, -3187.949, 164.0921, 2.426008, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+250 , 180406, 571, 1, 1, 1384.49, -3212.88, 164.9762, 0.9250238, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3998) +(@OGUID+251 , 180406, 571, 1, 1, 1383.839, -3200.095, 186.5387, 0.8203033, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3998) +(@OGUID+252 , 180406, 571, 1, 1, 1445.219, -3170.617, 170.5733, 1.186823, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3998) +(@OGUID+253 , 180406, 571, 1, 1, 1418.566, -3267.669, 165.7693, 4.572764, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3998) +(@OGUID+254 , 180406, 571, 1, 1, 1346.671, -3289.737, 174.4856, 4.852017, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3998) +(@OGUID+255 , 180406, 571, 1, 1, 1450.951, -3303.339, 174.5696, 3.38594, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3998) +(@OGUID+256 , 180406, 571, 1, 1, 652.8952, -5019.987, 9.652404, 5.427975, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3981) +(@OGUID+257 , 180406, 571, 1, 1, 592.6992, -4995.24, 8.920918, 3.769912, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3981) +(@OGUID+258 , 180406, 571, 1, 1, 575.4783, -4949.882, 18.02069, 5.515242, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3981) +(@OGUID+259 , 180406, 571, 1, 1, 540.7355, -4991.499, 13.16528, 1.553341, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3981) +(@OGUID+260 , 180406, 571, 1, 1, 568.0436, -5086.117, 8.824213, 1.518436, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 3981) +(@OGUID+261 , 180406, 571, 1, 1, 2464.109, -5036.51, 283.7771, 0.9599299, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4003) +(@OGUID+262 , 180406, 571, 1, 1, 2468.727, -5061.739, 283.3975, 5.393069, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4003) +(@OGUID+263 , 180406, 571, 1, 1, 2477.372, -5022.343, 286.6729, 5.846854, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4003) +(@OGUID+264 , 180406, 571, 1, 1, 2402.191, -5126.706, 280.6651, 0.4014249, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4003) +(@OGUID+265 , 180406, 571, 1, 1, 2439.455, -5132.638, 280.9637, 3.839725, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4003) +(@OGUID+266 , 180406, 571, 1, 1, 2501.871, -4993.182, 286.451, 2.984498, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4003) +(@OGUID+267 , 180406, 571, 1, 1, 3224.599, -659.952, 166.9673, 3.106652, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+268 , 180406, 571, 1, 1, 3201.955, -673.2883, 172.2883, 5.009095, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+269 , 180406, 571, 1, 1, 3209.774, -708.1309, 173.0541, 1.884953, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+270 , 180406, 571, 1, 1, 3267.898, -688.9091, 173.7409, 5.061456, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+271 , 180406, 571, 1, 1, 3240.571, -713.4294, 167.4516, 2.478367, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4186) +(@OGUID+272 , 180406, 571, 1, 1, 3296.688, -736.2324, 176.0992, 5.654869, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4186) +(@OGUID+273 , 180406, 571, 1, 1, 3280.63, -760.1717, 168.7784, 1.518436, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4186) +(@OGUID+274 , 180406, 571, 1, 1, 2552.256, -1990.83, 10.36751, 0.6108634, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4242) +(@OGUID+275 , 180406, 571, 1, 1, 2507.034, -1887.285, 12.20286, 3.438303, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4242) +(@OGUID+276 , 180406, 571, 1, 1, 2430.692, -1832.366, 3.701085, 0.6457717, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4242) +(@OGUID+277 , 180406, 571, 1, 1, 2478.468, -1812.107, 14.6144, 2.129301, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4242) +(@OGUID+278 , 180406, 571, 1, 1, 2595.189, -1786.51, 12.77725, 1.954769, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4242) +(@OGUID+279 , 180406, 571, 1, 1, 3799.054, -793.6374, 197.2281, 4.363324, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4177) +(@OGUID+280 , 180406, 571, 1, 1, 3848.534, -691.816, 225.1527, 1.186823, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4177) +(@OGUID+281 , 180406, 571, 1, 1, 3915.329, -690.8716, 242.072, 2.18166, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4177) +(@OGUID+282 , 180406, 571, 1, 1, 3669.287, -725.0473, 213.785, 1.902409, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4177) +(@OGUID+283 , 180406, 571, 1, 1, 3646.642, -722.6217, 226.0129, 3.438303, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4177) +(@OGUID+284 , 180406, 571, 1, 1, 3561.289, 246.9043, 47.2885, 4.049168, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4161) +(@OGUID+285 , 180406, 571, 1, 1, 3518.306, 281.8258, 47.28857, 1.553341, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4161) +(@OGUID+286 , 180406, 571, 1, 1, 3529.198, 287.327, 122.2979, 4.380776, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4161) +(@OGUID+287 , 180406, 571, 1, 1, 3569.296, 275.4532, 122.2979, 2.007128, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4161) +(@OGUID+288 , 180406, 571, 1, 1, 3555.43, 302.0915, 47.28843, 0.06981169, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4161) +(@OGUID+289 , 180406, 571, 1, 1, 3616.88, 268.3244, 52.26091, 2.670348, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4161) +(@OGUID+290 , 180406, 571, 1, 1, 3532.421, 255.4469, 122.2979, 5.829401, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4161) +(@OGUID+291 , 180406, 571, 1, 1, 3477.259, 278.0847, 52.25702, 5.846854, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4161) +(@OGUID+292 , 180406, 571, 1, 1, 2809.934, 900.2016, 21.38731, 1.745327, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4152) +(@OGUID+293 , 180406, 571, 1, 1, 2776.956, 897.387, 14.16927, 0.06981169, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4152) +(@OGUID+294 , 180406, 571, 1, 1, 2735.234, 880.1124, 6.758276, 3.961899, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4152) +(@OGUID+295 , 180406, 571, 1, 1, 2714.933, 887.4085, 4.232737, 5.619962, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4152) +(@OGUID+296 , 180406, 571, 1, 1, 3501.767, 1985.325, 65.36996, 3.455756, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4158) +(@OGUID+297 , 180406, 571, 1, 1, 3488.581, 1995.478, 64.86234, 4.729844, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4158) +(@OGUID+298 , 180406, 571, 1, 1, 3506.409, 2022.095, 64.86234, 3.892087, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4158) +(@OGUID+299 , 180406, 571, 1, 1, 3534.448, 1993.511, 65.57285, 0.4886912, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4158) +(@OGUID+300 , 180406, 571, 1, 1, 3533.5, 2028.148, 67.83711, 1.797689, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4158) +(@OGUID+301 , 180406, 571, 1, 1, 3797.447, 1625.543, 91.86301, 1.029743, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+302 , 180406, 571, 1, 1, 3811.2, 1676.326, 116.9827, 3.054327, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+303 , 180406, 571, 1, 1, 3826.005, 1580.641, 86.69843, 5.113817, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4165) +(@OGUID+304 , 180406, 571, 1, 1, 3792.57, 1555.635, 90.08284, 5.794494, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4165) +(@OGUID+305 , 180406, 571, 1, 1, 3892.407, 1621.969, 93.93169, 2.775069, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4165) +(@OGUID+306 , 180406, 571, 1, 1, 3763.325, 1539.438, 87.04325, 5.550147, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4165) +(@OGUID+307 , 180406, 571, 1, 1, 3857.26, 1532.173, 95.70817, 3.525572, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4165) +(@OGUID+308 , 180406, 571, 1, 1, 3825.578, 1499.48, 91.71698, 3.316144, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4165) +(@OGUID+309 , 180406, 571, 1, 1, 3839.292, 1480.273, 92.05128, 4.171338, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4165) +(@OGUID+310 , 180406, 571, 1, 1, 3854.936, 1480.276, 92.05779, 4.049168, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4165) +(@OGUID+311 , 180406, 571, 1, 1, 8436.645, -338.5753, 906.6075, 1.134463, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4436) +(@OGUID+312 , 180406, 571, 1, 1, 8420.556, -342.8851, 910.7804, 1.151916, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4484) +(@OGUID+313 , 180406, 571, 1, 1, 8412.648, -351.5258, 910.7804, 1.151916, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4484) +(@OGUID+314 , 180406, 571, 1, 1, 7834.21, -795.5672, 1183.377, 1.745327, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+315 , 180406, 571, 1, 1, 7764.518, -2819.573, 1220.469, 1.500983, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+316 , 180406, 571, 1, 1, 7791.312, -2800.402, 1221.756, 0.2268925, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+317 , 180406, 571, 1, 1, 7808.44, -2839.265, 1226.409, 5.235988, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+318 , 180406, 571, 1, 1, 7856.201, -2797.805, 1145.121, 1.361356, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4441) +(@OGUID+319 , 180406, 571, 1, 1, 7797.143, -2902.636, 1248.202, 1.797689, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4441) +(@OGUID+320 , 180406, 571, 1, 1, 7817.669, -2875.495, 1238.228, 4.625124, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4441) +(@OGUID+321 , 180406, 571, 1, 1, 7827.663, -2901.533, 1246.536, 5.445428, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4441) +(@OGUID+322 , 180406, 571, 1, 1, 7797.608, -2953.877, 1257.636, 2.740162, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4441) +(@OGUID+323 , 180406, 571, 1, 1, 7834.471, -2989.303, 1265.23, 4.24115, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4441) +(@OGUID+324 , 180406, 571, 1, 1, 6185.55, -1068.802, 417.2573, 2.91469, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4419) +(@OGUID+325 , 180406, 571, 1, 1, 6137.813, -1086.493, 412.2495, 3.769912, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4419) +(@OGUID+326 , 180406, 571, 1, 1, 6120.12, -1075.182, 411.8575, 3.33359, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4419) +(@OGUID+327 , 180406, 571, 1, 1, 6128.455, -1024.129, 414.0439, 3.822273, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4419) +(@OGUID+328 , 180406, 571, 1, 1, 6102.482, -1047.252, 413.5006, 3.892087, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4419) +(@OGUID+329 , 180406, 571, 1, 1, 6659.226, -249.2723, 962.2037, 6.161013, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4428) +(@OGUID+330 , 180406, 571, 1, 1, 6654.979, -197.8785, 952.4429, 1.710422, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4428) +(@OGUID+331 , 180406, 571, 1, 1, 6681.767, -266.9733, 961.7059, 4.852017, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4428) +(@OGUID+332 , 180406, 571, 1, 1, 5540.28, 5732.585, -75.04021, 5.288348, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4285) +(@OGUID+333 , 180406, 571, 1, 1, 5595.533, 5770.859, -71.57546, 2.583081, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4285) +(@OGUID+334 , 180406, 571, 1, 1, 5611.217, 5824.185, -67.32271, 5.777041, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4285) +(@OGUID+335 , 180406, 571, 1, 1, 5515.897, 4742.963, -194.0693, 5.288348, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4290) +(@OGUID+336 , 180406, 571, 1, 1, 5490.307, 4729.871, -194.7691, 3.141593, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4290) +(@OGUID+337 , 180406, 571, 1, 1, 4483.99, 5693.269, 84.82285, 6.161013, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4123) +(@OGUID+338 , 180406, 571, 1, 1, 4499.713, 5716.173, 84.6351, 3.630291, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4122) +(@OGUID+339 , 180406, 571, 1, 1, 4518.85, 5706.549, 82.58364, 4.520406, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4122) +(@OGUID+340 , 180406, 571, 1, 1, 4121.668, 5281.876, 25.64887, 0.4537851, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4108) +(@OGUID+341 , 180406, 571, 1, 1, 4040.769, 5277.135, 27.53135, 2.146753, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4108) +(@OGUID+342 , 180406, 571, 1, 1, 4131.17, 5250.665, 28.56509, 2.897245, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4108) +(@OGUID+343 , 180406, 571, 1, 1, 2903.725, 6231.557, 208.8394, 5.148723, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4020) +(@OGUID+344 , 180406, 571, 1, 1, 2931.82, 6242.545, 214.88, 4.921829, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4020) +(@OGUID+345 , 180406, 571, 1, 1, 2836.468, 6174.838, 124.0885, 5.305802, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4129) +(@OGUID+346 , 180406, 571, 1, 1, 2789.779, 6148.222, 86.61843, 2.408554, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4129) +(@OGUID+347 , 180406, 571, 1, 1, 2255.002, 5225.886, 14.71353, 1.850049, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4032) +(@OGUID+348 , 180406, 571, 1, 1, 2238.76, 5180.222, 14.71353, 1.919862, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4032) +(@OGUID+349 , 180406, 571, 1, 1, 2230.155, 5147.772, 6.842682, 1.53589, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4032) +(@OGUID+350 , 180406, 571, 1, 1, 3007.184, 4071.53, 37.50875, 3.33359, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4113) +(@OGUID+351 , 180406, 571, 1, 1, 2982.732, 4080.248, 26.95294, 2.740162, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4113) +(@OGUID+352 , 180406, 571, 1, 1, 2911.799, 4046.192, 1.700204, 1.850049, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4113) +(@OGUID+353 , 180406, 571, 1, 1, 2845.697, 4021.456, 5.048532, 3.874631, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4113) +(@OGUID+354 , 180406, 571, 1, 1, 3395.545, 4103.316, 30.25075, 6.0912, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+355 , 180406, 571, 1, 1, 3426.093, 4154.369, 31.73266, 0.2617982, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+356 , 180406, 571, 1, 1, 3380.001, 4144.935, 31.45782, 4.520406, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 0) +(@OGUID+357 , 180406, 571, 1, 1, 3466.665, 4145.107, 17.19302, 6.143561, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4043) +(@OGUID+358 , 180406, 571, 1, 1, 3482.742, 4135.432, 30.13783, 2.286379, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4043) +(@OGUID+359 , 180406, 571, 1, 1, 3459.587, 4199.699, 18.93058, 0.9250238, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4043) +(@OGUID+360 , 180406, 571, 1, 1, 3446.437, 4083.459, 26.36699, 3.508117, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4043) +(@OGUID+361 , 180406, 571, 1, 1, 3490.993, 4093.242, 27.72779, 3.560473, 0, 0, 0, 1, 120, 255, 1), -- 180406 (Area: 4043) +(@OGUID+362 , 180407, 571, 1, 1, 5186.266, -2193.768, 239.013, 3.42085, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+363 , 180407, 571, 1, 1, 5170.956, -2174.502, 236.5384, 0.1047193, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+364 , 180407, 571, 1, 1, 5131.898, -2198.527, 238.9261, 2.146753, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+365 , 180407, 571, 1, 1, 5118.4, -2225.201, 241.3221, 1.954769, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4317) +(@OGUID+366 , 180407, 571, 1, 1, 5410.509, -2652.607, 306.231, 5.410522, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4275) +(@OGUID+367 , 180407, 571, 1, 1, 5467.847, -2615.898, 312.4956, 5.742135, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4275) +(@OGUID+368 , 180407, 571, 1, 1, 5500.174, -2659.385, 303.9539, 1.850049, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4275) +(@OGUID+369 , 180407, 571, 1, 1, 5536.58, -2608.138, 304.0076, 1.867502, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4275) +(@OGUID+370 , 180407, 571, 1, 1, 5524.991, -2578.385, 303.9539, 6.230826, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4275) +(@OGUID+371 , 180407, 571, 1, 1, 5744.013, -3556, 386.8233, 1.727875, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+372 , 180407, 571, 1, 1, 5773.413, -3601.402, 386.8242, 3.839725, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4323) +(@OGUID+373 , 180407, 571, 1, 1, 5769.374, -3630.634, 386.852, 2.303831, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4323) +(@OGUID+374 , 180407, 571, 1, 1, 4578.956, -4263.669, 182.3578, 0.01745246, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+375 , 180407, 571, 1, 1, 3866.024, -4556.092, 217.1811, 0.9948372, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+376 , 180407, 571, 1, 1, 3839.12, -4556.077, 215.6738, 2.932139, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+377 , 180407, 571, 1, 1, 3876.9, -4547.333, 210.9542, 4.729844, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+378 , 180407, 571, 1, 1, 3834.391, -4523.571, 216.3354, 0.9948372, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+379 , 180407, 571, 1, 1, 3845.775, -4506.957, 213.2268, 3.68265, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4211) +(@OGUID+380 , 180407, 571, 1, 1, 4503.457, -4238.322, 166.302, 4.76475, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+381 , 180407, 571, 1, 1, 4553.079, -4233.049, 170.7654, 5.026549, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+382 , 180407, 571, 1, 1, 4591.484, -4252.421, 181.7474, 4.380776, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4159) +(@OGUID+383 , 180407, 571, 1, 1, 3419.264, -2808.972, 201.4093, 1.675514, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+384 , 180407, 571, 1, 1, 3428.19, -2778.842, 263.1267, 2.373644, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+385 , 180407, 571, 1, 1, 3361.911, -2812.032, 198.3222, 5.794494, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+386 , 180407, 571, 1, 1, 3414.363, -2778.031, 201.5204, 0.9948372, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+387 , 180407, 571, 1, 1, 3429.28, -2746.916, 199.4592, 0.2617982, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4204) +(@OGUID+388 , 180407, 571, 1, 1, 3249.329, -2372.51, 129.9958, 3.298687, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4217) +(@OGUID+389 , 180407, 571, 1, 1, 3309.994, -2284.978, 114.9895, 4.258607, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4248) +(@OGUID+390 , 180407, 571, 1, 1, 3195.763, -2280.448, 110.7325, 1.780234, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4248) +(@OGUID+391 , 180407, 571, 1, 1, 3239.406, -2232.858, 121.1309, 6.213374, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4206) +(@OGUID+392 , 180407, 571, 1, 1, 3297.919, -2236.022, 120.9063, 4.66003, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4206) +(@OGUID+393 , 180407, 571, 1, 1, 3312.651, -2213.69, 115.9192, 1.378809, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4206) +(@OGUID+394 , 180407, 571, 1, 1, 3358.979, -2188.361, 123.8899, 2.146753, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4206) +(@OGUID+395 , 180407, 571, 1, 1, 2697.765, -4328.043, 291.2906, 5.305802, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4065) +(@OGUID+396 , 180407, 571, 1, 1, 2662.834, -4358.088, 279.7958, 0.7155849, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4065) +(@OGUID+397 , 180407, 571, 1, 1, 2618.055, -4371.507, 283.3527, 5.061456, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4065) +(@OGUID+398 , 180407, 571, 1, 1, 2710.088, -4371.438, 278.8264, 1.082103, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4065) +(@OGUID+399 , 180407, 571, 1, 1, 2670.709, -4408.632, 290.6959, 4.031712, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4018) +(@OGUID+400 , 180407, 571, 1, 1, 2382.453, -5014.535, 254.0956, 0.4014249, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+401 , 180407, 571, 1, 1, 2385.039, -5056.534, 253.5052, 3.769912, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+402 , 180407, 571, 1, 1, 1924.839, -6128.684, 27.42144, 1.867502, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4060) +(@OGUID+403 , 180407, 571, 1, 1, 1846.395, -6081.321, 11.3513, 4.276057, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4060) +(@OGUID+404 , 180407, 571, 1, 1, 1929.122, -6143.407, 26.77677, 4.206246, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4000) +(@OGUID+405 , 180407, 571, 1, 1, 1893.114, -6154.604, 27.42172, 2.722713, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4000) +(@OGUID+406 , 180407, 571, 1, 1, 1890.457, -6159.884, 27.42142, 6.248279, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4000) +(@OGUID+407 , 180407, 571, 1, 1, 485.1177, -4663.222, 253.1473, 0.9599299, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+408 , 180407, 571, 1, 1, 496.8085, -4602.353, 249.5994, 1.902409, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+409 , 180407, 571, 1, 1, 401, -4688.146, 248.2407, 0.5759573, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 3991) +(@OGUID+410 , 180407, 571, 1, 1, 399.7902, -4712.554, 231.7376, 1.308995, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 3991) +(@OGUID+411 , 180407, 571, 1, 1, 389.0826, -4503.428, 242.6498, 3.019413, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 3991) +(@OGUID+412 , 180407, 571, 1, 1, 388.3697, -4480.479, 233.2288, 2.722713, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 3991) +(@OGUID+413 , 180407, 571, 1, 1, 490.7223, -4521.801, 248.6068, 2.775069, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 3991) +(@OGUID+414 , 180407, 571, 1, 1, 756.3785, -2948.583, 15.57896, 2.705255, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 3987) +(@OGUID+415 , 180407, 571, 1, 1, 769.6545, -2921.345, 12.84954, 4.101525, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 3987) +(@OGUID+416 , 180407, 571, 1, 1, 731.8281, -2922.661, 7.247694, 2.129301, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 3987) +(@OGUID+417 , 180407, 571, 1, 1, 801.8958, -2922.491, 17.85299, 5.811947, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 3987) +(@OGUID+418 , 180407, 571, 1, 1, 1346.989, -3181.646, 164.0921, 2.408554, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+419 , 180407, 571, 1, 1, 1366.228, -3171.427, 164.0921, 5.619962, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+420 , 180407, 571, 1, 1, 1434.518, -3152.928, 167.3012, 5.707228, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 3998) +(@OGUID+421 , 180407, 571, 1, 1, 1384.498, -3242.309, 168.7519, 0.2094394, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 3998) +(@OGUID+422 , 180407, 571, 1, 1, 1423.141, -3262.486, 181.0846, 4.433136, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 3998) +(@OGUID+423 , 180407, 571, 1, 1, 1461.795, -3320.668, 174.4624, 1.692969, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 3998) +(@OGUID+424 , 180407, 571, 1, 1, 637.7101, -5010.153, 4.615479, 5.253442, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 3981) +(@OGUID+425 , 180407, 571, 1, 1, 574.2803, -4943.381, 32.46601, 5.375615, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 3981) +(@OGUID+426 , 180407, 571, 1, 1, 592.1497, -5042.62, 6.364627, 0.7853968, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 3981) +(@OGUID+427 , 180407, 571, 1, 1, 519.3365, -4952.292, 32.97431, 1.343901, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 3981) +(@OGUID+428 , 180407, 571, 1, 1, 611.5425, -5094.039, 8.544552, 5.829401, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 3981) +(@OGUID+429 , 180407, 571, 1, 1, 2413.909, -5123.429, 280.2519, 0.6632232, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4003) +(@OGUID+430 , 180407, 571, 1, 1, 2429.419, -5167.8, 277.2554, 3.612838, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4003) +(@OGUID+431 , 180407, 571, 1, 1, 2446.935, -5152.328, 280.9121, 0.7853968, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4003) +(@OGUID+432 , 180407, 571, 1, 1, 2475.557, -5077.68, 282.9327, 5.009095, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4003) +(@OGUID+433 , 180407, 571, 1, 1, 2556.758, -5010.462, 293.3214, 4.171338, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4003) +(@OGUID+434 , 180407, 571, 1, 1, 2488.596, -5032.713, 286.0028, 5.98648, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4003) +(@OGUID+435 , 180407, 571, 1, 1, 3216.365, -654.7118, 173.1727, 2.652894, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+436 , 180407, 571, 1, 1, 3202.009, -689.5071, 172.0019, 1.431168, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+437 , 180407, 571, 1, 1, 3228.639, -707.2554, 167.6969, 2.635444, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+438 , 180407, 571, 1, 1, 3266.271, -712.002, 172.5156, 5.742135, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4186) +(@OGUID+439 , 180407, 571, 1, 1, 3269.517, -726.0446, 169.1231, 0.7679439, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4186) +(@OGUID+440 , 180407, 571, 1, 1, 2567.745, -1931.37, 3.347648, 1.902409, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4242) +(@OGUID+441 , 180407, 571, 1, 1, 2535.844, -2001.418, 10.57551, 0.8726639, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4242) +(@OGUID+442 , 180407, 571, 1, 1, 2513.919, -1892.11, 12.3828, 0.383971, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4242) +(@OGUID+443 , 180407, 571, 1, 1, 2499.634, -1811.967, 22.76959, 5.218536, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4242) +(@OGUID+444 , 180407, 571, 1, 1, 3794.182, -798.6522, 196.8896, 4.084071, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4177) +(@OGUID+445 , 180407, 571, 1, 1, 3934.507, -711.8297, 242.3191, 3.106652, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4177) +(@OGUID+446 , 180407, 571, 1, 1, 3718.244, -692.4291, 215.5753, 5.951575, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4177) +(@OGUID+447 , 180407, 571, 1, 1, 3670.186, -714.9221, 213.7414, 1.902409, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4177) +(@OGUID+448 , 180407, 571, 1, 1, 3655.985, -670.6024, 233.3351, 1.553341, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4177) +(@OGUID+449 , 180407, 571, 1, 1, 3564.145, 205.2086, 52.22747, 6.021387, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4254) +(@OGUID+450 , 180407, 571, 1, 1, 3549.064, 250.287, 122.2979, 0.4537851, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4161) +(@OGUID+451 , 180407, 571, 1, 1, 3572.962, 287.3582, 47.28861, 5.550147, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4161) +(@OGUID+452 , 180407, 571, 1, 1, 3520.549, 258.9889, 47.28859, 2.408554, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4161) +(@OGUID+453 , 180407, 571, 1, 1, 3614.126, 292.0934, 52.2594, 1.308995, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4161) +(@OGUID+454 , 180407, 571, 1, 1, 3561.172, 290.9487, 122.2979, 2.844883, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4161) +(@OGUID+455 , 180407, 571, 1, 1, 3551.001, 343.66, 52.22747, 4.34587, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4161) +(@OGUID+456 , 180407, 571, 1, 1, 2786.32, 920.1965, 22.35873, 0.1396245, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4152) +(@OGUID+457 , 180407, 571, 1, 1, 2790.073, 894.4512, 14.68251, 0, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4152) +(@OGUID+458 , 180407, 571, 1, 1, 2742.038, 884.5179, 6.728371, 4.01426, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4152) +(@OGUID+459 , 180407, 571, 1, 1, 3493.868, 2016.275, 64.86234, 0.5759573, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4158) +(@OGUID+460 , 180407, 571, 1, 1, 3512.788, 1992.762, 64.86221, 5.078908, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4158) +(@OGUID+461 , 180407, 571, 1, 1, 3519.225, 1980.357, 64.9095, 1.640607, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4158) +(@OGUID+462 , 180407, 571, 1, 1, 3509.91, 2013.012, 64.87511, 2.111848, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4158) +(@OGUID+463 , 180407, 571, 1, 1, 3513.616, 2026.584, 65.0184, 3.892087, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4158) +(@OGUID+464 , 180407, 571, 1, 1, 3792.06, 1680.653, 117.8903, 3.246347, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+465 , 180407, 571, 1, 1, 3771.654, 1604.742, 90.19121, 1.989672, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4165) +(@OGUID+466 , 180407, 571, 1, 1, 3876.597, 1645.691, 96.41532, 2.513274, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4165) +(@OGUID+467 , 180407, 571, 1, 1, 3835.953, 1580.846, 86.69843, 1.954769, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4165) +(@OGUID+468 , 180407, 571, 1, 1, 3798.435, 1543.227, 90.20327, 5.98648, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4165) +(@OGUID+469 , 180407, 571, 1, 1, 3826.736, 1532.038, 95.74288, 3.57793, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4165) +(@OGUID+470 , 180407, 571, 1, 1, 3772.262, 1518.21, 87.58628, 5.445428, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4165) +(@OGUID+471 , 180407, 571, 1, 1, 3845.135, 1480.392, 92.04202, 2.91469, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4165) +(@OGUID+472 , 180407, 571, 1, 1, 3829.847, 1480.661, 92.05907, 2.478367, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4165) +(@OGUID+473 , 180407, 571, 1, 1, 7849.781, -777.4718, 1180.518, 3.804818, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+474 , 180407, 571, 1, 1, 7769.292, -2813.385, 1219.706, 1.832595, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+475 , 180407, 571, 1, 1, 7798.998, -2801.392, 1221.274, 5.93412, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+476 , 180407, 571, 1, 1, 7816.222, -2886.335, 1241.734, 5.061456, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4441) +(@OGUID+477 , 180407, 571, 1, 1, 7800.365, -2891.346, 1244.112, 1.780234, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4441) +(@OGUID+478 , 180407, 571, 1, 1, 7815.249, -2847.6, 1226.733, 5.794494, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4441) +(@OGUID+479 , 180407, 571, 1, 1, 7815.913, -2922.443, 1253.22, 3.909541, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4441) +(@OGUID+480 , 180407, 571, 1, 1, 7823.335, -2991.151, 1264.953, 4.01426, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4441) +(@OGUID+481 , 180407, 571, 1, 1, 6188.896, -1062.919, 409.9726, 3.612838, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4419) +(@OGUID+482 , 180407, 571, 1, 1, 6160.541, -1068.3, 414.0189, 5.148723, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4419) +(@OGUID+483 , 180407, 571, 1, 1, 6122.874, -1074.873, 409.5521, 3.47321, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4419) +(@OGUID+484 , 180407, 571, 1, 1, 6130.21, -1071.851, 402.8137, 3.700105, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4419) +(@OGUID+485 , 180407, 571, 1, 1, 6129.499, -1046.194, 413.8744, 5.93412, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4419) +(@OGUID+486 , 180407, 571, 1, 1, 6111.876, -1089.197, 404.6797, 1.850049, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4419) +(@OGUID+487 , 180407, 571, 1, 1, 6111.486, -1046.028, 413.9368, 0.9250238, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4419) +(@OGUID+488 , 180407, 571, 1, 1, 6089.37, -1063.561, 413.63, 1.937312, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4419) +(@OGUID+489 , 180407, 571, 1, 1, 6651.599, -247.5624, 962.2744, 0.1396245, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+490 , 180407, 571, 1, 1, 6660.406, -183.2028, 954.8659, 6.143561, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4428) +(@OGUID+491 , 180407, 571, 1, 1, 5578.406, 5763.015, -75.20139, 1.378809, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4285) +(@OGUID+492 , 180407, 571, 1, 1, 5608.686, 5805.967, -70.46122, 3.106652, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4285) +(@OGUID+493 , 180407, 571, 1, 1, 5591.252, 5728.178, -71.99928, 5.899214, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4284) +(@OGUID+494 , 180407, 571, 1, 1, 5480.453, 4743.266, -196.4773, 1.902409, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4290) +(@OGUID+495 , 180407, 571, 1, 1, 5521.717, 4750.083, -188.2182, 5.235988, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4290) +(@OGUID+496 , 180407, 571, 1, 1, 5500.287, 4733.095, -194.4314, 4.956738, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4290) +(@OGUID+497 , 180407, 571, 1, 1, 4169.929, 5290.662, 28.58986, 5.323256, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4108) +(@OGUID+498 , 180407, 571, 1, 1, 4089.737, 5249.827, 25.98461, 3.159062, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4108) +(@OGUID+499 , 180407, 571, 1, 1, 4030.189, 5336.436, 27.57404, 3.42085, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4108) +(@OGUID+500 , 180407, 571, 1, 1, 4190.916, 5221.139, 27.44952, 4.223697, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4108) +(@OGUID+501 , 180407, 571, 1, 1, 2888.924, 6248.153, 208.8295, 0.122173, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4020) +(@OGUID+502 , 180407, 571, 1, 1, 2265.474, 5199.011, 26.29611, 4.747296, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4032) +(@OGUID+503 , 180407, 571, 1, 1, 2272.925, 5219.881, 13.58492, 4.642576, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4032) +(@OGUID+504 , 180407, 571, 1, 1, 2250.998, 5164.212, 14.44375, 4.590216, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4032) +(@OGUID+505 , 180407, 571, 1, 1, 3023.779, 4059.767, 26.16735, 2.722713, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4113) +(@OGUID+506 , 180407, 571, 1, 1, 2915.491, 4041.218, 1.718314, 2.862335, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4113) +(@OGUID+507 , 180407, 571, 1, 1, 2878.346, 4033.684, 5.24339, 2.408554, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4113) +(@OGUID+508 , 180407, 571, 1, 1, 2841.972, 4030.163, 5.0511, 0.8203033, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4113) +(@OGUID+509 , 180407, 571, 1, 1, 3378.039, 4127.827, 30.85807, 5.166176, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+510 , 180407, 571, 1, 1, 3410.067, 4095.503, 30.58323, 2.809975, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+511 , 180407, 571, 1, 1, 3409.243, 4154.036, 31.87858, 3.316144, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 0) +(@OGUID+512 , 180407, 571, 1, 1, 3477.146, 4149.458, 28.31626, 2.18166, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4043) +(@OGUID+513 , 180407, 571, 1, 1, 3458.126, 4079.161, 26.78951, 0.7330382, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4043) +(@OGUID+514 , 180407, 571, 1, 1, 3496.528, 4108.67, 28.63537, 1.867502, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4043) +(@OGUID+515 , 180407, 571, 1, 1, 3474.94, 4199.34, 18.7451, 3.630291, 0, 0, 0, 1, 120, 255, 1), -- 180407 (Area: 4043) +(@OGUID+516 , 180408, 571, 1, 1, 5764.419, -3572.029, 400.4677, 2.967041, 0, 0, 0, 1, 120, 255, 1), -- 180408 (Area: 4323) +(@OGUID+517 , 180408, 571, 1, 1, 5796.51, -3596.129, 396.4, 4.537859, 0, 0, 0, 1, 120, 255, 1), -- 180408 (Area: 4323) +(@OGUID+518 , 180408, 571, 1, 1, 3874.124, -4526.177, 220.1032, 3.054327, 0, 0, 0, 1, 120, 255, 1), -- 180408 (Area: 0) +(@OGUID+519 , 180408, 571, 1, 1, 3839.224, -4546.804, 217.41, 2.35619, 0, 0, 0, 1, 120, 255, 1), -- 180408 (Area: 0) +(@OGUID+520 , 180408, 571, 1, 1, 3874.079, -4498.493, 223.8581, 5.270896, 0, 0, 0, 1, 120, 255, 1), -- 180408 (Area: 4211) +(@OGUID+521 , 180408, 571, 1, 1, 3256.49, -2269.653, 114.1506, 2.844883, 0, 0, 0, 1, 120, 255, 1), -- 180408 (Area: 4248) +(@OGUID+522 , 180408, 571, 1, 1, 3517.16, 2000.169, 64.86235, 2.44346, 0, 0, 0, 1, 120, 255, 1), -- 180408 (Area: 4158) +(@OGUID+523 , 180408, 571, 1, 1, 8478.776, -335.0133, 907.4905, 4.502952, 0, 0, 0, 1, 120, 255, 1), -- 180408 (Area: 4436) +(@OGUID+524 , 180408, 571, 1, 1, 5547.182, 5734.344, -70.37753, 3.892087, 0, 0, 0, 1, 120, 255, 1), -- 180408 (Area: 4285) +(@OGUID+525 , 180408, 571, 1, 1, 5570.323, 5767.202, -65.55209, 1.466076, 0, 0, 0, 1, 120, 255, 1), -- 180408 (Area: 4285) +(@OGUID+526 , 180408, 571, 1, 1, 5590.967, 5749.478, -66.40426, 4.904376, 0, 0, 0, 1, 120, 255, 1), -- 180408 (Area: 4285) +(@OGUID+527 , 180408, 571, 1, 1, 4146.889, 5330.113, 33.63815, 3.909541, 0, 0, 0, 1, 120, 255, 1), -- 180408 (Area: 4108) +(@OGUID+528 , 180408, 571, 1, 1, 4154.61, 5340.539, 33.98043, 3.926996, 0, 0, 0, 1, 120, 255, 1), -- 180408 (Area: 4108) +(@OGUID+529 , 180408, 571, 1, 1, 4136.229, 5321.447, 33.53545, 3.68265, 0, 0, 0, 1, 120, 255, 1), -- 180408 (Area: 4108) +(@OGUID+530 , 180408, 571, 1, 1, 4119.863, 5304.662, 33.65726, 3.961899, 0, 0, 0, 1, 120, 255, 1), -- 180408 (Area: 4108) +(@OGUID+531 , 180408, 571, 1, 1, 4248.604, 5256.001, 76.13831, 4.031712, 0, 0, 0, 1, 120, 255, 1), -- 180408 (Area: 4108) +(@OGUID+532 , 180408, 571, 1, 1, 2923.913, 6238.717, 208.8952, 3.508117, 0, 0, 0, 1, 120, 255, 1), -- 180408 (Area: 4020) +(@OGUID+533 , 180408, 571, 1, 1, 2925.917, 6235.095, 216.3796, 3.944446, 0, 0, 0, 1, 120, 255, 1), -- 180408 (Area: 4020) +(@OGUID+534 , 180408, 571, 1, 1, 2927.372, 6251.385, 216.4442, 5.515242, 0, 0, 0, 1, 120, 255, 1), -- 180408 (Area: 4020) +(@OGUID+535 , 180410, 571, 1, 1, 5194.279, -2203.303, 239.6697, 3.57793, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 0) +(@OGUID+536 , 180410, 571, 1, 1, 5797.013, -3553.729, 387.8808, 3.211419, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4323) +(@OGUID+537 , 180410, 571, 1, 1, 5778.559, -3600.916, 387.5585, 1.483528, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4323) +(@OGUID+538 , 180410, 571, 1, 1, 3876.448, -4523.802, 218.1476, 2.059488, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 0) +(@OGUID+539 , 180410, 571, 1, 1, 4524.988, -4220.689, 171.5719, 5.98648, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 0) +(@OGUID+540 , 180410, 571, 1, 1, 4546.035, -4198.64, 174.7062, 3.124123, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4159) +(@OGUID+541 , 180410, 571, 1, 1, 4609.126, -4233.917, 181.1064, 3.106652, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4159) +(@OGUID+542 , 180410, 571, 1, 1, 4524.569, -4165.339, 174.2671, 5.951575, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4159) +(@OGUID+543 , 180410, 571, 1, 1, 3416.599, -2799.829, 203.2782, 2.286379, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 0) +(@OGUID+544 , 180410, 571, 1, 1, 3402.456, -2806.774, 203.5183, 3.926996, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 0) +(@OGUID+545 , 180410, 571, 1, 1, 3422.075, -2795.796, 203.1454, 2.251473, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 0) +(@OGUID+546 , 180410, 571, 1, 1, 3259.209, -2267.978, 114.4671, 1.937312, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4248) +(@OGUID+547 , 180410, 571, 1, 1, 3220.739, -2298.016, 108.4389, 0.7330382, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4248) +(@OGUID+548 , 180410, 571, 1, 1, 3263.73, -2264.506, 114.3535, 2.740162, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4248) +(@OGUID+549 , 180410, 571, 1, 1, 3252.173, -2171.068, 118.6485, 0.3490652, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4206) +(@OGUID+550 , 180410, 571, 1, 1, 3306.331, -2180.179, 118.5948, 3.630291, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4206) +(@OGUID+551 , 180410, 571, 1, 1, 1427.057, -3270.854, 169.2964, 0.9250238, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 3998) +(@OGUID+552 , 180410, 571, 1, 1, 590.5975, -4936.698, 30.04726, 3.403396, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 3981) +(@OGUID+553 , 180410, 571, 1, 1, 602.3406, -4924.361, 18.96176, 3.403396, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 3981) +(@OGUID+554 , 180410, 571, 1, 1, 601.4332, -4918.563, 31.67034, 4.921829, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 3981) +(@OGUID+555 , 180410, 571, 1, 1, 595.7699, -4919.979, 31.67729, 4.97419, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 3981) +(@OGUID+556 , 180410, 571, 1, 1, 580.9988, -4922.641, 19.96896, 4.921829, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 3981) +(@OGUID+557 , 180410, 571, 1, 1, 2487.015, -5066.922, 286.3527, 3.001947, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4003) +(@OGUID+558 , 180410, 571, 1, 1, 3658.518, -702.5648, 216.069, 4.502952, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4177) +(@OGUID+559 , 180410, 571, 1, 1, 3649.671, -718.9785, 226.6098, 1.308995, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4177) +(@OGUID+560 , 180410, 571, 1, 1, 3655.556, -719.8813, 226.5605, 1.518436, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4177) +(@OGUID+561 , 180410, 571, 1, 1, 3633.41, -715.426, 216.1156, 6.161013, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4177) +(@OGUID+562 , 180410, 571, 1, 1, 6677.345, -199.9435, 951.5283, 3.351047, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4428) +(@OGUID+563 , 180410, 571, 1, 1, 5534.461, 5748.173, -78.80743, 0.3141584, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4285) +(@OGUID+564 , 180410, 571, 1, 1, 2817.708, 6157.477, 87.63675, 3.874631, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4129) +(@OGUID+565 , 180410, 571, 1, 1, 2805.012, 6172.209, 87.67882, 3.822273, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4129) +(@OGUID+566 , 180410, 571, 1, 1, 2807.23, 6169.249, 87.58257, 3.717554, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4129) +(@OGUID+567 , 180410, 571, 1, 1, 2820.371, 6154.916, 87.65291, 3.787367, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4129) +(@OGUID+568 , 180410, 571, 1, 1, 2808.551, 6134.94, 87.93844, 2.321287, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4129) +(@OGUID+569 , 180410, 571, 1, 1, 2274.451, 5201.288, 13.85912, 6.021387, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4032) +(@OGUID+570 , 180410, 571, 1, 1, 2279.471, 5208.015, 23.90492, 4.276057, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4032) +(@OGUID+571 , 180410, 571, 1, 1, 2272.099, 5192.15, 12.74661, 1.099556, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4032) +(@OGUID+572 , 180410, 571, 1, 1, 2284.942, 5205.83, 24.19367, 4.293513, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4032) +(@OGUID+573 , 180410, 571, 1, 1, 2291.187, 5207.434, 24.68394, 4.276057, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4032) +(@OGUID+574 , 180410, 571, 1, 1, 2297.049, 5205.213, 23.75366, 4.363324, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4032) +(@OGUID+575 , 180410, 571, 1, 1, 2271.727, 5181.195, 21.453, 1.169369, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4032) +(@OGUID+576 , 180410, 571, 1, 1, 2302.244, 5203.075, 24.58699, 4.293513, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4032) +(@OGUID+577 , 180410, 571, 1, 1, 3460.282, 4177.789, 22.23072, 4.729844, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4043) +(@OGUID+578 , 180410, 571, 1, 1, 3468.992, 4177.352, 22.22953, 4.607672, 0, 0, 0, 1, 120, 255, 1), -- 180410 (Area: 4043) +(@OGUID+579 , 180411, 571, 1, 1, 5438.724, -2610.023, 317.467, 1.326448, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4275) +(@OGUID+580 , 180411, 571, 1, 1, 5464.751, -2610.872, 317.4325, 1.97222, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4275) +(@OGUID+581 , 180411, 571, 1, 1, 3410.139, -2792.103, 205.9287, 5.846854, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 0) +(@OGUID+582 , 180411, 571, 1, 1, 3416.794, -2787.165, 206.333, 3.176533, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 0) +(@OGUID+583 , 180411, 571, 1, 1, 3452.579, -2745.875, 191.9798, 3.38594, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4204) +(@OGUID+584 , 180411, 571, 1, 1, 1879.72, -6205.338, 27.26761, 4.136433, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4000) +(@OGUID+585 , 180411, 571, 1, 1, 466.7355, -4532.663, 248.7537, 0.8203033, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 3991) +(@OGUID+586 , 180411, 571, 1, 1, 700.5764, -2933.623, 0.497556, 2.757613, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 3987) +(@OGUID+587 , 180411, 571, 1, 1, 820.6528, -2907.458, 12.73376, 0.5934101, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 3987) +(@OGUID+588 , 180411, 571, 1, 1, 1372.837, -3207.151, 168.448, 1.902409, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 3998) +(@OGUID+589 , 180411, 571, 1, 1, 1421.961, -3261.482, 172.5474, 5.462882, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 3998) +(@OGUID+590 , 180411, 571, 1, 1, 627.3833, -4917.144, 35.51801, 0.2617982, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 3981) +(@OGUID+591 , 180411, 571, 1, 1, 594.2167, -4931.238, 21.88531, 4.799657, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 3981) +(@OGUID+592 , 180411, 571, 1, 1, 574.7415, -4943.303, 21.83569, 6.143561, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 3981) +(@OGUID+593 , 180411, 571, 1, 1, 2465.79, -5055.773, 303.4811, 6.108654, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4003) +(@OGUID+594 , 180411, 571, 1, 1, 2494.079, -5058.457, 288.5814, 5.811947, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4003) +(@OGUID+595 , 180411, 571, 1, 1, 3667.043, -707.4705, 220.4299, 3.630291, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4177) +(@OGUID+596 , 180411, 571, 1, 1, 2776.893, 930.918, 28.78174, 1.937312, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4152) +(@OGUID+597 , 180411, 571, 1, 1, 3842.228, 1495.968, 101.1961, 4.32842, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4165) +(@OGUID+598 , 180411, 571, 1, 1, 3841.892, 1477.297, 129.234, 3.246347, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4165) +(@OGUID+599 , 180411, 571, 1, 1, 8444.078, -340.1267, 915.4036, 3.595379, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4436) +(@OGUID+600 , 180411, 571, 1, 1, 6124.838, -1085.729, 407.7206, 3.089183, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4419) +(@OGUID+601 , 180411, 571, 1, 1, 6125.659, -1090.55, 406.7731, 3.996807, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4419) +(@OGUID+602 , 180411, 571, 1, 1, 6120.892, -1091.373, 407.3358, 5.044002, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4419) +(@OGUID+603 , 180411, 571, 1, 1, 6120.023, -1086.642, 407.4646, 1.675514, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4419) +(@OGUID+604 , 180411, 571, 1, 1, 4513.346, 5709.525, 87.73186, 0.8552105, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4122) +(@OGUID+605 , 180411, 571, 1, 1, 4180.499, 5282.511, 41.72525, 0.9599299, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4108) +(@OGUID+606 , 180411, 571, 1, 1, 4178.446, 5281.503, 32.45599, 3.804818, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4108) +(@OGUID+607 , 180411, 571, 1, 1, 2805.919, 6152.53, 95.5703, 5.951575, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4129) +(@OGUID+608 , 180411, 571, 1, 1, 3003.288, 4049.86, 32.18251, 3.351047, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4113) +(@OGUID+609 , 180411, 571, 1, 1, 3436.922, 4173.982, 26.38379, 5.777041, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 0) +(@OGUID+610 , 180411, 571, 1, 1, 3463.541, 4143.397, 25.56423, 5.462882, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4043) +(@OGUID+611 , 180411, 571, 1, 1, 3449.526, 4133.711, 25.4326, 5.67232, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4043) +(@OGUID+612 , 180411, 571, 1, 1, 3463.864, 4158.074, 25.55934, 2.600535, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4043) +(@OGUID+613 , 180411, 571, 1, 1, 3473.609, 4133.358, 25.26127, 5.358162, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4043) +(@OGUID+614 , 180411, 571, 1, 1, 3465.659, 4191.9, 27.78839, 6.161013, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4043) +(@OGUID+615 , 180411, 571, 1, 1, 3492.3, 4170.514, 26.55492, 3.961899, 0, 0, 0, 1, 120, 255, 1), -- 180411 (Area: 4043) +(@OGUID+616 , 180415, 571, 1, 1, 5231.531, -1307.568, 242.9937, 5.026549, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 66) +(@OGUID+617 , 180415, 571, 1, 1, 5231.807, -1317.45, 242.3508, 1.326448, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 66) +(@OGUID+618 , 180415, 571, 1, 1, 5232.045, -1311.97, 242.4411, 2.757613, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 66) +(@OGUID+619 , 180415, 571, 1, 1, 5228.543, -1303.112, 242.7879, 3.944446, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 66) +(@OGUID+620 , 180415, 571, 1, 1, 5223.873, -1297.311, 242.7593, 2.583081, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 66) +(@OGUID+621 , 180415, 571, 1, 1, 5219.208, -1294.684, 243.2743, 0.2792516, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 66) +(@OGUID+622 , 180415, 571, 1, 1, 5219.888, -1333.076, 242.3786, 0.2792516, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 66) +(@OGUID+623 , 180415, 571, 1, 1, 5214.489, -1333.5, 242.7952, 1.06465, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 66) +(@OGUID+624 , 180415, 571, 1, 1, 5200.362, -1331.64, 243.263, 2.792518, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 66) +(@OGUID+625 , 180415, 571, 1, 1, 5205.63, -1333.422, 243.3845, 2.408554, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 66) +(@OGUID+626 , 180415, 571, 1, 1, 5174.615, -2200.075, 237.0793, 5.811947, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+627 , 180415, 571, 1, 1, 5181.025, -2200.378, 238.9339, 1.029743, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+628 , 180415, 571, 1, 1, 5147.62, -2198.052, 237.614, 4.258607, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+629 , 180415, 571, 1, 1, 5179.311, -2200.378, 238.4566, 5.585054, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+630 , 180415, 571, 1, 1, 5147.989, -2198.857, 237.614, 2.478367, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+631 , 180415, 571, 1, 1, 5157.23, -2201.726, 237.5309, 4.886924, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+632 , 180415, 571, 1, 1, 5177.918, -2200.155, 237.9545, 4.555311, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+633 , 180415, 571, 1, 1, 5176.376, -2200.125, 237.5385, 2.82743, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+634 , 180415, 571, 1, 1, 5137.146, -2201.73, 237.8019, 0.5410506, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+635 , 180415, 571, 1, 1, 5147.455, -2202.927, 237.0062, 0.1745321, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+636 , 180415, 571, 1, 1, 5150.261, -2211.397, 238.8011, 2.984498, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+637 , 180415, 571, 1, 1, 5134.615, -2201.333, 238.8165, 3.089183, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+638 , 180415, 571, 1, 1, 5134.096, -2200.798, 238.8165, 5.777041, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+639 , 180415, 571, 1, 1, 5174.395, -2217.037, 237.1849, 5.113817, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4317) +(@OGUID+640 , 180415, 571, 1, 1, 5181.015, -2217.125, 238.9904, 0.1745321, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4317) +(@OGUID+641 , 180415, 571, 1, 1, 5179.321, -2217.104, 238.5324, 4.677484, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4317) +(@OGUID+642 , 180415, 571, 1, 1, 5177.742, -2217.072, 237.9756, 5.811947, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4317) +(@OGUID+643 , 180415, 571, 1, 1, 5141.178, -2211.442, 238.1585, 1.378809, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4317) +(@OGUID+644 , 180415, 571, 1, 1, 5140.784, -2211.82, 238.1585, 1.692969, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4317) +(@OGUID+645 , 180415, 571, 1, 1, 5176.154, -2217.055, 237.5818, 0.157079, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4317) +(@OGUID+646 , 180415, 571, 1, 1, 5377.697, -2612.275, 305.4919, 3.47321, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+647 , 180415, 571, 1, 1, 5378.776, -2637.334, 304.966, 5.98648, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+648 , 180415, 571, 1, 1, 5446.666, -2635.141, 306.7401, 4.031712, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4275) +(@OGUID+649 , 180415, 571, 1, 1, 5443.241, -2628.945, 306.7371, 4.32842, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4275) +(@OGUID+650 , 180415, 571, 1, 1, 5444.132, -2632.507, 306.7371, 3.68265, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4275) +(@OGUID+651 , 180415, 571, 1, 1, 5446.891, -2622.866, 306.733, 4.939284, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4275) +(@OGUID+652 , 180415, 571, 1, 1, 5450.479, -2621.981, 306.7277, 3.438303, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4275) +(@OGUID+653 , 180415, 571, 1, 1, 5453.979, -2622.99, 306.5936, 1.867502, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4275) +(@OGUID+654 , 180415, 571, 1, 1, 5450.222, -2636.167, 306.739, 3.298687, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4275) +(@OGUID+655 , 180415, 571, 1, 1, 5444.251, -2625.413, 306.7368, 2.35619, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4275) +(@OGUID+656 , 180415, 571, 1, 1, 5453.774, -2635.269, 306.7326, 5.305802, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4275) +(@OGUID+657 , 180415, 571, 1, 1, 5456.549, -2625.604, 306.6074, 5.340709, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4275) +(@OGUID+658 , 180415, 571, 1, 1, 5456.413, -2632.691, 306.7231, 0.9075702, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4275) +(@OGUID+659 , 180415, 571, 1, 1, 5457.469, -2629.154, 306.7375, 4.607672, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4275) +(@OGUID+660 , 180415, 571, 1, 1, 5528.001, -2665.6, 305.3742, 0.1047193, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4275) +(@OGUID+661 , 180415, 571, 1, 1, 5500.662, -2662.148, 304.9659, 3.211419, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4275) +(@OGUID+662 , 180415, 571, 1, 1, 5763.567, -3552.541, 386.5541, 2.565632, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+663 , 180415, 571, 1, 1, 5768.135, -3553.175, 386.5514, 5.410522, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+664 , 180415, 571, 1, 1, 5750.391, -3570.385, 386.6082, 2.042035, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4323) +(@OGUID+665 , 180415, 571, 1, 1, 5776.281, -3557.164, 386.5179, 2.129301, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4323) +(@OGUID+666 , 180415, 571, 1, 1, 5762.846, -3557.929, 386.7904, 5.98648, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4323) +(@OGUID+667 , 180415, 571, 1, 1, 5775.812, -3560.629, 386.5844, 3.159062, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4323) +(@OGUID+668 , 180415, 571, 1, 1, 5757.775, -3561.603, 386.7299, 2.199115, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4323) +(@OGUID+669 , 180415, 571, 1, 1, 5776.619, -3565.798, 386.6816, 6.213374, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4323) +(@OGUID+670 , 180415, 571, 1, 1, 5776.687, -3569.371, 386.6979, 1.692969, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4323) +(@OGUID+671 , 180415, 571, 1, 1, 5773.405, -3555.642, 386.5388, 2.44346, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4323) +(@OGUID+672 , 180415, 571, 1, 1, 5769.636, -3555.544, 386.6231, 4.223697, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4323) +(@OGUID+673 , 180415, 571, 1, 1, 5752.563, -3565.215, 386.6399, 5.742135, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4323) +(@OGUID+674 , 180415, 571, 1, 1, 5775.966, -3574.389, 387.2715, 6.248279, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4323) +(@OGUID+675 , 180415, 571, 1, 1, 5760.6, -3586.51, 386.5219, 5.585054, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4323) +(@OGUID+676 , 180415, 571, 1, 1, 5748.784, -3573.642, 386.5444, 1.97222, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4323) +(@OGUID+677 , 180415, 571, 1, 1, 5765.48, -3584.281, 386.6219, 4.24115, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4323) +(@OGUID+678 , 180415, 571, 1, 1, 5755.499, -3578.478, 386.6624, 5.410522, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4323) +(@OGUID+679 , 180415, 571, 1, 1, 5768.435, -3581.585, 386.7327, 3.839725, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4323) +(@OGUID+680 , 180415, 571, 1, 1, 5772.202, -3578.392, 386.7462, 0.4886912, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4323) +(@OGUID+681 , 180415, 571, 1, 1, 5759.083, -3583, 386.592, 5.637414, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4323) +(@OGUID+682 , 180415, 571, 1, 1, 3873.8, -4541.213, 210.1521, 0.5410506, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+683 , 180415, 571, 1, 1, 3871.856, -4548.686, 211.1932, 0.7155849, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+684 , 180415, 571, 1, 1, 3873.244, -4548.734, 211.219, 5.67232, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+685 , 180415, 571, 1, 1, 3862.183, -4548.674, 211.6033, 2.670348, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+686 , 180415, 571, 1, 1, 3865.728, -4534.643, 211.7069, 0.2967052, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+687 , 180415, 571, 1, 1, 3880.78, -4510.24, 218.4157, 3.019413, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+688 , 180415, 571, 1, 1, 3833.083, -4531.847, 213.2785, 6.19592, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+689 , 180415, 571, 1, 1, 3861.911, -4519.634, 211.6107, 1.745327, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+690 , 180415, 571, 1, 1, 3863.615, -4516.346, 214.1784, 1.832595, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+691 , 180415, 571, 1, 1, 3830.969, -4499.772, 206.4349, 5.619962, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4211) +(@OGUID+692 , 180415, 571, 1, 1, 3443.286, -2823.03, 202.9982, 3.368496, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+693 , 180415, 571, 1, 1, 3407.794, -2841.943, 202.67, 0.4014249, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+694 , 180415, 571, 1, 1, 3441.109, -2824.373, 202.9075, 2.164206, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+695 , 180415, 571, 1, 1, 3438.945, -2825.767, 203.0237, 2.809975, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+696 , 180415, 571, 1, 1, 3440.277, -2818.991, 203.0136, 1.431168, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+697 , 180415, 571, 1, 1, 3436.816, -2827.108, 202.9122, 2.303831, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+698 , 180415, 571, 1, 1, 3441.738, -2820.991, 202.9215, 0.3316107, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+699 , 180415, 571, 1, 1, 3434.637, -2828.344, 202.9919, 3.298687, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+700 , 180415, 571, 1, 1, 3406.82, -2839.58, 202.8193, 0.8552105, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+701 , 180415, 571, 1, 1, 3437.037, -2814.965, 202.884, 3.368496, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+702 , 180415, 571, 1, 1, 3438.661, -2816.929, 203.0817, 5.707228, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+703 , 180415, 571, 1, 1, 3405.275, -2832.076, 202.8215, 0, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+704 , 180415, 571, 1, 1, 3405.745, -2834.549, 202.8814, 6.056293, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+705 , 180415, 571, 1, 1, 3406.287, -2837.063, 202.8049, 2.059488, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+706 , 180415, 571, 1, 1, 3407.031, -2802.89, 212.337, 5.445428, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+707 , 180415, 571, 1, 1, 3444.464, -2796.757, 203.2364, 5.969027, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+708 , 180415, 571, 1, 1, 3400.99, -2811.019, 202.6149, 1.274088, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+709 , 180415, 571, 1, 1, 3413.189, -2802.605, 212.3711, 5.899214, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+710 , 180415, 571, 1, 1, 3415.103, -2800.74, 202.2157, 1.919862, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+711 , 180415, 571, 1, 1, 3400.969, -2809.62, 202.0353, 3.612838, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+712 , 180415, 571, 1, 1, 3400.82, -2811.734, 202.7707, 4.66003, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+713 , 180415, 571, 1, 1, 3411.195, -2811.007, 202.0898, 1.658062, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+714 , 180415, 571, 1, 1, 3411.819, -2803.252, 212.5847, 3.822273, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+715 , 180415, 571, 1, 1, 3441.908, -2797.017, 203.1431, 5.096362, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+716 , 180415, 571, 1, 1, 3407.968, -2803.407, 213.5988, 5.462882, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+717 , 180415, 571, 1, 1, 3407.057, -2802.274, 212.4086, 1.291542, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+718 , 180415, 571, 1, 1, 3457.735, -2786.757, 202.8651, 4.01426, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+719 , 180415, 571, 1, 1, 3455.872, -2783.97, 202.7178, 2.321287, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+720 , 180415, 571, 1, 1, 3400.54, -2799.177, 201.4966, 4.01426, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+721 , 180415, 571, 1, 1, 3456.458, -2789.083, 203.3248, 0.2443456, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+722 , 180415, 571, 1, 1, 3399.834, -2790.558, 212.2449, 3.106652, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+723 , 180415, 571, 1, 1, 3405.42, -2788.209, 203.0673, 4.084071, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+724 , 180415, 571, 1, 1, 3400.798, -2792.024, 212.3608, 4.799657, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+725 , 180415, 571, 1, 1, 3406.408, -2787.522, 203.0332, 4.677484, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+726 , 180415, 571, 1, 1, 3398.889, -2790.992, 213.4207, 4.24115, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+727 , 180415, 571, 1, 1, 3400.714, -2792.445, 212.2851, 1.675514, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+728 , 180415, 571, 1, 1, 3399.956, -2791.192, 212.2966, 6.248279, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+729 , 180415, 571, 1, 1, 3399.706, -2791.847, 212.3247, 4.468043, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+730 , 180415, 571, 1, 1, 3413.264, -2780.046, 202.9309, 3.857183, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+731 , 180415, 571, 1, 1, 3466.171, -2781.337, 202.358, 1.06465, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+732 , 180415, 571, 1, 1, 3458.188, -2776.3, 201.8077, 3.543024, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+733 , 180415, 571, 1, 1, 3472.556, -2782.05, 202.3065, 1.326448, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+734 , 180415, 571, 1, 1, 3404.212, -2786.731, 203.0216, 4.310966, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+735 , 180415, 571, 1, 1, 3408.607, -2785.961, 202.9851, 0.5235979, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+736 , 180415, 571, 1, 1, 3475.129, -2782.253, 202.1459, 3.961899, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+737 , 180415, 571, 1, 1, 3412.443, -2783.161, 202.9973, 5.183629, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+738 , 180415, 571, 1, 1, 3403.424, -2785.687, 202.9964, 3.57793, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+739 , 180415, 571, 1, 1, 3407.591, -2786.707, 202.9976, 5.270896, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+740 , 180415, 571, 1, 1, 3470.033, -2781.84, 202.4652, 5.951575, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+741 , 180415, 571, 1, 1, 3411.324, -2783.891, 202.9264, 1.53589, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+742 , 180415, 571, 1, 1, 3397.692, -2789.662, 213.2649, 1.867502, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+743 , 180415, 571, 1, 1, 3402.704, -2784.6, 202.9906, 3.543024, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+744 , 180415, 571, 1, 1, 3462.118, -2779.648, 202.4681, 4.607672, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+745 , 180415, 571, 1, 1, 3414.508, -2781.62, 202.9946, 3.57793, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+746 , 180415, 571, 1, 1, 3413.529, -2782.306, 202.9957, 0.4537851, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+747 , 180415, 571, 1, 1, 3413.155, -2777.403, 206.0491, 0.802851, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+748 , 180415, 571, 1, 1, 3419.603, -2772.811, 201.5641, 2.757613, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+749 , 180415, 571, 1, 1, 3425.753, -2769.791, 202.0575, 6.213374, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+750 , 180415, 571, 1, 1, 3456.768, -2774.179, 201.8534, 1.483528, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+751 , 180415, 571, 1, 1, 3411.746, -2778.068, 202.9529, 3.595379, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+752 , 180415, 571, 1, 1, 3406.269, -2781.944, 203.4021, 5.794494, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+753 , 180415, 571, 1, 1, 3425.471, -2770.199, 202.053, 4.363324, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+754 , 180415, 571, 1, 1, 3412.486, -2778.925, 202.9093, 2.967041, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+755 , 180415, 571, 1, 1, 3397.889, -2752.26, 201.1765, 3.298687, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+756 , 180415, 571, 1, 1, 3397.825, -2754.811, 201.1646, 0.7853968, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+757 , 180415, 571, 1, 1, 3455.441, -2749.057, 200.8513, 5.724681, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+758 , 180415, 571, 1, 1, 3440.693, -2745.642, 200.7106, 0.7853968, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+759 , 180415, 571, 1, 1, 3427.793, -2745.417, 200.9314, 4.031712, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+760 , 180415, 571, 1, 1, 3445.042, -2751.564, 199.4239, 1.343901, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+761 , 180415, 571, 1, 1, 3455.573, -2746.484, 200.8855, 3.42085, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+762 , 180415, 571, 1, 1, 3443.285, -2745.714, 200.7417, 6.108654, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+763 , 180415, 571, 1, 1, 3425.394, -2745.384, 200.891, 3.194002, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+764 , 180415, 571, 1, 1, 3445.895, -2745.695, 200.92, 1.151916, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+765 , 180415, 571, 1, 1, 3448.288, -2745.802, 200.9623, 3.717554, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+766 , 180415, 571, 1, 1, 3455.298, -2756.604, 201.076, 3.490667, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+767 , 180415, 571, 1, 1, 3455.351, -2754.038, 201.1146, 3.822273, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+768 , 180415, 571, 1, 1, 3422.8, -2745.42, 200.716, 5.375615, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+769 , 180415, 571, 1, 1, 3455.435, -2751.653, 201.1238, 1.588249, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+770 , 180415, 571, 1, 1, 3420.21, -2745.375, 200.6848, 4.398232, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+771 , 180415, 571, 1, 1, 3430.328, -2745.441, 200.9204, 3.089183, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+772 , 180415, 571, 1, 1, 3449.38, -2752.161, 199.3402, 5.410522, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+773 , 180415, 571, 1, 1, 3450.814, -2745.738, 201.1831, 1.204277, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+774 , 180415, 571, 1, 1, 3406.284, -2744.823, 200.6775, 0.802851, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+775 , 180415, 571, 1, 1, 3398.188, -2744.674, 200.9263, 5.462882, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+776 , 180415, 571, 1, 1, 3408.93, -2745.019, 200.7298, 0.4886912, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+777 , 180415, 571, 1, 1, 3398.062, -2747.274, 200.9093, 3.647741, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+778 , 180415, 571, 1, 1, 3411.495, -2744.974, 200.9156, 3.909541, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+779 , 180415, 571, 1, 1, 3398.008, -2749.851, 201.1351, 1.256636, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+780 , 180415, 571, 1, 1, 3413.885, -2745.063, 200.9569, 0.5585039, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+781 , 180415, 571, 1, 1, 3416.44, -2745.043, 200.9444, 5.899214, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4204) +(@OGUID+782 , 180415, 571, 1, 1, 3306.957, -2346.275, 114.2688, 4.71239, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4217) +(@OGUID+783 , 180415, 571, 1, 1, 3306.503, -2346.271, 114.2327, 3.612838, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4217) +(@OGUID+784 , 180415, 571, 1, 1, 3314.758, -2336.475, 113.8916, 1.640607, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4217) +(@OGUID+785 , 180415, 571, 1, 1, 3315.174, -2335.131, 112.3857, 5.218536, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4217) +(@OGUID+786 , 180415, 571, 1, 1, 3313.81, -2337.315, 112.3801, 2.949595, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4217) +(@OGUID+787 , 180415, 571, 1, 1, 3314.402, -2336.751, 113.8963, 5.218536, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4217) +(@OGUID+788 , 180415, 571, 1, 1, 3320.02, -2321.913, 114.3211, 4.572764, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4206) +(@OGUID+789 , 180415, 571, 1, 1, 3319.593, -2323.635, 112.2697, 5.637414, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4206) +(@OGUID+790 , 180415, 571, 1, 1, 3319.35, -2324.088, 112.2623, 4.380776, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4206) +(@OGUID+791 , 180415, 571, 1, 1, 3320.5, -2321.387, 114.3223, 5.009095, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4206) +(@OGUID+792 , 180415, 571, 1, 1, 3240.985, -2236.183, 117.2045, 6.213374, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4206) +(@OGUID+793 , 180415, 571, 1, 1, 3240.313, -2236.637, 117.1827, 5.846854, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4206) +(@OGUID+794 , 180415, 571, 1, 1, 3255.964, -2216.654, 117.3241, 1.047198, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4206) +(@OGUID+795 , 180415, 571, 1, 1, 3250.294, -2214.309, 117.3726, 4.34587, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4206) +(@OGUID+796 , 180415, 571, 1, 1, 3266.923, -2221.398, 117.2959, 6.108654, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4206) +(@OGUID+797 , 180415, 571, 1, 1, 3273.234, -2223.792, 117.3726, 3.630291, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4206) +(@OGUID+798 , 180415, 571, 1, 1, 3253.368, -2199.88, 117.029, 0.2443456, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4206) +(@OGUID+799 , 180415, 571, 1, 1, 3280.633, -2211.489, 117.029, 0.9599299, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4206) +(@OGUID+800 , 180415, 571, 1, 1, 3254.062, -2187.705, 118.7545, 0.01745246, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4206) +(@OGUID+801 , 180415, 571, 1, 1, 3256.237, -2188.316, 118.4933, 4.991644, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4206) +(@OGUID+802 , 180415, 571, 1, 1, 1904.515, -6141.503, 19.07745, 6.021387, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4000) +(@OGUID+803 , 180415, 571, 1, 1, 1904.164, -6141.786, 19.07746, 5.707228, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4000) +(@OGUID+804 , 180415, 571, 1, 1, 730.0452, -2931.608, 7.921721, 0, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3987) +(@OGUID+805 , 180415, 571, 1, 1, 726.9896, -2932.885, 7.942686, 0, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3987) +(@OGUID+806 , 180415, 571, 1, 1, 732.6979, -2930.411, 7.924031, 0, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3987) +(@OGUID+807 , 180415, 571, 1, 1, 732.0417, -2926.337, 7.959949, 0, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3987) +(@OGUID+808 , 180415, 571, 1, 1, 728.4393, -2932.286, 7.933091, 0, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3987) +(@OGUID+809 , 180415, 571, 1, 1, 725.5104, -2932.967, 8.092805, 0, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3987) +(@OGUID+810 , 180415, 571, 1, 1, 731.3733, -2930.993, 7.925742, 0, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3987) +(@OGUID+811 , 180415, 571, 1, 1, 697.434, -2944.288, -1.407539, 3.071766, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3987) +(@OGUID+812 , 180415, 571, 1, 1, 724.4271, -2926.127, 8.093702, 0, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3987) +(@OGUID+813 , 180415, 571, 1, 1, 725.8629, -2925.865, 7.972515, 0, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3987) +(@OGUID+814 , 180415, 571, 1, 1, 729.1215, -2926.113, 7.972516, 0, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3987) +(@OGUID+815 , 180415, 571, 1, 1, 706.757, -2944.646, -1.334748, 3.071766, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3987) +(@OGUID+816 , 180415, 571, 1, 1, 727.4358, -2925.96, 7.973504, 0, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3987) +(@OGUID+817 , 180415, 571, 1, 1, 730.5781, -2926.233, 7.968627, 0, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3987) +(@OGUID+818 , 180415, 571, 1, 1, 694.3993, -2923.686, -1.305829, 0, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3987) +(@OGUID+819 , 180415, 571, 1, 1, 704.0989, -2921.766, -1.33801, 2.478367, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3987) +(@OGUID+820 , 180415, 571, 1, 1, 1421.866, -3274.431, 175.8965, 4.34587, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3998) +(@OGUID+821 , 180415, 571, 1, 1, 1437.179, -3255.236, 168.5082, 0.4712385, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3998) +(@OGUID+822 , 180415, 571, 1, 1, 1423.415, -3272.469, 175.8965, 5.829401, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3998) +(@OGUID+823 , 180415, 571, 1, 1, 1440.88, -3258.736, 168.5083, 1.570796, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3998) +(@OGUID+824 , 180415, 571, 1, 1, 1421.422, -3276.337, 175.8964, 4.310966, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3998) +(@OGUID+825 , 180415, 571, 1, 1, 1421.38, -3278.174, 175.8965, 4.555311, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3998) +(@OGUID+826 , 180415, 571, 1, 1, 1421.837, -3279.875, 175.8964, 3.508117, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3998) +(@OGUID+827 , 180415, 571, 1, 1, 1443.076, -3260.196, 168.5083, 1.710422, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3998) +(@OGUID+828 , 180415, 571, 1, 1, 1443.797, -3259.285, 168.5083, 1.047198, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3998) +(@OGUID+829 , 180415, 571, 1, 1, 1437.932, -3254.321, 168.5089, 2.583081, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3998) +(@OGUID+830 , 180415, 571, 1, 1, 1438.714, -3257.005, 168.5084, 0.7679439, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3998) +(@OGUID+831 , 180415, 571, 1, 1, 1424.549, -3281.903, 175.8964, 6.03884, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3998) +(@OGUID+832 , 180415, 571, 1, 1, 1446.208, -3272.655, 171.3525, 3.68265, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3998) +(@OGUID+833 , 180415, 571, 1, 1, 1425.948, -3281.997, 175.8964, 1.640607, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3998) +(@OGUID+834 , 180415, 571, 1, 1, 1449.852, -3275.616, 171.3525, 5.811947, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3998) +(@OGUID+835 , 180415, 571, 1, 1, 1427.842, -3281.715, 175.8965, 0.9773831, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3998) +(@OGUID+836 , 180415, 571, 1, 1, 1429.609, -3280.913, 175.8965, 0.6283169, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3998) +(@OGUID+837 , 180415, 571, 1, 1, 1431.264, -3278.972, 175.8965, 2.024579, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3998) +(@OGUID+838 , 180415, 571, 1, 1, 1448.076, -3274.135, 171.3525, 4.450591, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3998) +(@OGUID+839 , 180415, 571, 1, 1, 1451.38, -3276.939, 171.3525, 2.111848, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3998) +(@OGUID+840 , 180415, 571, 1, 1, 607.8405, -4925.881, 24.95922, 3.57793, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+841 , 180415, 571, 1, 1, 608.6639, -4923.137, 31.06963, 3.717554, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+842 , 180415, 571, 1, 1, 606.8481, -4923.561, 31.05914, 5.777041, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+843 , 180415, 571, 1, 1, 592.6419, -4947.118, 27.2703, 3.822273, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+844 , 180415, 571, 1, 1, 601.7822, -4924.856, 31.09424, 0.2617982, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+845 , 180415, 571, 1, 1, 592.2818, -4945.582, 27.2703, 5.567601, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+846 , 180415, 571, 1, 1, 602.6741, -4929.257, 22.72639, 4.590216, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+847 , 180415, 571, 1, 1, 607.1002, -4923.413, 24.95922, 1.151916, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+848 , 180415, 571, 1, 1, 601.2928, -4929.597, 22.72639, 2.024579, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+849 , 180415, 571, 1, 1, 599.9999, -4925.255, 31.10255, 4.485497, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+850 , 180415, 571, 1, 1, 604.4755, -4924.116, 24.96138, 5.183629, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+851 , 180415, 571, 1, 1, 592.1803, -4952.106, 27.2703, 2.286379, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+852 , 180415, 571, 1, 1, 591.1564, -4953.459, 27.2703, 0, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+853 , 180415, 571, 1, 1, 605.0962, -4924.019, 31.05478, 1.640607, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+854 , 180415, 571, 1, 1, 592.8271, -4950.619, 27.2703, 0.8901166, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+855 , 180415, 571, 1, 1, 603.4061, -4924.424, 31.06834, 4.71239, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+856 , 180415, 571, 1, 1, 601.9756, -4924.741, 24.95593, 0.6806767, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+857 , 180415, 571, 1, 1, 595.087, -4926.527, 31.06053, 0.4014249, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+858 , 180415, 571, 1, 1, 599.5756, -4929.97, 22.72639, 2.792518, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+859 , 180415, 571, 1, 1, 587.9566, -4954.577, 27.2703, 1.692969, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+860 , 180415, 571, 1, 1, 593.6668, -4929.349, 31.07931, 4.136433, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+861 , 180415, 571, 1, 1, 596.3693, -4930.906, 22.72639, 2.33874, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+862 , 180415, 571, 1, 1, 597.8043, -4930.463, 22.72639, 3.735006, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+863 , 180415, 571, 1, 1, 598.4451, -4925.653, 31.07524, 5.864307, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+864 , 180415, 571, 1, 1, 601.3765, -4922.399, 24.95571, 4.293513, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+865 , 180415, 571, 1, 1, 586.3301, -4953.981, 27.2703, 3.700105, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+866 , 180415, 571, 1, 1, 596.6023, -4926.172, 31.03511, 5.375615, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+867 , 180415, 571, 1, 1, 600.8096, -4920.225, 24.95571, 1.186823, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+868 , 180415, 571, 1, 1, 590.7567, -4934.542, 31.1084, 4.869471, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+869 , 180415, 571, 1, 1, 584.8109, -4952.982, 27.2703, 1.099556, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+870 , 180415, 571, 1, 1, 593.1274, -4927, 31.07476, 4.101525, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+871 , 180415, 571, 1, 1, 582.5004, -4947.915, 27.2703, 1.553341, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+872 , 180415, 571, 1, 1, 584.9875, -4936.011, 31.05981, 3.263772, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+873 , 180415, 571, 1, 1, 586.9916, -4935.478, 31.03452, 5.689774, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+874 , 180415, 571, 1, 1, 591.3271, -4919.841, 24.76182, 5.881761, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+875 , 180415, 571, 1, 1, 582.8868, -4949.487, 27.2703, 2.024579, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+876 , 180415, 571, 1, 1, 589.015, -4934.996, 31.07944, 3.38594, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+877 , 180415, 571, 1, 1, 589.0734, -4924.763, 19.81484, 4.049168, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+878 , 180415, 571, 1, 1, 582.024, -4933.135, 31.07914, 3.752462, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+879 , 180415, 571, 1, 1, 586.677, -4921.894, 24.03878, 2.705255, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+880 , 180415, 571, 1, 1, 588.6942, -4923.249, 19.81484, 5.654869, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+881 , 180415, 571, 1, 1, 582.4625, -4934.822, 31.0773, 0.7679439, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+882 , 180415, 571, 1, 1, 589.4875, -4926.273, 19.81484, 2.024579, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 3981) +(@OGUID+883 , 180415, 571, 1, 1, 2492.693, -1907.169, 9.526185, 5.899214, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4242) +(@OGUID+884 , 180415, 571, 1, 1, 2490.183, -1883.224, 9.115799, 4.921829, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4242) +(@OGUID+885 , 180415, 571, 1, 1, 2501.102, -1882.176, 8.549006, 4.66003, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4242) +(@OGUID+886 , 180415, 571, 1, 1, 2501.947, -1893.583, 8.302938, 2.879789, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4242) +(@OGUID+887 , 180415, 571, 1, 1, 2506.74, -1900.911, 8.029154, 1.762782, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4242) +(@OGUID+888 , 180415, 571, 1, 1, 2490.393, -1897.489, 9.970935, 2.792518, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4242) +(@OGUID+889 , 180415, 571, 1, 1, 2477.013, -1901.73, 11.23512, 1.605702, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4242) +(@OGUID+890 , 180415, 571, 1, 1, 2480.636, -1898.305, 11.20697, 2.687807, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4242) +(@OGUID+891 , 180415, 571, 1, 1, 2465.555, -1903.595, 11.20657, 4.293513, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4242) +(@OGUID+892 , 180415, 571, 1, 1, 2470.907, -1903.663, 11.225, 1.343901, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4242) +(@OGUID+893 , 180415, 571, 1, 1, 3720.282, -703.4149, 216.9913, 3.403396, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+894 , 180415, 571, 1, 1, 3721.375, -700.6528, 217.3681, 4.991644, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+895 , 180415, 571, 1, 1, 3724.484, -697.309, 217.4367, 4.71239, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+896 , 180415, 571, 1, 1, 3723.878, -701.0903, 217.3764, 6.108654, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+897 , 180415, 571, 1, 1, 3722.675, -704.342, 217.2098, 0.4712385, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+898 , 180415, 571, 1, 1, 3723.472, -693.4011, 217.4225, 4.642576, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+899 , 180415, 571, 1, 1, 3721.266, -694.7188, 217.1692, 0.2268925, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+900 , 180415, 571, 1, 1, 3719.472, -692.0851, 217.2261, 1.727875, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+901 , 180415, 571, 1, 1, 3721.933, -697.5799, 217.3843, 4.886924, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+902 , 180415, 571, 1, 1, 3720.975, -690.0139, 217.1697, 4.747296, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+903 , 180415, 571, 1, 1, 3673.806, -704.4462, 215.2892, 1.326448, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+904 , 180415, 571, 1, 1, 3680.288, -702.743, 215.5022, 4.206246, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+905 , 180415, 571, 1, 1, 3663.695, -709.2948, 213.8031, 3.57793, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+906 , 180415, 571, 1, 1, 3662.965, -709.1875, 214.0366, 2.635444, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+907 , 180415, 571, 1, 1, 3663.579, -704.8941, 214.0316, 5.340709, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+908 , 180415, 571, 1, 1, 3664.109, -705.0291, 213.8467, 0.5759573, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+909 , 180415, 571, 1, 1, 3657.745, -692.2751, 223.6275, 1.937312, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+910 , 180415, 571, 1, 1, 3660.364, -700.371, 223.6275, 5.969027, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+911 , 180415, 571, 1, 1, 3650.258, -699.3051, 223.6275, 0.1396245, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+912 , 180415, 571, 1, 1, 3661.816, -704.7014, 214.8959, 0.8377575, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+913 , 180415, 571, 1, 1, 3654.531, -691.826, 223.6275, 4.834563, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+914 , 180415, 571, 1, 1, 3652.8, -692.9138, 223.6275, 3.38594, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+915 , 180415, 571, 1, 1, 3655.83, -710.9506, 227.4323, 3.735006, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+916 , 180415, 571, 1, 1, 3651.423, -694.3221, 223.6275, 6.19592, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+917 , 180415, 571, 1, 1, 3660.504, -697.7479, 223.6275, 1.413715, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+918 , 180415, 571, 1, 1, 3662.702, -704.8438, 214.3862, 5.288348, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+919 , 180415, 571, 1, 1, 3660.119, -695.2737, 223.6275, 5.270896, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+920 , 180415, 571, 1, 1, 3658.975, -693.3618, 223.6275, 0.5410506, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+921 , 180415, 571, 1, 1, 3650.527, -697.048, 223.6275, 2.251473, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+922 , 180415, 571, 1, 1, 3661.141, -709.1563, 214.8015, 3.560473, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+923 , 180415, 571, 1, 1, 3646.771, -712.575, 216.1448, 4.572764, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+924 , 180415, 571, 1, 1, 3639.381, -715.8611, 227.3913, 6.073746, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+925 , 180415, 571, 1, 1, 3655.505, -714.1703, 227.4361, 5.113817, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+926 , 180415, 571, 1, 1, 3643.311, -713.7602, 227.4366, 5.619962, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+927 , 180415, 571, 1, 1, 3649.78, -710.2109, 227.4335, 0.1919852, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+928 , 180415, 571, 1, 1, 3650.835, -720.3264, 216.1421, 4.049168, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+929 , 180415, 571, 1, 1, 3641.055, -711.5729, 218.9725, 6.073746, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+930 , 180415, 571, 1, 1, 3642.938, -716.2329, 227.4314, 2.705255, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+931 , 180415, 571, 1, 1, 3656.18, -720.6285, 216.1422, 3.839725, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+932 , 180415, 571, 1, 1, 3662.277, -709.184, 214.3835, 5.515242, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+933 , 180415, 571, 1, 1, 3653.458, -720.2587, 216.1421, 2.949595, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+934 , 180415, 571, 1, 1, 3620.047, -714.6027, 227.4171, 5.742135, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+935 , 180415, 571, 1, 1, 3630.439, -711.8963, 215.451, 4.921829, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+936 , 180415, 571, 1, 1, 3628.625, -714.6279, 221.3164, 2.460913, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+937 , 180415, 571, 1, 1, 3647.266, -723.0741, 220.1831, 2.007128, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+938 , 180415, 571, 1, 1, 3628.823, -712.1104, 221.3164, 0.4363316, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+939 , 180415, 571, 1, 1, 3636.598, -710.9913, 218.9725, 0.5585039, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+940 , 180415, 571, 1, 1, 3642.31, -722.2473, 220.5441, 2.164206, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+941 , 180415, 571, 1, 1, 3646.166, -718.1907, 216.172, 3.246347, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+942 , 180415, 571, 1, 1, 3635.955, -715.3896, 227.4597, 4.852017, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+943 , 180415, 571, 1, 1, 3639.688, -711.3333, 218.9725, 5.113817, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+944 , 180415, 571, 1, 1, 3633.46, -719.8217, 221.3129, 2.792518, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+945 , 180415, 571, 1, 1, 3632.302, -715.0294, 227.4236, 3.822273, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+946 , 180415, 571, 1, 1, 3630.115, -714.7449, 215.4509, 6.073746, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+947 , 180415, 571, 1, 1, 3633.867, -715.2915, 221.3129, 3.630291, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+948 , 180415, 571, 1, 1, 3628.883, -714.4942, 227.4169, 6.248279, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+949 , 180415, 571, 1, 1, 3629.475, -717.1203, 215.4509, 1.274088, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+950 , 180415, 571, 1, 1, 3635.079, -710.8333, 218.9725, 5.637414, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+951 , 180415, 571, 1, 1, 3645.829, -721.221, 216.172, 1.082103, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+952 , 180415, 571, 1, 1, 3619.787, -716.7102, 227.4115, 4.153885, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4177) +(@OGUID+953 , 180415, 571, 1, 1, 3539.074, 246.8349, 45.82254, 3.124123, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4161) +(@OGUID+954 , 180415, 571, 1, 1, 3560.01, 248.8549, 45.83335, 3.944446, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4161) +(@OGUID+955 , 180415, 571, 1, 1, 3549.851, 245.3113, 45.88549, 4.01426, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4161) +(@OGUID+956 , 180415, 571, 1, 1, 3520.715, 280.9288, 45.78613, 3.595379, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4161) +(@OGUID+957 , 180415, 571, 1, 1, 3564.364, 294.3126, 45.82972, 5.829401, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4161) +(@OGUID+958 , 180415, 571, 1, 1, 3526.05, 290.625, 45.8017, 3.246347, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4161) +(@OGUID+959 , 180415, 571, 1, 1, 3529.681, 251.9887, 45.82568, 3.38594, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4161) +(@OGUID+960 , 180415, 571, 1, 1, 3570.418, 286.1223, 45.8264, 5.131269, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4161) +(@OGUID+961 , 180415, 571, 1, 1, 3534.023, 297.516, 45.87384, 5.253442, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4161) +(@OGUID+962 , 180415, 571, 1, 1, 3573.903, 275.7938, 45.8153, 0.2094394, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4161) +(@OGUID+963 , 180415, 571, 1, 1, 3572.999, 265.1364, 45.80965, 0.03490625, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4161) +(@OGUID+964 , 180415, 571, 1, 1, 3585.963, 283.0799, 48.30828, 3.961899, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4161) +(@OGUID+965 , 180415, 571, 1, 1, 3554.604, 299.7266, 45.90679, 1.483528, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4161) +(@OGUID+966 , 180415, 571, 1, 1, 3568.259, 255.9597, 45.78259, 0.2617982, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4161) +(@OGUID+967 , 180415, 571, 1, 1, 3587.122, 271.1111, 48.3845, 2.809975, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4161) +(@OGUID+968 , 180415, 571, 1, 1, 3522.922, 260.132, 45.7541, 2.722713, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4161) +(@OGUID+969 , 180415, 571, 1, 1, 3596.911, 271.6074, 52.12251, 2.094393, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4161) +(@OGUID+970 , 180415, 571, 1, 1, 3519.316, 270.3384, 45.87571, 3.979355, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4161) +(@OGUID+971 , 180415, 571, 1, 1, 3595.522, 284.4653, 52.2077, 4.799657, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4161) +(@OGUID+972 , 180415, 571, 1, 1, 3544.37, 301.0424, 45.87925, 2.042035, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4161) +(@OGUID+973 , 180415, 571, 1, 1, 3453.492, 2004.011, 66.48942, 0, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+974 , 180415, 571, 1, 1, 3451.072, 2013.826, 67.11924, 3.33359, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+975 , 180415, 571, 1, 1, 3460.914, 1999.812, 64.96242, 0.4363316, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+976 , 180415, 571, 1, 1, 3450.717, 2005.431, 66.47033, 4.380776, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+977 , 180415, 571, 1, 1, 3464.852, 2005.66, 65.63439, 1.029743, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+978 , 180415, 571, 1, 1, 3457.145, 2001.683, 65.88113, 0.9424766, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+979 , 180415, 571, 1, 1, 3457.17, 2010.24, 67.18584, 4.782203, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+980 , 180415, 571, 1, 1, 3461.157, 2007.909, 66.50739, 2.652894, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+981 , 180415, 571, 1, 1, 3447.548, 2007.21, 66.4343, 2.495818, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+982 , 180415, 571, 1, 1, 3454.485, 2011.974, 67.24349, 2.844883, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+983 , 180415, 571, 1, 1, 3485.54, 1982.056, 66.64336, 4.869471, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+984 , 180415, 571, 1, 1, 3491.24, 1972.217, 66.67846, 5.654869, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+985 , 180415, 571, 1, 1, 3484.478, 1982.79, 66.10648, 4.71239, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+986 , 180415, 571, 1, 1, 3486.18, 1980.53, 66.75633, 1.082103, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+987 , 180415, 571, 1, 1, 3488.036, 1984.502, 66.5727, 4.398232, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+988 , 180415, 571, 1, 1, 3488.738, 1974.252, 66.48361, 1.815142, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+989 , 180415, 571, 1, 1, 3486.124, 1985.773, 66.13934, 4.677484, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+990 , 180415, 571, 1, 1, 3489.454, 1972.877, 66.5388, 0.5585039, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+991 , 180415, 571, 1, 1, 3486.32, 1978.385, 66.64598, 4.677484, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+992 , 180415, 571, 1, 1, 3484.899, 1984.623, 66.13567, 4.188792, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+993 , 180415, 571, 1, 1, 3490.6, 1973.335, 66.56937, 2.967041, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+994 , 180415, 571, 1, 1, 3486.279, 1984.052, 66.72491, 3.368496, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+995 , 180415, 571, 1, 1, 3488.017, 1982.2, 69.24107, 1.762782, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+996 , 180415, 571, 1, 1, 3496.877, 1986.814, 66.14459, 4.276057, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+997 , 180415, 571, 1, 1, 3499.981, 1976.101, 66.6926, 0.9424766, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+998 , 180415, 571, 1, 1, 3498.515, 1987.265, 66.15958, 0.3316107, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+999 , 180415, 571, 1, 1, 3494.6, 1971.783, 69.21862, 2.600535, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+1000, 180415, 571, 1, 1, 3498.208, 1985.489, 66.55852, 5.462882, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+1001, 180415, 571, 1, 1, 3492.497, 1984.687, 66.91064, 5.445428, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+1002, 180415, 571, 1, 1, 3499.862, 1974.142, 66.74924, 4.886924, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+1003, 180415, 571, 1, 1, 3499.545, 1986.568, 66.14841, 2.775069, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+1004, 180415, 571, 1, 1, 3497.163, 1972.785, 67.83695, 2.303831, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+1005, 180415, 571, 1, 1, 3498.545, 1983.968, 66.78958, 1.570796, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+1006, 180415, 571, 1, 1, 3499.741, 1984.807, 66.1551, 5.044002, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+1007, 180415, 571, 1, 1, 3496.604, 1985.285, 66.52729, 4.01426, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+1008, 180415, 571, 1, 1, 3490.234, 1984.203, 66.76582, 5.881761, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+1009, 180415, 571, 1, 1, 3494.507, 1985.543, 66.86245, 1.483528, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+1010, 180415, 571, 1, 1, 3492.613, 1987.125, 66.18999, 0.3141584, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+1011, 180415, 571, 1, 1, 3498.044, 1971.96, 67.97525, 1.710422, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+1012, 180415, 571, 1, 1, 3500.235, 1977.234, 66.79019, 1.361356, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4158) +(@OGUID+1013, 180415, 571, 1, 1, 8446.374, -338.7054, 906.5311, 0.4188786, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4436) +(@OGUID+1014, 180415, 571, 1, 1, 8441.133, -333.9722, 906.3853, 4.468043, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4436) +(@OGUID+1015, 180415, 571, 1, 1, 8449.194, -340.0696, 906.42, 1.082103, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4436) +(@OGUID+1016, 180415, 571, 1, 1, 8438.914, -336.882, 906.3645, 4.433136, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4436) +(@OGUID+1017, 180415, 571, 1, 1, 8450.9, -342.7731, 906.4547, 4.97419, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4436) +(@OGUID+1018, 180415, 571, 1, 1, 8436.891, -329.9302, 906.4619, 2.949595, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4436) +(@OGUID+1019, 180415, 571, 1, 1, 8440.131, -331.5573, 906.4849, 4.572764, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4436) +(@OGUID+1020, 180415, 571, 1, 1, 8443.484, -341.0681, 906.538, 6.056293, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4436) +(@OGUID+1021, 180415, 571, 1, 1, 8438.455, -346.809, 906.3992, 4.206246, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4484) +(@OGUID+1022, 180415, 571, 1, 1, 8434.126, -342.7607, 906.3992, 5.951575, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4484) +(@OGUID+1023, 180415, 571, 1, 1, 6135.286, -1087.107, 403.996, 3.019413, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4419) +(@OGUID+1024, 180415, 571, 1, 1, 6135.75, -1082.272, 403.9787, 0.9424766, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4419) +(@OGUID+1025, 180415, 571, 1, 1, 6131.089, -1077.924, 404.0315, 3.403396, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4419) +(@OGUID+1026, 180415, 571, 1, 1, 6124.53, -1100.04, 404.1576, 4.415683, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4419) +(@OGUID+1027, 180415, 571, 1, 1, 6129.471, -1100.338, 404.0967, 0.383971, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4419) +(@OGUID+1028, 180415, 571, 1, 1, 6134.075, -1100.798, 404.0411, 4.276057, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4419) +(@OGUID+1029, 180415, 571, 1, 1, 6135.558, -1078.466, 403.9826, 0.802851, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4419) +(@OGUID+1030, 180415, 571, 1, 1, 6135.308, -1092.608, 404.0045, 0.6806767, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4419) +(@OGUID+1031, 180415, 571, 1, 1, 6135.531, -1097.868, 403.998, 1.675514, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4419) +(@OGUID+1032, 180415, 571, 1, 1, 6128.174, -1077.363, 404.1137, 5.462882, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4419) +(@OGUID+1033, 180415, 571, 1, 1, 6114.59, -1100.005, 404.2581, 1.448622, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4419) +(@OGUID+1034, 180415, 571, 1, 1, 6119.64, -1099.892, 404.2052, 0.9948372, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4419) +(@OGUID+1035, 180415, 571, 1, 1, 6117.122, -1080.053, 403.8957, 2.617989, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4419) +(@OGUID+1036, 180415, 571, 1, 1, 6110.035, -1085.667, 404.2946, 1.745327, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4419) +(@OGUID+1037, 180415, 571, 1, 1, 6116.569, -1077.83, 403.8956, 5.270896, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4419) +(@OGUID+1038, 180415, 571, 1, 1, 6110.022, -1094.398, 404.3128, 2.984498, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4419) +(@OGUID+1039, 180415, 571, 1, 1, 6113.951, -1077.961, 403.9418, 5.323256, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4419) +(@OGUID+1040, 180415, 571, 1, 1, 6109.78, -1099.722, 404.3831, 0.8552105, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4419) +(@OGUID+1041, 180415, 571, 1, 1, 6109.548, -1083.051, 404.3193, 3.996807, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4419) +(@OGUID+1042, 180415, 571, 1, 1, 6108.985, -1078.398, 404.2991, 1.640607, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4419) +(@OGUID+1043, 180415, 571, 1, 1, 6665.15, -200.775, 950.982, 6.19592, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4428) +(@OGUID+1044, 180415, 571, 1, 1, 6667.429, -202.9508, 950.2484, 3.38594, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4428) +(@OGUID+1045, 180415, 571, 1, 1, 6670.192, -202.2401, 950.4054, 0.05235888, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4428) +(@OGUID+1046, 180415, 571, 1, 1, 6676.213, -197.9583, 951.1501, 0.2967052, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4428) +(@OGUID+1047, 180415, 571, 1, 1, 6676.812, -200.8755, 951.2551, 0.5410506, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4428) +(@OGUID+1048, 180415, 571, 1, 1, 6671.391, -199.7399, 951.0316, 3.57793, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4428) +(@OGUID+1049, 180415, 571, 1, 1, 6671.051, -196.6817, 951.0138, 0.4537851, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4428) +(@OGUID+1050, 180415, 571, 1, 1, 6666.553, -195.6487, 951.7457, 3.246347, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4428) +(@OGUID+1051, 180415, 571, 1, 1, 6680.188, -200.7511, 955.8945, 0.7155849, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4428) +(@OGUID+1052, 180415, 571, 1, 1, 6664.639, -197.5128, 951.639, 5.619962, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4428) +(@OGUID+1053, 180415, 571, 1, 1, 5534.743, 5748.256, -76.63572, 5.026549, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1054, 180415, 571, 1, 1, 5543.521, 5771.278, -76.01951, 0.7330382, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1055, 180415, 571, 1, 1, 5523.451, 5778.276, -78.78996, 0.122173, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1056, 180415, 571, 1, 1, 5543.232, 5771.354, -76.01951, 2.984498, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1057, 180415, 571, 1, 1, 5525.911, 5782.684, -78.17769, 2.513274, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1058, 180415, 571, 1, 1, 5555.896, 5763.036, -76.68411, 2.408554, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1059, 180415, 571, 1, 1, 5552.697, 5767.842, -75.99409, 2.565632, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1060, 180415, 571, 1, 1, 5557.079, 5767.963, -77.05219, 3.211419, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1061, 180415, 571, 1, 1, 5557.415, 5769.394, -76.74715, 0.5934101, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1062, 180415, 571, 1, 1, 5589.266, 5819.588, -69.22645, 5.969027, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1063, 180415, 571, 1, 1, 5585.25, 5746.126, -71.12965, 5.009095, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1064, 180415, 571, 1, 1, 5589.826, 5820.498, -69.06834, 4.24115, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1065, 180415, 571, 1, 1, 5598.222, 5811.789, -69.80727, 3.68265, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1066, 180415, 571, 1, 1, 5608.288, 5809.12, -70.3611, 0.3665176, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1067, 180415, 571, 1, 1, 5629.481, 5831.32, -63.68258, 3.700105, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1068, 180415, 571, 1, 1, 5624.22, 5848.555, -62.23083, 6.265733, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1069, 180415, 571, 1, 1, 5624.355, 5836.35, -64.11382, 5.340709, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1070, 180415, 571, 1, 1, 5615.792, 5854.673, -61.52033, 1.588249, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1071, 180415, 571, 1, 1, 5617.778, 5835.836, -64.42644, 4.502952, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1072, 180415, 571, 1, 1, 5621.542, 5839.372, -63.8798, 3.490667, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1073, 180415, 571, 1, 1, 5620.175, 5851.535, -61.9314, 4.450591, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1074, 180415, 571, 1, 1, 5617.97, 5842.27, -63.73035, 1.623156, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1075, 180415, 571, 1, 1, 5631.269, 5841.848, -62.78385, 1.221729, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1076, 180415, 571, 1, 1, 5614.699, 5845.393, -63.52262, 3.33359, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1077, 180415, 571, 1, 1, 5628.023, 5845.315, -62.64318, 3.630291, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1078, 180415, 571, 1, 1, 5599.996, 5811.131, -69.81374, 0.087266, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1079, 180415, 571, 1, 1, 5610.43, 5848.424, -63.39353, 1.710422, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1080, 180415, 571, 1, 1, 5609.851, 5840.359, -64.56908, 4.904376, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4285) +(@OGUID+1081, 180415, 571, 1, 1, 5638.223, 5830.514, -63.40969, 6.108654, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4284) +(@OGUID+1082, 180415, 571, 1, 1, 5635.809, 5835.991, -63.02237, 2.024579, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4284) +(@OGUID+1083, 180415, 571, 1, 1, 5512.584, 4747.444, -194.4338, 4.904376, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4290) +(@OGUID+1084, 180415, 571, 1, 1, 5476.778, 4745.321, -195.5257, 2.967041, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4290) +(@OGUID+1085, 180415, 571, 1, 1, 5509.279, 4742.423, -194.4338, 2.565632, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4290) +(@OGUID+1086, 180415, 571, 1, 1, 5498.675, 4751.812, -194.4338, 6.073746, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4290) +(@OGUID+1087, 180415, 571, 1, 1, 5503.33, 4741.617, -194.4338, 1.745327, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4290) +(@OGUID+1088, 180415, 571, 1, 1, 5504.156, 4755.996, -194.4338, 3.071766, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4290) +(@OGUID+1089, 180415, 571, 1, 1, 5498.581, 4745.667, -194.4338, 4.537859, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4290) +(@OGUID+1090, 180415, 571, 1, 1, 5477.044, 4749.278, -195.3024, 4.921829, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4290) +(@OGUID+1091, 180415, 571, 1, 1, 5510.276, 4753.492, -194.4338, 4.398232, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4290) +(@OGUID+1092, 180415, 571, 1, 1, 5485.467, 4727.866, -194.3498, 6.161013, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4290) +(@OGUID+1093, 180415, 571, 1, 1, 4472.118, 5710.065, 81.82111, 0.3141584, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4123) +(@OGUID+1094, 180415, 571, 1, 1, 4475.728, 5707.702, 81.28061, 2.740162, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4123) +(@OGUID+1095, 180415, 571, 1, 1, 4474.857, 5707.663, 81.27406, 0.6283169, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4123) +(@OGUID+1096, 180415, 571, 1, 1, 4470.187, 5711.333, 81.82111, 1.727875, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4123) +(@OGUID+1097, 180415, 571, 1, 1, 4502.521, 5716.321, 83.2894, 4.590216, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4122) +(@OGUID+1098, 180415, 571, 1, 1, 4501.978, 5716.594, 83.29294, 3.665196, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4122) +(@OGUID+1099, 180415, 571, 1, 1, 4512.208, 5702.231, 82.31032, 3.403396, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4122) +(@OGUID+1100, 180415, 571, 1, 1, 4508.148, 5720.678, 81.53056, 2.757613, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4122) +(@OGUID+1101, 180415, 571, 1, 1, 4508.037, 5721.736, 81.52561, 2.321287, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4122) +(@OGUID+1102, 180415, 571, 1, 1, 4511.359, 5702.256, 82.3114, 4.520406, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4122) +(@OGUID+1103, 180415, 571, 1, 1, 4175.995, 5285.556, 39.60876, 5.846854, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4108) +(@OGUID+1104, 180415, 571, 1, 1, 4174.72, 5282.509, 40.74071, 4.939284, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4108) +(@OGUID+1105, 180415, 571, 1, 1, 4182.015, 5285.288, 40.89171, 3.508117, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4108) +(@OGUID+1106, 180415, 571, 1, 1, 4176.526, 5277.981, 41.3796, 3.438303, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4108) +(@OGUID+1107, 180415, 571, 1, 1, 4182.998, 5284, 40.91432, 4.01426, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4108) +(@OGUID+1108, 180415, 571, 1, 1, 4175.992, 5278.304, 40.8171, 1.361356, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4108) +(@OGUID+1109, 180415, 571, 1, 1, 4174.827, 5281.086, 40.75976, 5.497789, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4108) +(@OGUID+1110, 180415, 571, 1, 1, 4181.757, 5280.178, 39.78754, 1.989672, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4108) +(@OGUID+1111, 180415, 571, 1, 1, 4177.348, 5277.492, 40.8917, 3.508117, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4108) +(@OGUID+1112, 180415, 571, 1, 1, 4176.902, 5277.699, 41.40043, 0.9773831, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4108) +(@OGUID+1113, 180415, 571, 1, 1, 2816.064, 6140.755, 84.60281, 2.094393, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1114, 180415, 571, 1, 1, 2817.546, 6142.036, 84.77279, 0.4537851, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1115, 180415, 571, 1, 1, 2808.348, 6133.652, 84.35007, 4.71239, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1116, 180415, 571, 1, 1, 2814.547, 6139.239, 84.48197, 1.117009, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1117, 180415, 571, 1, 1, 2813.243, 6137.908, 84.43053, 3.106652, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1118, 180415, 571, 1, 1, 2811.692, 6136.515, 84.40427, 3.106652, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1119, 180415, 571, 1, 1, 2809.904, 6135.145, 84.37815, 6.003934, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1120, 180415, 571, 1, 1, 2806.884, 6132.39, 84.32622, 2.129301, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1121, 180415, 571, 1, 1, 2787.17, 6166.139, 84.44685, 3.735006, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1122, 180415, 571, 1, 1, 2785.56, 6164.665, 84.41692, 4.450591, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1123, 180415, 571, 1, 1, 2784.033, 6163.104, 84.38836, 5.969027, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1124, 180415, 571, 1, 1, 2791.778, 6170.236, 84.69099, 4.555311, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1125, 180415, 571, 1, 1, 2790.21, 6168.888, 84.58121, 1.937312, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1126, 180415, 571, 1, 1, 2788.624, 6167.527, 84.47393, 0.9250238, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1127, 180415, 571, 1, 1, 2781.09, 6160.348, 84.3336, 0.6806767, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1128, 180415, 571, 1, 1, 2779.682, 6158.85, 84.30719, 4.223697, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1129, 180415, 571, 1, 1, 2805.326, 6131.063, 84.3011, 4.729844, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1130, 180415, 571, 1, 1, 2791.639, 6139.96, 84.81071, 5.515242, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1131, 180415, 571, 1, 1, 2803.804, 6129.789, 84.27695, 4.031712, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1132, 180415, 571, 1, 1, 2782.543, 6161.761, 84.36069, 1.884953, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1133, 180415, 571, 1, 1, 2788.538, 6143.428, 84.79273, 5.98648, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1134, 180415, 571, 1, 1, 2776.865, 6126.743, 91.12935, 2.600535, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1135, 180415, 571, 1, 1, 2788.898, 6137.514, 86.33366, 5.148723, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1136, 180415, 571, 1, 1, 2774.129, 6129.736, 91.13658, 2.565632, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1137, 180415, 571, 1, 1, 2780.254, 6135.889, 89.43606, 4.031712, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1138, 180415, 571, 1, 1, 2785.656, 6141.002, 86.35069, 1.448622, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1139, 180415, 571, 1, 1, 2778.103, 6157.446, 84.27789, 3.298687, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1140, 180415, 571, 1, 1, 2781.07, 6130.521, 90.43552, 5.515242, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1141, 180415, 571, 1, 1, 2785.955, 6135.013, 87.93523, 3.909541, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1142, 180415, 571, 1, 1, 2777.994, 6133.772, 90.43637, 1.850049, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1143, 180415, 571, 1, 1, 2782.876, 6138.491, 87.9035, 0.7853968, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1144, 180415, 571, 1, 1, 2783.253, 6132.512, 89.46143, 0.5061446, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1145, 180415, 571, 1, 1, 2779.491, 6129.215, 90.78801, 3.961899, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1146, 180415, 571, 1, 1, 2776.609, 6132.236, 90.81976, 2.565632, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1147, 180415, 571, 1, 1, 2772.306, 6123.107, 91.52767, 2.391098, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1148, 180415, 571, 1, 1, 2768.484, 6124.985, 97.70737, 3.717554, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1149, 180415, 571, 1, 1, 2771.088, 6121.854, 97.64502, 1.815142, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1150, 180415, 571, 1, 1, 2771.566, 6127.16, 91.71031, 4.956738, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1151, 180415, 571, 1, 1, 2773.846, 6124.534, 91.67098, 4.206246, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1152, 180415, 571, 1, 1, 2769.93, 6125.85, 91.52602, 2.967041, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4129) +(@OGUID+1153, 180415, 571, 1, 1, 2297.869, 5280.106, 13.11051, 6.021387, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1154, 180415, 571, 1, 1, 2292.861, 5276.689, 13.39523, 4.101525, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1155, 180415, 571, 1, 1, 2292.751, 5278.278, 13.39523, 3.804818, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1156, 180415, 571, 1, 1, 2293.383, 5279.647, 13.39523, 4.520406, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1157, 180415, 571, 1, 1, 2295.305, 5274.703, 13.39523, 2.007128, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1158, 180415, 571, 1, 1, 2291.743, 5276.248, 13.28105, 3.351047, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1159, 180415, 571, 1, 1, 2293.839, 5275.374, 13.39523, 5.410522, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1160, 180415, 571, 1, 1, 2293.025, 5274.428, 13.18383, 0, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1161, 180415, 571, 1, 1, 2298.755, 5278.823, 13.17301, 4.537859, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1162, 180415, 571, 1, 1, 2298.857, 5277.28, 13.15912, 3.036838, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1163, 180415, 571, 1, 1, 2269.472, 5199.901, 11.49839, 1.570796, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1164, 180415, 571, 1, 1, 2270.224, 5199.647, 11.84797, 5.67232, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1165, 180415, 571, 1, 1, 2267.266, 5195.724, 11.25468, 4.01426, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1166, 180415, 571, 1, 1, 2271.104, 5199.311, 12.33314, 3.595379, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1167, 180415, 571, 1, 1, 2262.667, 5194.889, 14.41752, 1.745327, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1168, 180415, 571, 1, 1, 2269.422, 5194.798, 12.2818, 2.18166, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1169, 180415, 571, 1, 1, 2268.748, 5200.188, 11.23592, 4.834563, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1170, 180415, 571, 1, 1, 2264.628, 5203.938, 12.71451, 4.799657, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1171, 180415, 571, 1, 1, 2268.505, 5195.202, 11.93541, 5.253442, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1172, 180415, 571, 1, 1, 2267.729, 5195.542, 11.41191, 3.47321, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1173, 180415, 571, 1, 1, 2269.927, 5181.998, 20.93, 3.874631, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1174, 180415, 571, 1, 1, 2288.382, 5209.055, 17.64837, 3.124123, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1175, 180415, 571, 1, 1, 2268.734, 5184.522, 20.88139, 1.151916, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1176, 180415, 571, 1, 1, 2271.566, 5188.706, 20.67995, 0.7330382, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1177, 180415, 571, 1, 1, 2271.873, 5189.512, 21.19639, 4.06662, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1178, 180415, 571, 1, 1, 2272.297, 5190.432, 21.74726, 5.794494, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1179, 180415, 571, 1, 1, 2292.874, 5206.81, 17.99297, 2.705255, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1180, 180415, 571, 1, 1, 2288.034, 5203.917, 13.63426, 4.729844, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1181, 180415, 571, 1, 1, 2289.651, 5198.8, 24.89842, 6.126106, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1182, 180415, 571, 1, 1, 2285.987, 5198.663, 13.60694, 1.745327, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1183, 180415, 571, 1, 1, 2289.193, 5206.791, 13.63426, 4.642576, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1184, 180415, 571, 1, 1, 2277.729, 5188.15, 21.78212, 1.815142, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1185, 180415, 571, 1, 1, 2300.695, 5202.11, 18.77489, 1.884953, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1186, 180415, 571, 1, 1, 2277.347, 5187.327, 21.23565, 3.996807, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1187, 180415, 571, 1, 1, 2299.122, 5197.798, 18.77534, 5.532695, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1188, 180415, 571, 1, 1, 2276.96, 5186.483, 20.70242, 1.954769, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1189, 180415, 571, 1, 1, 2303.15, 5193.464, 18.77864, 4.66003, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1190, 180415, 571, 1, 1, 2273.479, 5180.935, 20.96472, 2.460913, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1191, 180415, 571, 1, 1, 2304.057, 5195.878, 18.77864, 1.413715, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1192, 180415, 571, 1, 1, 2275.646, 5181.717, 21.01333, 2.775069, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4032) +(@OGUID+1193, 180415, 571, 1, 1, 3000.993, 4068.12, 30.11452, 1.291542, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1194, 180415, 571, 1, 1, 3014.259, 4067.539, 31.04936, 3.926996, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1195, 180415, 571, 1, 1, 3001.769, 4049.21, 26.07964, 0.3665176, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1196, 180415, 571, 1, 1, 3007.144, 4059.308, 26.76467, 5.969027, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1197, 180415, 571, 1, 1, 3003.417, 4061.542, 26.18109, 6.126106, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1198, 180415, 571, 1, 1, 3003.007, 4059.802, 26.62822, 1.012289, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1199, 180415, 571, 1, 1, 3007.312, 4061.112, 26.29614, 4.886924, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1200, 180415, 571, 1, 1, 3003.312, 4060.399, 26.59323, 0.8901166, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1201, 180415, 571, 1, 1, 3007.251, 4060.04, 26.53866, 3.874631, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1202, 180415, 571, 1, 1, 3004.535, 4048.617, 26.07964, 2.513274, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1203, 180415, 571, 1, 1, 2862.335, 4038.781, 5.057745, 5.98648, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1204, 180415, 571, 1, 1, 2860.901, 4036.917, 10.936, 0.9075702, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1205, 180415, 571, 1, 1, 2863.556, 4030.712, 10.90262, 2.513274, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1206, 180415, 571, 1, 1, 2870.361, 4032.718, 5.063904, 4.171338, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1207, 180415, 571, 1, 1, 2874.672, 4034.085, 5.337824, 2.792518, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1208, 180415, 571, 1, 1, 2871.422, 4041.642, 5.131527, 2.373644, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1209, 180415, 571, 1, 1, 2866.514, 4040.803, 5.103539, 0.2792516, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1210, 180415, 571, 1, 1, 2865.706, 4030.687, 5.018806, 2.007128, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1211, 180415, 571, 1, 1, 2852.11, 4024.6, 5.079292, 3.089183, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1212, 180415, 571, 1, 1, 2834.966, 4027.097, 5.066519, 2.740162, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1213, 180415, 571, 1, 1, 2857.513, 4036.657, 5.022579, 3.508117, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1214, 180415, 571, 1, 1, 2847.389, 4022.759, 5.015669, 1.134463, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1215, 180415, 571, 1, 1, 2848.344, 4032.73, 5.091734, 0, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1216, 180415, 571, 1, 1, 2839.194, 4028.807, 5.034027, 4.677484, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1217, 180415, 571, 1, 1, 2861.214, 4028.713, 4.992302, 4.01426, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1218, 180415, 571, 1, 1, 2853.19, 4035.031, 5.072161, 5.846854, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1219, 180415, 571, 1, 1, 2844.015, 4030.81, 5.057843, 2.234018, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1220, 180415, 571, 1, 1, 2842.966, 4020.906, 4.97491, 0.01745246, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1221, 180415, 571, 1, 1, 2856.586, 4026.636, 5.041717, 0.802851, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1222, 180415, 571, 1, 1, 2838.301, 4018.869, 5.02294, 4.66003, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4113) +(@OGUID+1223, 180415, 571, 1, 1, 3434.656, 4170.812, 14.18469, 5.707228, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+1224, 180415, 571, 1, 1, 3436.351, 4170.699, 14.72765, 6.056293, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+1225, 180415, 571, 1, 1, 3434.991, 4175.841, 14.25499, 5.602507, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+1226, 180415, 571, 1, 1, 3437.776, 4170.405, 15.33066, 2.373644, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+1227, 180415, 571, 1, 1, 3436.812, 4175.733, 14.72314, 3.124123, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 0) +(@OGUID+1228, 180415, 571, 1, 1, 3438.13, 4175.703, 15.35011, 5.515242, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1229, 180415, 571, 1, 1, 3439.169, 4170.2, 15.85179, 1.274088, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1230, 180415, 571, 1, 1, 3439.449, 4175.608, 15.88088, 3.525572, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1231, 180415, 571, 1, 1, 3441.065, 4175.682, 16.57793, 5.323256, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1232, 180415, 571, 1, 1, 3441.056, 4170.128, 16.49479, 4.956738, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1233, 180415, 571, 1, 1, 3460.127, 4139.347, 15.29107, 4.625124, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1234, 180415, 571, 1, 1, 3460.05, 4142.877, 16.52606, 2.740162, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1235, 180415, 571, 1, 1, 3465.668, 4142.377, 16.36272, 5.166176, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1236, 180415, 571, 1, 1, 3460.073, 4138.049, 15.04643, 6.056293, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1237, 180415, 571, 1, 1, 3459.941, 4140.769, 15.82715, 3.42085, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1238, 180415, 571, 1, 1, 3465.849, 4140.417, 15.76362, 5.078908, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1239, 180415, 571, 1, 1, 3458.424, 4132.354, 17.18105, 1.884953, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1240, 180415, 571, 1, 1, 3465.589, 4138.927, 15.2921, 1.500983, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1241, 180415, 571, 1, 1, 3458.859, 4132.616, 17.19908, 2.35619, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1242, 180415, 571, 1, 1, 3465.348, 4137.641, 15.11139, 0.122173, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1243, 180415, 571, 1, 1, 3491.878, 4167.745, 15.70641, 4.607672, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1244, 180415, 571, 1, 1, 3490.802, 4173.49, 16.09687, 3.700105, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1245, 180415, 571, 1, 1, 3493.248, 4167.78, 15.00927, 3.874631, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1246, 180415, 571, 1, 1, 3490.705, 4167.838, 16.1151, 3.979355, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1247, 180415, 571, 1, 1, 3497.003, 4167.765, 13.85431, 1.221729, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1248, 180415, 571, 1, 1, 3497.161, 4173.208, 13.8974, 3.263772, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1249, 180415, 571, 1, 1, 3495.283, 4173.163, 14.59191, 2.91469, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1250, 180415, 571, 1, 1, 3493.558, 4173.144, 15.14168, 3.857183, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1251, 180415, 571, 1, 1, 3495.103, 4167.599, 14.42155, 3.403396, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1252, 180415, 571, 1, 1, 3492.093, 4173.33, 15.54947, 3.508117, 0, 0, 0, 1, 120, 255, 1), -- 180415 (Area: 4043) +(@OGUID+1253, 180472, 571, 1, 1, 5202.763, -1310.045, 247.7712, 0.7155849, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 66) +(@OGUID+1254, 180472, 571, 1, 1, 5205.405, -1316.248, 247.7859, 0.5585039, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 66) +(@OGUID+1255, 180472, 571, 1, 1, 5196.807, -1312.714, 247.8102, 5.567601, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 66) +(@OGUID+1256, 180472, 571, 1, 1, 5198.6, -1318.504, 247.8461, 1.204277, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 66) +(@OGUID+1257, 180472, 571, 1, 1, 3842.744, -4550, 214.0861, 2.44346, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 0) +(@OGUID+1258, 180472, 571, 1, 1, 3877.871, -4502.53, 218.5026, 2.33874, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 0) +(@OGUID+1259, 180472, 571, 1, 1, 3843.904, -4545.311, 213.8107, 0.8552105, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 0) +(@OGUID+1260, 180472, 571, 1, 1, 3839.872, -4542.153, 213.6485, 1.588249, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 0) +(@OGUID+1261, 180472, 571, 1, 1, 3872.773, -4503.769, 218.4031, 1.239183, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 0) +(@OGUID+1262, 180472, 571, 1, 1, 3869.185, -4499.854, 218.2175, 0.157079, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4211) +(@OGUID+1263, 180472, 571, 1, 1, 3870.929, -4494.531, 218.1595, 5.375615, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4211) +(@OGUID+1264, 180472, 571, 1, 1, 3879.285, -4497.91, 218.7872, 3.368496, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4211) +(@OGUID+1265, 180472, 571, 1, 1, 3876.223, -4493.979, 218.6851, 4.363324, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4211) +(@OGUID+1266, 180472, 571, 1, 1, 2671.557, -4386.672, 291.2738, 2.879789, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4065) +(@OGUID+1267, 180472, 571, 1, 1, 2676.202, -4381.061, 290.9279, 2.373644, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4065) +(@OGUID+1268, 180472, 571, 1, 1, 422.7614, -4514.731, 254.5068, 0.7679439, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 3991) +(@OGUID+1269, 180472, 571, 1, 1, 422.1116, -4519.995, 254.5345, 5.462882, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 3991) +(@OGUID+1270, 180472, 571, 1, 1, 416.6321, -4519.402, 254.5415, 3.700105, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 3991) +(@OGUID+1271, 180472, 571, 1, 1, 417.3981, -4513.884, 254.597, 2.303831, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 3991) +(@OGUID+1272, 180472, 571, 1, 1, 723.5851, -2929.853, 11.01728, 0.06981169, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 3987) +(@OGUID+1273, 180472, 571, 1, 1, 695.5886, -2934.49, 3.196574, 0, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 3987) +(@OGUID+1274, 180472, 571, 1, 1, 811.0573, -2915.457, 17.58987, 3.874631, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 3987) +(@OGUID+1275, 180472, 571, 1, 1, 1421.413, -3278.163, 182.3756, 3.455756, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 3998) +(@OGUID+1276, 180472, 571, 1, 1, 1423.51, -3272.448, 182.0631, 2.583081, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 3998) +(@OGUID+1277, 180472, 571, 1, 1, 1422.446, -3281.979, 181.9594, 4.206246, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 3998) +(@OGUID+1278, 180472, 571, 1, 1, 1426.693, -3282.785, 182.3478, 4.799657, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 3998) +(@OGUID+1279, 180472, 571, 1, 1, 1431.63, -3279.372, 182.0839, 5.585054, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 3998) +(@OGUID+1280, 180472, 571, 1, 1, 639.705, -5012.253, 8.629839, 3.560473, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 3981) +(@OGUID+1281, 180472, 571, 1, 1, 592.1059, -4952.096, 34.07586, 5.811947, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 3981) +(@OGUID+1282, 180472, 571, 1, 1, 610.4792, -4920.491, 22.26099, 3.298687, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 3981) +(@OGUID+1283, 180472, 571, 1, 1, 586.1684, -4953.842, 33.8328, 4.223697, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 3981) +(@OGUID+1284, 180472, 571, 1, 1, 596.9149, -5010.774, 7.315163, 6.19592, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 3981) +(@OGUID+1285, 180472, 571, 1, 1, 580.2164, -4941.878, 23.65312, 3.560473, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 3981) +(@OGUID+1286, 180472, 571, 1, 1, 548.9089, -5022.439, 15.06125, 1.850049, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 3981) +(@OGUID+1287, 180472, 571, 1, 1, 2472.567, -5063.961, 290.0428, 2.792518, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4003) +(@OGUID+1288, 180472, 571, 1, 1, 2472.634, -5068.495, 290.1004, 3.857183, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4003) +(@OGUID+1289, 180472, 571, 1, 1, 2546.96, -1842.127, 15.45883, 4.939284, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4242) +(@OGUID+1290, 180472, 571, 1, 1, 2492.571, -1926.668, 18.88001, 2.513274, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4242) +(@OGUID+1291, 180472, 571, 1, 1, 2492.924, -1957.088, 19.6185, 2.967041, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4242) +(@OGUID+1292, 180472, 571, 1, 1, 2497.964, -1933.934, 18.74674, 6.021387, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4242) +(@OGUID+1293, 180472, 571, 1, 1, 2548.99, -1836.533, 16.33319, 2.042035, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4242) +(@OGUID+1294, 180472, 571, 1, 1, 2470.893, -1923.861, 19.63781, 3.595379, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4242) +(@OGUID+1295, 180472, 571, 1, 1, 2492.745, -1840.021, 15.76282, 5.480334, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4242) +(@OGUID+1296, 180472, 571, 1, 1, 2558.018, -1829.936, 16.32347, 1.675514, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4242) +(@OGUID+1297, 180472, 571, 1, 1, 2563.788, -1830.118, 15.46013, 3.124123, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4242) +(@OGUID+1298, 180472, 571, 1, 1, 3654.827, -701.1371, 229.9562, 4.625124, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4177) +(@OGUID+1299, 180472, 571, 1, 1, 3660.257, -706.6854, 219.9831, 2.216565, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4177) +(@OGUID+1300, 180472, 571, 1, 1, 3650.975, -716.6632, 220.7892, 3.071766, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4177) +(@OGUID+1301, 180472, 571, 1, 1, 3624.304, -716.2471, 218.5354, 3.176533, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4177) +(@OGUID+1302, 180472, 571, 1, 1, 3472.093, 1983.797, 70.11913, 5.410522, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4158) +(@OGUID+1303, 180472, 571, 1, 1, 3475.918, 2008.681, 70.16867, 0.6632232, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4158) +(@OGUID+1304, 180472, 571, 1, 1, 3842.197, 1512.92, 103.3451, 1.483528, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4165) +(@OGUID+1305, 180472, 571, 1, 1, 7777.079, -2831.855, 1230.241, 0.05235888, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 0) +(@OGUID+1306, 180472, 571, 1, 1, 7776.125, -2826.765, 1230.253, 0.01745246, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 0) +(@OGUID+1307, 180472, 571, 1, 1, 7799.851, -2952.78, 1268.356, 1.413715, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4441) +(@OGUID+1308, 180472, 571, 1, 1, 7809.275, -2957.787, 1268.587, 0.4537851, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4441) +(@OGUID+1309, 180472, 571, 1, 1, 6133.882, -1074.452, 408.0246, 4.747296, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4419) +(@OGUID+1310, 180472, 571, 1, 1, 6122.911, -1073.775, 408.7633, 1.727875, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4419) +(@OGUID+1311, 180472, 571, 1, 1, 6111.259, -1074.321, 408.5562, 4.66003, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4419) +(@OGUID+1312, 180472, 571, 1, 1, 6676.293, -199.2238, 957.2843, 3.612838, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4428) +(@OGUID+1313, 180472, 571, 1, 1, 5550.766, 5732.24, -72.42144, 6.108654, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4285) +(@OGUID+1314, 180472, 571, 1, 1, 5543.742, 5736.505, -72.40427, 0.2094394, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4285) +(@OGUID+1315, 180472, 571, 1, 1, 5545.069, 5730.92, -72.33108, 1.099556, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4285) +(@OGUID+1316, 180472, 571, 1, 1, 5549.416, 5737.876, -72.36977, 2.775069, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4285) +(@OGUID+1317, 180472, 571, 1, 1, 5563.28, 5767.702, -68.84998, 6.265733, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4285) +(@OGUID+1318, 180472, 571, 1, 1, 5570.772, 5774.083, -68.8186, 2.373644, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4285) +(@OGUID+1319, 180472, 571, 1, 1, 5577.149, 5766.814, -68.80267, 5.096362, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4285) +(@OGUID+1320, 180472, 571, 1, 1, 5569.961, 5760.628, -68.76757, 4.852017, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4285) +(@OGUID+1321, 180472, 571, 1, 1, 5482.561, 4728.407, -190.2393, 0.05235888, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4290) +(@OGUID+1322, 180472, 571, 1, 1, 4496.243, 5710.914, 87.39838, 4.118979, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4123) +(@OGUID+1323, 180472, 571, 1, 1, 4504.742, 5718.78, 88.16618, 2.426008, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4122) +(@OGUID+1324, 180472, 571, 1, 1, 4510.791, 5692.819, 87.46987, 4.01426, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4122) +(@OGUID+1325, 180472, 571, 1, 1, 4514.077, 5725.089, 87.45109, 2.775069, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4122) +(@OGUID+1326, 180472, 571, 1, 1, 4528.651, 5707.221, 87.4934, 1.274088, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4122) +(@OGUID+1327, 180472, 571, 1, 1, 4166.699, 5280.941, 32.17652, 3.228859, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4108) +(@OGUID+1328, 180472, 571, 1, 1, 2816.226, 6166.392, 93.11073, 0.8377575, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4129) +(@OGUID+1329, 180472, 571, 1, 1, 2271.969, 5196.342, 17.54031, 2.775069, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4032) +(@OGUID+1330, 180472, 571, 1, 1, 2283.616, 5204.792, 18.22377, 0.06981169, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4032) +(@OGUID+1331, 180472, 571, 1, 1, 2275.164, 5189.711, 27.38649, 1.169369, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4032) +(@OGUID+1332, 180472, 571, 1, 1, 3463.354, 4178.378, 23.5975, 4.258607, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4043) +(@OGUID+1333, 180472, 571, 1, 1, 3467.106, 4178.543, 23.5734, 4.01426, 0, 0, 0, 1, 120, 255, 1), -- 180472 (Area: 4043) +(@OGUID+1334, 180425, 571, 1, 1, 5220.801, -1312.929, 242.096, 0.1396245, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 66) +(@OGUID+1335, 180425, 571, 1, 1, 5219.449, -1310.885, 242.0745, 0.9250238, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 66) +(@OGUID+1336, 180425, 571, 1, 1, 5231.815, -1317.981, 242.3635, 2.932139, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 66) +(@OGUID+1337, 180425, 571, 1, 1, 5231.988, -1321.641, 242.3571, 5.67232, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 66) +(@OGUID+1338, 180425, 571, 1, 1, 5233.578, -1319.166, 242.3319, 5.811947, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 66) +(@OGUID+1339, 180425, 571, 1, 1, 5220.486, -1314.131, 242.052, 5.585054, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 66) +(@OGUID+1340, 180425, 571, 1, 1, 5218.222, -1315.866, 241.8938, 5.288348, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 66) +(@OGUID+1341, 180425, 571, 1, 1, 5220.872, -1331.886, 242.2099, 1.762782, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 66) +(@OGUID+1342, 180425, 571, 1, 1, 5222.452, -1332.75, 242.4185, 5.951575, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 66) +(@OGUID+1343, 180425, 571, 1, 1, 5213.813, -1299.402, 242.4057, 4.834563, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 66) +(@OGUID+1344, 180425, 571, 1, 1, 5221.667, -1334.106, 242.3032, 0.122173, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 66) +(@OGUID+1345, 180425, 571, 1, 1, 5219.712, -1332.302, 242.2887, 1.919862, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 66) +(@OGUID+1346, 180425, 571, 1, 1, 5214.818, -1299.522, 242.3706, 5.462882, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 66) +(@OGUID+1347, 180425, 571, 1, 1, 5763.354, -3564.075, 387.949, 1.082103, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 4323) +(@OGUID+1348, 180425, 571, 1, 1, 5765.062, -3566.035, 388.1909, 1.727875, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 4323) +(@OGUID+1349, 180425, 571, 1, 1, 5766.175, -3563.893, 387.8907, 1.082103, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 4323) +(@OGUID+1350, 180425, 571, 1, 1, 3407.464, -2802.637, 212.434, 1.029743, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 0) +(@OGUID+1351, 180425, 571, 1, 1, 3412.858, -2802.222, 212.7033, 2.670348, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 0) +(@OGUID+1352, 180425, 571, 1, 1, 3408.691, -2804.216, 212.4176, 1.553341, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 0) +(@OGUID+1353, 180425, 571, 1, 1, 3400.027, -2790.777, 212.3845, 0.2792516, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 0) +(@OGUID+1354, 180425, 571, 1, 1, 3397.131, -2788.776, 212.3823, 0.2617982, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 0) +(@OGUID+1355, 180425, 571, 1, 1, 3398.373, -2790.181, 212.3858, 0.4712385, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 0) +(@OGUID+1356, 180425, 571, 1, 1, 1904.425, -6141.741, 19.07745, 5.794494, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 4000) +(@OGUID+1357, 180425, 571, 1, 1, 605.681, -4923.877, 19.09374, 3.159062, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 3981) +(@OGUID+1358, 180425, 571, 1, 1, 606.3546, -4926.564, 19.09381, 3.665196, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 3981) +(@OGUID+1359, 180425, 571, 1, 1, 587.7562, -4951.589, 27.65986, 2.303831, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 3981) +(@OGUID+1360, 180425, 571, 1, 1, 582.8324, -4936.509, 31.0752, 4.206246, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 3981) +(@OGUID+1361, 180425, 571, 1, 1, 581.9504, -4926.806, 19.88217, 5.026549, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 3981) +(@OGUID+1362, 180425, 571, 1, 1, 5564.997, 5765.261, -74.12132, 1.134463, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 4285) +(@OGUID+1363, 180425, 571, 1, 1, 5587.477, 5747.581, -71.46241, 3.543024, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 4285) +(@OGUID+1364, 180425, 571, 1, 1, 5587.182, 5750.653, -71.4938, 2.391098, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 4285) +(@OGUID+1365, 180425, 571, 1, 1, 5589.738, 5741.145, -69.95851, 3.124123, 0, 0, 0, 1, 120, 255, 1), -- 180425 (Area: 4285) +(@OGUID+1366, 180426, 571, 1, 1, 5759.534, -3544.033, 396.188, 3.892087, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1367, 180426, 571, 1, 1, 5761.476, -3543.627, 394.9244, 4.904376, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1368, 180426, 571, 1, 1, 5760.164, -3544.849, 397.1731, 5.462882, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1369, 180426, 571, 1, 1, 5759.306, -3545.708, 394.7601, 4.468043, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1370, 180426, 571, 1, 1, 5761.338, -3545.427, 398.2059, 1.483528, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1371, 180426, 571, 1, 1, 3856.363, -4541.962, 219.7176, 3.228859, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1372, 180426, 571, 1, 1, 3854.806, -4539.307, 220.7594, 0.8203033, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1373, 180426, 571, 1, 1, 3856.938, -4540.484, 224.4462, 3.298687, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1374, 180426, 571, 1, 1, 3854.925, -4535.948, 222.5168, 3.665196, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1375, 180426, 571, 1, 1, 3857.097, -4538.585, 223.1828, 4.81711, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1376, 180426, 571, 1, 1, 4590.376, -4234.787, 193.9518, 1.553341, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4159) +(@OGUID+1377, 180426, 571, 1, 1, 4590.996, -4232.708, 196.9146, 2.007128, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4159) +(@OGUID+1378, 180426, 571, 1, 1, 4588.499, -4235.377, 199.5923, 4.101525, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4159) +(@OGUID+1379, 180426, 571, 1, 1, 3413.123, -2821.453, 213.0589, 3.263772, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1380, 180426, 571, 1, 1, 3408.973, -2821.946, 212.8639, 4.572764, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1381, 180426, 571, 1, 1, 3406.235, -2823.066, 211.4089, 4.06662, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1382, 180426, 571, 1, 1, 3407.286, -2820.172, 209.3393, 5.427975, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1383, 180426, 571, 1, 1, 3407.906, -2825.792, 214.426, 2.949595, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1384, 180426, 571, 1, 1, 3444.409, -2768.932, 208.7122, 3.351047, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1385, 180426, 571, 1, 1, 3442.279, -2768.483, 208.9515, 2.024579, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1386, 180426, 571, 1, 1, 3446.616, -2769.13, 209.847, 1.06465, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1387, 180426, 571, 1, 1, 3442.672, -2767.101, 211.0916, 0.2094394, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4204) +(@OGUID+1388, 180426, 571, 1, 1, 3441.674, -2765.563, 210.9066, 4.537859, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4204) +(@OGUID+1389, 180426, 571, 1, 1, 3255.571, -2257.918, 124.4686, 2.44346, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4248) +(@OGUID+1390, 180426, 571, 1, 1, 3261.756, -2252.54, 130.7128, 1.256636, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4206) +(@OGUID+1391, 180426, 571, 1, 1, 3255.756, -2251.26, 124.3831, 4.01426, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4206) +(@OGUID+1392, 180426, 571, 1, 1, 3245.001, -2244.356, 130.5014, 2.129301, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4206) +(@OGUID+1393, 180426, 571, 1, 1, 3245.857, -2254.095, 131.8804, 3.979355, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4206) +(@OGUID+1394, 180426, 571, 1, 1, 3249.491, -2250.945, 125.1241, 1.448622, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4206) +(@OGUID+1395, 180426, 571, 1, 1, 3242.157, -2246.462, 133.1835, 4.031712, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4206) +(@OGUID+1396, 180426, 571, 1, 1, 3251.072, -2245.957, 127.2621, 2.216565, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4206) +(@OGUID+1397, 180426, 571, 1, 1, 3253.139, -2253.7, 124.5425, 2.722713, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4206) +(@OGUID+1398, 180426, 571, 1, 1, 3258.291, -2247.109, 125.9945, 5.305802, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4206) +(@OGUID+1399, 180426, 571, 1, 1, 2665.021, -4365.307, 293.8361, 0.8901166, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4065) +(@OGUID+1400, 180426, 571, 1, 1, 2659.459, -4361.625, 304.2402, 3.996807, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4065) +(@OGUID+1401, 180426, 571, 1, 1, 2660.582, -4368.252, 294.3411, 2.268925, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4065) +(@OGUID+1402, 180426, 571, 1, 1, 2671.556, -4363.807, 296.0383, 6.248279, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4065) +(@OGUID+1403, 180426, 571, 1, 1, 762.1302, -2923.717, 34.17405, 0, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 3987) +(@OGUID+1404, 180426, 571, 1, 1, 761.934, -2924.54, 36.54957, 0, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 3987) +(@OGUID+1405, 180426, 571, 1, 1, 767.8195, -2920.502, 33.86417, 0, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 3987) +(@OGUID+1406, 180426, 571, 1, 1, 759.9549, -2911.951, 42.32548, 2.548179, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 3987) +(@OGUID+1407, 180426, 571, 1, 1, 766.9323, -2913.224, 34.78922, 1.221729, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 3987) +(@OGUID+1408, 180426, 571, 1, 1, 753.5833, -2915.382, 46.25695, 5.270896, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 3987) +(@OGUID+1409, 180426, 571, 1, 1, 769.243, -2910.061, 45.63573, 1.902409, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 3987) +(@OGUID+1410, 180426, 571, 1, 1, 755.2222, -2907.67, 46.01165, 0, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 3987) +(@OGUID+1411, 180426, 571, 1, 1, 1445.891, -3264.745, 200.1135, 1.762782, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 3998) +(@OGUID+1412, 180426, 571, 1, 1, 1426.741, -3276.997, 203.4877, 6.126106, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 3998) +(@OGUID+1413, 180426, 571, 1, 1, 1437.927, -3264.418, 201.1698, 5.044002, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 3998) +(@OGUID+1414, 180426, 571, 1, 1, 1453.434, -3267.578, 204.6001, 5.183629, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 3998) +(@OGUID+1415, 180426, 571, 1, 1, 1453.021, -3271.075, 202.1549, 0.4712385, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 3998) +(@OGUID+1416, 180426, 571, 1, 1, 585.0469, -4935.894, 57.77173, 5.044002, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 3981) +(@OGUID+1417, 180426, 571, 1, 1, 584.2552, -4927.658, 53.76381, 0.5585039, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 3981) +(@OGUID+1418, 180426, 571, 1, 1, 586.4132, -4924.658, 54.59381, 2.286379, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 3981) +(@OGUID+1419, 180426, 571, 1, 1, 579.7292, -4928.83, 52.11523, 2.094393, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 3981) +(@OGUID+1420, 180426, 571, 1, 1, 582.1268, -4925.632, 54.62183, 4.66003, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 3981) +(@OGUID+1421, 180426, 571, 1, 1, 2474.248, -5056.83, 313.3344, 4.136433, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4003) +(@OGUID+1422, 180426, 571, 1, 1, 2485.361, -5057.889, 309.7409, 3.211419, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4003) +(@OGUID+1423, 180426, 571, 1, 1, 2484.832, -5065.577, 312.5736, 3.47321, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4003) +(@OGUID+1424, 180426, 571, 1, 1, 2496.339, -5058.946, 314.3534, 4.101525, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4003) +(@OGUID+1425, 180426, 571, 1, 1, 2494.715, -5066.793, 317.6408, 0.8552105, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4003) +(@OGUID+1426, 180426, 571, 1, 1, 3677.996, -706.5052, 228.3673, 3.246347, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4177) +(@OGUID+1427, 180426, 571, 1, 1, 3677.367, -707.6371, 229.6971, 0.6283169, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4177) +(@OGUID+1428, 180426, 571, 1, 1, 3678.253, -708.9809, 226.644, 3.874631, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4177) +(@OGUID+1429, 180426, 571, 1, 1, 3676.219, -710.4948, 225.2403, 4.101525, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4177) +(@OGUID+1430, 180426, 571, 1, 1, 3676.188, -708.6979, 224.8116, 3.403396, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4177) +(@OGUID+1431, 180426, 571, 1, 1, 2785.015, 901.6146, 48.99309, 1.186823, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4152) +(@OGUID+1432, 180426, 571, 1, 1, 2783.98, 899.7049, 45.72382, 5.724681, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4152) +(@OGUID+1433, 180426, 571, 1, 1, 2782.839, 900.9566, 42.67208, 2.792518, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4152) +(@OGUID+1434, 180426, 571, 1, 1, 2784.394, 900.7917, 45.83669, 5.602507, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4152) +(@OGUID+1435, 180426, 571, 1, 1, 2785.267, 900.8837, 44.81691, 5.427975, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4152) +(@OGUID+1436, 180426, 571, 1, 1, 2791.718, 899.5538, 46.09661, 4.886924, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4152) +(@OGUID+1437, 180426, 571, 1, 1, 3476.73, 2003.599, 73.99326, 2.303831, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4158) +(@OGUID+1438, 180426, 571, 1, 1, 3478.633, 2003.365, 74.23189, 3.979355, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4158) +(@OGUID+1439, 180426, 571, 1, 1, 3477.792, 2004.891, 73.60688, 5.532695, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4158) +(@OGUID+1440, 180426, 571, 1, 1, 3832.804, 1582.106, 131.3168, 4.520406, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4165) +(@OGUID+1441, 180426, 571, 1, 1, 3834.938, 1583.884, 120.4484, 1.570796, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4165) +(@OGUID+1442, 180426, 571, 1, 1, 3833.898, 1575.861, 122.9623, 0, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4165) +(@OGUID+1443, 180426, 571, 1, 1, 3832.198, 1579.66, 132.7393, 0.6457717, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4165) +(@OGUID+1444, 180426, 571, 1, 1, 3832.526, 1581.196, 115.3859, 2.094393, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4165) +(@OGUID+1445, 180426, 571, 1, 1, 3828.906, 1584.929, 118.9345, 4.555311, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4165) +(@OGUID+1446, 180426, 571, 1, 1, 8451.43, -327.9097, 914.515, 2.932139, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4436) +(@OGUID+1447, 180426, 571, 1, 1, 8455.598, -326.3663, 917.7674, 3.263772, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4436) +(@OGUID+1448, 180426, 571, 1, 1, 8452.833, -325.8889, 914.8189, 4.834563, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4436) +(@OGUID+1449, 180426, 571, 1, 1, 8453.292, -324.0052, 920.886, 1.640607, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4436) +(@OGUID+1450, 180426, 571, 1, 1, 8455.642, -323.2222, 920.7881, 5.288348, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4436) +(@OGUID+1451, 180426, 571, 1, 1, 7844.746, -767.5608, 1191.334, 5.253442, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1452, 180426, 571, 1, 1, 7842.545, -767.6215, 1194.276, 2.199115, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1453, 180426, 571, 1, 1, 7852.141, -767.2952, 1195.834, 1.692969, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1454, 180426, 571, 1, 1, 7848.913, -766.7743, 1195.129, 3.560473, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1455, 180426, 571, 1, 1, 7846.739, -767.25, 1197.022, 5.759588, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1456, 180426, 571, 1, 1, 7784.639, -2821.964, 1236.108, 2.565632, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1457, 180426, 571, 1, 1, 7787.075, -2819.984, 1232.689, 2.094393, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1458, 180426, 571, 1, 1, 7785.59, -2818.872, 1223.526, 5.864307, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1459, 180426, 571, 1, 1, 7786.157, -2818.262, 1232.046, 5.358162, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1460, 180426, 571, 1, 1, 7786.893, -2823.276, 1229.596, 2.740162, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 0) +(@OGUID+1461, 180426, 571, 1, 1, 7809.587, -2948.196, 1286.938, 4.502952, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4441) +(@OGUID+1462, 180426, 571, 1, 1, 7808.482, -2948.068, 1278.769, 4.625124, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4441) +(@OGUID+1463, 180426, 571, 1, 1, 7811.129, -2948.326, 1271.424, 4.76475, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4441) +(@OGUID+1464, 180426, 571, 1, 1, 7809.795, -2948.993, 1281.115, 6.108654, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4441) +(@OGUID+1465, 180426, 571, 1, 1, 7809.976, -2947.82, 1273.044, 0.9599299, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4441) +(@OGUID+1466, 180426, 571, 1, 1, 6124.135, -1068.075, 411.8809, 4.852017, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4419) +(@OGUID+1467, 180426, 571, 1, 1, 6122.108, -1068.535, 420.491, 3.036838, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4419) +(@OGUID+1468, 180426, 571, 1, 1, 6123.244, -1067.774, 409.9026, 2.530723, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4419) +(@OGUID+1469, 180426, 571, 1, 1, 6122.385, -1067.681, 413.6337, 0.05235888, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4419) +(@OGUID+1470, 180426, 571, 1, 1, 6122.577, -1068.896, 413.7191, 3.368496, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4419) +(@OGUID+1471, 180426, 571, 1, 1, 6669.006, -214.7808, 958.1622, 0.2443456, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4428) +(@OGUID+1472, 180426, 571, 1, 1, 6664.553, -212.3703, 959.6836, 3.752462, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4428) +(@OGUID+1473, 180426, 571, 1, 1, 6666.44, -213.5402, 956.314, 1.832595, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4428) +(@OGUID+1474, 180426, 571, 1, 1, 6664.914, -213.9151, 950.6545, 2.775069, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4428) +(@OGUID+1475, 180426, 571, 1, 1, 6666.836, -214.4378, 958.3149, 3.124123, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4428) +(@OGUID+1476, 180426, 571, 1, 1, 5567.995, 5752.299, -62.10584, 0.1919852, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4285) +(@OGUID+1477, 180426, 571, 1, 1, 5568.181, 5751.221, -65.01084, 4.625124, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4285) +(@OGUID+1478, 180426, 571, 1, 1, 5568.765, 5752.361, -63.27361, 2.670348, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4285) +(@OGUID+1479, 180426, 571, 1, 1, 5568.257, 5751.483, -56.20333, 1.902409, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4285) +(@OGUID+1480, 180426, 571, 1, 1, 5567.479, 5751.587, -63.41621, 1.815142, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4285) +(@OGUID+1481, 180426, 571, 1, 1, 5568.979, 5751.631, -64.44835, 3.001947, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4285) +(@OGUID+1482, 180426, 571, 1, 1, 5568.839, 5751.018, -65.4025, 0.6283169, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4285) +(@OGUID+1483, 180426, 571, 1, 1, 4499.143, 5724.713, 94.13822, 4.415683, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4122) +(@OGUID+1484, 180426, 571, 1, 1, 4498.088, 5725.452, 96.62789, 4.293513, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4122) +(@OGUID+1485, 180426, 571, 1, 1, 4500.556, 5723.295, 96.2418, 1.97222, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4122) +(@OGUID+1486, 180426, 571, 1, 1, 4500.435, 5726.292, 99.393, 5.916668, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4122) +(@OGUID+1487, 180426, 571, 1, 1, 4499.346, 5726.276, 93.53715, 0.3316107, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4122) +(@OGUID+1488, 180426, 571, 1, 1, 4157.167, 5280.416, 44.40583, 2.286379, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4108) +(@OGUID+1489, 180426, 571, 1, 1, 4156.833, 5281.772, 41.02469, 2.705255, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4108) +(@OGUID+1490, 180426, 571, 1, 1, 4158.027, 5280.627, 37.15991, 0.4014249, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4108) +(@OGUID+1491, 180426, 571, 1, 1, 4154.264, 5279.829, 46.06804, 4.625124, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4108) +(@OGUID+1492, 180426, 571, 1, 1, 4155.604, 5278.076, 34.83815, 3.176533, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4108) +(@OGUID+1493, 180426, 571, 1, 1, 2257.031, 5204.031, 24.98001, 1.780234, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4032) +(@OGUID+1494, 180426, 571, 1, 1, 2254.734, 5204.108, 23.51893, 2.705255, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4032) +(@OGUID+1495, 180426, 571, 1, 1, 2257.891, 5202.354, 23.84128, 2.635444, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4032) +(@OGUID+1496, 180426, 571, 1, 1, 2255.429, 5202.67, 27.84299, 1.047198, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4032) +(@OGUID+1497, 180426, 571, 1, 1, 2254.955, 5201.296, 28.10752, 1.413715, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4032) +(@OGUID+1498, 180426, 571, 1, 1, 3005.91, 4082.433, 33.96024, 0.9424766, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4113) +(@OGUID+1499, 180426, 571, 1, 1, 3008.585, 4082.515, 34.65242, 2.548179, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4113) +(@OGUID+1500, 180426, 571, 1, 1, 3010.312, 4081.898, 33.98342, 5.550147, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4113) +(@OGUID+1501, 180426, 571, 1, 1, 3007.68, 4082.023, 37.0425, 1.326448, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4113) +(@OGUID+1502, 180426, 571, 1, 1, 3008.446, 4080.726, 38.37628, 5.288348, 0, 0, 0, 1, 120, 255, 1), -- 180426 (Area: 4113) +(@OGUID+1503, 180427, 571, 1, 1, 5761.307, -3544.524, 395.4309, 4.555311, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1504, 180427, 571, 1, 1, 5760.497, -3546.056, 402.0221, 3.543024, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1505, 180427, 571, 1, 1, 5759.438, -3544.823, 396.8367, 2.670348, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1506, 180427, 571, 1, 1, 5760.398, -3543.224, 397.3958, 0.087266, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1507, 180427, 571, 1, 1, 5760.684, -3547.167, 398.6145, 0.087266, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1508, 180427, 571, 1, 1, 3853.183, -4534.543, 222.1418, 4.450591, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1509, 180427, 571, 1, 1, 3852.957, -4539.858, 219.1484, 2.687807, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1510, 180427, 571, 1, 1, 3856.241, -4539.436, 221.1546, 0.2268925, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1511, 180427, 571, 1, 1, 3854.542, -4540.624, 227.1623, 5.305802, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1512, 180427, 571, 1, 1, 3856.855, -4536.955, 221.3848, 1.658062, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1513, 180427, 571, 1, 1, 4589.936, -4232.887, 187.0824, 4.171338, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4159) +(@OGUID+1514, 180427, 571, 1, 1, 4590.229, -4234.215, 186.7581, 6.143561, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4159) +(@OGUID+1515, 180427, 571, 1, 1, 4590.728, -4233.71, 184.4032, 1.97222, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4159) +(@OGUID+1516, 180427, 571, 1, 1, 3408.324, -2823.502, 209.3464, 3.630291, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1517, 180427, 571, 1, 1, 3406.425, -2821.385, 209.7437, 5.375615, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1518, 180427, 571, 1, 1, 3410.176, -2822.778, 209.1109, 4.223697, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1519, 180427, 571, 1, 1, 3409.967, -2820.047, 210.1583, 3.263772, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1520, 180427, 571, 1, 1, 3407.021, -2824.786, 209.5089, 5.951575, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1521, 180427, 571, 1, 1, 3447.131, -2770.391, 210.325, 0, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1522, 180427, 571, 1, 1, 3444.766, -2768.226, 210.0436, 6.003934, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1523, 180427, 571, 1, 1, 3444.436, -2767.122, 211.3138, 2.530723, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4204) +(@OGUID+1524, 180427, 571, 1, 1, 3441.46, -2766.443, 210.7611, 5.98648, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4204) +(@OGUID+1525, 180427, 571, 1, 1, 3446.277, -2767.188, 208.8508, 0.5759573, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4204) +(@OGUID+1526, 180427, 571, 1, 1, 3251.26, -2253.675, 124.9079, 0.7504908, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4206) +(@OGUID+1527, 180427, 571, 1, 1, 3251.778, -2250.464, 129.6705, 0.6806767, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4206) +(@OGUID+1528, 180427, 571, 1, 1, 3247.308, -2252, 130.7534, 6.248279, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4206) +(@OGUID+1529, 180427, 571, 1, 1, 3254.531, -2247.668, 129.1577, 5.480334, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4206) +(@OGUID+1530, 180427, 571, 1, 1, 3252.336, -2248.873, 122.8677, 1.500983, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4206) +(@OGUID+1531, 180427, 571, 1, 1, 3255.591, -2250.547, 129.6846, 2.809975, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4206) +(@OGUID+1532, 180427, 571, 1, 1, 3241.862, -2241.349, 122.2494, 2.495818, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4206) +(@OGUID+1533, 180427, 571, 1, 1, 3248.178, -2245.37, 125.104, 0.5410506, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4206) +(@OGUID+1534, 180427, 571, 1, 1, 3247.814, -2247.866, 124.5073, 5.323256, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4206) +(@OGUID+1535, 180427, 571, 1, 1, 3245.019, -2248.802, 122.5996, 2.216565, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4206) +(@OGUID+1536, 180427, 571, 1, 1, 2663.781, -4367.163, 302.1978, 1.012289, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4065) +(@OGUID+1537, 180427, 571, 1, 1, 2667.21, -4368.415, 300.2386, 4.886924, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4065) +(@OGUID+1538, 180427, 571, 1, 1, 2660.796, -4362.103, 307.4751, 5.916668, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4065) +(@OGUID+1539, 180427, 571, 1, 1, 768.6163, -2922.156, 38.30094, 0, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 3987) +(@OGUID+1540, 180427, 571, 1, 1, 762.2813, -2920.307, 44.85577, 0, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 3987) +(@OGUID+1541, 180427, 571, 1, 1, 767.7639, -2914.931, 50.20907, 0, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 3987) +(@OGUID+1542, 180427, 571, 1, 1, 771.118, -2914.354, 33.8317, 2.583081, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 3987) +(@OGUID+1543, 180427, 571, 1, 1, 764.632, -2912.734, 28.99734, 0, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 3987) +(@OGUID+1544, 180427, 571, 1, 1, 764.7379, -2907.014, 42.12639, 3.68265, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 3987) +(@OGUID+1545, 180427, 571, 1, 1, 1448.717, -3267.089, 201.6755, 0.7330382, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 3998) +(@OGUID+1546, 180427, 571, 1, 1, 1450.106, -3254.806, 202.5467, 5.864307, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 3998) +(@OGUID+1547, 180427, 571, 1, 1, 1432.74, -3253.945, 209.4203, 2.18166, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 3998) +(@OGUID+1548, 180427, 571, 1, 1, 1460.863, -3277.345, 207.5119, 5.794494, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 3998) +(@OGUID+1549, 180427, 571, 1, 1, 1461.863, -3264.878, 201.965, 2.722713, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 3998) +(@OGUID+1550, 180427, 571, 1, 1, 586.9097, -4944.667, 47.7813, 6.178466, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 3981) +(@OGUID+1551, 180427, 571, 1, 1, 587.7552, -4923.743, 55.51563, 4.991644, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 3981) +(@OGUID+1552, 180427, 571, 1, 1, 584.0382, -4927.713, 53.33385, 3.752462, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 3981) +(@OGUID+1553, 180427, 571, 1, 1, 586.8472, -4927.104, 56.76656, 0.8901166, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 3981) +(@OGUID+1554, 180427, 571, 1, 1, 576.6077, -4929.509, 55.73938, 2.600535, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 3981) +(@OGUID+1555, 180427, 571, 1, 1, 2473.661, -5056.833, 313.4054, 1.326448, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4003) +(@OGUID+1556, 180427, 571, 1, 1, 2484.688, -5057.96, 311.5289, 4.485497, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4003) +(@OGUID+1557, 180427, 571, 1, 1, 2496.554, -5058.851, 314.3859, 3.368496, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4003) +(@OGUID+1558, 180427, 571, 1, 1, 2485.07, -5065.702, 312.3187, 0.2443456, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4003) +(@OGUID+1559, 180427, 571, 1, 1, 2494.877, -5066.533, 313.6038, 2.530723, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4003) +(@OGUID+1560, 180427, 571, 1, 1, 3678.568, -707.9114, 225.9042, 2.722713, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4177) +(@OGUID+1561, 180427, 571, 1, 1, 3677.82, -709.7309, 223.8333, 3.019413, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4177) +(@OGUID+1562, 180427, 571, 1, 1, 3677.2, -708.3906, 226.7975, 0.5235979, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4177) +(@OGUID+1563, 180427, 571, 1, 1, 3676.558, -707.3646, 227.4937, 1.151916, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4177) +(@OGUID+1564, 180427, 571, 1, 1, 3676.709, -706.5208, 226.6307, 5.445428, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4177) +(@OGUID+1565, 180427, 571, 1, 1, 2788.414, 901.0035, 36.56704, 4.520406, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4152) +(@OGUID+1566, 180427, 571, 1, 1, 2785.122, 899.9236, 47.7719, 1.396262, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4152) +(@OGUID+1567, 180427, 571, 1, 1, 2777.589, 900.8507, 38.11501, 3.926996, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4152) +(@OGUID+1568, 180427, 571, 1, 1, 2781.267, 897.5538, 39.2057, 5.253442, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4152) +(@OGUID+1569, 180427, 571, 1, 1, 3478.735, 2004.005, 74.2953, 2.809975, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4158) +(@OGUID+1570, 180427, 571, 1, 1, 3477.231, 2002.613, 75.02769, 2.565632, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4158) +(@OGUID+1571, 180427, 571, 1, 1, 3477.298, 2003.34, 75.31145, 3.647741, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4158) +(@OGUID+1572, 180427, 571, 1, 1, 3827.1, 1578.188, 128.2818, 2.426008, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4165) +(@OGUID+1573, 180427, 571, 1, 1, 3830.623, 1585.576, 119.5804, 0.6457717, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4165) +(@OGUID+1574, 180427, 571, 1, 1, 3828.786, 1575.78, 123.5387, 1.06465, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4165) +(@OGUID+1575, 180427, 571, 1, 1, 3835.45, 1577.592, 123.1637, 3.455756, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4165) +(@OGUID+1576, 180427, 571, 1, 1, 3826.248, 1582.507, 126.0943, 0.5585039, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4165) +(@OGUID+1577, 180427, 571, 1, 1, 3835.907, 1582.106, 112.2748, 4.276057, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4165) +(@OGUID+1578, 180427, 571, 1, 1, 8456.487, -325.2882, 919.9067, 3.612838, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4436) +(@OGUID+1579, 180427, 571, 1, 1, 8455.944, -329.2031, 921.132, 3.769912, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4436) +(@OGUID+1580, 180427, 571, 1, 1, 8453.988, -324.809, 919.7067, 2.897245, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4436) +(@OGUID+1581, 180427, 571, 1, 1, 8454.191, -327.691, 920.1603, 2.042035, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4436) +(@OGUID+1582, 180427, 571, 1, 1, 8456.37, -323.9236, 922.8885, 4.747296, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4436) +(@OGUID+1583, 180427, 571, 1, 1, 7843.921, -768.7327, 1192.044, 4.293513, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1584, 180427, 571, 1, 1, 7850.358, -768.4479, 1195.303, 6.213374, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1585, 180427, 571, 1, 1, 7845.897, -769.2344, 1196.449, 6.19592, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1586, 180427, 571, 1, 1, 7849.522, -769.5695, 1199.962, 6.126106, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1587, 180427, 571, 1, 1, 7848.237, -768.1614, 1194.201, 4.310966, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1588, 180427, 571, 1, 1, 7784.186, -2819.071, 1242.727, 5.794494, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1589, 180427, 571, 1, 1, 7785.482, -2818.214, 1235.832, 2.33874, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1590, 180427, 571, 1, 1, 7784.766, -2818.804, 1243.944, 1.797689, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1591, 180427, 571, 1, 1, 7786.441, -2820.347, 1243.845, 3.33359, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 0) +(@OGUID+1592, 180427, 571, 1, 1, 7809.966, -2947.446, 1282.999, 2.775069, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4441) +(@OGUID+1593, 180427, 571, 1, 1, 7808.862, -2947.845, 1287.751, 6.056293, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4441) +(@OGUID+1594, 180427, 571, 1, 1, 7810.013, -2948.613, 1278.556, 3.001947, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4441) +(@OGUID+1595, 180427, 571, 1, 1, 6124.222, -1067.016, 412.4096, 5.305802, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4419) +(@OGUID+1596, 180427, 571, 1, 1, 6123.186, -1068.443, 417.4877, 0.8203033, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4419) +(@OGUID+1597, 180427, 571, 1, 1, 6121.662, -1067.535, 412.6524, 4.956738, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4419) +(@OGUID+1598, 180427, 571, 1, 1, 6122.928, -1067.632, 413.933, 3.647741, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4419) +(@OGUID+1599, 180427, 571, 1, 1, 6123.296, -1066.87, 411.8166, 3.595379, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4419) +(@OGUID+1600, 180427, 571, 1, 1, 6667.715, -213.3303, 956.631, 3.647741, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4428) +(@OGUID+1601, 180427, 571, 1, 1, 6669.567, -213.4681, 959.522, 3.019413, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4428) +(@OGUID+1602, 180427, 571, 1, 1, 6668.282, -214.2138, 957.4736, 5.67232, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4428) +(@OGUID+1603, 180427, 571, 1, 1, 6666.536, -212.2774, 960.9269, 3.263772, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4428) +(@OGUID+1604, 180427, 571, 1, 1, 6668.823, -212.848, 958.5125, 0.9424766, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4428) +(@OGUID+1605, 180427, 571, 1, 1, 5567.438, 5750.866, -63.57895, 4.171338, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4285) +(@OGUID+1606, 180427, 571, 1, 1, 5566.66, 5750.427, -61.74266, 4.415683, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4285) +(@OGUID+1607, 180427, 571, 1, 1, 5567.792, 5750.745, -66.3998, 1.553341, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4285) +(@OGUID+1608, 180427, 571, 1, 1, 5567.268, 5752.111, -65.63297, 2.530723, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4285) +(@OGUID+1609, 180427, 571, 1, 1, 5568.124, 5751.938, -64.30065, 1.762782, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4285) +(@OGUID+1610, 180427, 571, 1, 1, 5566.167, 5751.143, -59.03475, 4.642576, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4285) +(@OGUID+1611, 180427, 571, 1, 1, 5569.404, 5750.22, -68.71603, 4.607672, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4285) +(@OGUID+1612, 180427, 571, 1, 1, 4497.501, 5724.35, 92.66317, 0.2268925, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4122) +(@OGUID+1613, 180427, 571, 1, 1, 4499.618, 5724.213, 92.10083, 3.665196, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4122) +(@OGUID+1614, 180427, 571, 1, 1, 4498.766, 5723.341, 92.95933, 3.089183, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4122) +(@OGUID+1615, 180427, 571, 1, 1, 4500.167, 5725.043, 93.06795, 3.141593, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4122) +(@OGUID+1616, 180427, 571, 1, 1, 4498.657, 5724.655, 94.03511, 2.44346, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4122) +(@OGUID+1617, 180427, 571, 1, 1, 4155.36, 5279.535, 41.24209, 0.6283169, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4108) +(@OGUID+1618, 180427, 571, 1, 1, 4155.128, 5281.559, 43.11319, 5.218536, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4108) +(@OGUID+1619, 180427, 571, 1, 1, 4158.647, 5282.077, 43.25044, 2.251473, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4108) +(@OGUID+1620, 180427, 571, 1, 1, 4157.104, 5278.291, 42.53542, 4.415683, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4108) +(@OGUID+1621, 180427, 571, 1, 1, 4155.704, 5276.774, 34.64015, 3.735006, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4108) +(@OGUID+1622, 180427, 571, 1, 1, 2254.229, 5202.443, 25.58039, 1.239183, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4032) +(@OGUID+1623, 180427, 571, 1, 1, 2255.703, 5204.931, 32.91465, 6.265733, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4032) +(@OGUID+1624, 180427, 571, 1, 1, 2253.278, 5203.004, 26.03876, 4.136433, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4032) +(@OGUID+1625, 180427, 571, 1, 1, 2253.696, 5204.979, 23.99093, 4.834563, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4032) +(@OGUID+1626, 180427, 571, 1, 1, 2256.316, 5206.545, 25.55317, 2.146753, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4032) +(@OGUID+1627, 180427, 571, 1, 1, 3007.375, 4081.898, 36.05743, 0.8552105, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4113) +(@OGUID+1628, 180427, 571, 1, 1, 3009.335, 4081.919, 33.73442, 0.2967052, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4113) +(@OGUID+1629, 180427, 571, 1, 1, 3009.694, 4083.431, 32.96307, 2.268925, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4113) +(@OGUID+1630, 180427, 571, 1, 1, 3006.938, 4083.318, 34.42048, 4.886924, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4113) +(@OGUID+1631, 180427, 571, 1, 1, 3009.286, 4080.991, 33.72022, 1.378809, 0, 0, 0, 1, 120, 255, 1), -- 180427 (Area: 4113) +(@OGUID+1632, 180471, 571, 1, 1, 5204.491, -1317.474, 246.2982, 1.710422, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 66) +(@OGUID+1633, 180471, 571, 1, 1, 5204.556, -1311.417, 246.2742, 0.8203033, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 66) +(@OGUID+1634, 180471, 571, 1, 1, 5197.808, -1310.934, 246.395, 2.303831, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 66) +(@OGUID+1635, 180471, 571, 1, 1, 5197.694, -1316.509, 246.3158, 0, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 66) +(@OGUID+1636, 180471, 571, 1, 1, 3199.965, -2298.588, 111.0376, 1.431168, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4248) +(@OGUID+1637, 180471, 571, 1, 1, 1900.167, -6132.452, 23.4388, 4.031712, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4060) +(@OGUID+1638, 180471, 571, 1, 1, 1902.965, -6131.993, 23.66091, 2.844883, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4060) +(@OGUID+1639, 180471, 571, 1, 1, 1898.609, -6134.413, 23.38325, 3.735006, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4060) +(@OGUID+1640, 180471, 571, 1, 1, 1900.699, -6138.649, 23.68888, 5.899214, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4060) +(@OGUID+1641, 180471, 571, 1, 1, 1905.079, -6133.762, 23.68171, 2.076939, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4060) +(@OGUID+1642, 180471, 571, 1, 1, 1903.922, -6138.372, 23.43309, 0.6283169, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4060) +(@OGUID+1643, 180471, 571, 1, 1, 1905.227, -6136.752, 23.46658, 1.029743, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4060) +(@OGUID+1644, 180471, 571, 1, 1, 1899.095, -6137.361, 23.69575, 5.462882, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4060) +(@OGUID+1645, 180471, 571, 1, 1, 588.3511, -4940.63, 23.00664, 4.834563, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 3981) +(@OGUID+1646, 180471, 571, 1, 1, 587.6937, -4938.055, 22.97886, 4.852017, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 3981) +(@OGUID+1647, 180471, 571, 1, 1, 584.658, -4926.464, 22.94742, 4.869471, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 3981) +(@OGUID+1648, 180471, 571, 1, 1, 585.3281, -4928.837, 22.95987, 4.991644, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 3981) +(@OGUID+1649, 180471, 571, 1, 1, 3661.782, -704.7066, 218.3424, 2.530723, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4177) +(@OGUID+1650, 180471, 571, 1, 1, 3661.339, -709.0174, 218.379, 1.029743, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4177) +(@OGUID+1651, 180471, 571, 1, 1, 3651.781, -708.625, 219.3715, 3.752462, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4177) +(@OGUID+1652, 180471, 571, 1, 1, 3652.332, -704.342, 219.3648, 6.0912, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4177) +(@OGUID+1653, 180471, 571, 1, 1, 3579.464, 251.9427, 52.88466, 2.059488, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4161) +(@OGUID+1654, 180471, 571, 1, 1, 3575.279, 246.6563, 52.87777, 2.44346, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4161) +(@OGUID+1655, 180471, 571, 1, 1, 3523.501, 237.7691, 52.94661, 1.919862, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4161) +(@OGUID+1656, 180471, 571, 1, 1, 3517.737, 242.4236, 52.90497, 4.782203, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4161) +(@OGUID+1657, 180471, 571, 1, 1, 3512.637, 297, 52.89811, 0.6632232, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4161) +(@OGUID+1658, 180471, 571, 1, 1, 3517.312, 302.6024, 52.912, 0.802851, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4161) +(@OGUID+1659, 180471, 571, 1, 1, 3568.188, 304.9097, 52.96114, 4.834563, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4161) +(@OGUID+1660, 180471, 571, 1, 1, 3573.999, 300.1875, 52.88476, 0.2617982, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4161) +(@OGUID+1661, 180471, 571, 1, 1, 3480.169, 1977.233, 70.1636, 2.705255, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4158) +(@OGUID+1662, 180471, 571, 1, 1, 3484.095, 2013.983, 69.28771, 0.5759573, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4158) +(@OGUID+1663, 180471, 571, 1, 1, 3506.038, 1986.319, 68.24009, 3.717554, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4158) +(@OGUID+1664, 180471, 571, 1, 1, 4508.732, 5716.75, 84.35536, 3.717554, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4122) +(@OGUID+1665, 180471, 571, 1, 1, 4506.331, 5715.979, 85.08492, 0.9424766, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4122) +(@OGUID+1666, 180471, 571, 1, 1, 4506.083, 5715.355, 84.23188, 0.2617982, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4122) +(@OGUID+1667, 180471, 571, 1, 1, 4508.761, 5717.552, 85.0927, 4.904376, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4122) +(@OGUID+1668, 180471, 571, 1, 1, 2869.387, 6211.827, 213.7105, 0.3141584, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4020) +(@OGUID+1669, 180471, 571, 1, 1, 2867.295, 6213.874, 213.6728, 1.343901, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4020) +(@OGUID+1670, 180471, 571, 1, 1, 2816.863, 6165.138, 90.56039, 2.44346, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4129) +(@OGUID+1671, 180471, 571, 1, 1, 2814.848, 6167.205, 90.52396, 0.2268925, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4129) +(@OGUID+1672, 180471, 571, 1, 1, 2791.958, 6145.722, 91.96442, 0.6632232, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4129) +(@OGUID+1673, 180471, 571, 1, 1, 2793.936, 6143.066, 92.17467, 5.009095, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4129) +(@OGUID+1674, 180471, 571, 1, 1, 2769.591, 6124.062, 95.95924, 5.270896, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4129) +(@OGUID+1675, 180471, 571, 1, 1, 2770.471, 6122.91, 95.92594, 2.478367, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4129) +(@OGUID+1676, 180471, 571, 1, 1, 2278.516, 5192.333, 16.84088, 2.44346, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4032) +(@OGUID+1677, 180471, 571, 1, 1, 2280.049, 5196.121, 16.84082, 0.5934101, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4032) +(@OGUID+1678, 180471, 571, 1, 1, 3003.927, 4062.122, 33.84514, 0.5759573, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4113) +(@OGUID+1679, 180471, 571, 1, 1, 3006.915, 4061.78, 33.92781, 0.5410506, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4113) +(@OGUID+1680, 180471, 571, 1, 1, 3006.462, 4067.487, 34.17837, 2.967041, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4113) +(@OGUID+1681, 180471, 571, 1, 1, 3026.681, 4045.708, 28.72306, 4.747296, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4113) +(@OGUID+1682, 180471, 571, 1, 1, 3005.008, 4059.406, 34.61089, 2.391098, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4113) +(@OGUID+1683, 180471, 571, 1, 1, 2979.829, 4053.98, 28.70936, 1.466076, 0, 0, 0, 1, 120, 255, 1), -- 180471 (Area: 4113) +(@OGUID+1684, 180523, 571, 1, 1, 5471.11, -2643.376, 307.0311, 4.502952, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4275) +(@OGUID+1685, 180523, 571, 1, 1, 5757.718, -3563.73, 386.8262, 4.625124, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4323) +(@OGUID+1686, 180523, 571, 1, 1, 3864.262, -4536.794, 209.4336, 4.97419, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 0) +(@OGUID+1687, 180523, 571, 1, 1, 4604.042, -4237.24, 178.9002, 4.06662, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4159) +(@OGUID+1688, 180523, 571, 1, 1, 3402.777, -2788.145, 201.5207, 1.675514, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 0) +(@OGUID+1689, 180523, 571, 1, 1, 3256.107, -2192.384, 117.3726, 3.106652, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4206) +(@OGUID+1690, 180523, 571, 1, 1, 2678.036, -4392.695, 284.8349, 6.213374, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4018) +(@OGUID+1691, 180523, 571, 1, 1, 1889.731, -6193.472, 23.6236, 0.9773831, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4000) +(@OGUID+1692, 180523, 571, 1, 1, 452.467, -4536.335, 244.877, 5.113817, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 3991) +(@OGUID+1693, 180523, 571, 1, 1, 698.1771, -2928.019, -2.640473, 1.553341, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 3987) +(@OGUID+1694, 180523, 571, 1, 1, 1436.052, -3258.58, 167.779, 5.166176, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 3998) +(@OGUID+1695, 180523, 571, 1, 1, 578.6011, -4929.339, 19.16861, 0.6283169, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 3981) +(@OGUID+1696, 180523, 571, 1, 1, 2481.56, -5054.175, 284.8836, 4.97419, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4003) +(@OGUID+1697, 180523, 571, 1, 1, 3211.594, -677.0414, 167.9602, 1.326448, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 0) +(@OGUID+1698, 180523, 571, 1, 1, 3657.321, -716.2959, 215.2677, 0.8552105, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4177) +(@OGUID+1699, 180523, 571, 1, 1, 3575.916, 257.0831, 47.28813, 4.921829, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4161) +(@OGUID+1700, 180523, 571, 1, 1, 2775.545, 925.4372, 22.99003, 0.9948372, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4152) +(@OGUID+1701, 180523, 571, 1, 1, 3468.981, 2004.253, 64.86234, 3.42085, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4158) +(@OGUID+1702, 180523, 571, 1, 1, 3847.863, 1505.001, 92.51198, 2.268925, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4165) +(@OGUID+1703, 180523, 571, 1, 1, 8437.674, -355.5473, 906.4015, 5.602507, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4484) +(@OGUID+1704, 180523, 571, 1, 1, 7839.014, -805.3143, 1183.294, 3.106652, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 0) +(@OGUID+1705, 180523, 571, 1, 1, 7798.68, -2973.132, 1259.494, 3.595379, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4441) +(@OGUID+1706, 180523, 571, 1, 1, 6128.351, -1083.17, 402.6452, 2.251473, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4419) +(@OGUID+1707, 180523, 571, 1, 1, 6675.385, -195.2562, 951.1111, 0.9424766, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4428) +(@OGUID+1708, 180523, 571, 1, 1, 5565.757, 5759.502, -75.22591, 4.886924, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4285) +(@OGUID+1709, 180523, 571, 1, 1, 4506.858, 5710.637, 81.51824, 0.4712385, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4122) +(@OGUID+1710, 180523, 571, 1, 1, 4175.616, 5283.527, 26.69308, 4.136433, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4108) +(@OGUID+1711, 180523, 571, 1, 1, 2804.783, 6168.423, 85.37867, 4.310966, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4129) +(@OGUID+1712, 180523, 571, 1, 1, 2299.602, 5193.956, 11.70278, 0.1047193, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4032) +(@OGUID+1713, 180523, 571, 1, 1, 3007.872, 4052.658, 26.60726, 2.897245, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4113) +(@OGUID+1714, 180523, 571, 1, 1, 3468.352, 4151.25, 17.5926, 4.118979, 0, 0, 0, 1, 120, 255, 1), -- 180523 (Area: 4043) +(@OGUID+1715, 180431, 571, 1, 1, 5448.499, -2687.353, 317.0294, 3.298687, 0, 0, 0, 1, 120, 255, 1), -- 180431 (Area: 0) +(@OGUID+1716, 180431, 571, 1, 1, 3885.052, -4516.659, 244.4485, 5.201083, 0, 0, 0, 1, 120, 255, 1), -- 180431 (Area: 0) +(@OGUID+1717, 180431, 571, 1, 1, 3326.384, -2324.99, 148.8137, 4.468043, 0, 0, 0, 1, 120, 255, 1), -- 180431 (Area: 0) +(@OGUID+1718, 180431, 571, 1, 1, 3249.887, -2332.044, 113.358, 3.281239, 0, 0, 0, 1, 120, 255, 1), -- 180431 (Area: 0) +(@OGUID+1719, 180431, 571, 1, 1, 3228.007, -2376.978, 142.2661, 6.265733, 0, 0, 0, 1, 120, 255, 1), -- 180431 (Area: 0) +(@OGUID+1720, 180431, 571, 1, 1, 3194.981, -2324.08, 142.3525, 2.426008, 0, 0, 0, 1, 120, 255, 1), -- 180431 (Area: 0) +(@OGUID+1721, 180431, 571, 1, 1, 3355.472, -2264.87, 151.9365, 1.710422, 0, 0, 0, 1, 120, 255, 1), -- 180431 (Area: 0) +(@OGUID+1722, 180431, 571, 1, 1, 2534.615, -1939.123, 6.753963, 4.502952, 0, 0, 0, 1, 120, 255, 1), -- 180431 (Area: 394) +(@OGUID+1723, 180431, 571, 1, 1, 2505.454, -1955.444, 11.24014, 2.722713, 0, 0, 0, 1, 120, 255, 1), -- 180431 (Area: 394) +(@OGUID+1724, 180431, 571, 1, 1, 2576.156, -1817.301, 10.01707, 2.740162, 0, 0, 0, 1, 120, 255, 1), -- 180431 (Area: 394) +(@OGUID+1725, 180431, 571, 1, 1, 2545.243, -1802.575, 11.32091, 0.1745321, 0, 0, 0, 1, 120, 255, 1), -- 180431 (Area: 4242) +(@OGUID+1726, 180431, 571, 1, 1, 3690.41, 272.8268, 52.22741, 1.588249, 0, 0, 0, 1, 120, 255, 1), -- 180431 (Area: 4254) +(@OGUID+1727, 180431, 571, 1, 1, 3687.912, 302.2261, 52.22742, 2.600535, 0, 0, 0, 1, 120, 255, 1), -- 180431 (Area: 4254) +(@OGUID+1728, 180431, 571, 1, 1, 4512.567, 5708.924, 97.69891, 4.433136, 0, 0, 0, 1, 120, 255, 1); -- 180431 (Area: 4123) + +SET @OGUID:=81188; +SET @Event:=12; +DELETE FROM `game_event_gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+2471 AND `eventEntry`=@Event; +INSERT INTO game_event_gameobject SELECT @Event, gameobject.guid FROM `gameobject` WHERE gameobject.guid BETWEEN @OGUID+0 AND @OGUID+1728; diff --git a/sql/updates/world/2015_11_12_01_world.sql b/sql/updates/world/2015_11_12_01_world.sql new file mode 100644 index 00000000000..c08ebda2471 --- /dev/null +++ b/sql/updates/world/2015_11_12_01_world.sql @@ -0,0 +1,93 @@ +-- creature (2 entries) +SET @CGUID = 49818; +-- gameobject (2 entries) +SET @OGUID = 5747; + +-- ensure spell data for difficulties is there +DELETE FROM `spelldifficulty_dbc` WHERE `id` IN (28134,28135,28167); +INSERT INTO `spelldifficulty_dbc` (`id`,`spellid0`,`spellid1`,`spellid2`,`spellid3`) VALUES +(28134,54529,28134,0,0), -- Stalagg - Power Surge (yes, these are supposed to be backwards) +(28135,28135,54528,0,0), -- Feugen - Static Field +(28167,28167,54531,0,0); -- Thaddius - Chain Lightning + +-- magnetic pull +DELETE FROM `spell_scripts` WHERE `id`=54517; +DELETE FROM `spell_script_names` WHERE `spell_id`=54517; +INSERT INTO `spell_script_names` (`spell_id`,`scriptname`) VALUES (54517,"spell_thaddius_magnetic_pull"); + +-- thaddius +UPDATE `creature_template` set `unit_flags`=64 WHERE `entry`=15928; +UPDATE `creature` set `MovementType`=0 WHERE `id`=15928; + +-- tesla coil +UPDATE `creature_template` set `inhabittype`=4,`unit_flags`=33554688,`unit_flags2`=2048,`ScriptName`="npc_tesla",`MovementType`=0,`flags_extra`=0 WHERE `entry`=16218; +DELETE FROM `creature_addon` WHERE `guid` IN (select `guid` from `creature` WHERE `id` = 16218); +DELETE FROM `creature` WHERE `id` = 16218; +INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`movementtype`,`VerifiedBuild`) VALUES +(@CGUID+0,16218,533,3,1,3527.807,-2952.382,319.3258,3.909538,0,0,0,0), +(@CGUID+1,16218,533,3,1,3487.762,-2911.198,319.4061,3.909538,0,0,0,0); +INSERT INTO `creature_addon` (`guid`,`auras`) VALUES +(@CGUID+0,28109), +(@CGUID+1,28097); + +-- tesla coil search trigger range (index 30 is 500 yards) +UPDATE `spell_dbc` set `EffectRadiusIndex1`=30, `AttributesEx2`=0 WHERE `Id` IN (28098,28110); +-- tesla coil search ignores LoS +DELETE FROM `disables` WHERE `sourceType`=0 AND `entry` IN (28096,28098,28110,28111); +INSERT INTO `disables` (`sourceType`,`entry`,`flags`,`comment`) VALUES +(0,28098,64,"Stalagg Tesla Periodic - Ignore LoS"), +(0,28096,64,"Stalagg Tesla Visual - Ignore LoS"), +(0,28110,64,"Feugen Tesla Periodic - Ignore LoS"), +(0,28111,64,"Feugen Tesla Visual - Ignore LoS"); +-- tesla coil shock visual needs implicit target +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (28096,28111,28159); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`Comment`) VALUES +(13,1,28096,0,0,31,0,3,15929,0,0,"Stalagg Chain Visual - Target Stalagg"), +(13,1,28111,0,0,31,0,3,15930,0,0,"Feugen Chain Visual - Target Feugen"), +(13,1,28159,0,0,31,0,3,15928,0,0,"Thaddius Shock Visual - Target Thaddius"); + +-- tesla coil visual +DELETE FROM `gameobject` WHERE `id` IN (181477,181478); +INSERT INTO `gameobject` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`position_x`,`position_y`,`position_z`,`orientation`,`rotation0`,`rotation1`,`rotation2`,`rotation3`,`spawntimesecs`,`VerifiedBuild`) VALUES +(@OGUID+0,181477,533,3,1,3527.94,-2952.263,318.8983,3.141593,0,0,-1,0,0,0), +(@OGUID+1,181478,533,3,1,3487.324,-2911.383,318.8983,3.141593,0,0,-1,0,0,0); + +-- polarity shift scripts +DELETE FROM `spell_scripts` WHERE `id` IN (28059,28062,28084,28085,28089,29659,29660); +DELETE FROM `spell_script_names` WHERE `spell_id` IN (28059,28062,28084,28085,28089,29659,29660); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(28062,"spell_thaddius_polarity_charge"), +(28085,"spell_thaddius_polarity_charge"), +(28089,"spell_thaddius_polarity_shift"); + +-- shocking! achievement +DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (7604,7605); +INSERT INTO `achievement_criteria_data` (`criteria_id`,`type`,`value1`,`value2`,`ScriptName`) VALUES +(7604,11,0,0,"achievement_thaddius_shocking"), +(7604,12,0,0,""), +(7605,11,0,0,"achievement_thaddius_shocking"), +(7605,12,1,0,""); + +-- move 20% trigger rate for "killed target" texts from script to DB +UPDATE `creature_text` set `probability`=20 WHERE `entry`=15929 AND `groupid`=1; +UPDATE `creature_text` set `probability`=20 WHERE `entry`=15930 AND `groupid`=1; +UPDATE `creature_text` set `probability`=20 WHERE `entry`=15928 AND `groupid`=2; + +-- add missing creature_text entries for thaddius, feugen, stalagg and tesla coil +DELETE FROM `creature_text` WHERE `entry`=15928 AND `groupid`=6; +DELETE FROM `creature_text` WHERE `entry` IN (15929,15930) AND `groupid` IN (3,4); +DELETE FROM `creature_text` WHERE `entry`=16218; +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`probability`,`BroadcastTextId`,`TextRange`,`comment`) VALUES +(15928,6,0,"The polarity has shifted!",41,100,32324,3,"Thaddius EMOTE_POLARITY_SHIFTED"), +(15929,3,0,"%s dies.",16,100,10453,3,"Stalagg EMOTE_FEIGN_DEATH"), +(15930,3,0,"%s dies.",16,100,10453,3,"Feugen EMOTE_FEIGN_DEATH"), +(15929,4,0,"%s is jolted back to life!",16,100,12155,3,"Stalagg EMOTE_FEIGN_REVIVE"), +(15930,4,0,"%s is jolted back to life!",16,100,12155,3,"Feugen EMOTE_FEIGN_REVIVE"), +(16218,0,0,"%s loses its link!",41,100,12156,3,"Tesla Coil EMOTE_TESLA_LINK_BREAKS"), +(16218,1,0,"%s overloads!",41,100,12178,3,"Tesla Coil EMOTE_TESLA_OVERLOAD"); + + +-- trigger when entering thaddius' room +DELETE FROM `areatrigger_scripts` WHERE `entry`=4113; +INSERT INTO `areatrigger_scripts` (`entry`,`ScriptName`) VALUES +(4113,"at_thaddius_entrance"); diff --git a/sql/updates/world/2015_11_20_00_world.sql b/sql/updates/world/2015_11_20_00_world.sql new file mode 100644 index 00000000000..7c5fe7ea426 --- /dev/null +++ b/sql/updates/world/2015_11_20_00_world.sql @@ -0,0 +1,35 @@ +-- +UPDATE `creature_addon` SET `auras`="44792" WHERE `guid`=100024; +UPDATE `creature_template` SET `InhabitType`=4 WHERE `entry` IN (24883, 24876, 24877, 24875); +UPDATE `creature` SET `MovementType`=0, `spawndist`=0, `position_z`=329.648 WHERE `id`=24883; + +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry` IN (24883); +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (24883) AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(24883,0,0,0,1,0,70,0,0,5000,6000,10000,11,44788,0,0,0,0,0,19,24876,20,0,0,0,0,0,"Rodin Lightning Enabler - Ooc - Cast Rodin's Lightning Bolt"), +(24883,0,1,0,1,0,70,0,0,5000,6000,10000,11,44787,0,0,0,0,0,19,24876,20,0,0,0,0,0,"Rodin Lightning Enabler - Ooc - Cast Rodin's Lightning Bolt"), +(24883,0,2,0,1,0,70,0,0,5000,6000,10000,11,44789,0,0,0,0,0,19,24876,20,0,0,0,0,0,"Rodin Lightning Enabler - Ooc - Cast Rodin's Lightning Bolt"), +(24883,0,3,0,1,0,70,0,0,5000,6000,10000,11,44791,0,0,0,0,0,19,24876,20,0,0,0,0,0,"Rodin Lightning Enabler - Ooc - Cast Rodin's Lightning Bolt"), +(24883,0,4,0,1,0,70,0,0,5000,6000,10000,11,44790,0,0,0,0,0,19,24876,20,0,0,0,0,0,"Rodin Lightning Enabler - Ooc - Cast Rodin's Lightning Bolt"); + +DELETE FROM `creature_text` WHERE `entry` IN (24876, 24875, 24877, 24874) AND `groupid`=1; +INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`, `BroadcastTextId`) VALUES +(24874, 1, 0, 'From sundered ground the sacrament was stolen. The Shield of Aesirites is lost. Unrest will be eternal.', 12, 0, 100, 0, 0, 0, 'Fengir the Disgraced', 23970), +(24876, 1, 0, 'The Staff of Storm''s Fury pilfered. A curse upon this land! The storms will never cease!', 12, 0, 100, 0, 0, 0, 'Rodin the Reckless', 23971), +(24877, 1, 0, 'The Frozen Heart of Isuldof will consume this land until it is returned. Woe unto those that hold the heart as the curse of frozen blood besets them...', 12, 0, 100, 0, 0, 0, 'Isuldof Iceheart', 23972), +(24875, 1, 0, 'The anguish of ten-thousand years awaits any foolish enough to don the Ancient Armor of the Kvaldir. Beware the mist and fog, mortals; for with them comes your end.', 12, 0, 100, 0, 0, 0, 'Windan of the Kvaldir', 23973); + +UPDATE `gameobject_template` SET `AIName`='SmartGameObjectAI' WHERE `entry` IN (187023, 187026, 187022, 187027); +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (187023, 187026, 187022, 187027) AND `source_type`=1; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (24876, 24875, 24877, 24874) AND `source_type`=0 AND id=2; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(187023, 1, 0, 0, 70, 0, 100, 0, 1, 0, 0, 0, 45, 0, 1, 0, 0, 0, 0, 19, 24876, 30, 0, 0, 0, 0, 0, 'Relic - On State 1 - Set data'), +(187026, 1, 0, 0, 70, 0, 100, 0, 1, 0, 0, 0, 45, 0, 1, 0, 0, 0, 0, 19, 24877, 30, 0, 0, 0, 0, 0, 'Relic - On State 1 - Set data'), +(187022, 1, 0, 0, 70, 0, 100, 0, 1, 0, 0, 0, 45, 0, 1, 0, 0, 0, 0, 19, 24874, 30, 0, 0, 0, 0, 0, 'Relic - On State 1 - Set data'), +(187027, 1, 0, 0, 70, 0, 100, 0, 1, 0, 0, 0, 45, 0, 1, 0, 0, 0, 0, 19, 24875, 30, 0, 0, 0, 0, 0, 'Relic - On State 1 - Set data'), +(24876, 0, 2, 0, 38, 0, 100, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Rodin the Reckless - On data set - Say line 2'), +(24877, 0, 2, 0, 38, 0, 100, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Isuldof Iceheart - On data set - Say line 2'), +(24874, 0, 2, 0, 38, 0, 100, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Fengir the Disgraced - On data set - Say line 2'), +(24875, 0, 2, 0, 38, 0, 100, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Windan of the Kvaldir - On data set - Say line 2'); + +UPDATE `creature_template` SET `MovementType`=0 WHERE `entry`=30331; -- fix a DB error not related to the quest diff --git a/sql/updates/world/2015_11_22_00_world.sql b/sql/updates/world/2015_11_22_00_world.sql new file mode 100644 index 00000000000..2b70a2c97b6 --- /dev/null +++ b/sql/updates/world/2015_11_22_00_world.sql @@ -0,0 +1,2 @@ +-- Remove wrong spawn of Cornish Rex Cat in Dun Morogh: +DELETE FROM `creature` WHERE `guid`= 1528 and `id`= 7384; diff --git a/sql/updates/world/2015_11_22_01_world.sql b/sql/updates/world/2015_11_22_01_world.sql new file mode 100644 index 00000000000..ba63c72ba16 --- /dev/null +++ b/sql/updates/world/2015_11_22_01_world.sql @@ -0,0 +1,2 @@ +-- +UPDATE `game_tele` SET `name` = 'OdesyusLanding' WHERE `id` = 693; diff --git a/sql/updates/world/2015_11_22_02_world.sql b/sql/updates/world/2015_11_22_02_world.sql new file mode 100644 index 00000000000..7fcbc7ec9aa --- /dev/null +++ b/sql/updates/world/2015_11_22_02_world.sql @@ -0,0 +1,22 @@ +DELETE FROM `spell_custom_attr` WHERE `entry` IN (1130,1725,3600,14323,14324,14325,32375,32592,35009,39897,42650,43263,43264,53338,58831,58832,58833,58834,58838); +INSERT INTO `spell_custom_attr` (`entry`, `attributes`) VALUES +(1130, 64), -- Hunter spell 1130, Hunter's Mark Rank 1 +(1725, 64), -- Rogue spell 1725, Distract +(3600, 64), -- Greater Earthbind Totem spell 3600, Earthbind +(14323, 64), -- Hunter spell 14323, Hunter's Mark Rank 2 +(14324, 64), -- Hunter spell 14324, Hunter's Mark Rank 3 +(14325, 64), -- Hunter spell 14325, Hunter's Mark Rank 4 +(32375, 64), -- Priest Discipline spell 32375, Mass Dispel +(32592, 64), -- Priest Discipline spell 32592, Mass Dispel +-- Spell ID 35009 - Server-side - Invisibility - Reducing threat +(35009, 64), -- Triggered by Mage Invisibility (Level 68), spells 66 & 67765 +(39897, 64), -- Priest Discipline spell 39897, Mass Dispel +(42650, 64), -- Death Knight Unholy spell 42650, Army of the Dead +(43263, 64), -- Ghoul level 66 spell 43263, Ghoul Taunt +(43264, 64), -- Periodic Taunt, Trigger for Ghoul Taunt +(53338, 64), -- Hunter spell 53338, Hunter's Mark Rank 5 +(58831, 64), -- Mirror Image, spawns left Mirror Image NPC +(58832, 64), -- Mirror Image, Triggers 58831,58833,58834 +(58833, 64), -- Mirror Image, spawns center Mirror Image NPC +(58834, 64), -- Mirror Image, spawns right Mirror Image NPC +(58838, 64); -- Inherit Master's Threat List diff --git a/sql/updates/world/2015_11_22_03_world_355.sql b/sql/updates/world/2015_11_22_03_world_355.sql new file mode 100644 index 00000000000..9bf71a146d0 --- /dev/null +++ b/sql/updates/world/2015_11_22_03_world_355.sql @@ -0,0 +1,17 @@ +-- Seal of Ascension 4743 + +-- Emberstrife Template +UPDATE creature_template SET spell8=16054, AIName="SmartAI" WHERE entry=10321; + +-- Emberstrife Text +DELETE FROM creature_text WHERE entry=10321; +INSERT INTO creature_text (entry, groupid, id, TEXT, TYPE, LANGUAGE, probability, emote, duration, textrange, COMMENT) VALUES +(10321, 0, 0, "Emberstrife will falters!", 41, 0, 100, 0, 2000, 50, "Emberstrife Emote when below 10%"); + +-- Emberstrife AI +DELETE FROM `smart_scripts` WHERE (source_type = 0 AND entryorguid = 10321); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(10321, 0, 0, 0, 2, 0, 100, 0, 0, 10, 60000, 60000, 1, 0, 2000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Emberstrife - Emote Below 10%'), +(10321, 0, 1, 0, 0, 0, 100, 0, 2000, 5000, 5000, 12000, 11, 9573, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Emberstrife - Flame Breath'), +(10321, 0, 2, 0, 0, 0, 100, 0, 2000, 5000, 4000, 10000, 11, 40504, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Emberstrife - Cleave'), +(10321, 0, 3, 0, 2, 0, 100, 0, 0, 10, 60000, 60000, 11, 8269, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Emberstrife - Frenzy below 10%'); diff --git a/sql/updates/world/2015_11_23_00_world_335.sql b/sql/updates/world/2015_11_23_00_world_335.sql new file mode 100644 index 00000000000..fffc4531e5e --- /dev/null +++ b/sql/updates/world/2015_11_23_00_world_335.sql @@ -0,0 +1,74 @@ +-- +-- Quest Tomb of the Lighbringer - 9446 +-- Old scripts cleanup +DELETE FROM `script_waypoint` WHERE `entry`=17238; +-- Creature text +DELETE FROM `creature_text` WHERE `entry`=17238; +INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `TEXT`, `TYPE`, `LANGUAGE`, `probability`, `emote`, `duration`, `sound`, `TextRange`, `COMMENT`, `BroadcastTextId`) VALUES +(17238, 0, 0, "Shall we begin, my friend?", 12, 7, 100, 6, 0, 0, 0, "Q Tomb of the Lighbringer", 13613), +(17238, 1, 0, "This area is known to be full of foul Scourge. You may want to take a moment to prepare any defenses at your disposal.", 12, 7, 100, 1, 0, 0, 0, "Q Tomb of the Lighbringer", 13614), +(17238, 2, 0, "Beware! We are attacked!", 12, 7, 100, 5, 0, 0, 0, "Q Tomb of the Lighbringer", 13616), +(17238, 3, 0, "It must be the purity of the Mark of the Lightbringer that is drawing forth the Scourge to us. We must proceed with caution lest we be overwhelmed!", 12, 7, 100, 1, 0, 0, 0, "Q Tomb of the Lighbringer", 13617), +(17238, 4, 0, "We are beset upon again! Defend yourself!", 12, 7, 100, 5, 0, 0, 0, "Q Tomb of the Lighbringer", 13618), +(17238, 5, 0, "This land truly needs to be cleansed by the Light! Let us continue on to the tomb. It isn't far now.", 12, 7, 100, 1, 0, 0, 0, "Q Tomb of the Lighbringer", 13619), +(17238, 6, 0, "Very well, let us continue.", 12, 7, 100, 1, 0, 0, 0, "Q Tomb of the Lighbringer", 13615), +(17238, 7, 0, "Thank you my friend for making this possible. This is a day that I shall never forget! I think I will stay a while. Please return to High Priestess MacDonnell at the camp. I know that she'll be keenly interested to know of what has transpired here.", 12, 7, 100, 2, 0, 0, 0, "Q Tomb of the Lighbringer", 13624); + +-- Anchorite Truuen AI +UPDATE `creature_template` SET `scriptname`="", `AIName`="SmartAI" WHERE `entry` IN (17238, 17233); +DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `entryorguid` IN (17238, 17233); +DELETE FROM `smart_scripts` WHERE `source_type` = 9 AND `entryorguid` IN (1723800, 1723801, 1723300); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(17238, 0, 0, 1, 19, 0, 100, 0, 9446, 0, 0, 0, 1, 0, 2000, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Truuen - Quest Taken - Say text'), +(17238, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 53, 0, 17238, 0, 9446, 45000, 1, 17, 0, 30, 0, 0, 0, 0, 0, 'Anchorite Truuen - Quest Taken - Start WP'), +(17238, 0, 2, 3, 61, 0, 100, 0, 0, 0, 0, 0, 54, 5000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Truuen - Quest Taken - Pause before movements'), +(17238, 0, 3, 18, 61, 0, 100, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Truuen - Quest Taken - Remove npc flag'), +(17238, 0, 4, 5, 40, 0, 100, 0, 3, 0, 0, 0, 54, 15000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Truuen - On wp reached - Pause at WP 3'), +(17238, 0, 5, 0, 61, 0, 100, 0, 0, 0, 0, 0, 1, 1, 6000, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Truuen - On wp reached - Speak'), +(17238, 0, 6, 7, 40, 0, 100, 0, 5, 0, 0, 0, 12, 4472, 3, 60000, 1, 0, 0, 8, 0, 0, 0, 1039.984, -1577.659, 61.437, 1.753951, 'Anchorite Truuen - On wp reached - Summon creature'), +(17238, 0, 7, 8, 61, 0, 100, 0, 0, 0, 0, 0, 12, 1802, 3, 60000, 1, 0, 0, 8, 0, 0, 0, 1031.033, -1576.279, 62.436, 0.265621, 'Anchorite Truuen - On wp reached - Summon creature'), +(17238, 0, 8, 0, 61, 0, 100, 0, 0, 0, 0, 0, 1, 2, 2000, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Truuen - On wp reached - Say text'), +(17238, 0, 9, 0, 40, 0, 100, 0, 7, 0, 0, 0, 1, 3, 2000, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Truuen - On wp reached - Say text'), +(17238, 0, 10, 11, 40, 0, 100, 0, 11, 0, 0, 0, 1, 4, 2000, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Truuen - On wp reached - Say text'), +(17238, 0, 11, 12, 61, 0, 100, 0, 0, 0, 0, 0, 12, 4475, 3, 60000, 1, 0, 0, 8, 0, 0, 0, 1110.658, -1742.137, 61.019, 2.413687, 'Anchorite Truuen - On wp reached - Summon creature'), +(17238, 0, 12, 13, 61, 0, 100, 0, 0, 0, 0, 0, 12, 4475, 3, 60000, 1, 0, 0, 8, 0, 0, 0, 1106.837, -1750.592, 61.174, 2.409762, 'Anchorite Truuen - On wp reached - Summon creature'), +(17238, 0, 13, 14, 61, 0, 100, 0, 0, 0, 0, 0, 12, 4475, 3, 60000, 1, 0, 0, 8, 0, 0, 0, 1111.725, -1753.404, 61.459, 2.755339, 'Anchorite Truuen - On wp reached - Summon creature'), +(17238, 0, 14, 0, 61, 0, 100, 0, 0, 0, 0, 0, 12, 4475, 3, 60000, 1, 0, 0, 8, 0, 0, 0, 1117.459, -1743.327, 61.000, 2.853514, 'Anchorite Truuen - On wp reached - Summon creature'), +(17238, 0, 15, 0, 40, 0, 100, 0, 12, 0, 0, 0, 1, 5, 2000, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Truuen - On wp reached - say text'), +(17238, 0, 16, 17, 40, 0, 100, 0, 17, 0, 0, 0, 12, 17233, 3, 60000, 0, 0, 0, 8, 0, 0, 0, 971.86, -1825.42, 84, 0, 'Anchorite Truuen - On wp reached - Summon creature'), +(17238, 0, 17, 0, 61, 0, 100, 0, 0, 0, 0, 0, 90, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Truuen - On wp reached - Kneels'), +(17238, 0, 18, 0, 61, 0, 100, 0, 0, 0, 0, 0, 2, 250, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Truuen - On quest taken - Set Faction'), +(17238, 0, 19, 0, 40, 0, 100, 0, 3, 0, 0, 0, 80, 1723800, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Truuen - On wp reached - Action list'), +(1723800, 9, 0, 0, 0, 0, 100, 0, 15000, 15000, 0, 0, 1, 6, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Truuen - Action list - Say text'), +(17238, 0, 20, 0, 38, 0, 100, 0, 0, 1, 0, 0, 80, 1723801, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Truuen - On data set - Action list'), +(1723801, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 91, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Truuen - Action list - remove kneel'), +(1723801, 9, 1, 0, 0, 0, 100, 0, 10000, 10000, 0, 0, 1, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Truuen - Action list - Say text'), +(1723801, 9, 2, 0, 0, 0, 100, 0, 12000, 12000, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Truuen - Action list - Despawns'), +(17233, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 80, 1723300, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ghost of Uther - Just summoned - Action list'), +(1723300, 9, 0, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ghost of Uther - Action list - Say text'), +(1723300, 9, 1, 0, 0, 0, 100, 0, 9000, 9000, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ghost of Uther - Action list - Say text'), +(1723300, 9, 2, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 45, 0, 1, 0, 0, 0, 0, 19, 17238, 20, 0, 0, 0, 0, 0, 'Ghost of Uther - Action list - Set data'), +(1723300, 9, 3, 0, 0, 0, 100, 0, 8000, 8000, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ghost of Uther - Action list - Despawn'); + +-- Waypoints +DELETE FROM `waypoints` WHERE `entry`=17238; +INSERT INTO `waypoints` (`entry`, `pointid`, `position_x`, `position_y`, `position_z`, `point_comment`) VALUES +(17238, 1, 946, -1430, 64, "anchorite_truuen_Q9446"), +(17238, 2, 974, -1439, 66, "anchorite_truuen_Q9446"), +(17238, 3, 1031, -1474, 64, "anchorite_truuen_Q9446"), +(17238, 4, 1039, -1503, 66, "anchorite_truuen_Q9446"), +(17238, 5, 1036, -1566, 62, "anchorite_truuen_Q9446"), +(17238, 6, 1036, -1568, 62, "anchorite_truuen_Q9446"), +(17238, 7, 1038, -1662, 61, "anchorite_truuen_Q9446"), +(17238, 8, 1047, -1683, 61, "anchorite_truuen_Q9446"), +(17238, 9, 1064, -1710, 61, "anchorite_truuen_Q9446"), +(17238, 10, 1099, -1738, 61, "anchorite_truuen_Q9446"), +(17238, 11, 1113, -1746, 61, "anchorite_truuen_Q9446"), +(17238, 12, 1118, -1750, 61, "anchorite_truuen_Q9446"), +(17238, 13, 1156, -1761, 61, "anchorite_truuen_Q9446"), +(17238, 14, 1152, -1773, 61, "anchorite_truuen_Q9446"), +(17238, 15, 1080, -1802, 65, "anchorite_truuen_Q9446"), +(17238, 16, 1019, -1810, 78, "anchorite_truuen_Q9446"), +(17238, 17, 976, -1823, 81, "anchorite_truuen_Q9446"); + +UPDATE `creature_text` SET `text`="%s's will falters.", `BroadcastTextId`=5594 WHERE `entry`=10321 AND `groupid`=0 AND `id`=0; -- Fix text for a previous commit diff --git a/sql/updates/world/2015_11_23_01_world_335.sql b/sql/updates/world/2015_11_23_01_world_335.sql new file mode 100644 index 00000000000..8432c2d14fd --- /dev/null +++ b/sql/updates/world/2015_11_23_01_world_335.sql @@ -0,0 +1,3 @@ +UPDATE `creature_template` SET `skinloot` = 0 WHERE `entry` IN (721,883,890,1933,2098,2442,2620,4166,5951,10780,12296,12297,12298,12299,17467); +-- Remove unreferenced skinning_loot_template entries because of this update: +DELETE FROM `skinning_loot_template` WHERE `Entry` IN (1933,12299,100000); diff --git a/sql/updates/world/2015_11_23_02_world_335.sql b/sql/updates/world/2015_11_23_02_world_335.sql new file mode 100644 index 00000000000..ba569d1420f --- /dev/null +++ b/sql/updates/world/2015_11_23_02_world_335.sql @@ -0,0 +1,134 @@ +-- +-- Fill in the blanks in the `Comment` fields in `skinning_loot_template`: +UPDATE `skinning_loot_template` SET `Comment`= 'Light Hide' WHERE `Item`= 783 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Light Leather' WHERE `Item`= 2318 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Medium Leather' WHERE `Item`= 2319 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Wool Cloth' WHERE `Item`= 2592 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Ruined Leather Scraps' WHERE `Item`= 2934 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Medium Hide' WHERE `Item`= 4232 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Heavy Leather' WHERE `Item`= 4234 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Heavy Hide' WHERE `Item`= 4235 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Thick Leather' WHERE `Item`= 4304 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Deviate Scale' WHERE `Item`= 6470 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Perfect Deviate Scale' WHERE `Item`= 6471 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Black Whelp Scale' WHERE `Item`= 7286 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Red Whelp Scale' WHERE `Item`= 7287 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Green Whelp Scale' WHERE `Item`= 7392 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Shadowcat Hide' WHERE `Item`= 7428 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Zesty Clam Meat' WHERE `Item`= 7974 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Scorpid Scale' WHERE `Item`= 8154 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Worn Dragonscale' WHERE `Item`= 8165 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Turtle Scale' WHERE `Item`= 8167 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Thick Hide' WHERE `Item`= 8169 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Rugged Leather' WHERE `Item`= 8170 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Rugged Hide' WHERE `Item`= 8171 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Thick Wolfhide' WHERE `Item`= 8368 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Thick Yeti Hide' WHERE `Item`= 8973 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Patch of Tainted Skin' WHERE `Item`= 11512 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Thick Yeti Fur' WHERE `Item`= 12366 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Brilliant Chromatic Scale' WHERE `Item`= 12607 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Pristine Hide of the Beast' WHERE `Item`= 12731 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Heavy Scorpid Scale' WHERE `Item`= 15408 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Scale of Onyxia' WHERE `Item`= 15410 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Green Dragonscale' WHERE `Item`= 15412 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Red Dragonscale' WHERE `Item`= 15414 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Blue Dragonscale' WHERE `Item`= 15415 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Black Dragonscale' WHERE `Item`= 15416 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Devilsaur Leather' WHERE `Item`= 15417 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Warbear Leather' WHERE `Item`= 15419 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Frostsaber Leather' WHERE `Item`= 15422 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Chimera Leather' WHERE `Item`= 15423 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Core Leather' WHERE `Item`= 17012 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Shiny Fish Scales' WHERE `Item`= 17057 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Rage Scar Yeti Hide' WHERE `Item`= 18947 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Primal Bat Leather' WHERE `Item`= 19767 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Primal Tiger Leather' WHERE `Item`= 19768 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Silithid Chitin' WHERE `Item`= 20498 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Broken Silithid Chitin' WHERE `Item`= 20499 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Light Silithid Carapace' WHERE `Item`= 20500 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Heavy Silithid Carapace' WHERE `Item`= 20501 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Knothide Leather' WHERE `Item`= 21887 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Flame Spessarite' WHERE `Item`= 21929 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Mote of Air' WHERE `Item`= 22572 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Mote of Earth' WHERE `Item`= 22573 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Mote of Life' WHERE `Item`= 22575 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Mote of Mana' WHERE `Item`= 22576 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Mote of Shadow' WHERE `Item`= 22577 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Mote of Water' WHERE `Item`= 22578 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Felweed' WHERE `Item`= 22785 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Dreaming Glory' WHERE `Item`= 22786 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Ragveil' WHERE `Item`= 22787 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Terocone' WHERE `Item`= 22789 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Ancient Lichen' WHERE `Item`= 22790 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Mana Thistle' WHERE `Item`= 22793 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Fel Lotus' WHERE `Item`= 22794 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Blood Garnet' WHERE `Item`= 23077 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Deep Peridot' WHERE `Item`= 23079 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Shadow Draenite' WHERE `Item`= 23107 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Golden Draenite' WHERE `Item`= 23112 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Azure Moonstone' WHERE `Item`= 23117 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Adamantite Ore' WHERE `Item`= 23425 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Living Ruby' WHERE `Item`= 23436 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Talasite' WHERE `Item`= 23437 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Star of Elune' WHERE `Item`= 23438 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Noble Topaz' WHERE `Item`= 23439 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Dawnstone' WHERE `Item`= 23440 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Nightseye' WHERE `Item`= 23441 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Moongraze Buck Hide' WHERE `Item`= 23677 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Crystalline Fragments' WHERE `Item`= 24189 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Unidentified Plant Parts' WHERE `Item`= 24401 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Knothide Leather Scraps' WHERE `Item`= 25649 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Crystal Infused Leather' WHERE `Item`= 25699 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Fel Scales' WHERE `Item`= 25700 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Fel Hide' WHERE `Item`= 25707 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Thick Clefthoof Leather' WHERE `Item`= 25708 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Small Mushroom' WHERE `Item`= 25813 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Zangar Caps' WHERE `Item`= 27859 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Sporeggar Mushroom' WHERE `Item`= 29453 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Cobra Scales' WHERE `Item`= 29539 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Wind Scales' WHERE `Item`= 29547 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Nether Dragonscales' WHERE `Item`= 29548 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Lionseye' WHERE `Item`= 32229 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Nethermine Flayer Hide' WHERE `Item`= 32470 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Honey-Spiced Lichen' WHERE `Item`= 33452 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Borean Leather Scraps' WHERE `Item`= 33567 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Borean Leather' WHERE `Item`= 33568 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Nether Residue' WHERE `Item`= 35229 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Ice Shard Cluster' WHERE `Item`= 36728 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Sprung Sprocket' WHERE `Item`= 36813 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Goldclover' WHERE `Item`= 36901 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Constrictor Grass' WHERE `Item`= 36902 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Adder\'s Tongue' WHERE `Item`= 36903 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Tiger Lily' WHERE `Item`= 36904 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Lichbloom' WHERE `Item`= 36905 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Icethorn' WHERE `Item`= 36906 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Talandra\'s Rose' WHERE `Item`= 36907 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Crystallized Air' WHERE `Item`= 37700 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Crystallized Earth' WHERE `Item`= 37701 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Crystallized Fire' WHERE `Item`= 37702 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Crystallized Life' WHERE `Item`= 37704 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Crystallized Water' WHERE `Item`= 37705 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Icy Dragonscale' WHERE `Item`= 38557 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Nerubian Chitin' WHERE `Item`= 38558 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Jormungar Scale' WHERE `Item`= 38561 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Geodesic Fragments' WHERE `Item`= 39220 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Frosty Mushroom' WHERE `Item`= 39516 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Handful of Cobalt Bolts' WHERE `Item`= 39681 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Overcharged Capacitor' WHERE `Item`= 39682 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Hair Trigger' WHERE `Item`= 39684 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Indestructible Frame' WHERE `Item`= 39685 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Volatile Blasting Trigger' WHERE `Item`= 39690 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Arctic Fur' WHERE `Item`= 44128 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Whizzed-Out Gizmo' WHERE `Item`= 41337 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Sprung Whirlygig' WHERE `Item`= 41338 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Stoic Mammoth Hide' WHERE `Item`= 42542 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Loque\'Nahak\'s Pelt' WHERE `Item`= 44687 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Schematic: Jeeves' WHERE `Item`= 49050 AND `Comment` IS NULL; +-- Reference loot +UPDATE `skinning_loot_template` SET `Comment`= 'Pattern: Cobrascale Gloves' WHERE `Entry`= 29724 and `Reference`= 50017 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Pattern: Windscale Hood' WHERE `Entry`= 29725 and `Reference`= 50013 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Pattern: Hood of Primal Life' WHERE `Entry`= 29726 and `Reference`= 50014 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Pattern: Gloves of the Living Touch' WHERE `Entry`= 29727 and `Reference`= 50016 AND `Comment` IS NULL; +UPDATE `skinning_loot_template` SET `Comment`= 'Pattern: Windslayer Wraps' WHERE `Entry`= 29728 and `Reference`= 50015 AND `Comment` IS NULL;UPDATE `creature_template` SET `skinloot` = 0 WHERE `entry` IN (721,883,890,1933,2098,2442,2620,4166,5951,10780,12296,12297,12298,12299,17467); +-- Remove unreferenced skinning_loot_template entries because of this update: +DELETE FROM `skinning_loot_template` WHERE `Entry` IN (1933,12299,100000); diff --git a/sql/updates/world/2015_11_23_03_world_335.sql b/sql/updates/world/2015_11_23_03_world_335.sql new file mode 100644 index 00000000000..9ef011f551e --- /dev/null +++ b/sql/updates/world/2015_11_23_03_world_335.sql @@ -0,0 +1,13 @@ +-- Mottled Boar - Skinning Loot +UPDATE `creature_template` SET `skinloot`= 3098 WHERE `entry` = 3098; +DELETE FROM `skinning_loot_template` WHERE `Entry`=3098; +INSERT INTO `skinning_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(3098, 2318, 0, 10, 0, 1, 1, 1, 1, NULL), -- Light Leather, 10% chance +(3098, 2934, 0, 88, 0, 1, 1, 1, 1, NULL); -- Ruined Leather Scraps, 88% chance + +-- Scorpid Worker - Skinning Loot +UPDATE `creature_template` SET `skinloot`= 3124 WHERE `entry` = 3124; +DELETE FROM `skinning_loot_template` WHERE `Entry`= 3124; +INSERT INTO `skinning_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(3124, 2318, 0, 10, 0, 1, 1, 1, 1, NULL), -- Light Leather, 10% chance +(3124, 2934, 0, 88, 0, 1, 1, 1, 1, NULL); -- Ruined Leather Scraps, 88% chance diff --git a/sql/updates/world/2015_11_23_04_world_335.sql b/sql/updates/world/2015_11_23_04_world_335.sql new file mode 100644 index 00000000000..845eefeb7ca --- /dev/null +++ b/sql/updates/world/2015_11_23_04_world_335.sql @@ -0,0 +1,29 @@ +SET @NPCTEXT= 724006; + +DELETE FROM `gossip_menu` WHERE `entry`=6539 AND `text_id`=@NPCTEXT; +INSERT INTO `gossip_menu` (`entry`, `text_id`) VALUES +(6539, @NPCTEXT); + +DELETE FROM `gossip_menu_option` WHERE `menu_id`=6539 AND `id`=0; +INSERT INTO `gossip_menu_option` (`menu_id`,`id`,`option_icon`,`option_text`,`OptionBroadcastTextID`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`,`BoxBroadcastTextID`) VALUES +(6539,0,0,'I am ready, Anachronos. Please grant me the Scepter of the Shifting Sands.',11331,1,1,0,0,0,0,'',0); + +DELETE FROM `npc_text` WHERE `ID`=@NPCTEXT; +INSERT INTO `npc_text` (`ID`, `text0_0`, `text0_1`, `BroadcastTextID0`, `lang0`, `Probability0`, `em0_0`, `em0_1`, `em0_2`, `em0_3`, `em0_4`, `em0_5`, `text1_0`, `text1_1`, `lang1`, `Probability1`, `em1_0`, `em1_1`, `em1_2`, `em1_3`, `em1_4`, `em1_5`, `text2_0`, `text2_1`, `lang2`, `Probability2`, `em2_0`, `em2_1`, `em2_2`, `em2_3`, `em2_4`, `em2_5`, `text3_0`, `text3_1`, `lang3`, `Probability3`, `em3_0`, `em3_1`, `em3_2`, `em3_3`, `em3_4`, `em3_5`, `text4_0`, `text4_1`, `lang4`, `Probability4`, `em4_0`, `em4_1`, `em4_2`, `em4_3`, `em4_4`, `em4_5`, `text5_0`, `text5_1`, `lang5`, `Probability5`, `em5_0`, `em5_1`, `em5_2`, `em5_3`, `em5_4`, `em5_5`, `text6_0`, `text6_1`, `lang6`, `Probability6`, `em6_0`, `em6_1`, `em6_2`, `em6_3`, `em6_4`, `em6_5`, `text7_0`, `text7_1`, `lang7`, `Probability7`, `em7_0`, `em7_1`, `em7_2`, `em7_3`, `em7_4`, `em7_5`, `VerifiedBuild`) VALUES +(@NPCTEXT, "The Scepter of the Shifting Sands is whole once more, $n.$B$BIt is you who must lead your armies into the cursed fortress city of Ahn'Qiraj and mete justice to its inhabitants.$B$BVenture to Silithus and present the Scepter of the Shifting Sands to Jonathan the Revelator.", '', 11333, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, -1); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=14 AND `SourceGroup`=6539 AND `SourceEntry`=@NPCTEXT; +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=6539 AND `SourceEntry`=0; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(14,6539,@NPCTEXT,0,0,8,0,8742,0,0,0,0,0,'','Show gossip text after quest The Might of Kalimdor rewarded'), +(14,6539,@NPCTEXT,0,0,2,0,21175,1,1,1,0,0,'','Show gossip text if doesnt have item The Scepter of the Shifting Sands'), +(14,6539,@NPCTEXT,0,0,8,0,8745,0,0,1,0,0,'','Show gossip text if Treasure of the Timeless One is not rewarded'), +(15,6539,0,0,0,8,0,8742,0,0,0,0,0,'','Show gossip menu option after quest The Might of Kalimdor rewarded'), +(15,6539,0,0,0,2,0,21175,1,1,1,0,0,'','Show gossip menu option if doesnt have item The Scepter of the Shifting Sands'), +(15,6539,0,0,0,8,0,8745,0,0,1,0,0,'','Show gossip menu option if Treasure of the Timeless One is not rewarded'); + +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=15192; +DELETE FROM `smart_scripts` WHERE `source_type`=0 AND `entryorguid`=15192; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(15192,0,0,1,62,0,100,0,6539,0,0,0,11,25861,0,0,0,0,0,7,0,0,0,0,0,0,0,'Anachronos - On Gossip Option 0 Selected - Cast \'Call Scepter DND\''), +(15192,0,1,0,61,0,100,0,0,0,0,0,72,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'Anachronos - On Gossip Option 0 Selected - Close Gossip'); diff --git a/sql/updates/world/2015_11_23_05_world.sql b/sql/updates/world/2015_11_23_05_world.sql new file mode 100644 index 00000000000..579af5a5ca1 --- /dev/null +++ b/sql/updates/world/2015_11_23_05_world.sql @@ -0,0 +1,6 @@ +-- +DELETE FROM `conditions` WHERE `SourceEntry` = 56099 AND `SourceTypeOrReferenceId` = 13; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(13,1,56099,0,0,31,0,3,30169,0,0,0,'','Essence of Ice target Smoldering Scrap Bunny'); + +DELETE FROM `creature` WHERE `guid` IN (116640, 116641, 116642); -- duplicated spawns diff --git a/sql/updates/world/2015_11_24_00_world_355.sql b/sql/updates/world/2015_11_24_00_world_355.sql new file mode 100644 index 00000000000..0983d03e649 --- /dev/null +++ b/sql/updates/world/2015_11_24_00_world_355.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature_text` SET `TextRange`=0 WHERE `entry`=10321 AND `groupid`=0 AND `id`=0; diff --git a/sql/updates/world/2015_11_27_00_world.sql b/sql/updates/world/2015_11_27_00_world.sql new file mode 100644 index 00000000000..632dec537dd --- /dev/null +++ b/sql/updates/world/2015_11_27_00_world.sql @@ -0,0 +1,15 @@ +UPDATE `spell_dbc` SET `Effect1`=28,`EffectMiscValueB1`=64 WHERE `Id` IN(38922,38928); + +DELETE FROM `smart_scripts` WHERE `entryorguid`=21251 AND `source_type`=0 AND `id`>6; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN(2125100,2125101,2125102,2125103) AND `source_type`=9; + +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(21251, 0, 7, 0, 11, 0, 100, 0, 0, 0, 0, 0, 42, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - On Spawn - Set Invincibility HP'), +(21251, 0, 8, 0, 2, 0, 100, 1, 0, 1, 0, 0, 87, 2125100, 2125101, 2125102, 2125103, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - On Less than 1% HP - Run Random Script'), +(2125100, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 11, 38718, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - Script 1 - Cast \'Toxic Pool\' '), +(2125100, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - Script 1 - Die'), +(2125101, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 11, 38922, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - Script 2 - Cast \'Summon Colossus Lurkers\' '), +(2125101, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - Script 2 - Die'), +(2125102, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 11, 38928, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - Script 3 - Cast \'Summon Colossus Ragers\' '), +(2125102, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - Script 3 - Die'), +(2125103, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - Script 4 - Die'); diff --git a/sql/updates/world/2015_11_28_00_world.sql b/sql/updates/world/2015_11_28_00_world.sql new file mode 100644 index 00000000000..0a1dd574fb4 --- /dev/null +++ b/sql/updates/world/2015_11_28_00_world.sql @@ -0,0 +1,16 @@ +-- +UPDATE `creature_template` SET `InhabitType`=4 WHERE `entry` IN (22268, 22460); +UPDATE `gameobject` SET `position_z`=-16.9 WHERE `guid`=99984 AND `id`= 185307; +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `Entry` IN (22268, 22460); +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (22268, 22460) AND `source_type`=0; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (2226800, 2246000) AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(22460, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 80, 2246000, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Spirit - Just summoned - action list'), +(2246000, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 3672.275635, 5286.437988, 20.585167, 5.40622, 'Spirit - action list - move to pos'), +(2246000, 9, 1, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 3672.275635, 5286.437988, 20.585167, 5.40622, 'Spirit - action list - Set Orientation'), +(2246000, 9, 2, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 9, 0, 0, 0, 0, 0, 0, 20, 185296, 20, 0, 0, 0, 0, 0, 'Spirit - action list - Activate object'), +(2246000, 9, 3, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 45, 0, 1, 0, 0, 0, 0, 19, 22268, 20, 0, 0, 0, 0, 0, 'Spirit - action list - Set data'), +(2246000, 9, 4, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Spirit - action list - Despawn'), +(22268, 0, 0, 0, 38, 0, 100, 0, 0, 1, 0, 0, 80, 2226800, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Leok - On data set - action list'), +(2226800, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 3638.89575, 5343.02978, 23.28319, 2.086646, 'Leok - action list - Move to pos'), +(2226800, 9, 1, 0, 0, 0, 100, 0, 12000, 12000, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Leok - action list - Despawn'); diff --git a/sql/updates/world/2015_11_28_01_world_335.sql b/sql/updates/world/2015_11_28_01_world_335.sql new file mode 100644 index 00000000000..4bec178ecee --- /dev/null +++ b/sql/updates/world/2015_11_28_01_world_335.sql @@ -0,0 +1,3 @@ +DELETE FROM `trinity_string` WHERE `entry` = 11010; +INSERT INTO `trinity_string` (`entry`,`content_default`) VALUES +(11010, 'You didn''t get kicked out of the instance even if Player::CheckInstanceLoginValid() returned false and without .gm on flag'); diff --git a/sql/updates/world/2015_11_29_00_world.sql b/sql/updates/world/2015_11_29_00_world.sql new file mode 100644 index 00000000000..fd64b65bd02 --- /dev/null +++ b/sql/updates/world/2015_11_29_00_world.sql @@ -0,0 +1,41 @@ +-- Talbuk Doe SAI +SET @ENTRY := 20610; -- Talbuk Doe +SET @SPELL_GORE := 32019; -- Gore +SET @SPELL_TAG := 35771; -- Tag Subbued Talbuk +SET @SPELL_TAG_CREDIT := 40347; -- Talbuk Tagging Credit +SET @SPELL_SLEEPING := 14915; -- Sleeping Sleep +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY,@ENTRY*100); +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,0,0,0,4,0,100,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talbuk Doe - On Aggro - Say text 0"), +(@ENTRY,0,1,0,0,0,100,0,1000,1000,8000,11000,11,@SPELL_GORE,0,0,0,0,0,2,0,0,0,0,0,0,0,"Talbuk Doe - In Combat - Cast Gore"), +(@ENTRY,0,2,0,2,0,100,1,0,20,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talbuk Doe - At 20% HP - Say Text 1"), +(@ENTRY,0,5,0,4,0,100,0,0,0,0,0,45,0,1,0,0,0,0,19,20777,30,0,0,0,0,0,"Talbuk Doe - On Aggro - Set data"), +(@ENTRY,0,3,0,8,0,100,0,@SPELL_TAG,0,0,0,80,@ENTRY*100,2,0,0,0,0,1,0,0,0,0,0,0,0,"Talbuk Doe - On Spellhit - Run Script"), +(@ENTRY,0,4,0,11,0,100,0,0,0,0,0,19,386,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talbuk Doe - On Respawn - Remove Unit Flag"), +(@ENTRY*100,9,0,0,0,0,100,0,0,0,0,0,85,@SPELL_TAG_CREDIT ,0,0,0,0,0,7,0,0,0,0,0,0,0,"Talbuk Doe - Script - Give Quest Credit"), +(@ENTRY*100,9,1,0,0,0,100,1,0,0,0,0,27,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talbuk Doe - Script - Stop combat"), +(@ENTRY*100,9,2,0,0,0,100,0,0,0,0,0,18,386,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talbuk Doe - Script - Set Unit Flag"), +(@ENTRY*100,9,3,0,0,0,100,0,0,0,0,0,11,@SPELL_SLEEPING,1,0,0,0,0,1,0,0,0,0,0,0,0,"Talbuk Doe - Script - Cast Sleeping Sleep"), +(@ENTRY*100,9,4,0,0,0,100,0,0,0,0,0,11,55795,1,0,0,0,0,1,0,0,0,0,0,0,0,"Talbuk Doe - Script - Cast visual death state"), +(@ENTRY*100, 9, 5, 0, 0, 0, 100, 0, 30000, 30000, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Talbuk Doe - On Script - Despawn'); + +-- Talbuk Sire SAI +SET @ENTRY := 20777; -- Talbuk Sire +SET @SPELL_STOMP := 32023; -- Hoof Stomp +SET @SPELL_TAG := 35771; -- Tag Subbued Talbuk +SET @SPELL_SLEEPING := 14915; -- Sleeping Sleep +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY,@ENTRY*100); +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,0,0,0,0,0,100,0,4000,6000,8000,11000,11,@SPELL_STOMP,0,0,0,0,0,2,0,0,0,0,0,0,0,"Talbuk Sire - In Combat - Cast Hoof Stomp"), +(@ENTRY,0,1,0,2,0,100,1,0,20,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talbuk Sire - At 20% HP - Say Text 0"), +(@ENTRY,0,4,0,38,0,100,0,0,1,0,0,49,0,0,0,0,0,0,21,40,0,0,0,0,0,0,"Talbuk Sire - On data set - Start attack"), +(@ENTRY,0,2,0,8,0,100,0,@SPELL_TAG,0,0,0,80,@ENTRY*100,2,0,0,0,0,1,0,0,0,0,0,0,0,"Talbuk Sire - On Spellhit - Run Script"), +(@ENTRY,0,3,0,11,0,100,0,0,0,0,0,19,386,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talbuk Sire - On Respawn - Remove Unit Flag"), +(@ENTRY*100,9,0,0,0,0,100,0,0,0,0,0,85,@SPELL_TAG_CREDIT ,0,0,0,0,0,7,0,0,0,0,0,0,0,"Talbuk Sire - Script - Give Quest Credit"), +(@ENTRY*100,9,1,0,0,0,100,1,0,0,0,0,27,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talbuk Sire - Script - Stop combat"), +(@ENTRY*100,9,2,0,0,0,100,0,0,0,0,0,18,386,0,0,0,0,0,1,0,0,0,0,0,0,0,"Talbuk Sire - Script - Set Unit Flag"), +(@ENTRY*100,9,3,0,0,0,100,0,0,0,0,0,11,@SPELL_SLEEPING,1,0,0,0,0,1,0,0,0,0,0,0,0,"Talbuk Sire - Script - Cast Sleeping Sleep"), +(@ENTRY*100,9,4,0,0,0,100,0,0,0,0,0,11,55795,1,0,0,0,0,1,0,0,0,0,0,0,0,"Talbuk Sire - Script - Cast visual death state"), +(@ENTRY*100, 9, 5, 0, 0, 0, 100, 0, 30000, 30000, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Talbuk Sire - On Script - Despawn'); diff --git a/sql/updates/world/2015_11_29_01_world.sql b/sql/updates/world/2015_11_29_01_world.sql new file mode 100644 index 00000000000..cd46800c5dd --- /dev/null +++ b/sql/updates/world/2015_11_29_01_world.sql @@ -0,0 +1,15 @@ +-- +DELETE FROM `creature_text` WHERE `entry` = 22293; +INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `TextRange`, `comment`, `BroadcastTextId`) VALUES +(22293, 0, 0, "%s begins to sputter as its engine malfunctions.", 16, 0, 100, 0, 0, 0, 0, "Inactive Fel Reaver", 20103); + +-- Creature Script - Inactive Fel Reaver +DELETE FROM `smart_scripts` WHERE (source_type = 0 AND entryorguid = 22293); +DELETE FROM `smart_scripts` WHERE (source_type = 9 AND entryorguid = 2229300); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(22293, 0, 0, 0, 20, 0, 100, 0, 10850, 0, 0, 0, 80, 2229300, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Inactive Fel Reaver - On Quest complete - Action list'), +(2229300, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Inactive Fel Reaver - Action list - Say text'), +(2229300, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 83, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Inactive Fel Reaver - Action list - Remove npc flag'), +(2229300, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 89, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Inactive Fel Reaver - Action list - Random Move'), +(2229300, 9, 3, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 33, 22293, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Inactive Fel Reaver - Action list - Give Credit'), +(2229300, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Inactive Fel Reaver - Action list - Kill Itself'); diff --git a/sql/updates/world/2015_12_01_00_world.sql b/sql/updates/world/2015_12_01_00_world.sql new file mode 100644 index 00000000000..1572245a517 --- /dev/null +++ b/sql/updates/world/2015_12_01_00_world.sql @@ -0,0 +1,12 @@ +-- +-- Hallowed wand spell script names +DELETE FROM `spell_script_names` WHERE `ScriptName`= 'spell_hallow_end_wand'; +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(24717, 'spell_hallow_end_wand'), -- Pirate Costume +(24718, 'spell_hallow_end_wand'), -- Ninja Costume +(24719, 'spell_hallow_end_wand'), -- Leper Gnome Costume +(24720, 'spell_hallow_end_wand'), -- Random Costume +(24724, 'spell_hallow_end_wand'), -- Skeleton Costume +(24733, 'spell_hallow_end_wand'), -- Bat Costume +(24737, 'spell_hallow_end_wand'), -- Ghost Costume +(24741, 'spell_hallow_end_wand'); -- Wisp Costume diff --git a/sql/updates/world/2015_12_04_00_world.sql b/sql/updates/world/2015_12_04_00_world.sql new file mode 100644 index 00000000000..ee721273bef --- /dev/null +++ b/sql/updates/world/2015_12_04_00_world.sql @@ -0,0 +1,34 @@ +-- +DELETE FROM `gameobject` WHERE `id`=185295; +DELETE FROM `creature_text` WHERE `entry` IN (21514, 10204); +INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `TextRange`, `comment`, `BroadcastTextId`) VALUES +(10204, 0, 0, "Misha lets OUT a loud roar AS she rakes her claws AGAINST the gronn's altar.", 16, 0, 100, 0, 0, 0, 0, "Misha", 20261), +(21514, 0, 0, "Who dares defile the altar of Gorgrom the Dragon-Eater?", 14, 0, 100, 0, 0, 0, 0, "Gorgrom the Dragon-Eater", 20262), +(21514, 1, 0, "I will crush it and flay it and eat its meat and crack its bones one by one when I am done.", 14, 0, 100, 0, 0, 0, 0, "Gorgrom the Dragon-Eater", 20264); + +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry` IN (21514, 10204); +DELETE FROM `smart_scripts` WHERE source_type = 0 AND entryorguid IN (21514, 10204); +DELETE FROM `smart_scripts` WHERE source_type = 9 AND entryorguid IN (2151400, 1020400); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(21514, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 80, 2151400, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Gorgrom the Dragon-Eater - On Just summoned - Action list'), +(2151400, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 18, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Gorgrom the Dragon-Eater - Action list - Set unit flag'), +(2151400, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Gorgrom the Dragon-Eater - Action list - Say text'), +(2151400, 9, 2, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Gorgrom the Dragon-Eater - Action list - Say text'), +(2151400, 9, 3, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 69, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 3608.135986, 7183.374023, 139.581833, 2.321033, 'Gorgrom the Dragon-Eater - Action list - Move to pos'), +(2151400, 9, 4, 0, 0, 0, 100, 0, 2500, 2500, 0, 0, 11, 35470, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Gorgrom the Dragon-Eater - Action list - Cast explosion'), +(2151400, 9, 5, 0, 0, 0, 100, 0, 0, 0, 0, 0, 50, 185295, 60, 0, 0, 0, 0, 8, 0, 0, 0, 3608.135986, 7183.374023, 139.581833, 2.321033, 'Gorgrom the Dragon-Eater - Action list - Summon Gorgrom corpse spell focus object'), +(2151400, 9, 6, 0, 0, 0, 100, 0, 400, 400, 0, 0, 11, 58951, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Gorgrom the Dragon-Eater - Action list - cast Permanent Feign Death'), +(2151400, 9, 7, 0, 0, 0, 100, 0, 40000, 40000, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Gorgrom the Dragon-Eater - Action list - Despawn'), +(10204, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 80, 1020400, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Misha - On Just summoned - Action list'), +(1020400, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 18, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Misha - Action list - Set unit flag'), +(1020400, 9, 1, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Misha - Action list - Say text'), +(1020400, 9, 2, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 69, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 3612.911865, 7193.020508, 139.651291, 5.472856, 'Misha - Action list - Move to pos'), +(1020400, 9, 3, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 3612.911865, 7193.020508, 139.651291, 5.472856, 'Misha - Action list - Set Orientation'), +(1020400, 9, 4, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Misha - Action list - Despawn'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=17 AND `SourceEntry` IN (39264, 39220); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(17, 0, 39264, 0, 0, 29, 1, 21514, 30, 0, 1, 0, 0, '', "Sablemane's Trap Require Gorgrom the Dragon-Eater not around"), +(17, 0, 39220, 0, 0, 29, 1, 21514, 30, 0, 1, 0, 0, '', "Sablemane's Trap Require Gorgrom the Dragon-Eater not around"), +(17, 0, 39264, 0, 0, 28, 0, 10802, 0, 0, 1, 0, 0, '', "Sablemane's Trap RequireGorgrom the Dragon-Eater not Completed"), +(17, 0, 39220, 0, 0, 28, 0, 10723, 0, 0, 1, 0, 0, '', "Sablemane's Trap RequireGorgrom the Dragon-Eater not Completed"); diff --git a/sql/updates/world/2015_12_05_00_world.sql b/sql/updates/world/2015_12_05_00_world.sql new file mode 100644 index 00000000000..c2c90164a4f --- /dev/null +++ b/sql/updates/world/2015_12_05_00_world.sql @@ -0,0 +1,8 @@ +-- +SET @TATJANA := 27627; +DELETE FROM `smart_scripts` WHERE `entryorguid`IN (27627) AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@TATJANA,0,0,1,8,0,100,0,49134,0,0,0,11,49135,2,0,0,0,0,1,0,0,0,0,0,0,0,'Tatjana - On spellhit Tranquilizer Dart - Spellcast Tatjana Ping'), +(@TATJANA,0,1,2,61,0,100,0,0,0,0,0,2,35,0,0,0,0,0,1,0,0,0,0,0,0,0,'Tatjana - On spellhit Tranquilizer Dart - Set faction'), +(@TATJANA,0,2,0,61,0,100,0,0,0,0,0,20,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'Tatjana - On Spellhit \'Tranquilizer Dart\' - Stop Attack'), +(@TATJANA,0,3,0,0,0,100,0,2000,6000,9000,12000,11,32009,0,0,0,0,0,2,0,0,0,0,0,0,0,'Tatjana - On update IC - Spellcast Cutdown'); diff --git a/sql/updates/world/2015_12_06_00_world.sql b/sql/updates/world/2015_12_06_00_world.sql new file mode 100644 index 00000000000..b60d4d3e88c --- /dev/null +++ b/sql/updates/world/2015_12_06_00_world.sql @@ -0,0 +1,35 @@ +-- +UPDATE `creature_template` SET `AIName`='SmartAI', `ScriptName`='' WHERE `entry`=11956; + +DELETE FROM `smart_scripts` WHERE `entryorguid`=11956 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(11956, 0, 0, 0, 62, 0, 100, 0, 3884, 0, 0, 0, 15, 5930, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Great Bear Spirit - On Gossip Select - Quest explored'), +(11956, 0, 1, 0, 62, 0, 100, 0, 3884, 1, 0, 0, 15, 5929, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Great Bear Spirit - On Gossip Select - Quest explored'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=3884; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(15,3884,0,0,9,5930,0,0,0,0,'','Show the gossip option if the quest 5930 is taken'), +(15,3884,1,0,9,5929,0,0,0,0,'','Show the gossip option if the quest 5929 is taken'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=14 AND `SourceGroup`=3882; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`ErrorTextId`,`Comment`) VALUES +(14,3882,4719,0,9,5929,0,0,0,"Only show text_id 4719 if the quest 5929 is taken"), +(14,3882,4719,1,9,5930,0,0,0,"Only show text_id 4719 if the quest 5930 is taken"); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=3882; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(15,3882,0,0,9,5930,0,0,0,0,'','Show the gossip option if the quest 5930 is taken'), +(15,3882,0,1,9,5929,0,0,0,0,'','Show the gossip option if the quest 5929 is taken'); + +DELETE FROM `gossip_menu` WHERE `entry`=3882 AND `text_id`=4719; +INSERT INTO `gossip_menu` (`entry`, `text_id`) VALUES (3882, 4719); + +DELETE FROM `gossip_menu` WHERE `entry`=3882 AND `text_id`=4719; +INSERT INTO `gossip_menu` (`entry`, `text_id`) VALUES (3882, 4719); +DELETE FROM `gossip_menu_option` WHERE `menu_id` IN (3881, 3882, 3883, 3884); +INSERT INTO `gossip_menu_option` (`menu_id`,`id`,`option_icon`,`option_text`,`OptionBroadcastTextID`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`,`BoxBroadcastTextID`) VALUES +(3882,0,0,'What do you represent, spirit?',7439,1,1,3881,0,0,0,'',0), +(3881,0,0,'I seek to understand the importance of strength of the body.',7442,1,1,3883,0,0,0,'',0), +(3883,0,0,'I seek to understand the importance of strength of the heart.',7444,1,1,3884,0,0,0,'',0), +(3884,0,0,'I have heard your words, Great Bear Spirit, and I understand. I now seek your blessings to fully learn the way of the Claw.',7446,1,1,3885,0,0,0,'',0), +(3884,1,0,'I have heard your words, Great Bear Spirit, and I understand. I now seek your blessings to fully learn the way of the Claw.',7446,1,1,3885,0,0,0,'',0); diff --git a/sql/updates/world/2015_12_08_00_world_335.sql b/sql/updates/world/2015_12_08_00_world_335.sql new file mode 100644 index 00000000000..e742130b1a4 --- /dev/null +++ b/sql/updates/world/2015_12_08_00_world_335.sql @@ -0,0 +1,15 @@ +-- +DELETE FROM `gossip_menu_option` WHERE `menu_id` IN (2562) AND `id`=1; +INSERT INTO `gossip_menu_option` (`menu_id`,`id`,`option_icon`,`option_text`,`OptionBroadcastTextID`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`,`BoxBroadcastTextID`) VALUES +(2562,1,0,"Gubber, I don't know how to fish.",5529,1,1,0,0,0,0,'',0); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=2562; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(15,2562,1,0,9,1141,0,0,0,0,'','Show the gossip option if the quest 1141 is taken'), +(15,2562,1,0,25,7620,0,0,1,0,'','Show the gossip option if Fishing is not learned'); + +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=10216; +DELETE FROM `smart_scripts` WHERE `entryorguid`=10216 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(10216, 0, 0, 1, 62, 0, 100, 0, 2562, 1, 0, 0, 85, 7733, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Gubber Blump- On Gossip Select - Cast Fishing'), +(10216, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Gubber Blump- On Gossip Select - Close gossip'); diff --git a/sql/updates/world/2015_12_08_01_world.sql b/sql/updates/world/2015_12_08_01_world.sql new file mode 100644 index 00000000000..9e24acd91db --- /dev/null +++ b/sql/updates/world/2015_12_08_01_world.sql @@ -0,0 +1,2 @@ +-- +UPDATE `smart_scripts` SET `event_param2`=7 WHERE `entryorguid` IN (34146, 34150, 34151) AND `source_type`=0 AND `id`=0; diff --git a/sql/updates/world/2015_12_08_02_world.sql b/sql/updates/world/2015_12_08_02_world.sql new file mode 100644 index 00000000000..375d0941adb --- /dev/null +++ b/sql/updates/world/2015_12_08_02_world.sql @@ -0,0 +1,6 @@ +-- maexxna cleanup +DELETE FROM `creature_text` WHERE `entry`=15952; +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`probability`,`BroadcastTextId`,`TextRange`,`comment`) VALUES +(15952,0,0,"Spiderlings appear on the web!",41,100,32305,3,"Maexxna EMOTE_SPIDERS"), +(15952,1,0,"%s spins her web into a cocoon!",41,100,32303,3,"Maexxna EMOTE_WEB_WRAP"), +(15952,2,0,"%s sprays strands of web everywhere!",41,100,32304,3,"Maexxna EMOTE_WEB_SPRAY"); diff --git a/sql/updates/world/2015_12_09_00_world.sql b/sql/updates/world/2015_12_09_00_world.sql new file mode 100644 index 00000000000..6ac4da31404 --- /dev/null +++ b/sql/updates/world/2015_12_09_00_world.sql @@ -0,0 +1,3 @@ +-- +UPDATE `smart_scripts` SET `event_param1`=15, `comment`="Short John Mithril - On Waypoint 15 Reached - Say Line 1" WHERE `entryorguid`=14508 AND `source_Type`=0 AND `id` IN (2); +UPDATE `smart_scripts` SET `event_param1`=15, `comment`="Short John Mithril - On Waypoint 15 Reached - Cast 'Summon Pirate Booty (DND)'" WHERE `entryorguid`=14508 AND `source_Type`=0 AND `id` IN (3); diff --git a/sql/updates/world/2015_12_09_01_world.sql b/sql/updates/world/2015_12_09_01_world.sql new file mode 100644 index 00000000000..d27bc7ff49a --- /dev/null +++ b/sql/updates/world/2015_12_09_01_world.sql @@ -0,0 +1,13 @@ +-- +SET @ENTRY := 27131; +UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=@ENTRY; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,0,0,0,1,0,100,0,10000,15000,10000,15000,5,7,0,0,0,0,0,1,0,0,0,0,0,0,0,"Grizzly Bear - Out of Combat - Play Emote 7"); + +SET @ENTRY := 2713100; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=9; + +DELETE FROM `vehicle_template_accessory` WHERE `entry`=27131; +INSERT INTO `vehicle_template_accessory` (`entry`,`accessory_entry`,`seat_id`,`minion`,`description`) VALUES +(27131,27438,0,1, 'Grizzly Bear - Rainbow Trout'); diff --git a/sql/updates/world/2015_12_11_00_world.sql b/sql/updates/world/2015_12_11_00_world.sql new file mode 100644 index 00000000000..dc5fd8c40b6 --- /dev/null +++ b/sql/updates/world/2015_12_11_00_world.sql @@ -0,0 +1,19 @@ +-- +DELETE FROM `smart_scripts` WHERE `entryorguid`=27530 AND `source_type`=0 AND `id`=1; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(27530,0,1,0,8,0,100,1,49349,0,0,0,41,5000,0,0,0,0,0,1,0,0,0,0,0,0,0,'Ruby Keeper - On Spellhit - Despawn'); + +DELETE FROM `creature_addon` WHERE `guid` IN (108202,108203,108328,108329, 108330); +INSERT INTO `creature_addon` (`guid`, `bytes1`, `auras`) VALUES +(108202,33554432 ,""),(108203,33554432 ,""),(108328,33554432 ,""),(108329,33554432 ,""),(108330,33554432 ,""); +UPDATE `creature_template` SET `InhabitType`=4 WHERE `entry`=27530; +UPDATE `creature` SET `MovementType`=1, `spawndist`=10 WHERE `guid` IN (108202,108203,108328,108329, 108330); + +SET @GUID := 48254; +DELETE FROM `creature` WHERE `guid` IN (@GUID,@GUID+1,@GUID+2,@GUID+3); +INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`modelid`,`equipment_id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`currentwaypoint`,`curhealth`,`curmana`,`MovementType`, `unit_flags`, `dynamicflags`) VALUES +(@GUID,27530,571,1,1,24137,0,3690.58, 1034.33, 55.7121, 1.43117,300,0,0,102820,0,0,537133568,32), +(@GUID+1,27530,571,1,1,24137,0,3690.58, 1034.33, 55.7121, 1.43117,300,0,0,102820,0,0,537133568,32), +(@GUID+2,27530,571,1,1,24137,0,3722.78, 872.282, 56.4471, 3.56587,300,0,0,102820,0,0,537133568,32), +(@GUID+3,27530,571,1,1,24137,0,3678.09, 938.621, 57.2201, 1.50971,300,0,0,102820,0,0,537133568,32); +UPDATE `creature` SET `unit_flags`=537133568 WHERE `id`=27530 AND `dynamicflags`=32; diff --git a/sql/updates/world/2015_12_14_00_world.sql b/sql/updates/world/2015_12_14_00_world.sql new file mode 100644 index 00000000000..85faf4448e2 --- /dev/null +++ b/sql/updates/world/2015_12_14_00_world.sql @@ -0,0 +1,32 @@ +-- instructor razuvious cleanup +DELETE FROM `creature_text` WHERE `entry`=16061; +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`probability`,`sound`,`BroadcastTextId`,`TextRange`,`comment`) VALUES +(16061,0,0,"Do as I taught you!",14,100,8855,13075,3,"Razuvious SAY_AGGRO #1"), +(16061,0,1,"The time for practice is over! Show me what you have learned!",14,100,8859,13078,3,"Razuvious SAY_AGGRO #2"), +(16061,0,2,"Show them no mercy!",14,100,8856,13076,3,"Razuvious SAY_AGGRO #3"), +(16061,1,0,"%s lets loose a triumphant shout.",41,30,0,13082,3,"Razuvious SAY_SLAY"), +(16061,2,0,"You should have stayed home.",14,50,8861,13081,3,"Razuvious SAY_TAUNTED #1"), +(16061,2,1,"You disappoint me, students!",14,50,8858,13077,3,"Razuvious SAY_TAUNTED #2"), +(16061,2,2,"I'm just getting warmed up!",14,50,8852,13072,3,"Razuvious SAY_TAUNTED #3"), +(16061,2,3,"Stand and fight!",14,50,8853,13073,3,"Razuvious SAY_TAUNTED #4"), +(16061,2,4,"Sweep the leg... Do you have a problem with that?",14,50,8861,13080,3,"Razuvious SAY_TAUNTED #5"), +(16061,3,0,"An honorable... death.",14,100,8860,13079,3,"Razuvious SAY_DEATH"); + +-- move understudies to summon groups for proper reset behavior +DELETE FROM `creature` WHERE `guid` IN (128184,128185); +DELETE FROM `linked_respawn` WHERE `guid` IN (128184,128185); +DELETE FROM `creature_summon_groups` WHERE `summonerId`=16061 AND `summonerType`=0; +INSERT INTO `creature_summon_groups` (`summonerId`,`summonerType`,`groupId`,`entry`,`position_x`,`position_y`,`position_z`,`orientation`,`summonType`) VALUES +(16061,0,1,16803,2757.476,-3111.519,267.7678,3.926991,8), +(16061,0,1,16803,2762.049,-3084.467,267.7678,2.129302,8), +(16061,0,2,16803,2778.911,-3114.142,267.7678,5.288348,8), +(16061,0,2,16803,2781.866,-3088.187,267.7678,0.9075712,8); + +-- "Hopeless" debuff on death may only target understudies +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=29125; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`NegativeCondition`,`Comment`) VALUES +(13,1,29125,31,0,3,16803,0,"Instructor Razuvious - Hopeless debuff - only target Death Knight Understudy"); + +-- transition understudies to scripted AI to prevent them overriding player control +UPDATE `creature_template` SET `AIName`="",`ScriptName`="npc_dk_understudy" WHERE `entry`=16803; +DELETE FROM `smart_scripts` WHERE `entryorguid`=16803 AND `source_type`=0; diff --git a/sql/updates/world/2015_12_15_00_world.sql b/sql/updates/world/2015_12_15_00_world.sql new file mode 100644 index 00000000000..f27bb448bbd --- /dev/null +++ b/sql/updates/world/2015_12_15_00_world.sql @@ -0,0 +1,2 @@ +-- +DELETE FROM `creature` WHERE `guid` IN (111277, 111300); diff --git a/sql/updates/world/2015_12_15_01_world.sql b/sql/updates/world/2015_12_15_01_world.sql new file mode 100644 index 00000000000..86fbec83c38 --- /dev/null +++ b/sql/updates/world/2015_12_15_01_world.sql @@ -0,0 +1,2 @@ +-- trinity_string 2022 (ticket message) +UPDATE `trinity_string` SET `content_default`='|cff00ff00Ticket Message|r: [%s]|r ' WHERE `entry`=2022; diff --git a/sql/updates/world/2015_12_15_02_world.sql b/sql/updates/world/2015_12_15_02_world.sql new file mode 100644 index 00000000000..eda5c26550f --- /dev/null +++ b/sql/updates/world/2015_12_15_02_world.sql @@ -0,0 +1,22 @@ +-- +UPDATE `creature_text` SET `sound`=14211 WHERE `BroadcastTextID`=25357; +UPDATE `creature_text` SET `sound`=14212 WHERE `BroadcastTextID`=25358; +UPDATE `creature_text` SET `sound`=14756 WHERE `BroadcastTextID`=25362; +UPDATE `creature_text` SET `sound`=14212 WHERE `BroadcastTextID`=28189; +UPDATE `creature_text` SET `sound`=14664 WHERE `BroadcastTextID`=25359; +UPDATE `creature_text` SET `sound`=14665 WHERE `BroadcastTextID`=25360; +UPDATE `creature_text` SET `sound`=14757 WHERE `BroadcastTextID`=25363; +UPDATE `creature_text` SET `sound`=14666 WHERE `BroadcastTextID`=25366; +UPDATE `creature_text` SET `sound`=14213 WHERE `BroadcastTextID`=25361; +UPDATE `creature_text` SET `sound`=14758 WHERE `BroadcastTextID`=25364; +UPDATE `creature_text` SET `sound`=14214 WHERE `BroadcastTextID`=25365; +UPDATE `creature_text` SET `sound`=14196 WHERE `BroadcastTextID`=25841; +UPDATE `creature_text` SET `sound`=14489 WHERE `BroadcastTextID`=25842; +UPDATE `creature_text` SET `sound`=14197 WHERE `BroadcastTextID`=25847; +UPDATE `creature_text` SET `sound`=14667 WHERE `BroadcastTextID`=25844; +UPDATE `creature_text` SET `sound`=14490 WHERE `BroadcastTextID`=25843; +UPDATE `creature_text` SET `sound`=14668 WHERE `BroadcastTextID`=25845; +UPDATE `creature_text` SET `sound`=14491 WHERE `BroadcastTextID`=25848; +UPDATE `creature_text` SET `sound`=14669 WHERE `BroadcastTextID`=25846; +UPDATE `creature_text` SET `sound`=14492 WHERE `BroadcastTextID`=25849; +UPDATE `creature_text` SET `sound`=14670 WHERE `BroadcastTextID`=25850; diff --git a/sql/updates/world/yyyy_mm_dd_xx.sql b/sql/updates/world/2015_12_15_03_world.sql index 99cc9e14646..99cc9e14646 100644 --- a/sql/updates/world/yyyy_mm_dd_xx.sql +++ b/sql/updates/world/2015_12_15_03_world.sql diff --git a/src/common/Debugging/Errors.cpp b/src/common/Debugging/Errors.cpp index 45f130ceb3b..4c7e91a8219 100644 --- a/src/common/Debugging/Errors.cpp +++ b/src/common/Debugging/Errors.cpp @@ -59,10 +59,15 @@ void Assert(char const* file, int line, char const* function, char const* messag exit(1); } -void Fatal(char const* file, int line, char const* function, char const* message) +void Fatal(char const* file, int line, char const* function, char const* message, ...) { - fprintf(stderr, "\n%s:%i in %s FATAL ERROR:\n %s\n", - file, line, function, message); + va_list args; + va_start(args, message); + + fprintf(stderr, "\n%s:%i in %s FATAL ERROR:\n ", file, line, function); + vfprintf(stderr, message, args); + fprintf(stderr, "\n"); + fflush(stderr); std::this_thread::sleep_for(std::chrono::seconds(10)); *((volatile int*)NULL) = 0; diff --git a/src/common/Debugging/Errors.h b/src/common/Debugging/Errors.h index 3ceaf2c328f..9e526933acc 100644 --- a/src/common/Debugging/Errors.h +++ b/src/common/Debugging/Errors.h @@ -26,7 +26,7 @@ namespace Trinity DECLSPEC_NORETURN void Assert(char const* file, int line, char const* function, char const* message) ATTR_NORETURN; DECLSPEC_NORETURN void Assert(char const* file, int line, char const* function, char const* message, char const* format, ...) ATTR_NORETURN ATTR_PRINTF(5, 6); - DECLSPEC_NORETURN void Fatal(char const* file, int line, char const* function, char const* message) ATTR_NORETURN; + DECLSPEC_NORETURN void Fatal(char const* file, int line, char const* function, char const* message, ...) ATTR_NORETURN ATTR_PRINTF(4, 5); DECLSPEC_NORETURN void Error(char const* file, int line, char const* function, char const* message) ATTR_NORETURN; @@ -45,7 +45,7 @@ namespace Trinity #endif #define WPAssert(cond, ...) ASSERT_BEGIN do { if (!(cond)) Trinity::Assert(__FILE__, __LINE__, __FUNCTION__, #cond, ##__VA_ARGS__); } while(0) ASSERT_END -#define WPFatal(cond, msg) ASSERT_BEGIN do { if (!(cond)) Trinity::Fatal(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0) ASSERT_END +#define WPFatal(cond, ...) ASSERT_BEGIN do { if (!(cond)) Trinity::Fatal(__FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); } while(0) ASSERT_END #define WPError(cond, msg) ASSERT_BEGIN do { if (!(cond)) Trinity::Error(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0) ASSERT_END #define WPWarning(cond, msg) ASSERT_BEGIN do { if (!(cond)) Trinity::Warning(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0) ASSERT_END #define WPAbort() ASSERT_BEGIN do { Trinity::Abort(__FILE__, __LINE__, __FUNCTION__); } while(0) ASSERT_END diff --git a/src/common/Utilities/Util.cpp b/src/common/Utilities/Util.cpp index 33c273fb05f..9f61dd12e4c 100644 --- a/src/common/Utilities/Util.cpp +++ b/src/common/Utilities/Util.cpp @@ -58,6 +58,13 @@ uint32 urand(uint32 min, uint32 max) return GetRng()->URandom(min, max); } +uint32 urandms(uint32 min, uint32 max) +{ + ASSERT(max >= min); + ASSERT(INT_MAX/IN_MILLISECONDS >= max); + return GetRng()->URandom(min * IN_MILLISECONDS, max * IN_MILLISECONDS); +} + float frand(float min, float max) { ASSERT(max >= min); diff --git a/src/common/Utilities/Util.h b/src/common/Utilities/Util.h index 6a872b44a60..b748e83408b 100644 --- a/src/common/Utilities/Util.h +++ b/src/common/Utilities/Util.h @@ -82,6 +82,9 @@ 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 millisecond value between min and max seconds. Functionally equivalent to urand(min*IN_MILLISECONDS, max*IN_MILLISECONDS). */ +uint32 urandms(uint32 min, uint32 max); + /* Return a random number in the range 0 .. UINT32_MAX. */ uint32 rand32(); diff --git a/src/server/database/Database/DatabaseLoader.cpp b/src/server/database/Database/DatabaseLoader.cpp index 69e212cf7e1..39719e4c6a1 100644 --- a/src/server/database/Database/DatabaseLoader.cpp +++ b/src/server/database/Database/DatabaseLoader.cpp @@ -37,14 +37,14 @@ DatabaseLoader& DatabaseLoader::AddDatabase(DatabaseWorkerPool<T>& pool, std::st std::string const dbString = sConfigMgr->GetStringDefault(name + "DatabaseInfo", ""); if (dbString.empty()) { - TC_LOG_ERROR(_logger.c_str(), "Database %s not specified in configuration file!", name.c_str()); + TC_LOG_ERROR(_logger, "Database %s not specified in configuration file!", name.c_str()); return false; } uint8 const asyncThreads = uint8(sConfigMgr->GetIntDefault(name + "Database.WorkerThreads", 1)); if (asyncThreads < 1 || asyncThreads > 32) { - TC_LOG_ERROR(_logger.c_str(), "%s database: invalid number of worker threads specified. " + TC_LOG_ERROR(_logger, "%s database: invalid number of worker threads specified. " "Please pick a value between 1 and 32.", name.c_str()); return false; } @@ -85,7 +85,7 @@ DatabaseLoader& DatabaseLoader::AddDatabase(DatabaseWorkerPool<T>& pool, std::st { if (!DBUpdater<T>::Populate(pool)) { - TC_LOG_ERROR(_logger.c_str(), "Could not populate the %s database, see log for details.", name.c_str()); + TC_LOG_ERROR(_logger, "Could not populate the %s database, see log for details.", name.c_str()); return false; } return true; @@ -95,7 +95,7 @@ DatabaseLoader& DatabaseLoader::AddDatabase(DatabaseWorkerPool<T>& pool, std::st { if (!DBUpdater<T>::Update(pool)) { - TC_LOG_ERROR(_logger.c_str(), "Could not update the %s database, see log for details.", name.c_str()); + TC_LOG_ERROR(_logger, "Could not update the %s database, see log for details.", name.c_str()); return false; } return true; @@ -106,7 +106,7 @@ DatabaseLoader& DatabaseLoader::AddDatabase(DatabaseWorkerPool<T>& pool, std::st { if (!pool.PrepareStatements()) { - TC_LOG_ERROR(_logger.c_str(), "Could not prepare statements of the %s database, see log for details.", name.c_str()); + TC_LOG_ERROR(_logger, "Could not prepare statements of the %s database, see log for details.", name.c_str()); return false; } return true; diff --git a/src/server/database/Database/DatabaseWorkerPool.h b/src/server/database/Database/DatabaseWorkerPool.h index 32837daf5da..c7b5d8c8fea 100644 --- a/src/server/database/Database/DatabaseWorkerPool.h +++ b/src/server/database/Database/DatabaseWorkerPool.h @@ -67,6 +67,8 @@ class DatabaseWorkerPool WPFatal(mysql_thread_safe(), "Used MySQL library isn't thread-safe."); WPFatal(mysql_get_client_version() >= MIN_MYSQL_CLIENT_VERSION, "TrinityCore does not support MySQL versions below 5.1"); + WPFatal(mysql_get_client_version() == MYSQL_VERSION_ID, "Used MySQL library version (%s) does not match the version used to compile TrinityCore (%s).", + mysql_get_client_info(), MYSQL_SERVER_VERSION); } ~DatabaseWorkerPool() diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp index 7b145268d22..9a6742b5ebc 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp @@ -97,7 +97,6 @@ bool SummonList::HasEntry(uint32 entry) const } ScriptedAI::ScriptedAI(Creature* creature) : CreatureAI(creature), - me(creature), IsFleeing(false), _evadeCheckCooldown(2500), _isCombatMovementAllowed(true) diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h index 7d7811d9e75..242acbcd44d 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h @@ -184,9 +184,6 @@ struct ScriptedAI : public CreatureAI // Variables // ************* - //Pointer to creature we are manipulating - Creature* me; - //For fleeing bool IsFleeing; diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index a1703dfa78f..7ca4274bc40 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -979,7 +979,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { if (me && !me->isDead()) { - me->Kill(me); + me->KillSelf(); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_DIE: Creature %u", me->GetGUID().GetCounter()); } break; @@ -1249,7 +1249,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (!IsUnit(*itr)) continue; - (*itr)->ToUnit()->Kill((*itr)->ToUnit()); + (*itr)->ToUnit()->KillSelf(); } delete targets; diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index 6f9046520b0..1c4b9a51ece 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -248,7 +248,7 @@ class SmartScript void DecPhase(int32 p = 1) { - if(mEventPhase > (uint32)p) + if (mEventPhase > (uint32)p) mEventPhase -= (uint32)p; else mEventPhase = 0; diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 2bacaff496f..a6359a353eb 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -1533,7 +1533,7 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) //! Since no common attributes were found, (not even in titleRewardFlags field) //! we explicitly check by ID. Maybe in the future we could move the achievement_reward //! condition fields to the condition system. - if (uint32 titleId = reward->titleId[achievement->ID == 1793 ? GetPlayer()->getGender() : (GetPlayer()->GetTeam() == ALLIANCE ? 0 : 1)]) + if (uint32 titleId = reward->titleId[achievement->ID == 1793 ? GetPlayer()->GetByteValue(PLAYER_BYTES_3, 0) : (GetPlayer()->GetTeam() == ALLIANCE ? 0 : 1)]) if (CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId)) GetPlayer()->SetTitle(titleEntry); diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index 768def2ff4d..20d30704c13 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -83,12 +83,23 @@ uint32 AuctionHouseMgr::GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 float multiplier = CalculatePct(float(entry->depositPercent), 3); uint32 timeHr = (((time / 60) / 60) / 12); - uint32 deposit = uint32(((multiplier * MSV * count / 3) * timeHr * 3) * sWorld->getRate(RATE_AUCTION_DEPOSIT)); + uint32 deposit = uint32(MSV * multiplier * sWorld->getRate(RATE_AUCTION_DEPOSIT)); + float remainderbase = float(MSV * multiplier * sWorld->getRate(RATE_AUCTION_DEPOSIT)) - deposit; + + deposit *= timeHr * count; + + int i = count; + while (i > 0 && (remainderbase * i) != uint32(remainderbase * i)) + i--; + + if (i) + deposit += remainderbase * i * timeHr; TC_LOG_DEBUG("auctionHouse", "MSV: %u", MSV); TC_LOG_DEBUG("auctionHouse", "Items: %u", count); TC_LOG_DEBUG("auctionHouse", "Multiplier: %f", multiplier); TC_LOG_DEBUG("auctionHouse", "Deposit: %u", deposit); + TC_LOG_DEBUG("auctionHouse", "Deposit rm: %f", remainderbase * count); if (deposit < AH_MINIMUM_DEPOSIT * sWorld->getRate(RATE_AUCTION_DEPOSIT)) return AH_MINIMUM_DEPOSIT * sWorld->getRate(RATE_AUCTION_DEPOSIT); @@ -389,6 +400,116 @@ bool AuctionHouseMgr::RemoveAItem(ObjectGuid::LowType id, bool deleteItem) return true; } +void AuctionHouseMgr::PendingAuctionAdd(Player* player, AuctionEntry* aEntry) +{ + PlayerAuctions* thisAH; + auto itr = pendingAuctionMap.find(player->GetGUID()); + if (itr != pendingAuctionMap.end()) + thisAH = itr->second.first; + else + { + thisAH = new PlayerAuctions; + pendingAuctionMap[player->GetGUID()] = AuctionPair(thisAH, 0); + } + thisAH->push_back(aEntry); +} + +uint32 AuctionHouseMgr::PendingAuctionCount(const Player* player) const +{ + auto const itr = pendingAuctionMap.find(player->GetGUID()); + if (itr != pendingAuctionMap.end()) + return itr->second.first->size(); + + return 0; +} + +void AuctionHouseMgr::PendingAuctionProcess(Player* player) +{ + auto iterMap = pendingAuctionMap.find(player->GetGUID()); + if (iterMap == pendingAuctionMap.end()) + return; + + PlayerAuctions* thisAH = iterMap->second.first; + + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + + uint32 totalItems = 0; + for (auto itrAH = thisAH->begin(); itrAH != thisAH->end(); ++itrAH) + { + AuctionEntry* AH = (*itrAH); + totalItems += AH->itemCount; + } + + uint32 totaldeposit = 0; + auto itr = (*thisAH->begin()); + + if (Item* item = GetAItem(itr->itemGUIDLow)) + totaldeposit = GetAuctionDeposit(itr->auctionHouseEntry, itr->etime, item, totalItems); + + uint32 depositremain = totaldeposit; + for (auto itr = thisAH->begin(); itr != thisAH->end(); ++itr) + { + AuctionEntry* AH = (*itr); + + if (next(itr) == thisAH->end()) + AH->deposit = depositremain; + else + { + AH->deposit = totaldeposit / thisAH->size(); + depositremain -= AH->deposit; + } + + AH->DeleteFromDB(trans); + AH->SaveToDB(trans); + } + + CharacterDatabase.CommitTransaction(trans); + pendingAuctionMap.erase(player->GetGUID()); + delete thisAH; + player->ModifyMoney(-int32(totaldeposit)); +} + +void AuctionHouseMgr::UpdatePendingAuctions() +{ + for (auto itr = pendingAuctionMap.begin(); itr != pendingAuctionMap.end();) + { + ObjectGuid playerGUID = itr->first; + if (Player* player = ObjectAccessor::FindConnectedPlayer(playerGUID)) + { + // Check if there were auctions since last update process if not + if (PendingAuctionCount(player) == itr->second.second) + { + ++itr; + PendingAuctionProcess(player); + } + else + { + ++itr; + pendingAuctionMap[playerGUID].second = PendingAuctionCount(player); + } + } + else + { + // Expire any auctions that we couldn't get a deposit for + TC_LOG_WARN("auctionHouse", "Player %s was offline, unable to retrieve deposit!", playerGUID.ToString().c_str()); + PlayerAuctions* thisAH = itr->second.first; + ++itr; + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + for (auto AHitr = thisAH->begin(); AHitr != thisAH->end();) + { + AuctionEntry* AH = (*AHitr); + ++AHitr; + AH->expire_time = time(NULL); + AH->DeleteFromDB(trans); + AH->SaveToDB(trans); + } + CharacterDatabase.CommitTransaction(trans); + pendingAuctionMap.erase(playerGUID); + delete thisAH; + } + } +} + void AuctionHouseMgr::Update() { mHordeAuctions.Update(); diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.h b/src/server/game/AuctionHouse/AuctionHouseMgr.h index 45cdba361f3..1f885837a44 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.h +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.h @@ -22,6 +22,7 @@ #include "Common.h" #include "DatabaseEnv.h" #include "DBCStructure.h" +#include <set> class Item; class Player; @@ -82,6 +83,7 @@ struct AuctionEntry time_t expire_time; ObjectGuid::LowType bidder; uint32 deposit; //deposit can be calculated only when creating auction + uint32 etime; AuctionHouseEntry const* auctionHouseEntry; // in AuctionHouse.dbc // helpers @@ -151,6 +153,8 @@ class AuctionHouseMgr } typedef std::unordered_map<ObjectGuid::LowType, Item*> ItemMap; + typedef std::vector<AuctionEntry*> PlayerAuctions; + typedef std::pair<PlayerAuctions*, uint32> AuctionPair; AuctionHouseObject* GetAuctionsMap(uint32 factionTemplateId); AuctionHouseObject* GetAuctionsMapByHouseId(uint8 auctionHouseId); @@ -184,7 +188,10 @@ class AuctionHouseMgr void AddAItem(Item* it); bool RemoveAItem(ObjectGuid::LowType id, bool deleteItem = false); - + void PendingAuctionAdd(Player* player, AuctionEntry* aEntry); + uint32 PendingAuctionCount(const Player* player) const; + void PendingAuctionProcess(Player* player); + void UpdatePendingAuctions(); void Update(); private: @@ -193,6 +200,8 @@ class AuctionHouseMgr AuctionHouseObject mAllianceAuctions; AuctionHouseObject mNeutralAuctions; + std::map<ObjectGuid, AuctionPair> pendingAuctionMap; + ItemMap mAitems; }; diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp index 87e07e15191..223b71eb8c5 100644 --- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp +++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp @@ -1069,7 +1069,7 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) if (bgQueue.IsPlayerInvited(m_PlayerGuid, m_BgInstanceGUID, m_RemoveTime)) { // track if player leaves the BG by not clicking enter button - if (bg->isBattleground() && sWorld->getBoolConfig(CONFIG_BATTLEGROUND_TRACK_DESERTERS) && + if (bg && bg->isBattleground() && sWorld->getBoolConfig(CONFIG_BATTLEGROUND_TRACK_DESERTERS) && (bg->GetStatus() == STATUS_IN_PROGRESS || bg->GetStatus() == STATUS_WAIT_JOIN)) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_DESERTER_TRACK); diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index d9fa125b64c..bae400adcc2 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -89,7 +89,7 @@ ConditionMgr::ConditionTypeInfo const ConditionMgr::StaticConditionTypeData[COND { "PhaseMask", true, false, false }, { "Level", true, true, false }, { "Quest Completed", true, false, false }, - { "Near Creature", true, true, false }, + { "Near Creature", true, true, true }, { "Near GameObject", true, true, false }, { "Object Entry or Guid", true, true, true }, { "Object TypeMask", true, false, false }, @@ -280,7 +280,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const } case CONDITION_NEAR_CREATURE: { - condMeets = GetClosestCreatureWithEntry(object, ConditionValue1, (float)ConditionValue2) ? true : false; + condMeets = GetClosestCreatureWithEntry(object, ConditionValue1, (float)ConditionValue2, bool(!ConditionValue3)) ? true : false; break; } case CONDITION_NEAR_GAMEOBJECT: @@ -324,7 +324,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const Unit* unit = object->ToUnit(); if (toUnit && unit) { - switch (ConditionValue2) + switch (static_cast<RelationType>(ConditionValue2)) { case RELATION_SELF: condMeets = unit == toUnit; @@ -344,6 +344,8 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const case RELATION_CREATED_BY: condMeets = unit->GetCreatorGUID() == toUnit->GetGUID(); break; + default: + break; } } } diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index 81fe379f0db..43454aba049 100644 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -59,7 +59,7 @@ enum ConditionTypes CONDITION_PHASEMASK = 26, // phasemask 0 0 true if object is in phasemask CONDITION_LEVEL = 27, // level ComparisonType 0 true if unit's level is equal to param1 (param2 can modify the statement) CONDITION_QUEST_COMPLETE = 28, // quest_id 0 0 true if player has quest_id with all objectives complete, but not yet rewarded - CONDITION_NEAR_CREATURE = 29, // creature entry distance 0 true if there is a creature of entry in range + CONDITION_NEAR_CREATURE = 29, // creature entry distance dead (0/1) true if there is a creature of entry in range CONDITION_NEAR_GAMEOBJECT = 30, // gameobject entry distance 0 true if there is a gameobject of entry in range CONDITION_OBJECT_ENTRY_GUID = 31, // TypeID entry guid true if object is type TypeID and the entry is 0 or matches entry of the object or matches guid of the object CONDITION_TYPE_MASK = 32, // TypeMask 0 0 true if object is type object's TypeMask matches provided TypeMask diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index dc4ad55d9c2..a419864a194 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -809,7 +809,7 @@ struct CreatureModelDataEntry { uint32 Id; uint32 Flags; - //char* ModelPath[16] + char* ModelPath; //uint32 Unk1; float Scale; // Used in calculation of unit collision data //int32 Unk2 diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index c75c0fff625..e81db5924f6 100644 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -42,7 +42,7 @@ char const CinematicSequencesEntryfmt[] = "nxxxxxxxxx"; char const CreatureDisplayInfofmt[] = "nixifxxxxxxxxxxx"; char const CreatureDisplayInfoExtrafmt[] = "diixxxxxxxxxxxxxxxxxx"; char const CreatureFamilyfmt[] = "nfifiiiiixssssssssssssssssxx"; -char const CreatureModelDatafmt[] = "nixxfxxxxxxxxxxffxxxxxxxxxxx"; +char const CreatureModelDatafmt[] = "nisxfxxxxxxxxxxffxxxxxxxxxxx"; char const CreatureSpellDatafmt[] = "niiiixxxx"; char const CreatureTypefmt[] = "nxxxxxxxxxxxxxxxxxx"; char const CurrencyTypesfmt[] = "xnxi"; diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 9173d44ae86..6ba8fb44e09 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -103,6 +103,48 @@ uint32 CreatureTemplate::GetFirstValidModelId() const return 0; } +uint32 CreatureTemplate::GetFirstInvisibleModel() const +{ + CreatureModelInfo const* modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid1); + if (modelInfo && modelInfo->is_trigger) + return Modelid1; + + modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid2); + if (modelInfo && modelInfo->is_trigger) + return Modelid2; + + modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid3); + if (modelInfo && modelInfo->is_trigger) + return Modelid3; + + modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid4); + if (modelInfo && modelInfo->is_trigger) + return Modelid4; + + return 11686; +} + +uint32 CreatureTemplate::GetFirstVisibleModel() const +{ + CreatureModelInfo const* modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid1); + if (modelInfo && !modelInfo->is_trigger) + return Modelid1; + + modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid2); + if (modelInfo && !modelInfo->is_trigger) + return Modelid2; + + modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid3); + if (modelInfo && !modelInfo->is_trigger) + return Modelid3; + + modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid4); + if (modelInfo && !modelInfo->is_trigger) + return Modelid4; + + return 17519; +} + bool AssistDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) { if (Unit* victim = ObjectAccessor::GetUnit(m_owner, m_victim)) @@ -440,8 +482,8 @@ bool Creature::UpdateEntry(uint32 entry, CreatureData const* data /*= nullptr*/) ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true); } - LoadCreaturesAddon(); UpdateMovementFlags(); + LoadCreaturesAddon(); return true; } diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 9a41c8570ed..966944e099f 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -137,6 +137,8 @@ struct CreatureTemplate uint32 ScriptID; uint32 GetRandomValidModelId() const; uint32 GetFirstValidModelId() const; + uint32 GetFirstInvisibleModel() const; + uint32 GetFirstVisibleModel() const; // helpers SkillType GetRequiredLootSkill() const @@ -278,6 +280,7 @@ struct CreatureModelInfo float combat_reach; uint8 gender; uint32 modelid_other_gender; + bool is_trigger; }; // Benchmarked: Faster than std::map (insert/find) diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 19cf9beff21..1b7914fd85f 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -28,6 +28,7 @@ #include "ConditionMgr.h" #include "Player.h" #include "WorldSession.h" +#include "TradeData.h" void AddItemsSetItem(Player* player, Item* item) { diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 0121194e327..a399600d2f2 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -52,7 +52,7 @@ Pet::Pet(Player* owner, PetType type) : } m_name = "Pet"; - m_regenTimer = PET_FOCUS_REGEN_INTERVAL; + m_focusRegenTimer = PET_FOCUS_REGEN_INTERVAL; } Pet::~Pet() @@ -589,22 +589,22 @@ void Pet::Update(uint32 diff) } //regenerate focus for hunter pets or energy for deathknight's ghoul - if (m_regenTimer) + if (m_focusRegenTimer) { - if (m_regenTimer > diff) - m_regenTimer -= diff; + if (m_focusRegenTimer > diff) + m_focusRegenTimer -= diff; else { switch (getPowerType()) { case POWER_FOCUS: Regenerate(POWER_FOCUS); - m_regenTimer += PET_FOCUS_REGEN_INTERVAL - diff; - if (!m_regenTimer) ++m_regenTimer; + m_focusRegenTimer += PET_FOCUS_REGEN_INTERVAL - diff; + if (!m_focusRegenTimer) ++m_focusRegenTimer; // Reset if large diff (lag) causes focus to get 'stuck' - if (m_regenTimer > PET_FOCUS_REGEN_INTERVAL) - m_regenTimer = PET_FOCUS_REGEN_INTERVAL; + if (m_focusRegenTimer > PET_FOCUS_REGEN_INTERVAL) + m_focusRegenTimer = PET_FOCUS_REGEN_INTERVAL; break; @@ -615,7 +615,7 @@ void Pet::Update(uint32 diff) // if (!m_regenTimer) ++m_regenTimer; // break; default: - m_regenTimer = 0; + m_focusRegenTimer = 0; break; } } diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index 85c1f83d4a7..c8e95a06a2c 100644 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -152,7 +152,7 @@ class Pet : public Guardian int32 m_duration; // time until unsummon (used mostly for summoned guardians and not used for controlled pets) uint64 m_auraRaidUpdateMask; bool m_loading; - uint32 m_regenTimer; + uint32 m_focusRegenTimer; DeclinedName *m_declinedname; diff --git a/src/server/game/Entities/Player/KillRewarder.cpp b/src/server/game/Entities/Player/KillRewarder.cpp new file mode 100644 index 00000000000..ad2f8f641ea --- /dev/null +++ b/src/server/game/Entities/Player/KillRewarder.cpp @@ -0,0 +1,274 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://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/>. + */ + +#include "KillRewarder.h" +#include "SpellAuraEffects.h" +#include "Creature.h" +#include "Formulas.h" +#include "Group.h" +#include "Guild.h" +#include "GuildMgr.h" +#include "InstanceScript.h" +#include "Pet.h" +#include "Player.h" + + // == KillRewarder ==================================================== + // KillRewarder encapsulates logic of rewarding player upon kill with: + // * XP; + // * honor; + // * reputation; + // * kill credit (for quest objectives). + // Rewarding is initiated in two cases: when player kills unit in Unit::Kill() + // and on battlegrounds in Battleground::RewardXPAtKill(). + // + // Rewarding algorithm is: + // 1. Initialize internal variables to default values. + // 2. In case when player is in group, initialize variables necessary for group calculations: + // 2.1. _count - number of alive group members within reward distance; + // 2.2. _sumLevel - sum of levels of alive group members within reward distance; + // 2.3. _maxLevel - maximum level of alive group member within reward distance; + // 2.4. _maxNotGrayMember - maximum level of alive group member within reward distance, + // for whom victim is not gray; + // 2.5. _isFullXP - flag identifying that for all group members victim is not gray, + // so 100% XP will be rewarded (50% otherwise). + // 3. Reward killer (and group, if necessary). + // 3.1. If killer is in group, reward group. + // 3.1.1. Initialize initial XP amount based on maximum level of group member, + // for whom victim is not gray. + // 3.1.2. Alter group rate if group is in raid (not for battlegrounds). + // 3.1.3. Reward each group member (even dead) within reward distance (see 4. for more details). + // 3.2. Reward single killer (not group case). + // 3.2.1. Initialize initial XP amount based on killer's level. + // 3.2.2. Reward killer (see 4. for more details). + // 4. Reward player. + // 4.1. Give honor (player must be alive and not on BG). + // 4.2. Give XP. + // 4.2.1. If player is in group, adjust XP: + // * set to 0 if player's level is more than maximum level of not gray member; + // * cut XP in half if _isFullXP is false. + // 4.2.2. Apply auras modifying rewarded XP. + // 4.2.3. Give XP to player. + // 4.2.4. If player has pet, reward pet with XP (100% for single player, 50% for group case). + // 4.3. Give reputation (player must not be on BG). + // 4.4. Give kill credit (player must not be in group, or he must be alive or without corpse). + // 5. Credit instance encounter. + +KillRewarder::KillRewarder(Player* killer, Unit* victim, bool isBattleGround) : + // 1. Initialize internal variables to default values. + _killer(killer), _victim(victim), _group(killer->GetGroup()), + _groupRate(1.0f), _maxNotGrayMember(nullptr), _count(0), _sumLevel(0), _xp(0), + _isFullXP(false), _maxLevel(0), _isBattleGround(isBattleGround), _isPvP(false) +{ + // mark the credit as pvp if victim is player + if (victim->GetTypeId() == TYPEID_PLAYER) + _isPvP = true; + // or if its owned by player and its not a vehicle + else if (victim->GetCharmerOrOwnerGUID().IsPlayer()) + _isPvP = !victim->IsVehicle(); + + _InitGroupData(); +} + +inline void KillRewarder::_InitGroupData() +{ + if (_group) + { + // 2. In case when player is in group, initialize variables necessary for group calculations: + for (GroupReference* itr = _group->GetFirstMember(); itr != nullptr; itr = itr->next()) + if (Player* member = itr->GetSource()) + if (member->IsAlive() && member->IsAtGroupRewardDistance(_victim)) + { + const uint8 lvl = member->getLevel(); + // 2.1. _count - number of alive group members within reward distance; + ++_count; + // 2.2. _sumLevel - sum of levels of alive group members within reward distance; + _sumLevel += lvl; + // 2.3. _maxLevel - maximum level of alive group member within reward distance; + if (_maxLevel < lvl) + _maxLevel = lvl; + // 2.4. _maxNotGrayMember - maximum level of alive group member within reward distance, + // for whom victim is not gray; + uint32 grayLevel = Trinity::XP::GetGrayLevel(lvl); + if (_victim->getLevel() > grayLevel && (!_maxNotGrayMember || _maxNotGrayMember->getLevel() < lvl)) + _maxNotGrayMember = member; + } + // 2.5. _isFullXP - flag identifying that for all group members victim is not gray, + // so 100% XP will be rewarded (50% otherwise). + _isFullXP = _maxNotGrayMember && (_maxLevel == _maxNotGrayMember->getLevel()); + } + else + _count = 1; +} + +inline void KillRewarder::_InitXP(Player* player) +{ + // Get initial value of XP for kill. + // XP is given: + // * on battlegrounds; + // * otherwise, not in PvP; + // * not if killer is on vehicle. + if (_isBattleGround || (!_isPvP && !_killer->GetVehicle())) + _xp = Trinity::XP::Gain(player, _victim, _isBattleGround); +} + +inline void KillRewarder::_RewardHonor(Player* player) +{ + // Rewarded player must be alive. + if (player->IsAlive()) + player->RewardHonor(_victim, _count, -1, true); +} + +inline void KillRewarder::_RewardXP(Player* player, float rate) +{ + uint32 xp(_xp); + if (_group) + { + // 4.2.1. If player is in group, adjust XP: + // * set to 0 if player's level is more than maximum level of not gray member; + // * cut XP in half if _isFullXP is false. + if (_maxNotGrayMember && player->IsAlive() && + _maxNotGrayMember->getLevel() >= player->getLevel()) + xp = _isFullXP ? + uint32(xp * rate) : // Reward FULL XP if all group members are not gray. + uint32(xp * rate / 2) + 1; // Reward only HALF of XP if some of group members are gray. + else + xp = 0; + } + if (xp) + { + // 4.2.2. Apply auras modifying rewarded XP (SPELL_AURA_MOD_XP_PCT). + for (auto const& aura : player->GetAuraEffectsByType(SPELL_AURA_MOD_XP_PCT)) + AddPct(xp, aura->GetAmount()); + + // 4.2.3. Give XP to player. + player->GiveXP(xp, _victim, _groupRate); + if (Pet* pet = player->GetPet()) + // 4.2.4. If player has pet, reward pet with XP (100% for single player, 50% for group case). + pet->GivePetXP(_group ? xp / 2 : xp); + } +} + +inline void KillRewarder::_RewardReputation(Player* player, float rate) +{ + // 4.3. Give reputation (player must not be on BG). + // Even dead players and corpses are rewarded. + player->RewardReputation(_victim, rate); +} + +inline void KillRewarder::_RewardKillCredit(Player* player) +{ + // 4.4. Give kill credit (player must not be in group, or he must be alive or without corpse). + if (!_group || player->IsAlive() || !player->GetCorpse()) + if (Creature* target = _victim->ToCreature()) + { + player->KilledMonster(target->GetCreatureTemplate(), target->GetGUID()); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE, target->GetCreatureType(), 1, target); + } +} + +void KillRewarder::_RewardPlayer(Player* player, bool isDungeon) +{ + // 4. Reward player. + if (!_isBattleGround) + { + // 4.1. Give honor (player must be alive and not on BG). + _RewardHonor(player); + // 4.1.1 Send player killcredit for quests with PlayerSlain + if (_victim->GetTypeId() == TYPEID_PLAYER) + player->KilledPlayerCredit(); + } + // Give XP only in PvE or in battlegrounds. + // Give reputation and kill credit only in PvE. + if (!_isPvP || _isBattleGround) + { + float const rate = _group ? + _groupRate * float(player->getLevel()) / _sumLevel : // Group rate depends on summary level. + 1.0f; // Personal rate is 100%. + if (_xp) + // 4.2. Give XP. + _RewardXP(player, rate); + if (!_isBattleGround) + { + // If killer is in dungeon then all members receive full reputation at kill. + _RewardReputation(player, isDungeon ? 1.0f : rate); + _RewardKillCredit(player); + } + } +} + +void KillRewarder::_RewardGroup() +{ + if (_maxLevel) + { + if (_maxNotGrayMember) + // 3.1.1. Initialize initial XP amount based on maximum level of group member, + // for whom victim is not gray. + _InitXP(_maxNotGrayMember); + // To avoid unnecessary calculations and calls, + // proceed only if XP is not ZERO or player is not on battleground + // (battleground rewards only XP, that's why). + if (!_isBattleGround || _xp) + { + bool const isDungeon = !_isPvP && sMapStore.LookupEntry(_killer->GetMapId())->IsDungeon(); + if (!_isBattleGround) + { + // 3.1.2. Alter group rate if group is in raid (not for battlegrounds). + bool const isRaid = !_isPvP && sMapStore.LookupEntry(_killer->GetMapId())->IsRaid() && _group->isRaidGroup(); + _groupRate = Trinity::XP::xp_in_group_rate(_count, isRaid); + } + + // 3.1.3. Reward each group member (even dead or corpse) within reward distance. + for (GroupReference* itr = _group->GetFirstMember(); itr != nullptr; itr = itr->next()) + { + if (Player* member = itr->GetSource()) + { + if (member->IsAtGroupRewardDistance(_victim)) + { + _RewardPlayer(member, isDungeon); + member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, _victim); + } + } + } + } + } +} + +void KillRewarder::Reward() +{ + // 3. Reward killer (and group, if necessary). + if (_group) + // 3.1. If killer is in group, reward group. + _RewardGroup(); + else + { + // 3.2. Reward single killer (not group case). + // 3.2.1. Initialize initial XP amount based on killer's level. + _InitXP(_killer); + // To avoid unnecessary calculations and calls, + // proceed only if XP is not ZERO or player is not on battleground + // (battleground rewards only XP, that's why). + if (!_isBattleGround || _xp) + // 3.2.2. Reward killer. + _RewardPlayer(_killer, false); + } + + // 5. Credit instance encounter. + if (Creature* victim = _victim->ToCreature()) + if (victim->IsDungeonBoss()) + if (InstanceScript* instance = _victim->GetInstanceScript()) + instance->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, _victim->GetEntry(), _victim); +} diff --git a/src/server/game/Entities/Player/KillRewarder.h b/src/server/game/Entities/Player/KillRewarder.h new file mode 100644 index 00000000000..577a8ffea20 --- /dev/null +++ b/src/server/game/Entities/Player/KillRewarder.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://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 KillRewarder_h__ +#define KillRewarder_h__ + +#include "Define.h" + +class Player; +class Unit; +class Group; + +class KillRewarder +{ +public: + KillRewarder(Player* killer, Unit* victim, bool isBattleGround); + + void Reward(); + +private: + void _InitXP(Player* player); + void _InitGroupData(); + + void _RewardHonor(Player* player); + void _RewardXP(Player* player, float rate); + void _RewardReputation(Player* player, float rate); + void _RewardKillCredit(Player* player); + void _RewardPlayer(Player* player, bool isDungeon); + void _RewardGroup(); + + Player* _killer; + Unit* _victim; + Group* _group; + float _groupRate; + Player* _maxNotGrayMember; + uint32 _count; + uint32 _sumLevel; + uint32 _xp; + bool _isFullXP; + uint8 _maxLevel; + bool _isBattleGround; + bool _isPvP; +}; + +#endif // KillRewarder_h__ diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 3d11e786d52..ceab7d06c96 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -48,6 +48,7 @@ #include "GuildMgr.h" #include "InstanceSaveMgr.h" #include "InstanceScript.h" +#include "KillRewarder.h" #include "LFGMgr.h" #include "Language.h" #include "Log.h" @@ -289,374 +290,6 @@ std::ostringstream& operator<< (std::ostringstream& ss, PlayerTaxi const& taxi) return ss; } -//== TradeData ================================================= - -TradeData* TradeData::GetTraderData() const -{ - return m_trader->GetTradeData(); -} - -Item* TradeData::GetItem(TradeSlots slot) const -{ - return m_items[slot] ? m_player->GetItemByGuid(m_items[slot]) : NULL; -} - -bool TradeData::HasItem(ObjectGuid itemGuid) const -{ - for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i) - if (m_items[i] == itemGuid) - return true; - - return false; -} - -TradeSlots TradeData::GetTradeSlotForItem(ObjectGuid itemGuid) const -{ - for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i) - if (m_items[i] == itemGuid) - return TradeSlots(i); - - return TRADE_SLOT_INVALID; -} - -Item* TradeData::GetSpellCastItem() const -{ - return m_spellCastItem ? m_player->GetItemByGuid(m_spellCastItem) : NULL; -} - -void TradeData::SetItem(TradeSlots slot, Item* item, bool update /*= false*/) -{ - ObjectGuid itemGuid; - if (item) - itemGuid = item->GetGUID(); - - if (m_items[slot] == itemGuid && !update) - return; - - m_items[slot] = itemGuid; - - SetAccepted(false); - GetTraderData()->SetAccepted(false); - - Update(); - - // need remove possible trader spell applied to changed item - if (slot == TRADE_SLOT_NONTRADED) - GetTraderData()->SetSpell(0); - - // need remove possible player spell applied (possible move reagent) - SetSpell(0); -} - -void TradeData::SetSpell(uint32 spell_id, Item* castItem /*= NULL*/) -{ - ObjectGuid itemGuid = castItem ? castItem->GetGUID() : ObjectGuid::Empty; - - if (m_spell == spell_id && m_spellCastItem == itemGuid) - return; - - m_spell = spell_id; - m_spellCastItem = itemGuid; - - SetAccepted(false); - GetTraderData()->SetAccepted(false); - - Update(true); // send spell info to item owner - Update(false); // send spell info to caster self -} - -void TradeData::SetMoney(uint32 money) -{ - if (m_money == money) - return; - - if (!m_player->HasEnoughMoney(money)) - { - TradeStatusInfo info; - info.Status = TRADE_STATUS_CLOSE_WINDOW; - info.Result = EQUIP_ERR_NOT_ENOUGH_MONEY; - m_player->GetSession()->SendTradeStatus(info); - return; - } - - m_money = money; - - SetAccepted(false); - GetTraderData()->SetAccepted(false); - - Update(true); -} - -void TradeData::Update(bool forTarget /*= true*/) -{ - if (forTarget) - m_trader->GetSession()->SendUpdateTrade(true); // player state for trader - else - m_player->GetSession()->SendUpdateTrade(false); // player state for player -} - -void TradeData::SetAccepted(bool state, bool crosssend /*= false*/) -{ - m_accepted = state; - - if (!state) - { - TradeStatusInfo info; - info.Status = TRADE_STATUS_BACK_TO_TRADE; - if (crosssend) - m_trader->GetSession()->SendTradeStatus(info); - else - m_player->GetSession()->SendTradeStatus(info); - } -} - -// == KillRewarder ==================================================== -// KillRewarder incapsulates logic of rewarding player upon kill with: -// * XP; -// * honor; -// * reputation; -// * kill credit (for quest objectives). -// Rewarding is initiated in two cases: when player kills unit in Unit::Kill() -// and on battlegrounds in Battleground::RewardXPAtKill(). -// -// Rewarding algorithm is: -// 1. Initialize internal variables to default values. -// 2. In case when player is in group, initialize variables necessary for group calculations: -// 2.1. _count - number of alive group members within reward distance; -// 2.2. _sumLevel - sum of levels of alive group members within reward distance; -// 2.3. _maxLevel - maximum level of alive group member within reward distance; -// 2.4. _maxNotGrayMember - maximum level of alive group member within reward distance, -// for whom victim is not gray; -// 2.5. _isFullXP - flag identifying that for all group members victim is not gray, -// so 100% XP will be rewarded (50% otherwise). -// 3. Reward killer (and group, if necessary). -// 3.1. If killer is in group, reward group. -// 3.1.1. Initialize initial XP amount based on maximum level of group member, -// for whom victim is not gray. -// 3.1.2. Alter group rate if group is in raid (not for battlegrounds). -// 3.1.3. Reward each group member (even dead) within reward distance (see 4. for more details). -// 3.2. Reward single killer (not group case). -// 3.2.1. Initialize initial XP amount based on killer's level. -// 3.2.2. Reward killer (see 4. for more details). -// 4. Reward player. -// 4.1. Give honor (player must be alive and not on BG). -// 4.2. Give XP. -// 4.2.1. If player is in group, adjust XP: -// * set to 0 if player's level is more than maximum level of not gray member; -// * cut XP in half if _isFullXP is false. -// 4.2.2. Apply auras modifying rewarded XP. -// 4.2.3. Give XP to player. -// 4.2.4. If player has pet, reward pet with XP (100% for single player, 50% for group case). -// 4.3. Give reputation (player must not be on BG). -// 4.4. Give kill credit (player must not be in group, or he must be alive or without corpse). -// 5. Credit instance encounter. -KillRewarder::KillRewarder(Player* killer, Unit* victim, bool isBattleGround) : - // 1. Initialize internal variables to default values. - _killer(killer), _victim(victim), _group(killer->GetGroup()), - _groupRate(1.0f), _maxNotGrayMember(NULL), _count(0), _sumLevel(0), _xp(0), - _isFullXP(false), _maxLevel(0), _isBattleGround(isBattleGround), _isPvP(false) -{ - // mark the credit as pvp if victim is player - if (victim->GetTypeId() == TYPEID_PLAYER) - _isPvP = true; - // or if its owned by player and its not a vehicle - else if (victim->GetCharmerOrOwnerGUID().IsPlayer()) - _isPvP = !victim->IsVehicle(); - - _InitGroupData(); -} - -inline void KillRewarder::_InitGroupData() -{ - if (_group) - { - // 2. In case when player is in group, initialize variables necessary for group calculations: - for (GroupReference* itr = _group->GetFirstMember(); itr != NULL; itr = itr->next()) - if (Player* member = itr->GetSource()) - if (member->IsAlive() && member->IsAtGroupRewardDistance(_victim)) - { - const uint8 lvl = member->getLevel(); - // 2.1. _count - number of alive group members within reward distance; - ++_count; - // 2.2. _sumLevel - sum of levels of alive group members within reward distance; - _sumLevel += lvl; - // 2.3. _maxLevel - maximum level of alive group member within reward distance; - if (_maxLevel < lvl) - _maxLevel = lvl; - // 2.4. _maxNotGrayMember - maximum level of alive group member within reward distance, - // for whom victim is not gray; - uint32 grayLevel = Trinity::XP::GetGrayLevel(lvl); - if (_victim->getLevel() > grayLevel && (!_maxNotGrayMember || _maxNotGrayMember->getLevel() < lvl)) - _maxNotGrayMember = member; - } - // 2.5. _isFullXP - flag identifying that for all group members victim is not gray, - // so 100% XP will be rewarded (50% otherwise). - _isFullXP = _maxNotGrayMember && (_maxLevel == _maxNotGrayMember->getLevel()); - } - else - _count = 1; -} - -inline void KillRewarder::_InitXP(Player* player) -{ - // Get initial value of XP for kill. - // XP is given: - // * on battlegrounds; - // * otherwise, not in PvP; - // * not if killer is on vehicle. - if (_isBattleGround || (!_isPvP && !_killer->GetVehicle())) - _xp = Trinity::XP::Gain(player, _victim, _isBattleGround); -} - -inline void KillRewarder::_RewardHonor(Player* player) -{ - // Rewarded player must be alive. - if (player->IsAlive()) - player->RewardHonor(_victim, _count, -1, true); -} - -inline void KillRewarder::_RewardXP(Player* player, float rate) -{ - uint32 xp(_xp); - if (_group) - { - // 4.2.1. If player is in group, adjust XP: - // * set to 0 if player's level is more than maximum level of not gray member; - // * cut XP in half if _isFullXP is false. - if (_maxNotGrayMember && player->IsAlive() && - _maxNotGrayMember->getLevel() >= player->getLevel()) - xp = _isFullXP ? - uint32(xp * rate) : // Reward FULL XP if all group members are not gray. - uint32(xp * rate / 2) + 1; // Reward only HALF of XP if some of group members are gray. - else - xp = 0; - } - if (xp) - { - // 4.2.2. Apply auras modifying rewarded XP (SPELL_AURA_MOD_XP_PCT). - Unit::AuraEffectList const& auras = player->GetAuraEffectsByType(SPELL_AURA_MOD_XP_PCT); - for (Unit::AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i) - AddPct(xp, (*i)->GetAmount()); - - // 4.2.3. Give XP to player. - player->GiveXP(xp, _victim, _groupRate); - if (Pet* pet = player->GetPet()) - // 4.2.4. If player has pet, reward pet with XP (100% for single player, 50% for group case). - pet->GivePetXP(_group ? xp / 2 : xp); - } -} - -inline void KillRewarder::_RewardReputation(Player* player, float rate) -{ - // 4.3. Give reputation (player must not be on BG). - // Even dead players and corpses are rewarded. - player->RewardReputation(_victim, rate); -} - -inline void KillRewarder::_RewardKillCredit(Player* player) -{ - // 4.4. Give kill credit (player must not be in group, or he must be alive or without corpse). - if (!_group || player->IsAlive() || !player->GetCorpse()) - if (Creature* target = _victim->ToCreature()) - { - player->KilledMonster(target->GetCreatureTemplate(), target->GetGUID()); - player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE, target->GetCreatureType(), 1, target); - } -} - -void KillRewarder::_RewardPlayer(Player* player, bool isDungeon) -{ - // 4. Reward player. - if (!_isBattleGround) - { - // 4.1. Give honor (player must be alive and not on BG). - _RewardHonor(player); - // 4.1.1 Send player killcredit for quests with PlayerSlain - if (_victim->GetTypeId() == TYPEID_PLAYER) - player->KilledPlayerCredit(); - } - // Give XP only in PvE or in battlegrounds. - // Give reputation and kill credit only in PvE. - if (!_isPvP || _isBattleGround) - { - const float rate = _group ? - _groupRate * float(player->getLevel()) / _sumLevel : // Group rate depends on summary level. - 1.0f; // Personal rate is 100%. - if (_xp) - // 4.2. Give XP. - _RewardXP(player, rate); - if (!_isBattleGround) - { - // If killer is in dungeon then all members receive full reputation at kill. - _RewardReputation(player, isDungeon ? 1.0f : rate); - _RewardKillCredit(player); - } - } -} - -void KillRewarder::_RewardGroup() -{ - if (_maxLevel) - { - if (_maxNotGrayMember) - // 3.1.1. Initialize initial XP amount based on maximum level of group member, - // for whom victim is not gray. - _InitXP(_maxNotGrayMember); - // To avoid unnecessary calculations and calls, - // proceed only if XP is not ZERO or player is not on battleground - // (battleground rewards only XP, that's why). - if (!_isBattleGround || _xp) - { - const bool isDungeon = !_isPvP && sMapStore.LookupEntry(_killer->GetMapId())->IsDungeon(); - if (!_isBattleGround) - { - // 3.1.2. Alter group rate if group is in raid (not for battlegrounds). - const bool isRaid = !_isPvP && sMapStore.LookupEntry(_killer->GetMapId())->IsRaid() && _group->isRaidGroup(); - _groupRate = Trinity::XP::xp_in_group_rate(_count, isRaid); - } - - // 3.1.3. Reward each group member (even dead or corpse) within reward distance. - for (GroupReference* itr = _group->GetFirstMember(); itr != NULL; itr = itr->next()) - { - if (Player* member = itr->GetSource()) - { - if (member->IsAtGroupRewardDistance(_victim)) - { - _RewardPlayer(member, isDungeon); - member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, _victim); - } - } - } - } - } -} - -void KillRewarder::Reward() -{ - // 3. Reward killer (and group, if necessary). - if (_group) - // 3.1. If killer is in group, reward group. - _RewardGroup(); - else - { - // 3.2. Reward single killer (not group case). - // 3.2.1. Initialize initial XP amount based on killer's level. - _InitXP(_killer); - // To avoid unnecessary calculations and calls, - // proceed only if XP is not ZERO or player is not on battleground - // (battleground rewards only XP, that's why). - if (!_isBattleGround || _xp) - // 3.2.2. Reward killer. - _RewardPlayer(_killer, false); - } - - // 5. Credit instance encounter. - if (Creature* victim = _victim->ToCreature()) - if (victim->IsDungeonBoss()) - if (InstanceScript* instance = _victim->GetInstanceScript()) - instance->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, _victim->GetEntry(), _victim); -} - Player::Player(WorldSession* session): Unit(true) { m_speakTime = 0; @@ -902,6 +535,8 @@ Player::Player(WorldSession* session): Unit(true) SetPendingBind(0, 0); _activeCheats = CHEAT_NONE; + healthBeforeDuel = 0; + manaBeforeDuel = 0; m_achievementMgr = new AchievementMgr(this); m_reputationMgr = new ReputationMgr(this); } @@ -1900,6 +1535,7 @@ void Player::Update(uint32 p_time) //because we don't want player's ghost teleported from graveyard if (IsHasDelayedTeleport() && IsAlive()) TeleportTo(m_teleport_dest, m_teleport_options); + } void Player::setDeathState(DeathState s) @@ -2514,6 +2150,17 @@ void Player::RemoveFromWorld() } } +bool Player::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const +{ + // players are immune to taunt (the aura and the spell effect) + if (spellInfo->Effects[index].IsAura(SPELL_AURA_MOD_TAUNT)) + return true; + if (spellInfo->Effects[index].IsEffect(SPELL_EFFECT_ATTACK_ME)) + return true; + + return Unit::IsImmunedToSpellEffect(spellInfo, index); +} + void Player::RegenerateAll() { //if (m_regenTimer <= 500) @@ -2926,6 +2573,11 @@ void Player::SetGameMaster(bool on) UpdateObjectVisibility(); } +bool Player::CanBeGameMaster() const +{ + return GetSession()->HasPermission(rbac::RBAC_PERM_COMMAND_GM); +} + void Player::SetGMVisible(bool on) { if (on) @@ -5124,7 +4776,7 @@ Corpse* Player::CreateCorpse() // prevent existence 2 corpse for player SpawnCorpseBones(); - uint32 _uf, _pb, _pb2, _cfb1, _cfb2; + uint32 _pb, _pb2, _cfb1, _cfb2; Corpse* corpse = new Corpse((m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH) ? CORPSE_RESURRECTABLE_PVP : CORPSE_RESURRECTABLE_PVE); SetPvPDeath(false); @@ -5137,18 +4789,16 @@ Corpse* Player::CreateCorpse() _corpseLocation.WorldRelocate(*this); - _uf = GetUInt32Value(UNIT_FIELD_BYTES_0); _pb = GetUInt32Value(PLAYER_BYTES); _pb2 = GetUInt32Value(PLAYER_BYTES_2); - uint8 race = (uint8)(_uf); uint8 skin = (uint8)(_pb); uint8 face = (uint8)(_pb >> 8); uint8 hairstyle = (uint8)(_pb >> 16); uint8 haircolor = (uint8)(_pb >> 24); uint8 facialhair = (uint8)(_pb2); - _cfb1 = ((0x00) | (race << 8) | (getGender() << 16) | (skin << 24)); + _cfb1 = ((0x00) | (getRace() << 8) | (GetByteValue(PLAYER_BYTES_3, 0) << 16) | (skin << 24)); _cfb2 = ((face) | (hairstyle << 8) | (haircolor << 16) | (facialhair << 24)); corpse->SetUInt32Value(CORPSE_FIELD_BYTES_1, _cfb1); @@ -6187,8 +5837,6 @@ void Player::UpdateCombatSkills(Unit* victim, WeaponAttackType attType, bool def uint8 plevel = getLevel(); // if defense than victim == attacker uint8 greylevel = Trinity::XP::GetGrayLevel(plevel); uint8 moblevel = victim->getLevelForTarget(this); - if (moblevel < greylevel) - return; if (moblevel > plevel + 5) moblevel = plevel + 5; @@ -13592,36 +13240,25 @@ void Player::TradeCancel(bool sendback) void Player::UpdateSoulboundTradeItems() { - if (m_itemSoulboundTradeable.empty()) - return; - // also checks for garbage data - for (ItemDurationList::iterator itr = m_itemSoulboundTradeable.begin(); itr != m_itemSoulboundTradeable.end();) + for (GuidUnorderedSet::iterator itr = m_itemSoulboundTradeable.begin(); itr != m_itemSoulboundTradeable.end();) { - ASSERT(*itr); - if ((*itr)->GetOwnerGUID() != GetGUID()) - { - m_itemSoulboundTradeable.erase(itr++); - continue; - } - if ((*itr)->CheckSoulboundTradeExpire()) - { - m_itemSoulboundTradeable.erase(itr++); - continue; - } - ++itr; + Item* item = GetItemByGuid(*itr); + if (!item || item->GetOwnerGUID() != GetGUID() || item->CheckSoulboundTradeExpire()) + itr = m_itemSoulboundTradeable.erase(itr); + else + ++itr; } } void Player::AddTradeableItem(Item* item) { - m_itemSoulboundTradeable.push_back(item); + m_itemSoulboundTradeable.insert(item->GetGUID()); } -/// @todo should never allow an item to be added to m_itemSoulboundTradeable twice void Player::RemoveTradeableItem(Item* item) { - m_itemSoulboundTradeable.remove(item); + m_itemSoulboundTradeable.erase(item->GetGUID()); } void Player::UpdateItemDuration(uint32 time, bool realtimeonly) @@ -15927,8 +15564,9 @@ bool Player::GetQuestRewardStatus(uint32 quest_id) const if (qInfo->IsSeasonal() && !qInfo->IsRepeatable()) { uint16 eventId = sGameEventMgr->GetEventIdForQuest(qInfo); - if (m_seasonalquests.find(eventId) != m_seasonalquests.end()) - return m_seasonalquests.find(eventId)->second.find(quest_id) != m_seasonalquests.find(eventId)->second.end(); + auto seasonalQuestItr = m_seasonalquests.find(eventId); + if (seasonalQuestItr != m_seasonalquests.end()) + return seasonalQuestItr->second.find(quest_id) != seasonalQuestItr->second.end(); return false; } @@ -15956,7 +15594,8 @@ QuestStatus Player::GetQuestStatus(uint32 quest_id) const if (qInfo->IsSeasonal() && !qInfo->IsRepeatable()) { uint16 eventId = sGameEventMgr->GetEventIdForQuest(qInfo); - if (m_seasonalquests.find(eventId) == m_seasonalquests.end() || m_seasonalquests.find(eventId)->second.find(quest_id) == m_seasonalquests.find(eventId)->second.end()) + auto seasonalQuestItr = m_seasonalquests.find(eventId); + if (seasonalQuestItr == m_seasonalquests.end() || seasonalQuestItr->second.find(quest_id) == seasonalQuestItr->second.end()) return QUEST_STATUS_NONE; } @@ -19037,17 +18676,28 @@ bool Player::CheckInstanceLoginValid(Map* map) { // cannot be in raid instance without a group if (!GetGroup()) - return false; + return IsInstanceLoginGameMasterException(); } else { // cannot be in normal instance without a group and more players than 1 in instance if (!GetGroup() && map->GetPlayersCountExceptGMs() > 1) - return false; + return IsInstanceLoginGameMasterException(); } // do checks for satisfy accessreqs, instance full, encounter in progress (raid), perm bind group != perm bind player - return sMapMgr->CanPlayerEnter(map->GetId(), this, true); + return sMapMgr->CanPlayerEnter(map->GetId(), this, true) || IsInstanceLoginGameMasterException(); +} + +bool Player::IsInstanceLoginGameMasterException() const +{ + if (CanBeGameMaster()) + { + ChatHandler(GetSession()).SendSysMessage(LANG_INSTANCE_LOGIN_GAMEMASTER_EXCEPTION); + return true; + } + else + return false; } bool Player::CheckInstanceCount(uint32 instanceId) const @@ -21432,7 +21082,7 @@ void Player::InitDisplayIds() return; } - uint8 gender = getGender(); + uint8 gender = GetByteValue(PLAYER_BYTES_3, 0); switch (gender) { case GENDER_FEMALE: @@ -24182,7 +23832,7 @@ void Player::SetViewpoint(WorldObject* target, bool apply) // farsight dynobj or puppet may be very far away UpdateVisibilityOf(target); - if (target->isType(TYPEMASK_UNIT) && !GetVehicle()) + if (target->isType(TYPEMASK_UNIT) && target != GetVehicleBase()) ((Unit*)target)->AddPlayerToVision(this); } else @@ -24195,7 +23845,7 @@ void Player::SetViewpoint(WorldObject* target, bool apply) return; } - if (target->isType(TYPEMASK_UNIT) && !GetVehicle()) + if (target->isType(TYPEMASK_UNIT) && target != GetVehicleBase()) ((Unit*)target)->RemovePlayerFromVision(this); //must immediately set seer back otherwise may crash diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 7c0700fa244..26944de9770 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -29,6 +29,7 @@ #include "SpellMgr.h" #include "SpellHistory.h" #include "Unit.h" +#include "TradeData.h" #include <limits> #include <string> @@ -687,14 +688,6 @@ struct ItemPosCount }; typedef std::vector<ItemPosCount> ItemPosCountVec; -enum TradeSlots -{ - TRADE_SLOT_COUNT = 7, - TRADE_SLOT_TRADED_COUNT = 6, - TRADE_SLOT_NONTRADED = 6, - TRADE_SLOT_INVALID = -1 -}; - enum TransferAbortReason { TRANSFER_ABORT_NONE = 0x00, @@ -1007,88 +1000,6 @@ struct TradeStatusInfo uint8 Slot; }; -class TradeData -{ - public: // constructors - TradeData(Player* player, Player* trader) : - m_player(player), m_trader(trader), m_accepted(false), m_acceptProccess(false), - m_money(0), m_spell(0), m_spellCastItem() { } - - Player* GetTrader() const { return m_trader; } - TradeData* GetTraderData() const; - - Item* GetItem(TradeSlots slot) const; - bool HasItem(ObjectGuid itemGuid) const; - TradeSlots GetTradeSlotForItem(ObjectGuid itemGuid) const; - void SetItem(TradeSlots slot, Item* item, bool update = false); - - uint32 GetSpell() const { return m_spell; } - void SetSpell(uint32 spell_id, Item* castItem = NULL); - - Item* GetSpellCastItem() const; - bool HasSpellCastItem() const { return !m_spellCastItem.IsEmpty(); } - - uint32 GetMoney() const { return m_money; } - void SetMoney(uint32 money); - - bool IsAccepted() const { return m_accepted; } - void SetAccepted(bool state, bool crosssend = false); - - bool IsInAcceptProcess() const { return m_acceptProccess; } - void SetInAcceptProcess(bool state) { m_acceptProccess = state; } - - private: // internal functions - - void Update(bool for_trader = true); - - private: // fields - - Player* m_player; // Player who own of this TradeData - Player* m_trader; // Player who trade with m_player - - bool m_accepted; // m_player press accept for trade list - bool m_acceptProccess; // one from player/trader press accept and this processed - - uint32 m_money; // m_player place money to trade - - uint32 m_spell; // m_player apply spell to non-traded slot item - ObjectGuid m_spellCastItem; // applied spell cast by item use - - ObjectGuid m_items[TRADE_SLOT_COUNT]; // traded items from m_player side including non-traded slot -}; - -class KillRewarder -{ -public: - KillRewarder(Player* killer, Unit* victim, bool isBattleGround); - - void Reward(); - -private: - void _InitXP(Player* player); - void _InitGroupData(); - - void _RewardHonor(Player* player); - void _RewardXP(Player* player, float rate); - void _RewardReputation(Player* player, float rate); - void _RewardKillCredit(Player* player); - void _RewardPlayer(Player* player, bool isDungeon); - void _RewardGroup(); - - Player* _killer; - Unit* _victim; - Group* _group; - float _groupRate; - Player* _maxNotGrayMember; - uint32 _count; - uint32 _sumLevel; - uint32 _xp; - bool _isFullXP; - uint8 _maxLevel; - bool _isBattleGround; - bool _isPvP; -}; - class Player : public Unit, public GridObject<Player> { friend class WorldSession; @@ -1123,6 +1034,8 @@ class Player : public Unit, public GridObject<Player> static bool BuildEnumData(PreparedQueryResult result, WorldPacket* data); + bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const override; + void SetInWater(bool apply); bool IsInWater() const override { return m_isInWater; } @@ -1161,6 +1074,7 @@ class Player : public Unit, public GridObject<Player> bool isAcceptWhispers() const { return (m_ExtraFlags & PLAYER_EXTRA_ACCEPT_WHISPERS) != 0; } void SetAcceptWhispers(bool on) { if (on) m_ExtraFlags |= PLAYER_EXTRA_ACCEPT_WHISPERS; else m_ExtraFlags &= ~PLAYER_EXTRA_ACCEPT_WHISPERS; } bool IsGameMaster() const { return (m_ExtraFlags & PLAYER_EXTRA_GM_ON) != 0; } + bool CanBeGameMaster() const; void SetGameMaster(bool on); bool isGMChat() const { return (m_ExtraFlags & PLAYER_EXTRA_GM_CHAT) != 0; } void SetGMChat(bool on) { if (on) m_ExtraFlags |= PLAYER_EXTRA_GM_CHAT; else m_ExtraFlags &= ~PLAYER_EXTRA_GM_CHAT; } @@ -1325,7 +1239,7 @@ class Player : public Unit, public GridObject<Player> float GetReputationPriceDiscount(Creature const* creature) const; - Player* GetTrader() const { return m_trade ? m_trade->GetTrader() : NULL; } + Player* GetTrader() const { return m_trade ? m_trade->GetTrader() : nullptr; } TradeData* GetTradeData() const { return m_trade; } void TradeCancel(bool sendback); @@ -1947,6 +1861,12 @@ class Player : public Unit, public GridObject<Player> void SetHonorPoints(uint32 value); void SetArenaPoints(uint32 value); + // duel health and mana reset methods + void SaveHealthBeforeDuel() { healthBeforeDuel = GetHealth(); } + void SaveManaBeforeDuel() { manaBeforeDuel = GetPower(POWER_MANA); } + void RestoreHealthAfterDuel() { SetHealth(healthBeforeDuel); } + void RestoreManaAfterDuel() { SetPower(POWER_MANA, manaBeforeDuel); } + //End of PvP System void SetDrunkValue(uint8 newDrunkValue, uint32 itemId = 0); @@ -2474,7 +2394,7 @@ class Player : public Unit, public GridObject<Player> EnchantDurationList m_enchantDuration; ItemDurationList m_itemDuration; - ItemDurationList m_itemSoulboundTradeable; + GuidUnorderedSet m_itemSoulboundTradeable; void ResetTimeSync(); void SendTimeSync(); @@ -2583,6 +2503,8 @@ class Player : public Unit, public GridObject<Player> bool IsHasDelayedTeleport() const { return m_bHasDelayedTeleport; } void SetDelayedTeleportFlag(bool setting) { m_bHasDelayedTeleport = setting; } void ScheduleDelayedOperation(uint32 operation) { if (operation < DELAYED_END) m_DelayedOperations |= operation; } + + bool IsInstanceLoginGameMasterException() const; MapReference m_mapRef; @@ -2630,6 +2552,10 @@ class Player : public Unit, public GridObject<Player> uint32 _activeCheats; + // variables to save health and mana before duel and restore them after duel + uint32 healthBeforeDuel; + uint32 manaBeforeDuel; + WorldLocation _corpseLocation; }; diff --git a/src/server/game/Entities/Player/TradeData.cpp b/src/server/game/Entities/Player/TradeData.cpp new file mode 100644 index 00000000000..bbbd1c81773 --- /dev/null +++ b/src/server/game/Entities/Player/TradeData.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://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/>. + */ + +#include "TradeData.h" +#include "Player.h" +#include "WorldSession.h" + +TradeData* TradeData::GetTraderData() const +{ + return _trader->GetTradeData(); +} + +Item* TradeData::GetItem(TradeSlots slot) const +{ + return !_items[slot].IsEmpty() ? _player->GetItemByGuid(_items[slot]) : nullptr; +} + +bool TradeData::HasItem(ObjectGuid itemGuid) const +{ + for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i) + if (_items[i] == itemGuid) + return true; + + return false; +} + +TradeSlots TradeData::GetTradeSlotForItem(ObjectGuid itemGuid) const +{ + for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i) + if (_items[i] == itemGuid) + return TradeSlots(i); + + return TRADE_SLOT_INVALID; +} + +Item* TradeData::GetSpellCastItem() const +{ + return !_spellCastItem.IsEmpty() ? _player->GetItemByGuid(_spellCastItem) : nullptr; +} + +void TradeData::SetItem(TradeSlots slot, Item* item, bool update /*= false*/) +{ + ObjectGuid itemGuid; + if (item) + itemGuid = item->GetGUID(); + + if (_items[slot] == itemGuid && !update) + return; + + _items[slot] = itemGuid; + + SetAccepted(false); + GetTraderData()->SetAccepted(false); + + Update(); + + // need remove possible trader spell applied to changed item + if (slot == TRADE_SLOT_NONTRADED) + GetTraderData()->SetSpell(0); + + // need remove possible player spell applied (possible move reagent) + SetSpell(0); +} + +void TradeData::SetSpell(uint32 spell_id, Item* castItem /*= nullptr*/) +{ + ObjectGuid itemGuid = castItem ? castItem->GetGUID() : ObjectGuid::Empty; + + if (_spell == spell_id && _spellCastItem == itemGuid) + return; + + _spell = spell_id; + _spellCastItem = itemGuid; + + SetAccepted(false); + GetTraderData()->SetAccepted(false); + + Update(true); // send spell info to item owner + Update(false); // send spell info to caster self +} + +void TradeData::SetMoney(uint32 money) +{ + if (_money == money) + return; + + if (!_player->HasEnoughMoney(money)) + { + TradeStatusInfo info; + info.Status = TRADE_STATUS_CLOSE_WINDOW; + info.Result = EQUIP_ERR_NOT_ENOUGH_MONEY; + _player->GetSession()->SendTradeStatus(info); + return; + } + + _money = money; + + SetAccepted(false); + GetTraderData()->SetAccepted(false); + + Update(true); +} + +void TradeData::Update(bool forTrader /*= true*/) const +{ + if (forTrader) + _trader->GetSession()->SendUpdateTrade(true); // player state for trader + else + _player->GetSession()->SendUpdateTrade(false); // player state for player +} + +void TradeData::SetAccepted(bool state, bool forTrader /*= false*/) +{ + _accepted = state; + + if (!state) + { + TradeStatusInfo info; + info.Status = TRADE_STATUS_BACK_TO_TRADE; + if (forTrader) + _trader->GetSession()->SendTradeStatus(info); + else + _player->GetSession()->SendTradeStatus(info); + } +} diff --git a/src/server/game/Entities/Player/TradeData.h b/src/server/game/Entities/Player/TradeData.h new file mode 100644 index 00000000000..cfaf066bde0 --- /dev/null +++ b/src/server/game/Entities/Player/TradeData.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://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 TradeData_h__ +#define TradeData_h__ + +#include "ObjectGuid.h" + +enum TradeSlots +{ + TRADE_SLOT_COUNT = 7, + TRADE_SLOT_TRADED_COUNT = 6, + TRADE_SLOT_NONTRADED = 6, + TRADE_SLOT_INVALID = -1 +}; + +class Item; +class Player; + +class TradeData +{ +public: + TradeData(Player* player, Player* trader) : + _player(player), _trader(trader), _accepted(false), _acceptProccess(false), + _money(0), _spell(0), _spellCastItem() { } + + Player* GetTrader() const { return _trader; } + TradeData* GetTraderData() const; + + Item* GetItem(TradeSlots slot) const; + bool HasItem(ObjectGuid itemGuid) const; + TradeSlots GetTradeSlotForItem(ObjectGuid itemGuid) const; + void SetItem(TradeSlots slot, Item* item, bool update = false); + + uint32 GetSpell() const { return _spell; } + void SetSpell(uint32 spell_id, Item* castItem = nullptr); + + Item* GetSpellCastItem() const; + bool HasSpellCastItem() const { return !_spellCastItem.IsEmpty(); } + + uint32 GetMoney() const { return _money; } + void SetMoney(uint32 money); + + bool IsAccepted() const { return _accepted; } + void SetAccepted(bool state, bool forTrader = false); + + bool IsInAcceptProcess() const { return _acceptProccess; } + void SetInAcceptProcess(bool state) { _acceptProccess = state; } + +private: + void Update(bool for_trader = true) const; + + Player* _player; // Player who own of this TradeData + Player* _trader; // Player who trade with _player + + bool _accepted; // _player press accept for trade list + bool _acceptProccess; // one from player/trader press accept and this processed + + uint32 _money; // _player place money to trade + + uint32 _spell; // _player apply spell to non-traded slot item + ObjectGuid _spellCastItem; // applied spell cast by item use + + ObjectGuid _items[TRADE_SLOT_COUNT]; // traded items from _player side including non-traded slot +}; + +#endif // TradeData_h__ diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 6b234df5860..27f6d5f614d 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -7475,8 +7475,8 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, Sp uint32 stack = triggeredByAura->GetStackAmount(); int32 const mod = (GetMap()->GetSpawnMode() & 1) ? 1500 : 1250; int32 dmg = 0; - for (uint8 i = 1; i < stack; ++i) - dmg += mod * stack; + for (uint8 i = 1; i <= stack; ++i) + dmg += mod * i; if (Unit* caster = triggeredByAura->GetCaster()) caster->CastCustomSpell(70701, SPELLVALUE_BASE_POINT0, dmg); break; @@ -8291,6 +8291,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg case 15337: // Improved Spirit Tap (Rank 1) case 15338: // Improved Spirit Tap (Rank 2) { + ASSERT(procSpell); if (procSpell->SpellFamilyFlags[0] & 0x800000) if ((procSpell->Id != 58381) || !roll_chance_i(50)) return false; @@ -8552,7 +8553,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg // try detect target manually if not set if (target == NULL) - target = !(procFlags & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS)) && triggerEntry && triggerEntry->IsPositive() ? this : victim; + target = !(procFlags & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS)) && triggerEntry->IsPositive() ? this : victim; if (basepoints0) CastCustomSpell(target, trigger_spell_id, &basepoints0, NULL, NULL, true, castItem, triggeredByAura); @@ -9648,7 +9649,7 @@ Unit* Unit::GetMagicHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo) && _IsValidAttackTarget(magnet, spellInfo)) { /// @todo handle this charge drop by proc in cast phase on explicit target - if (victim && spellInfo->Speed > 0.0f) + if (spellInfo->Speed > 0.0f) { // Set up missile speed based delay uint32 delay = uint32(std::floor(std::max<float>(victim->GetDistance(this), 5.0f) / spellInfo->Speed * 1000.0f)); @@ -12987,9 +12988,6 @@ void Unit::ModSpellCastTime(SpellInfo const* spellInfo, int32 & castTime, Spell* if (!spellInfo || castTime < 0) return; - if (spellInfo->IsChanneled() && !spellInfo->HasAttribute(SPELL_ATTR5_HASTE_AFFECT_DURATION)) - return; - // called from caster if (Player* modOwner = GetSpellModOwner()) modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CASTING_TIME, castTime, spell); @@ -13003,6 +13001,25 @@ void Unit::ModSpellCastTime(SpellInfo const* spellInfo, int32 & castTime, Spell* castTime = 500; } +void Unit::ModSpellDurationTime(SpellInfo const* spellInfo, int32 & duration, Spell* spell) +{ + if (!spellInfo || duration < 0) + return; + + if (spellInfo->IsChanneled() && !spellInfo->HasAttribute(SPELL_ATTR5_HASTE_AFFECT_DURATION)) + return; + + // called from caster + if (Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CASTING_TIME, duration, spell); + + if (!(spellInfo->HasAttribute(SPELL_ATTR0_ABILITY) || spellInfo->HasAttribute(SPELL_ATTR0_TRADESPELL) || spellInfo->HasAttribute(SPELL_ATTR3_NO_DONE_BONUS)) && + ((GetTypeId() == TYPEID_PLAYER && spellInfo->SpellFamilyName) || GetTypeId() == TYPEID_UNIT)) + duration = int32(float(duration) * GetFloatValue(UNIT_MOD_CAST_SPEED)); + else if (spellInfo->HasAttribute(SPELL_ATTR0_REQ_AMMO) && !spellInfo->HasAttribute(SPELL_ATTR2_AUTOREPEAT_FLAG)) + duration = int32(float(duration) * m_modAttackSpeedPct[RANGED_ATTACK]); +} + DiminishingLevels Unit::GetDiminishing(DiminishingGroup group) { for (Diminishing::iterator i = m_Diminishing.begin(); i != m_Diminishing.end(); ++i) @@ -13772,7 +13789,7 @@ void CharmInfo::InitPossessCreateSpells() break; } - for (uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) + for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) { uint32 spellId = _unit->ToCreature()->m_spells[i]; SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); @@ -13781,7 +13798,7 @@ void CharmInfo::InitPossessCreateSpells() if (spellInfo->IsPassive()) _unit->CastSpell(_unit, spellInfo, true); else - AddSpellToActionBar(spellInfo, ACT_PASSIVE); + AddSpellToActionBar(spellInfo, ACT_PASSIVE, i % MAX_UNIT_ACTION_BAR_INDEX); } } } @@ -13839,11 +13856,12 @@ void CharmInfo::InitCharmCreateSpells() } } -bool CharmInfo::AddSpellToActionBar(SpellInfo const* spellInfo, ActiveStates newstate) +bool CharmInfo::AddSpellToActionBar(SpellInfo const* spellInfo, ActiveStates newstate, uint8 preferredSlot) { uint32 spell_id = spellInfo->Id; uint32 first_id = spellInfo->GetFirstRankSpell()->Id; + ASSERT(preferredSlot < MAX_UNIT_ACTION_BAR_INDEX); // new spell rank can be already listed for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) { @@ -13860,9 +13878,10 @@ bool CharmInfo::AddSpellToActionBar(SpellInfo const* spellInfo, ActiveStates new // or use empty slot in other case for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) { - if (!PetActionBar[i].GetAction() && PetActionBar[i].IsActionBarForSpell()) + uint8 j = (preferredSlot + i) % MAX_UNIT_ACTION_BAR_INDEX; + if (!PetActionBar[j].GetAction() && PetActionBar[j].IsActionBarForSpell()) { - SetActionBar(i, spell_id, newstate == ACT_DECIDE ? spellInfo->IsAutocastable() ? ACT_DISABLED : ACT_PASSIVE : newstate); + SetActionBar(j, spell_id, newstate == ACT_DECIDE ? spellInfo->IsAutocastable() ? ACT_DISABLED : ACT_PASSIVE : newstate); return true; } } @@ -15802,7 +15821,7 @@ void Unit::SetFeared(bool apply) } if (Player* player = ToPlayer()) - if(!player->HasUnitState(UNIT_STATE_POSSESSED)) + if (!player->HasUnitState(UNIT_STATE_POSSESSED)) player->SetClientControl(this, !apply); } @@ -16023,7 +16042,7 @@ void Unit::RemoveCharmedBy(Unit* charmer) // Vehicle should not attack its passenger after he exists the seat if (type != CHARM_TYPE_VEHICLE) - LastCharmerGUID = charmer->GetGUID(); + LastCharmerGUID = ASSERT_NOTNULL(charmer)->GetGUID(); } // If charmer still exists @@ -17772,22 +17791,8 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) } if (cinfo->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER) - { if (target->IsGameMaster()) - { - if (cinfo->Modelid1) - displayId = cinfo->Modelid1; // Modelid1 is a visible model for gms - else - displayId = 17519; // world visible trigger's model - } - else - { - if (cinfo->Modelid2) - displayId = cinfo->Modelid2; // Modelid2 is an invisible model for players - else - displayId = 11686; // world invisible trigger's model - } - } + displayId = cinfo->GetFirstVisibleModel(); } fieldBuffer << uint32(displayId); diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 39b1c34be55..2ddbe398f76 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -898,6 +898,12 @@ public: uint32 GetHitMask() const { return _hitMask; } SpellInfo const* GetSpellInfo() const { return NULL; } + SpellInfo const* EnsureSpellInfo() const + { + SpellInfo const* spellInfo = GetSpellInfo(); + ASSERT(spellInfo); + return spellInfo; + } SpellSchoolMask GetSchoolMask() const { return SPELL_SCHOOL_MASK_NONE; } DamageInfo* GetDamageInfo() const { return _damageInfo; } @@ -1119,7 +1125,7 @@ struct CharmInfo void InitEmptyActionBar(bool withAttack = true); //return true if successful - bool AddSpellToActionBar(SpellInfo const* spellInfo, ActiveStates newstate = ACT_DECIDE); + bool AddSpellToActionBar(SpellInfo const* spellInfo, ActiveStates newstate = ACT_DECIDE, uint8 preferredSlot = 0); bool RemoveSpellFromActionBar(uint32 spell_id); void LoadPetActionBar(const std::string& data); void BuildActionBar(WorldPacket* data); @@ -1395,6 +1401,7 @@ class Unit : public WorldObject void DealDamageMods(Unit* victim, uint32 &damage, uint32* absorb); uint32 DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDamage = NULL, DamageEffectType damagetype = DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* spellProto = NULL, bool durabilityLoss = true); void Kill(Unit* victim, bool durabilityLoss = true); + void KillSelf(bool durabilityLoss = true) { Kill(this, durabilityLoss); } int32 DealHeal(Unit* victim, uint32 addhealth); void ProcDamageAndSpell(Unit* victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType = BASE_ATTACK, SpellInfo const* procSpell = NULL, SpellInfo const* procAura = NULL); @@ -1982,6 +1989,7 @@ class Unit : public WorldObject int32 CalcSpellDuration(SpellInfo const* spellProto); int32 ModSpellDuration(SpellInfo const* spellProto, Unit const* target, int32 duration, bool positive, uint32 effectMask); void ModSpellCastTime(SpellInfo const* spellProto, int32& castTime, Spell* spell = NULL); + void ModSpellDurationTime(SpellInfo const* spellProto, int32& castTime, Spell* spell = NULL); float CalculateLevelPenalty(SpellInfo const* spellProto) const; void addFollower(FollowerReference* pRef) { m_FollowingRefManager.insertFirst(pRef); } diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 046ce422cd2..6f5368ed150 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -1236,7 +1236,11 @@ uint32 ObjectMgr::ChooseDisplayId(CreatureTemplate const* cinfo, CreatureData co if (data && data->displayid) return data->displayid; - return cinfo->GetRandomValidModelId(); + if (!(cinfo->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER)) + return cinfo->GetRandomValidModelId(); + + // Triggers by default receive the invisible model + return cinfo->GetFirstInvisibleModel(); } void ObjectMgr::ChooseCreatureFlags(const CreatureTemplate* cinfo, uint32& npcflag, uint32& unit_flags, uint32& dynamicflags, const CreatureData* data /*= NULL*/) @@ -1301,6 +1305,12 @@ void ObjectMgr::LoadCreatureModelInfo() Field* fields = result->Fetch(); uint32 modelId = fields[0].GetUInt32(); + CreatureDisplayInfoEntry const* creatureDisplay = sCreatureDisplayInfoStore.LookupEntry(modelId); + if (!creatureDisplay) + { + TC_LOG_ERROR("sql.sql", "Table `creature_model_info` has model for nonexistent display id (%u).", modelId); + continue; + } CreatureModelInfo& modelInfo = _creatureModelStore[modelId]; @@ -1308,12 +1318,10 @@ void ObjectMgr::LoadCreatureModelInfo() modelInfo.combat_reach = fields[2].GetFloat(); modelInfo.gender = fields[3].GetUInt8(); modelInfo.modelid_other_gender = fields[4].GetUInt32(); + modelInfo.is_trigger = false; // Checks - if (!sCreatureDisplayInfoStore.LookupEntry(modelId)) - TC_LOG_ERROR("sql.sql", "Table `creature_model_info` has model for nonexistent display id (%u).", modelId); - if (modelInfo.gender > GENDER_NONE) { TC_LOG_ERROR("sql.sql", "Table `creature_model_info` has wrong gender (%u) for display id (%u).", uint32(modelInfo.gender), modelId); @@ -1329,6 +1337,9 @@ void ObjectMgr::LoadCreatureModelInfo() if (modelInfo.combat_reach < 0.1f) modelInfo.combat_reach = DEFAULT_COMBAT_REACH; + if (CreatureModelDataEntry const* modelData = sCreatureModelDataStore.LookupEntry(creatureDisplay->ModelId)) + modelInfo.is_trigger = strstr(modelData->ModelPath, "InvisibleStalker") != nullptr; + ++count; } while (result->NextRow()); @@ -2347,6 +2358,12 @@ void ObjectMgr::LoadItemTemplates() itemTemplate.ContainerSlots = uint32(fields[26].GetUInt8()); itemTemplate.StatsCount = uint32(fields[27].GetUInt8()); + if (itemTemplate.StatsCount > MAX_ITEM_PROTO_STATS) + { + TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has too large value in statscount (%u), replace by hardcoded limit (%u).", entry, itemTemplate.StatsCount, MAX_ITEM_PROTO_STATS); + itemTemplate.StatsCount = MAX_ITEM_PROTO_STATS; + } + for (uint8 i = 0; i < itemTemplate.StatsCount; ++i) { itemTemplate.ItemStat[i].ItemStatType = uint32(fields[28 + i*2].GetUInt8()); @@ -2594,12 +2611,6 @@ void ObjectMgr::LoadItemTemplates() itemTemplate.ContainerSlots = MAX_BAG_SIZE; } - if (itemTemplate.StatsCount > MAX_ITEM_PROTO_STATS) - { - TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has too large value in statscount (%u), replace by hardcoded limit (%u).", entry, itemTemplate.StatsCount, MAX_ITEM_PROTO_STATS); - itemTemplate.StatsCount = MAX_ITEM_PROTO_STATS; - } - for (uint8 j = 0; j < itemTemplate.StatsCount; ++j) { // for ItemStatValue != 0 diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 5f500156f58..4f8accee69c 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -539,7 +539,7 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R } // Reevaluate group enchanter if the leaving player had enchanting skill or the player is offline - if ((player && player->GetSkillValue(SKILL_ENCHANTING)) || !player) + if (!player || player->GetSkillValue(SKILL_ENCHANTING)) ResetMaxEnchantingLevel(); // Remove player from loot rolls diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index 8ecf86680ca..a9680ff69bb 100644 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -303,18 +303,21 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) AH->buyout = buyout; AH->expire_time = time(NULL) + auctionTime; AH->deposit = deposit; + AH->etime = etime; AH->auctionHouseEntry = auctionHouseEntry; TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) with count %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", _player->GetName().c_str(), _player->GetGUID().GetCounter(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetGUID().GetCounter(), item->GetCount(), bid, buyout, auctionTime, AH->GetHouseId()); sAuctionMgr->AddAItem(item); auctionHouse->AddAuction(AH); + sAuctionMgr->PendingAuctionAdd(_player, AH); _player->MoveItemFromInventory(item->GetBagSlot(), item->GetSlot(), true); SQLTransaction trans = CharacterDatabase.BeginTransaction(); item->DeleteFromInventoryDB(trans); item->SaveToDB(trans); + AH->SaveToDB(trans); _player->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); @@ -351,12 +354,14 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) AH->buyout = buyout; AH->expire_time = time(NULL) + auctionTime; AH->deposit = deposit; + AH->etime = etime; AH->auctionHouseEntry = auctionHouseEntry; TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) with count %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", _player->GetName().c_str(), _player->GetGUID().GetCounter(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(), newItem->GetGUID().GetCounter(), newItem->GetCount(), bid, buyout, auctionTime, AH->GetHouseId()); sAuctionMgr->AddAItem(newItem); auctionHouse->AddAuction(AH); + sAuctionMgr->PendingAuctionAdd(_player, AH); for (uint32 j = 0; j < itemsCount; ++j) { @@ -396,8 +401,6 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); } - - _player->ModifyMoney(-int32(deposit)); } //this function is called when client bids or buys out auction diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index e5b32f548f9..60ec60443d6 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -642,7 +642,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte TC_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Create Character:[%s] (GUID: %u)", GetAccountId(), GetRemoteAddress().c_str(), createInfo->Name.c_str(), newChar.GetGUID().GetCounter()); sScriptMgr->OnPlayerCreate(&newChar); - sWorld->AddCharacterInfo(newChar.GetGUID(), GetAccountId(), newChar.GetName(), newChar.getGender(), newChar.getRace(), newChar.getClass(), newChar.getLevel()); + sWorld->AddCharacterInfo(newChar.GetGUID(), GetAccountId(), newChar.GetName(), newChar.GetByteValue(PLAYER_BYTES_3, 0), newChar.getRace(), newChar.getClass(), newChar.getLevel()); newChar.CleanupsBeforeDelete(); delete createInfo; @@ -1242,20 +1242,20 @@ void WorldSession::HandleAlterAppearance(WorldPacket& recvData) BarberShopStyleEntry const* bs_hair = sBarberShopStyleStore.LookupEntry(Hair); - if (!bs_hair || bs_hair->type != 0 || bs_hair->race != _player->getRace() || bs_hair->gender != _player->getGender()) + if (!bs_hair || bs_hair->type != 0 || bs_hair->race != _player->getRace() || bs_hair->gender != _player->GetByteValue(PLAYER_BYTES_3, 0)) return; BarberShopStyleEntry const* bs_facialHair = sBarberShopStyleStore.LookupEntry(FacialHair); - if (!bs_facialHair || bs_facialHair->type != 2 || bs_facialHair->race != _player->getRace() || bs_facialHair->gender != _player->getGender()) + if (!bs_facialHair || bs_facialHair->type != 2 || bs_facialHair->race != _player->getRace() || bs_facialHair->gender != _player->GetByteValue(PLAYER_BYTES_3, 0)) return; BarberShopStyleEntry const* bs_skinColor = sBarberShopStyleStore.LookupEntry(SkinColor); - if (bs_skinColor && (bs_skinColor->type != 3 || bs_skinColor->race != _player->getRace() || bs_skinColor->gender != _player->getGender())) + if (bs_skinColor && (bs_skinColor->type != 3 || bs_skinColor->race != _player->getRace() || bs_skinColor->gender != _player->GetByteValue(PLAYER_BYTES_3, 0))) return; - if (!Player::ValidateAppearance(_player->getRace(), _player->getClass(), _player->getGender(), bs_hair->hair_id, Color, _player->GetByteValue(PLAYER_BYTES, 1), bs_facialHair->hair_id, bs_skinColor ? bs_skinColor->hair_id : _player->GetByteValue(PLAYER_BYTES, 0))) + if (!Player::ValidateAppearance(_player->getRace(), _player->getClass(), _player->GetByteValue(PLAYER_BYTES_3, 0), bs_hair->hair_id, Color, _player->GetByteValue(PLAYER_BYTES, 1), bs_facialHair->hair_id, bs_skinColor ? bs_skinColor->hair_id : _player->GetByteValue(PLAYER_BYTES, 0))) return; GameObject* go = _player->FindNearestGameObjectOfType(GAMEOBJECT_TYPE_BARBER_CHAIR, 5.0f); diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 30764fea2a3..9f225df8427 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -991,7 +991,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket &recvData) data.put<uint64>(maskPos, auraMask); // GROUP_UPDATE_FLAG_AURAS if (updateFlags & GROUP_UPDATE_FLAG_PET_GUID) - data << uint64(pet->GetGUID()); + data << uint64(ASSERT_NOTNULL(pet)->GetGUID()); data << std::string(pet ? pet->GetName() : ""); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet ? pet->GetDisplayId() : 0); // GROUP_UPDATE_FLAG_PET_MODEL_ID diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 2eebbfc1004..6dcd3242a6c 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -283,7 +283,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData) continue; uint32 pzoneid = target->GetZoneId(); - uint8 gender = target->getGender(); + uint8 gender = target->GetByteValue(PLAYER_BYTES_3, 0); bool z_show = true; for (uint32 i = 0; i < zones_count; ++i) diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp index fbfd16ae1c6..1bb21971935 100644 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -28,6 +28,7 @@ #include "SocialMgr.h" #include "Language.h" #include "AccountMgr.h" +#include "TradeData.h" void WorldSession::SendTradeStatus(TradeStatusInfo const& info) { @@ -454,6 +455,8 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) SendTradeStatus(myCanCompleteInfo); my_trade->SetAccepted(false); his_trade->SetAccepted(false); + delete my_spell; + delete his_spell; return; } else if (hisCanCompleteInfo.Result != EQUIP_ERR_OK) @@ -466,6 +469,8 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) trader->GetSession()->SendTradeStatus(hisCanCompleteInfo); my_trade->SetAccepted(false); his_trade->SetAccepted(false); + delete my_spell; + delete his_spell; return; } diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index de117905b3d..85971396619 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -1202,7 +1202,8 @@ enum TrinityStrings LANG_BAN_ACCOUNT_YOUPERMBANNEDMESSAGE_WORLD = 11007, LANG_NPCINFO_INHABIT_TYPE = 11008, - LANG_NPCINFO_FLAGS_EXTRA = 11009 + LANG_NPCINFO_FLAGS_EXTRA = 11009, + LANG_INSTANCE_LOGIN_GAMEMASTER_EXCEPTION = 11010 }; #endif diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp index 58bc4915d3f..a3f662f2ade 100644 --- a/src/server/game/Quests/QuestDef.cpp +++ b/src/server/game/Quests/QuestDef.cpp @@ -127,6 +127,18 @@ Quest::Quest(Field* questRecord) for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i) if (RewardChoiceItemId[i]) ++_rewChoiceItemsCount; + + for (int i = 0; i < QUEST_EMOTE_COUNT; ++i) + DetailsEmote[i] = 0; + + for (int i = 0; i < QUEST_EMOTE_COUNT; ++i) + DetailsEmoteDelay[i] = 0; + + for (int i = 0; i < QUEST_EMOTE_COUNT; ++i) + OfferRewardEmote[i] = 0; + + for (int i = 0; i < QUEST_EMOTE_COUNT; ++i) + OfferRewardEmoteDelay[i] = 0; } void Quest::LoadQuestDetails(Field* fields) diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index b1a043c4b5b..6ae63f2efa3 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -341,7 +341,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet"); else if (_player->IsInWorld()) LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world"); - else if(AntiDOS.EvaluateOpcode(*packet, currentTime)) + else if (AntiDOS.EvaluateOpcode(*packet, currentTime)) { sScriptMgr->OnPacketReceive(this, *packet); (this->*opHandle.handler)(*packet); @@ -858,9 +858,8 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi) // MOVEMENTFLAG_ROOT + MOVEMENTFLAG_PITCH_UP (0x840) // MOVEMENTFLAG_ROOT + MOVEMENTFLAG_PITCH_DOWN (0x880) // If none of these are true, clear the root - if (mi->HasMovementFlag(MOVEMENTFLAG_ROOT) && mi->HasMovementFlag(MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT | MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN)) - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ROOT), - MOVEMENTFLAG_MASK_MOVING); + REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ROOT) && mi->HasMovementFlag(MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT | MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN), + MOVEMENTFLAG_MASK_MOVING); } else { diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 5e70d953be9..01f27a38e9c 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -541,10 +541,7 @@ void AuraEffect::CalculatePeriodic(Unit* caster, bool create, bool load) { // Haste modifies periodic time of channeled spells if (m_spellInfo->IsChanneled()) - { - if (m_spellInfo->HasAttribute(SPELL_ATTR5_HASTE_AFFECT_DURATION)) - caster->ModSpellCastTime(m_spellInfo, m_amplitude); - } + caster->ModSpellDurationTime(m_spellInfo, m_amplitude); // and periodic time of auras affected by SPELL_AURA_PERIODIC_HASTE else if (caster->HasAuraTypeWithAffectMask(SPELL_AURA_PERIODIC_HASTE, m_spellInfo) || m_spellInfo->HasAttribute(SPELL_ATTR5_HASTE_AFFECT_DURATION)) m_amplitude = int32(m_amplitude * caster->GetFloatValue(UNIT_MOD_CAST_SPEED)); @@ -1866,43 +1863,43 @@ void AuraEffect::HandleAuraTransform(AuraApplication const* aurApp, uint8 mode, { // Blood Elf case RACE_BLOODELF: - target->SetDisplayId(target->getGender() == GENDER_MALE ? 17829 : 17830); + target->SetDisplayId(target->getGender() == GENDER_FEMALE ? 17830 : 17829); break; // Orc case RACE_ORC: - target->SetDisplayId(target->getGender() == GENDER_MALE ? 10139 : 10140); + target->SetDisplayId(target->getGender() == GENDER_FEMALE ? 10140 : 10139); break; // Troll case RACE_TROLL: - target->SetDisplayId(target->getGender() == GENDER_MALE ? 10135 : 10134); + target->SetDisplayId(target->getGender() == GENDER_FEMALE ? 10134 : 10135); break; // Tauren case RACE_TAUREN: - target->SetDisplayId(target->getGender() == GENDER_MALE ? 10136 : 10147); + target->SetDisplayId(target->getGender() == GENDER_FEMALE ? 10147 : 10136); break; // Undead case RACE_UNDEAD_PLAYER: - target->SetDisplayId(target->getGender() == GENDER_MALE ? 10146 : 10145); + target->SetDisplayId(target->getGender() == GENDER_FEMALE ? 10145 : 10146); break; // Draenei case RACE_DRAENEI: - target->SetDisplayId(target->getGender() == GENDER_MALE ? 17827 : 17828); + target->SetDisplayId(target->getGender() == GENDER_FEMALE ? 17828 : 17827); break; // Dwarf case RACE_DWARF: - target->SetDisplayId(target->getGender() == GENDER_MALE ? 10141 : 10142); + target->SetDisplayId(target->getGender() == GENDER_FEMALE ? 10142 : 10141); break; // Gnome case RACE_GNOME: - target->SetDisplayId(target->getGender() == GENDER_MALE ? 10148 : 10149); + target->SetDisplayId(target->getGender() == GENDER_FEMALE ? 10149 : 10148); break; // Human case RACE_HUMAN: - target->SetDisplayId(target->getGender() == GENDER_MALE ? 10137 : 10138); + target->SetDisplayId(target->getGender() == GENDER_FEMALE ? 10138 : 10137); break; // Night Elf case RACE_NIGHTELF: - target->SetDisplayId(target->getGender() == GENDER_MALE ? 10143 : 10144); + target->SetDisplayId(target->getGender() == GENDER_FEMALE ? 10144 : 10143); break; default: break; @@ -4646,17 +4643,10 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool { if (caster) { - switch (caster->getGender()) - { - case GENDER_FEMALE: - caster->CastSpell(target, 37095, true, NULL, this); // Blood Elf Disguise - break; - case GENDER_MALE: - caster->CastSpell(target, 37093, true, NULL, this); - break; - default: - break; - } + if (caster->getGender() == GENDER_FEMALE) + caster->CastSpell(target, 37095, true, NULL, this); // Blood Elf Disguise + else + caster->CastSpell(target, 37093, true, NULL, this); } break; } @@ -4686,15 +4676,10 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool case 46354: // Blood Elf Illusion if (caster) { - switch (caster->getGender()) - { - case GENDER_FEMALE: - caster->CastSpell(target, 46356, true, NULL, this); - break; - case GENDER_MALE: - caster->CastSpell(target, 46355, true, NULL, this); - break; - } + if (caster->getGender() == GENDER_FEMALE) + caster->CastSpell(target, 46356, true, NULL, this); + else + caster->CastSpell(target, 46355, true, NULL, this); } break; case 46361: // Reinforced Net @@ -5577,7 +5562,7 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) case 31347: { target->CastSpell(target, 31350, true, NULL, this); - target->Kill(target); + target->KillSelf(); return; } // Spellcloth diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 76eefa0bb0e..4f3b60d6f37 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -53,6 +53,7 @@ #include "SpellHistory.h" #include "Battlefield.h" #include "BattlefieldMgr.h" +#include "TradeData.h" extern pEffect SpellEffects[TOTAL_SPELL_EFFECTS]; @@ -2428,9 +2429,8 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) { m_caster->CombatStart(unit, !m_spellInfo->HasAttribute(SPELL_ATTR3_NO_INITIAL_AGGRO)); - if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_AURA_CC)) - if (!unit->IsStandState()) - unit->SetStandState(UNIT_STAND_STATE_STAND); + if (!unit->IsStandState()) + unit->SetStandState(UNIT_STAND_STATE_STAND); } if (spellHitTarget) @@ -2514,8 +2514,8 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA if (m_caster->_IsValidAttackTarget(unit, m_spellInfo)) { unit->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_HITBYSPELL); - /// @todo This is a hack. But we do not know what types of stealth should be interrupted by CC - if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_AURA_CC) && unit->IsControlledByPlayer()) + + if (!m_spellInfo->HasAttribute(SPELL_ATTR0_CU_DONT_BREAK_STEALTH)) unit->RemoveAurasByType(SPELL_AURA_MOD_STEALTH); } else if (m_caster->IsFriendlyTo(unit)) @@ -2624,7 +2624,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA // Haste modifies duration of channeled spells if (m_spellInfo->IsChanneled()) - m_originalCaster->ModSpellCastTime(aurSpellInfo, duration, this); + m_originalCaster->ModSpellDurationTime(aurSpellInfo, duration, this); // and duration of auras affected by SPELL_AURA_PERIODIC_HASTE else if (m_originalCaster->HasAuraTypeWithAffectMask(SPELL_AURA_PERIODIC_HASTE, aurSpellInfo) || m_spellInfo->HasAttribute(SPELL_ATTR5_HASTE_AFFECT_DURATION)) duration = int32(duration * m_originalCaster->GetFloatValue(UNIT_MOD_CAST_SPEED)); @@ -3258,7 +3258,7 @@ void Spell::handle_immediate() modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration); // Apply haste mods - m_caster->ModSpellCastTime(m_spellInfo, duration, this); + m_caster->ModSpellDurationTime(m_spellInfo, duration, this); m_spellState = SPELL_STATE_CASTING; m_caster->AddInterruptMask(m_spellInfo->ChannelInterruptFlags); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index b345c5affea..b3ab72dcbff 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -5638,7 +5638,7 @@ void Spell::EffectGameObjectDamage(SpellEffIndex /*effIndex*/) FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry(); FactionTemplateEntry const* targetFaction = sFactionTemplateStore.LookupEntry(gameObjTarget->GetUInt32Value(GAMEOBJECT_FACTION)); // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons) - if ((casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction)) || !targetFaction) + if (!targetFaction || (casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction))) gameObjTarget->ModifyHealth(-damage, caster, GetSpellInfo()->Id); } diff --git a/src/server/game/Spells/SpellHistory.cpp b/src/server/game/Spells/SpellHistory.cpp index d2cf03dc936..faad54d0af7 100644 --- a/src/server/game/Spells/SpellHistory.cpp +++ b/src/server/game/Spells/SpellHistory.cpp @@ -41,6 +41,7 @@ struct SpellHistory::PersistenceHelper<Player> if (!sSpellMgr->GetSpellInfo(*spellId)) return false; + cooldownEntry->SpellId = *spellId; cooldownEntry->CooldownEnd = Clock::from_time_t(time_t(fields[2].GetUInt32())); cooldownEntry->ItemId = fields[1].GetUInt32(); cooldownEntry->CategoryId = fields[3].GetUInt32(); @@ -72,6 +73,7 @@ struct SpellHistory::PersistenceHelper<Pet> if (!sSpellMgr->GetSpellInfo(*spellId)) return false; + cooldownEntry->SpellId = *spellId; cooldownEntry->CooldownEnd = Clock::from_time_t(time_t(fields[1].GetUInt32())); cooldownEntry->ItemId = 0; cooldownEntry->CategoryId = fields[2].GetUInt32(); @@ -280,32 +282,7 @@ void SpellHistory::StartCooldown(SpellInfo const* spellInfo, uint32 itemId, Spel int32 cooldown = -1; int32 categoryCooldown = -1; - // some special item spells without correct cooldown in SpellInfo - // cooldown information stored in item prototype - if (itemId) - { - if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId)) - { - for (uint8 idx = 0; idx < MAX_ITEM_PROTO_SPELLS; ++idx) - { - if (uint32(proto->Spells[idx].SpellId) == spellInfo->Id) - { - categoryId = proto->Spells[idx].SpellCategory; - cooldown = proto->Spells[idx].SpellCooldown; - categoryCooldown = proto->Spells[idx].SpellCategoryCooldown; - break; - } - } - } - } - - // if no cooldown found above then base at DBC data - if (cooldown < 0 && categoryCooldown < 0) - { - categoryId = spellInfo->GetCategory(); - cooldown = spellInfo->RecoveryTime; - categoryCooldown = spellInfo->CategoryRecoveryTime; - } + GetCooldownDurations(spellInfo, itemId, &cooldown, &categoryId, &categoryCooldown); Clock::time_point curTime = Clock::now(); Clock::time_point catrecTime; @@ -381,23 +358,39 @@ void SpellHistory::StartCooldown(SpellInfo const* spellInfo, uint32 itemId, Spel void SpellHistory::SendCooldownEvent(SpellInfo const* spellInfo, uint32 itemId /*= 0*/, Spell* spell /*= nullptr*/, bool startCooldown /*= true*/) { - // start cooldowns at server side, if any - if (startCooldown) - StartCooldown(spellInfo, itemId, spell); - // Send activate cooldown timer (possible 0) at client side if (Player* player = GetPlayerOwner()) { + uint32 category = spellInfo->GetCategory(); + GetCooldownDurations(spellInfo, itemId, nullptr, &category, nullptr); + + auto categoryItr = _categoryCooldowns.find(category); + if (categoryItr != _categoryCooldowns.end() && categoryItr->second->SpellId != spellInfo->Id) + { + WorldPacket data(SMSG_COOLDOWN_EVENT, 4 + 8); + data << uint32(categoryItr->second->SpellId); + data << uint64(_owner->GetGUID()); + player->SendDirectMessage(&data); + + if (startCooldown) + StartCooldown(sSpellMgr->EnsureSpellInfo(categoryItr->second->SpellId), itemId, spell); + } + WorldPacket data(SMSG_COOLDOWN_EVENT, 4 + 8); data << uint32(spellInfo->Id); data << uint64(_owner->GetGUID()); player->SendDirectMessage(&data); } + + // start cooldowns at server side, if any + if (startCooldown) + StartCooldown(spellInfo, itemId, spell); } void SpellHistory::AddCooldown(uint32 spellId, uint32 itemId, Clock::time_point cooldownEnd, uint32 categoryId, Clock::time_point categoryEnd, bool onHold /*= false*/) { CooldownEntry& cooldownEntry = _spellCooldowns[spellId]; + cooldownEntry.SpellId = spellId; cooldownEntry.CooldownEnd = cooldownEnd; cooldownEntry.ItemId = itemId; cooldownEntry.CategoryId = categoryId; @@ -478,21 +471,7 @@ bool SpellHistory::HasCooldown(SpellInfo const* spellInfo, uint32 itemId /*= 0*/ return true; uint32 category = 0; - if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId)) - { - for (uint32 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) - { - if (uint32(itemTemplate->Spells[i].SpellId) == spellInfo->Id) - { - category = itemTemplate->Spells[i].SpellCategory; - break; - } - } - } - - if (!category) - category = spellInfo->GetCategory(); - + GetCooldownDurations(spellInfo, itemId, nullptr, &category, nullptr); if (!category) return false; @@ -651,6 +630,48 @@ void SpellHistory::BuildCooldownPacket(WorldPacket& data, uint8 flags, PacketCoo } } +void SpellHistory::GetCooldownDurations(SpellInfo const* spellInfo, uint32 itemId, int32* cooldown, uint32* categoryId, int32* categoryCooldown) +{ + ASSERT(cooldown || categoryId || categoryCooldown); + int32 tmpCooldown = -1; + uint32 tmpCategoryId = 0; + int32 tmpCategoryCooldown = -1; + + // some special item spells without correct cooldown in SpellInfo + // cooldown information stored in item prototype + if (itemId) + { + if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId)) + { + for (uint8 idx = 0; idx < MAX_ITEM_PROTO_SPELLS; ++idx) + { + if (uint32(proto->Spells[idx].SpellId) == spellInfo->Id) + { + tmpCooldown = proto->Spells[idx].SpellCooldown; + tmpCategoryId = proto->Spells[idx].SpellCategory; + tmpCategoryCooldown = proto->Spells[idx].SpellCategoryCooldown; + break; + } + } + } + } + + // if no cooldown found above then base at DBC data + if (tmpCooldown < 0 && tmpCategoryCooldown < 0) + { + tmpCooldown = spellInfo->RecoveryTime; + tmpCategoryId = spellInfo->GetCategory(); + tmpCategoryCooldown = spellInfo->CategoryRecoveryTime; + } + + if (cooldown) + *cooldown = tmpCooldown; + if (categoryId) + *categoryId = tmpCategoryId; + if (categoryCooldown) + *categoryCooldown = tmpCategoryCooldown; +} + void SpellHistory::SaveCooldownStateBeforeDuel() { _spellCooldownsBeforeDuel = _spellCooldowns; @@ -671,19 +692,12 @@ void SpellHistory::RestoreCooldownStateAfterDuel() _spellCooldownsBeforeDuel[itr->first] = _spellCooldowns[itr->first]; } - _spellCooldowns = _spellCooldownsBeforeDuel; - - // update the client: clear all cooldowns - std::vector<int32> resetCooldowns; - resetCooldowns.reserve(_spellCooldowns.size()); - - for (auto itr = _spellCooldowns.begin(); itr != _spellCooldowns.end(); ++itr) - resetCooldowns.push_back(itr->first); - - if (resetCooldowns.empty()) - return; - - SendClearCooldowns(resetCooldowns); + // check for spell with onHold active before and during the duel + for (auto itr = _spellCooldownsBeforeDuel.begin(); itr != _spellCooldownsBeforeDuel.end(); ++itr) + { + if (!itr->second.OnHold && !_spellCooldowns[itr->first].OnHold) + _spellCooldowns[itr->first] = _spellCooldownsBeforeDuel[itr->first]; + } // update the client: restore old cooldowns PacketCooldowns cooldowns; @@ -694,14 +708,14 @@ void SpellHistory::RestoreCooldownStateAfterDuel() uint32 cooldownDuration = itr->second.CooldownEnd > now ? std::chrono::duration_cast<std::chrono::milliseconds>(itr->second.CooldownEnd - now).count() : 0; // cooldownDuration must be between 0 and 10 minutes in order to avoid any visual bugs - if (cooldownDuration == 0 || cooldownDuration > 10 * MINUTE * IN_MILLISECONDS) + if (cooldownDuration <= 0 || cooldownDuration > 10 * MINUTE * IN_MILLISECONDS || itr->second.OnHold) continue; cooldowns[itr->first] = cooldownDuration; } WorldPacket data; - BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_NONE, cooldowns); + BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_INCLUDE_EVENT_COOLDOWNS, cooldowns); player->SendDirectMessage(&data); } } diff --git a/src/server/game/Spells/SpellHistory.h b/src/server/game/Spells/SpellHistory.h index 6a1da28f08f..db65cd50c3e 100644 --- a/src/server/game/Spells/SpellHistory.h +++ b/src/server/game/Spells/SpellHistory.h @@ -38,6 +38,7 @@ public: struct CooldownEntry { + uint32 SpellId = 0; Clock::time_point CooldownEnd; uint32 ItemId = 0; uint32 CategoryId = 0; @@ -135,6 +136,8 @@ private: typedef std::unordered_map<uint32, uint32> PacketCooldowns; void BuildCooldownPacket(WorldPacket& data, uint8 flags, PacketCooldowns const& cooldowns) const; + static void GetCooldownDurations(SpellInfo const* spellInfo, uint32 itemId, int32* cooldown, uint32* categoryId, int32* categoryCooldown); + Unit* _owner; CooldownStorageType _spellCooldowns; CooldownStorageType _spellCooldownsBeforeDuel; diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 241e7df9544..d042f926d02 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -176,7 +176,7 @@ enum SpellCustomAttributes SPELL_ATTR0_CU_CONE_LINE = 0x00000004, SPELL_ATTR0_CU_SHARE_DAMAGE = 0x00000008, SPELL_ATTR0_CU_NO_INITIAL_THREAT = 0x00000010, - SPELL_ATTR0_CU_AURA_CC = 0x00000040, + SPELL_ATTR0_CU_DONT_BREAK_STEALTH = 0x00000040, SPELL_ATTR0_CU_DIRECT_DAMAGE = 0x00000100, SPELL_ATTR0_CU_CHARGE = 0x00000200, SPELL_ATTR0_CU_PICKPOCKET = 0x00000400, diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 6305d0a456f..debe4ac3cbf 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -969,10 +969,10 @@ bool SpellMgr::CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcE // check spell family name/flags (if set) for spells if (eventInfo.GetTypeMask() & (PERIODIC_PROC_FLAG_MASK | SPELL_PROC_FLAG_MASK | PROC_FLAG_DONE_TRAP_ACTIVATION)) { - if (procEntry.spellFamilyName && eventInfo.GetSpellInfo() && (procEntry.spellFamilyName != eventInfo.GetSpellInfo()->SpellFamilyName)) + if (procEntry.spellFamilyName && eventInfo.GetSpellInfo() && (procEntry.spellFamilyName != eventInfo.EnsureSpellInfo()->SpellFamilyName)) return false; - if (procEntry.spellFamilyMask && eventInfo.GetSpellInfo() && !(procEntry.spellFamilyMask & eventInfo.GetSpellInfo()->SpellFamilyFlags)) + if (procEntry.spellFamilyMask && eventInfo.GetSpellInfo() && !(procEntry.spellFamilyMask & eventInfo.EnsureSpellInfo()->SpellFamilyFlags)) return false; } @@ -2801,14 +2801,6 @@ void SpellMgr::LoadSpellInfoCustomAttributes() { switch (spellInfo->Effects[j].ApplyAuraName) { - case SPELL_AURA_MOD_POSSESS: - case SPELL_AURA_MOD_CONFUSE: - case SPELL_AURA_MOD_CHARM: - case SPELL_AURA_AOE_CHARM: - case SPELL_AURA_MOD_FEAR: - case SPELL_AURA_MOD_STUN: - spellInfo->AttributesCu |= SPELL_ATTR0_CU_AURA_CC; - break; case SPELL_AURA_PERIODIC_HEAL: case SPELL_AURA_PERIODIC_DAMAGE: case SPELL_AURA_PERIODIC_DAMAGE_PERCENT: @@ -2901,22 +2893,6 @@ void SpellMgr::LoadSpellInfoCustomAttributes() if (spellInfo->SpellVisual[0] == 3879) spellInfo->AttributesCu |= SPELL_ATTR0_CU_CONE_BACK; - switch (spellInfo->SpellFamilyName) - { - case SPELLFAMILY_WARRIOR: - // Shout - if (spellInfo->SpellFamilyFlags[0] & 0x20000 || spellInfo->SpellFamilyFlags[1] & 0x20) - spellInfo->AttributesCu |= SPELL_ATTR0_CU_AURA_CC; - break; - case SPELLFAMILY_DRUID: - // Roar - if (spellInfo->SpellFamilyFlags[0] & 0x8) - spellInfo->AttributesCu |= SPELL_ATTR0_CU_AURA_CC; - break; - default: - break; - } - spellInfo->_InitializeExplicitTargetMask(); } @@ -2947,6 +2923,11 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->Speed = SPEED_CHARGE; break; } + + // Passive talent auras cannot target pets + if (spellInfo->IsPassive() && GetTalentSpellCost(i)) + if (spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET) + spellInfo->Effects[j].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER); } if (spellInfo->ActiveIconID == 2158) // flight @@ -3072,6 +3053,7 @@ void SpellMgr::LoadSpellInfoCorrections() case 52479: // Gift of the Harvester case 48246: // Ball of Flame case 36327: // Shoot Arcane Explosion Arrow + case 55479: // Force Obedience spellInfo->MaxAffectedTargets = 1; break; case 36384: // Skartax Purple Beam diff --git a/src/server/game/Texts/CreatureTextMgr.cpp b/src/server/game/Texts/CreatureTextMgr.cpp index 9f75d917aea..034fe96306e 100644 --- a/src/server/game/Texts/CreatureTextMgr.cpp +++ b/src/server/game/Texts/CreatureTextMgr.cpp @@ -293,7 +293,7 @@ uint32 CreatureTextMgr::SendChat(Creature* source, uint8 textGroup, WorldObject SendChatPacket(finalSource, builder, finalType, whisperTarget, range, team, gmOnly); } - if (isEqualChanced || (!isEqualChanced && totalChance == 100.0f)) + if (isEqualChanced || totalChance == 100.0f) SetRepeatId(source, textGroup, iter->id); return iter->duration; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index bb4de29ad56..bcfd105f3c6 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1183,6 +1183,7 @@ void World::LoadConfigSettings(bool reload) m_bool_configs[CONFIG_START_ALL_SPELLS] = sConfigMgr->GetBoolDefault("PlayerStart.AllSpells", false); m_int_configs[CONFIG_HONOR_AFTER_DUEL] = sConfigMgr->GetIntDefault("HonorPointsAfterDuel", 0); m_bool_configs[CONFIG_RESET_DUEL_COOLDOWNS] = sConfigMgr->GetBoolDefault("ResetDuelCooldowns", false); + m_bool_configs[CONFIG_RESET_DUEL_HEALTH_MANA] = sConfigMgr->GetBoolDefault("ResetDuelHealthMana", false); m_bool_configs[CONFIG_START_ALL_EXPLORED] = sConfigMgr->GetBoolDefault("PlayerStart.MapsExplored", false); m_bool_configs[CONFIG_START_ALL_REP] = sConfigMgr->GetBoolDefault("PlayerStart.AllReputation", false); m_bool_configs[CONFIG_ALWAYS_MAXSKILL] = sConfigMgr->GetBoolDefault("AlwaysMaxWeaponSkill", false); @@ -1781,6 +1782,7 @@ void World::SetInitialWorldSettings() m_timers[WUPDATE_WEATHERS].SetInterval(1*IN_MILLISECONDS); m_timers[WUPDATE_AUCTIONS].SetInterval(MINUTE*IN_MILLISECONDS); + m_timers[WUPDATE_AUCTIONS_PENDING].SetInterval(250); m_timers[WUPDATE_UPTIME].SetInterval(m_int_configs[CONFIG_UPTIME_UPDATE]*MINUTE*IN_MILLISECONDS); //Update "uptime" table based on configuration entry in minutes. m_timers[WUPDATE_CORPSES].SetInterval(20 * MINUTE * IN_MILLISECONDS); @@ -2051,6 +2053,13 @@ void World::Update(uint32 diff) sAuctionMgr->Update(); } + if (m_timers[WUPDATE_AUCTIONS_PENDING].Passed()) + { + m_timers[WUPDATE_AUCTIONS_PENDING].Reset(); + + sAuctionMgr->UpdatePendingAuctions(); + } + /// <li> Handle AHBot operations if (m_timers[WUPDATE_AHBOT].Passed()) { diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index e3dc3b55681..c76b11276cc 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -69,6 +69,7 @@ enum ShutdownExitCode enum WorldTimers { WUPDATE_AUCTIONS, + WUPDATE_AUCTIONS_PENDING, WUPDATE_WEATHERS, WUPDATE_UPTIME, WUPDATE_CORPSES, @@ -164,6 +165,7 @@ enum WorldBoolConfigs CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA, CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA, CONFIG_RESET_DUEL_COOLDOWNS, + CONFIG_RESET_DUEL_HEALTH_MANA, BOOL_CONFIG_VALUE_COUNT }; diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp index b35e71dbd50..30ee8254f72 100644 --- a/src/server/scripts/Commands/cs_wp.cpp +++ b/src/server/scripts/Commands/cs_wp.cpp @@ -374,6 +374,12 @@ public: if (show == "del") { + if (!arg_id) + { + handler->SendSysMessage("|cffff33ffERROR: Waypoint script guid not present.|r"); + return true; + } + id = atoi(arg_id); stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID); diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp index 0b5c3302890..96c7c5d8102 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp @@ -108,7 +108,7 @@ public: { Talk(SAY_DEATH); if (Unit* midnight = ObjectAccessor::GetUnit(*me, Midnight)) - midnight->Kill(midnight); + midnight->KillSelf(); } void UpdateAI(uint32 diff) override; @@ -264,7 +264,7 @@ void boss_attumen::boss_attumenAI::UpdateAI(uint32 diff) } Midnight.Clear(); me->SetVisible(false); - me->Kill(me); + me->KillSelf(); } else ResetTimer -= diff; } diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp index 0abba3dfff4..d11c4a6e584 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp @@ -295,7 +295,7 @@ public: { Unit* axe = ObjectAccessor::GetUnit(*me, axes[i]); if (axe && axe->IsAlive()) - axe->Kill(axe); + axe->KillSelf(); axes[i].Clear(); } } diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp index a95ac9aaa20..e4cc7c0e84a 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp @@ -473,7 +473,7 @@ public: if (FlameStrikeTimer <= diff) { DoCast(me, SPELL_FLAMESTRIKE1_NORMAL, true); - me->Kill(me); + me->KillSelf(); } else FlameStrikeTimer -= diff; } }; @@ -636,7 +636,7 @@ public: if (HatchTimer <= diff) { me->SummonCreature(CREATURE_PHOENIX, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000); - me->Kill(me); + me->KillSelf(); } else HatchTimer -= diff; } }; @@ -675,7 +675,7 @@ public: void UpdateAI(uint32 diff) override { if (DespawnTimer <= diff) - me->Kill(me); + me->KillSelf(); else DespawnTimer -= diff; diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp index f57de5316ab..480fd8848f5 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp @@ -139,7 +139,7 @@ class boss_selin_fireheart : public CreatureScript for (Creature* crystal : Crystals) { if (crystal && crystal->IsAlive()) - crystal->Kill(crystal); + crystal->KillSelf(); } } @@ -218,7 +218,7 @@ class boss_selin_fireheart : public CreatureScript Creature* CrystalChosen = ObjectAccessor::GetCreature(*me, CrystalGUID); if (CrystalChosen && CrystalChosen->IsAlive()) - CrystalChosen->Kill(CrystalChosen); + CrystalChosen->KillSelf(); CrystalGUID.Clear(); diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp index 2714d65774f..ce8b094bb83 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp @@ -1218,7 +1218,7 @@ public: if (Creature* temp = ObjectAccessor::GetCreature(*me, uiLichKingGUID)) // Lich king disappears here { temp->AI()->Talk(EMOTE_LIGHT_OF_DAWN17); - temp->Kill(temp); + temp->KillSelf(); } JumpToNextStep(10000); break; @@ -1633,7 +1633,7 @@ public: if (temp->IsAlive()) { temp->SetVisible(false); - temp->Kill(temp); + temp->KillSelf(); } } }; diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp index a78ad740c97..bac4e450a03 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp @@ -359,8 +359,8 @@ public: { die = false; if (Unit* body = ObjectAccessor::GetUnit(*me, bodyGUID)) - body->Kill(body); - me->Kill(me); + body->KillSelf(); + me->KillSelf(); } else wait -= diff; } diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp index ed9f7ccb6dd..c41b1d87d61 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp @@ -121,7 +121,7 @@ class instance_scarlet_monastery : public InstanceMapScript { Creature* add = instance->GetCreature(guid); if (add && add->IsAlive()) - add->Kill(add); + add->KillSelf(); } HorsemanAdds.clear(); HandleGameObject(PumpkinShrineGUID, false); diff --git a/src/server/scripts/EasternKingdoms/Stratholme/stratholme.cpp b/src/server/scripts/EasternKingdoms/Stratholme/stratholme.cpp index ba99df8cdd5..60dd27eed90 100644 --- a/src/server/scripts/EasternKingdoms/Stratholme/stratholme.cpp +++ b/src/server/scripts/EasternKingdoms/Stratholme/stratholme.cpp @@ -170,7 +170,7 @@ public: { if (Player* player = temp->ToPlayer()) player->KilledMonsterCredit(NPC_RESTLESS, me->GetGUID()); - me->Kill(me); + me->KillSelf(); } } else @@ -248,7 +248,7 @@ public: if (Tagged) { if (Die_Timer <= diff) - me->Kill(me); + me->KillSelf(); else Die_Timer -= diff; } diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp index 31ca716e0fb..77e0e680f4a 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp @@ -698,7 +698,7 @@ public: if (KillTimer <= diff) { - me->Kill(me); + me->KillSelf(); KillTimer = 9999999; } else KillTimer -= diff; diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp index 4d544ccdeab..e3deac506b0 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp @@ -1112,7 +1112,7 @@ public: else if (me->IsWithinDistInMap(me->GetVictim(), 3)) // Explode if it's close enough to it's target { DoCastVictim(SPELL_FELFIRE_FISSION); - me->Kill(me); + me->KillSelf(); } } }; @@ -1172,7 +1172,7 @@ public: uiTimer = 5000; break; case 3: - me->Kill(me); + me->KillSelf(); me->RemoveCorpse(); break; } diff --git a/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp b/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp index 9cecbc31665..9af23f17dca 100644 --- a/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp @@ -277,145 +277,6 @@ public: }; /*###### -## npc_anchorite_truuen -######*/ - -enum Truuen -{ - NPC_GHOST_UTHER = 17233, - NPC_THEL_DANIS = 1854, - NPC_GHOUL = 1791, //ambush - - QUEST_TOMB_LIGHTBRINGER = 9446, - - SAY_WP_0 = 0, //Beware! We are attacked! - SAY_WP_1 = 1, //It must be the purity of the Mark of the Lightbringer that is drawing forth the Scourge to attack us. We must proceed with caution lest we be overwhelmed! - SAY_WP_2 = 2, //This land truly needs to be cleansed by the Light! Let us continue on to the tomb. It isn't far now... - SAY_WP_3 = 0, //Be welcome, friends! - SAY_WP_4 = 0, //Thank you for coming here in remembrance of me. Your efforts in recovering that symbol, while unnecessary, are certainly touching to an old man's heart. - SAY_WP_5 = 1, //Please, rise my friend. Keep the Blessing as a symbol of the strength of the Light and how heroes long gone might once again rise in each of us to inspire. - SAY_WP_6 = 2 //Thank you my friend for making this possible. This is a day that I shall never forget! I think I will stay a while. Please return to High Priestess MacDonnell at the camp. I know that she'll be keenly interested to know of what has transpired here. -}; - -class npc_anchorite_truuen : public CreatureScript -{ -public: - npc_anchorite_truuen() : CreatureScript("npc_anchorite_truuen") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override - { - if (quest->GetQuestId() == QUEST_TOMB_LIGHTBRINGER) - { - npc_escortAI* pEscortAI = ENSURE_AI(npc_anchorite_truuen::npc_anchorite_truuenAI, creature->AI()); - pEscortAI->Start(true, true, player->GetGUID()); - } - return false; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_anchorite_truuenAI(creature); - } - - struct npc_anchorite_truuenAI : public npc_escortAI - { - npc_anchorite_truuenAI(Creature* creature) : npc_escortAI(creature) - { - Initialize(); - } - - void Initialize() - { - m_uiChatTimer = 7000; - } - - uint32 m_uiChatTimer; - - ObjectGuid UghostGUID; - - void Reset() override - { - Initialize(); - } - - void JustSummoned(Creature* summoned) override - { - if (summoned->GetEntry() == NPC_GHOUL) - summoned->AI()->AttackStart(me); - } - - void WaypointReached(uint32 waypointId) override - { - Player* player = GetPlayerForEscort(); - - switch (waypointId) - { - case 8: - Talk(SAY_WP_0); - me->SummonCreature(NPC_GHOUL, me->GetPositionX()+7.0f, me->GetPositionY()+7.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 90000); - me->SummonCreature(NPC_GHOUL, me->GetPositionX()+5.0f, me->GetPositionY()+5.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 90000); - break; - case 9: - Talk(SAY_WP_1); - break; - case 14: - me->SummonCreature(NPC_GHOUL, me->GetPositionX()+7.0f, me->GetPositionY()+7.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 90000); - me->SummonCreature(NPC_GHOUL, me->GetPositionX()+5.0f, me->GetPositionY()+5.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 90000); - me->SummonCreature(NPC_GHOUL, me->GetPositionX()+10.0f, me->GetPositionY()+10.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 90000); - me->SummonCreature(NPC_GHOUL, me->GetPositionX()+8.0f, me->GetPositionY()+8.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 90000); - break; - case 15: - Talk(SAY_WP_2); - break; - case 21: - if (Creature* Theldanis = GetClosestCreatureWithEntry(me, NPC_THEL_DANIS, 150)) - Theldanis->AI()->Talk(SAY_WP_3); - break; - case 23: - if (Creature* Ughost = me->SummonCreature(NPC_GHOST_UTHER, 971.86f, -1825.42f, 81.99f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000)) - { - UghostGUID = Ughost->GetGUID(); - Ughost->SetDisableGravity(true); - Ughost->AI()->Talk(SAY_WP_4, me); - } - m_uiChatTimer = 4000; - break; - case 24: - if (Creature* Ughost = ObjectAccessor::GetCreature(*me, UghostGUID)) - Ughost->AI()->Talk(SAY_WP_5, me); - m_uiChatTimer = 4000; - break; - case 25: - if (Creature* Ughost = ObjectAccessor::GetCreature(*me, UghostGUID)) - Ughost->AI()->Talk(SAY_WP_6, me); - m_uiChatTimer = 4000; - break; - case 26: - if (player) - player->GroupEventHappens(QUEST_TOMB_LIGHTBRINGER, me); - break; - } - } - - void EnterCombat(Unit* /*who*/) override { } - - void JustDied(Unit* /*killer*/) override - { - if (Player* player = GetPlayerForEscort()) - player->FailQuest(QUEST_TOMB_LIGHTBRINGER); - } - - void UpdateAI(uint32 uiDiff) override - { - npc_escortAI::UpdateAI(uiDiff); - DoMeleeAttackIfReady(); - if (HasEscortState(STATE_ESCORT_ESCORTING)) - m_uiChatTimer = 6000; - } - }; -}; - -/*###### ## ######*/ @@ -425,5 +286,4 @@ void AddSC_western_plaguelands() new npc_myranda_the_hag(); new npc_the_scourge_cauldron(); new npc_andorhal_tower(); - new npc_anchorite_truuen(); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp index 254e3a41d6b..d0a9b233454 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp @@ -235,7 +235,7 @@ public: if (AnetheronGUID) { Creature* boss = ObjectAccessor::GetCreature(*me, AnetheronGUID); - if (!boss || (boss && boss->isDead())) + if (!boss || boss->isDead()) { me->setDeathState(JUST_DIED); me->RemoveCorpse(); diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp index 08942e3393f..8bfdee067b2 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp @@ -200,7 +200,6 @@ public: CrippleTimer = 50000; WarstompTimer = 10000; CheckTimer = 5000; - instance = creature->GetInstanceScript(); AzgalorGUID = instance->GetGuidData(DATA_AZGALOR); } @@ -208,7 +207,6 @@ public: uint32 WarstompTimer; uint32 CheckTimer; ObjectGuid AzgalorGUID; - InstanceScript* instance; void Reset() override { @@ -248,7 +246,7 @@ public: if (AzgalorGUID) { Creature* boss = ObjectAccessor::GetCreature(*me, AzgalorGUID); - if (!boss || (boss && boss->isDead())) + if (!boss || boss->isDead()) { me->setDeathState(JUST_DIED); me->RemoveCorpse(); diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp index 70ecaad3d8d..c39fbc90795 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp @@ -218,7 +218,7 @@ public: break; case 5: me->SetVisible(false); - me->Kill(me); + me->KillSelf(); break; } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp index b5d2931377f..a73a6b8d998 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp @@ -817,7 +817,7 @@ public: cityman1->AI()->Talk(SAY_PHASE204); cityman1->SetTarget(me->GetGUID()); if (Creature* cityman0 = ObjectAccessor::GetCreature(*me, citymenGUID[0])) - cityman0->Kill(cityman0); + cityman0->KillSelf(); me->SetTarget(citymenGUID[1]); } JumpToNextStep(0); @@ -829,7 +829,7 @@ public: break; case 33: if (Creature* cityman1 = ObjectAccessor::GetCreature(*me, citymenGUID[1])) - cityman1->Kill(cityman1); + cityman1->KillSelf(); JumpToNextStep(1000); break; case 34: diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp index 8e84f1b4265..6016893a785 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp @@ -917,7 +917,7 @@ public: void JustDied(Unit* /*killer*/) override { if (Unit* p = ObjectAccessor::GetUnit(*me, Portal)) - p->Kill(p); + p->KillSelf(); } void Reset() override @@ -943,7 +943,7 @@ public: //KillSelfTimer if (KillSelfTimer <= diff) { - me->Kill(me); + me->KillSelf(); return; } else KillSelfTimer -= diff; @@ -997,7 +997,7 @@ public: void JustDied(Unit* /*killer*/) override { if (Unit* p = ObjectAccessor::GetUnit(*me, Portal)) - p->Kill(p); + p->KillSelf(); } void Reset() override @@ -1025,7 +1025,7 @@ public: if (EvadeTimer <= diff) { if (Unit* p = ObjectAccessor::GetUnit(*me, Portal)) - p->Kill(p); + p->KillSelf(); //Dissapear and reappear at new position me->SetVisible(false); @@ -1033,7 +1033,7 @@ public: Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); if (!target) { - me->Kill(me); + me->KillSelf(); return; } @@ -1113,7 +1113,7 @@ public: void JustDied(Unit* /*killer*/) override { if (Unit* p = ObjectAccessor::GetUnit(*me, Portal)) - p->Kill(p); + p->KillSelf(); } void Reset() override @@ -1142,7 +1142,7 @@ public: if (EvadeTimer <= diff) { if (Unit* p = ObjectAccessor::GetUnit(*me, Portal)) - p->Kill(p); + p->KillSelf(); //Dissapear and reappear at new position me->SetVisible(false); @@ -1150,7 +1150,7 @@ public: Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); if (!target) { - me->Kill(me); + me->KillSelf(); return; } @@ -1231,7 +1231,7 @@ public: void JustDied(Unit* /*killer*/) override { if (Unit* p = ObjectAccessor::GetUnit(*me, Portal)) - p->Kill(p); + p->KillSelf(); } void Reset() override diff --git a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp index b0800918765..fba0956ccfc 100644 --- a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp +++ b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp @@ -352,7 +352,7 @@ class spell_ooze_zap_channel_end : public SpellScriptLoader PreventHitDefaultEffect(effIndex); if (Player* player = GetCaster()->ToPlayer()) player->CastSpell(player, SPELL_OOZE_CHANNEL_CREDIT, true); - GetHitUnit()->Kill(GetHitUnit()); + GetHitUnit()->KillSelf(); } void Register() override diff --git a/src/server/scripts/Kalimdor/zone_moonglade.cpp b/src/server/scripts/Kalimdor/zone_moonglade.cpp index 163620230ef..c7decd3e286 100644 --- a/src/server/scripts/Kalimdor/zone_moonglade.cpp +++ b/src/server/scripts/Kalimdor/zone_moonglade.cpp @@ -108,64 +108,6 @@ public: }; /*###### -## npc_great_bear_spirit -######*/ - -#define GOSSIP_BEAR1 "What do you represent, spirit?" -#define GOSSIP_BEAR2 "I seek to understand the importance of strength of the body." -#define GOSSIP_BEAR3 "I seek to understand the importance of strength of the heart." -#define GOSSIP_BEAR4 "I have heard your words, Great Bear Spirit, and I understand. I now seek your blessings to fully learn the way of the Claw." - -class npc_great_bear_spirit : public CreatureScript -{ -public: - npc_great_bear_spirit() : CreatureScript("npc_great_bear_spirit") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(4721, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(4733, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->SEND_GOSSIP_MENU(4734, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 3: - player->SEND_GOSSIP_MENU(4735, creature->GetGUID()); - if (player->GetQuestStatus(5929) == QUEST_STATUS_INCOMPLETE) - player->AreaExploredOrEventHappens(5929); - if (player->GetQuestStatus(5930) == QUEST_STATUS_INCOMPLETE) - player->AreaExploredOrEventHappens(5930); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - //ally or horde quest - if (player->GetQuestStatus(5929) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(5930) == QUEST_STATUS_INCOMPLETE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - player->SEND_GOSSIP_MENU(4719, creature->GetGUID()); - } - else - player->SEND_GOSSIP_MENU(4718, creature->GetGUID()); - - return true; - } - -}; - -/*###### ## npc_silva_filnaveth ######*/ @@ -712,7 +654,6 @@ public: void AddSC_moonglade() { new npc_bunthen_plainswind(); - new npc_great_bear_spirit(); new npc_silva_filnaveth(); new npc_clintar_spirit(); new npc_omen(); diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp index 5890b9cbec7..240e8a7b957 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp @@ -433,7 +433,7 @@ public: { ENSURE_AI(boss_jedoga_shadowseeker::boss_jedoga_shadowseekerAI, boss->AI())->bOpFerok = true; ENSURE_AI(boss_jedoga_shadowseeker::boss_jedoga_shadowseekerAI, boss->AI())->bOpFerokFail = false; - me->Kill(me); + me->KillSelf(); } } break; diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp index eac84d1f6c9..3b12104a90b 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp @@ -338,14 +338,14 @@ struct dummy_dragonAI : public ScriptedAI if (instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS) instance->SetBossState(DATA_SHADRON, DONE); if (Creature* acolyte = me->FindNearestCreature(NPC_ACOLYTE_OF_SHADRON, 100.0f)) - acolyte->Kill(acolyte); + acolyte->KillSelf(); break; case NPC_VESPERON: spellId = SPELL_POWER_OF_VESPERON; if (instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS) instance->SetBossState(DATA_VESPERON, DONE); if (Creature* acolyte = me->FindNearestCreature(NPC_ACOLYTE_OF_VESPERON, 100.0f)) - acolyte->Kill(acolyte); + acolyte->KillSelf(); break; } @@ -948,7 +948,7 @@ public: //DoCastVictim(57620, true); //DoCastVictim(57874, true); me->RemoveAllAuras(); - me->Kill(me); + me->KillSelf(); } } diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp index 0b8fa7459a8..6bc49de5319 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp @@ -360,11 +360,11 @@ class boss_halion : public CreatureScript if (Creature* twilightHalion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_TWILIGHT_HALION))) if (twilightHalion->IsAlive()) - twilightHalion->Kill(twilightHalion); + twilightHalion->KillSelf(); if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HALION_CONTROLLER))) if (controller->IsAlive()) - controller->Kill(controller); + controller->KillSelf(); } Position const* GetMeteorStrikePosition() const { return &_meteorStrikePos; } @@ -523,7 +523,7 @@ class boss_twilight_halion : public CreatureScript if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HALION_CONTROLLER))) if (controller->IsAlive()) - controller->Kill(controller); + controller->KillSelf(); instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp index b2aa6dadd84..78a279b94fd 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp @@ -831,7 +831,7 @@ class npc_vengeful_shade : public CreatureScript case SPELL_VENGEFUL_BLAST_25N: case SPELL_VENGEFUL_BLAST_10H: case SPELL_VENGEFUL_BLAST_25H: - me->Kill(me); + me->KillSelf(); break; default: break; @@ -1019,7 +1019,7 @@ class spell_cultist_dark_martyrdom : public SpellScriptLoader if (Unit* owner = GetCaster()->ToTempSummon()->GetSummoner()) owner->GetAI()->SetGUID(GetCaster()->GetGUID(), GUID_CULTIST); - GetCaster()->Kill(GetCaster()); + GetCaster()->KillSelf(); GetCaster()->SetDisplayId(uint32(GetCaster()->GetEntry() == NPC_CULT_FANATIC ? 38009 : 38010)); } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp b/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp index 47569a6b85f..11fe5f41455 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp @@ -197,7 +197,7 @@ public: if (!guardCorpses.empty()) { if (ObjectGuid target = Trinity::Containers::SelectRandomContainerElement(guardCorpses)) - if(Creature* creatureTarget = ObjectAccessor::GetCreature(*me, target)) + if (Creature* creatureTarget = ObjectAccessor::GetCreature(*me, target)) { creatureTarget->CastSpell(creatureTarget, SPELL_SUMMON_CORPSE_SCARABS_MOB, true, nullptr, nullptr, me->GetGUID()); creatureTarget->AI()->Talk(EMOTE_SCARAB); diff --git a/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp b/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp index e52731d003e..0d938122f28 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp @@ -18,6 +18,7 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "PassiveAI.h" +#include "SpellScript.h" #include "naxxramas.h" enum Spells @@ -28,6 +29,14 @@ enum Spells SPELL_NECROTIC_POISON = 28776, SPELL_FRENZY = 54123 }; +#define SPELL_FRENZY_HELPER RAID_MODE(54123,54124) + +enum Emotes +{ + EMOTE_SPIDERS = 0, + EMOTE_WEB_WRAP = 1, + EMOTE_WEB_SPRAY = 2 +}; enum Creatures { @@ -35,12 +44,16 @@ enum Creatures NPC_SPIDERLING = 17055, }; -#define MAX_POS_WRAP 3 -const Position PosWrap[MAX_POS_WRAP] = +#define MAX_WRAP_POSITION 7 +const Position WrapPositions[MAX_WRAP_POSITION] = { - {3546.796f, -3869.082f, 296.450f, 0.0f}, - {3531.271f, -3847.424f, 299.450f, 0.0f}, - {3497.067f, -3843.384f, 302.384f, 0.0f}, + {3453.818f, -3854.651f, 308.7581f, 4.362833f}, + {3535.042f, -3842.383f, 300.795f, 3.179324f}, + {3538.399f, -3846.088f, 299.964f, 4.310297f}, + {3548.464f, -3854.676f, 298.6075f, 4.546609f}, + {3557.663f, -3870.123f, 297.5027f, 3.756433f}, + {3560.546f, -3879.353f, 297.4843f, 2.508937f}, + {3562.535f, -3892.507f, 298.532f, 6.022466f}, }; enum Events @@ -51,7 +64,24 @@ enum Events EVENT_POISON, EVENT_WRAP, EVENT_SUMMON, - EVENT_FRENZY, +}; + +const float WEB_WRAP_MOVE_SPEED = 20.0f; + +struct WebTargetSelector : public std::unary_function<Unit*, bool> +{ + WebTargetSelector(Unit* maexxna) : _maexxna(maexxna) {} + bool operator()(Unit const* target) const + { + if (_maexxna->GetVictim() == target) // never target tank + return false; + if (target->HasAura(SPELL_WEB_WRAP)) // never target targets that are already webbed + return false; + return true; + } + + private: + const Unit* _maexxna; }; class boss_maexxna : public CreatureScript @@ -66,27 +96,22 @@ public: struct boss_maexxnaAI : public BossAI { - boss_maexxnaAI(Creature* creature) : BossAI(creature, BOSS_MAEXXNA) - { - Initialize(); - } + boss_maexxnaAI(Creature* creature) : BossAI(creature, BOSS_MAEXXNA) { } - void Initialize() + void EnterCombat(Unit* /*who*/) override { - enraged = false; + _EnterCombat(); + events.ScheduleEvent(EVENT_WRAP, 20 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_SPRAY, 40 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_SHOCK, urandms(5, 10)); + events.ScheduleEvent(EVENT_POISON, urandms(10, 15)); + events.ScheduleEvent(EVENT_SUMMON, 30 * IN_MILLISECONDS); } - bool enraged; - - void EnterCombat(Unit* /*who*/) override + void Reset() override { - _EnterCombat(); - Initialize(); - events.ScheduleEvent(EVENT_WRAP, 20000); - events.ScheduleEvent(EVENT_SPRAY, 40000); - events.ScheduleEvent(EVENT_SHOCK, urand(5000, 10000)); - events.ScheduleEvent(EVENT_POISON, urand(10000, 15000)); - events.ScheduleEvent(EVENT_SUMMON, 30000); + _Reset(); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_WEB_WRAP); } void UpdateAI(uint32 diff) override @@ -94,10 +119,9 @@ public: if (!UpdateVictim() || !CheckInRoom()) return; - if (!enraged && HealthBelowPct(30)) + if (HealthBelowPct(30) && !me->HasAura(SPELL_FRENZY_HELPER)) { - enraged = true; - events.ScheduleEvent(EVENT_FRENZY, 0); // will be cast immediately + DoCast(SPELL_FRENZY); } events.Update(diff); @@ -107,41 +131,49 @@ public: switch (eventId) { case EVENT_WRAP: - /// @todo Add missing text - for (uint8 i = 0; i < RAID_MODE(1, 2); ++i) + { + std::list<Unit*> targets; + SelectTargetList(targets, WebTargetSelector(me), RAID_MODE(1, 2), SELECT_TARGET_RANDOM); + if (!targets.empty()) { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0, true, -SPELL_WEB_WRAP)) + Talk(EMOTE_WEB_WRAP); + int8 wrapPos = -1; + for (Unit* target : targets) { + if (wrapPos == -1) // allow all positions on the first target + wrapPos = urand(0, MAX_WRAP_POSITION - 1); + else // on subsequent iterations, only allow positions that are not equal to the previous one (this is sufficient since we should only have two targets at most, ever) + wrapPos = (wrapPos + urand(1, MAX_WRAP_POSITION - 1)) % MAX_WRAP_POSITION; + target->RemoveAura(sSpellMgr->GetSpellIdForDifficulty(SPELL_WEB_SPRAY, me)); - uint8 pos = rand32() % MAX_POS_WRAP; - target->GetMotionMaster()->MoveJump(PosWrap[pos].GetPositionX(), PosWrap[pos].GetPositionY(), PosWrap[pos].GetPositionZ(), 20, 20); - if (Creature* wrap = DoSummon(NPC_WEB_WRAP, PosWrap[pos], 0, TEMPSUMMON_CORPSE_DESPAWN)) - wrap->AI()->SetGUID(target->GetGUID()); + if (Creature* wrap = DoSummon(NPC_WEB_WRAP, WrapPositions[wrapPos], 70 * IN_MILLISECONDS, TEMPSUMMON_TIMED_DESPAWN)) + { + wrap->AI()->SetGUID(target->GetGUID()); // handles application of debuff + target->GetMotionMaster()->MoveJump(WrapPositions[wrapPos], WEB_WRAP_MOVE_SPEED, WEB_WRAP_MOVE_SPEED); // move after stun to avoid stun cancelling move + } } } events.ScheduleEvent(EVENT_WRAP, 40000); break; + } case EVENT_SPRAY: + Talk(EMOTE_WEB_SPRAY); DoCastAOE(SPELL_WEB_SPRAY); events.ScheduleEvent(EVENT_SPRAY, 40000); break; case EVENT_SHOCK: DoCastAOE(SPELL_POISON_SHOCK); - events.ScheduleEvent(EVENT_SHOCK, urand(10000, 20000)); + events.ScheduleEvent(EVENT_SHOCK, urandms(10, 20)); break; case EVENT_POISON: DoCastVictim(SPELL_NECROTIC_POISON); - events.ScheduleEvent(EVENT_POISON, urand(10000, 20000)); - break; - case EVENT_FRENZY: - DoCast(me, SPELL_FRENZY, true); - events.ScheduleEvent(EVENT_FRENZY, 600000); + events.ScheduleEvent(EVENT_POISON, urandms(10, 20)); break; case EVENT_SUMMON: - /// @todo Add missing text + Talk(EMOTE_SPIDERS); uint8 amount = urand(8, 10); for (uint8 i = 0; i < amount; ++i) - DoSummon(NPC_SPIDERLING, me, 0, TEMPSUMMON_CORPSE_DESPAWN); + DoSummon(NPC_SPIDERLING, me, 4.0f, 5 * IN_MILLISECONDS, TEMPSUMMON_CORPSE_TIMED_DESPAWN); events.ScheduleEvent(EVENT_SUMMON, 40000); break; } @@ -165,23 +197,49 @@ public: struct npc_webwrapAI : public NullCreatureAI { - npc_webwrapAI(Creature* creature) : NullCreatureAI(creature) { } + npc_webwrapAI(Creature* creature) : NullCreatureAI(creature), visibleTimer(0) { } ObjectGuid victimGUID; + uint32 visibleTimer; + + void InitializeAI() override + { + me->SetVisible(false); + } void SetGUID(ObjectGuid guid, int32 /*param*/) override { + if (!guid) + return; victimGUID = guid; - if (me->m_spells[0] && victimGUID) - if (Unit* victim = ObjectAccessor::GetUnit(*me, victimGUID)) - victim->CastSpell(victim, me->m_spells[0], true, NULL, NULL, me->GetGUID()); + if (Unit* victim = ObjectAccessor::GetUnit(*me, victimGUID)) + { + visibleTimer = (me->GetDistance2d(victim)/WEB_WRAP_MOVE_SPEED + 0.5f) * IN_MILLISECONDS; + victim->CastSpell(victim, SPELL_WEB_WRAP, true, NULL, NULL, me->GetGUID()); + } + } + + void UpdateAI(uint32 diff) override + { + if (!visibleTimer) + return; + + if (diff >= visibleTimer) + { + visibleTimer = 0; + me->SetVisible(true); + } + else + visibleTimer -= diff; } void JustDied(Unit* /*killer*/) override { - if (me->m_spells[0] && victimGUID) + if (victimGUID) if (Unit* victim = ObjectAccessor::GetUnit(*me, victimGUID)) - victim->RemoveAurasDueToSpell(me->m_spells[0], me->GetGUID()); + victim->RemoveAurasDueToSpell(SPELL_WEB_WRAP, me->GetGUID()); + + me->DespawnOrUnsummon(5 * IN_MILLISECONDS); } }; diff --git a/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp b/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp index 106661b70bf..7b3a9f8ac74 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp @@ -155,7 +155,7 @@ public: void KilledUnit(Unit* victim) override { - if(victim->GetTypeId() == TYPEID_PLAYER) + if (victim->GetTypeId() == TYPEID_PLAYER) Talk(SAY_SLAY); } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp b/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp index 1683667a02a..f94f7b227bf 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp @@ -17,43 +17,40 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "SpellInfo.h" #include "naxxramas.h" -//Razuvious - NO TEXT sound only -//8852 aggro01 - Hah hah, I'm just getting warmed up! -//8853 aggro02 Stand and fight! -//8854 aggro03 Show me what you've got! -//8861 slay1 - You should've stayed home! -//8863 slay2- -//8858 cmmnd3 - You disappoint me, students! -//8855 cmmnd1 - Do as I taught you! -//8856 cmmnd2 - Show them no mercy! -//8859 cmmnd4 - The time for practice is over! Show me what you've learned! -//8861 Sweep the leg! Do you have a problem with that? -//8860 death - An honorable... death... -//8947 - Aggro Mixed? - ? - -#define SOUND_AGGRO RAND(8852, 8853, 8854) -#define SOUND_SLAY RAND(8861, 8863) -#define SOUND_COMMND RAND(8855, 8856, 8858, 8859, 8861) -#define SOUND_DEATH 8860 -#define SOUND_AGGROMIX 8847 +enum Yells +{ + SAY_AGGRO = 0, + SAY_SLAY = 1, + SAY_TAUNTED = 2, + SAY_DEATH = 3 +}; enum Spells { - SPELL_UNBALANCING_STRIKE = 26613, - SPELL_DISRUPTING_SHOUT = 29107, - SPELL_JAGGED_KNIFE = 55550, - SPELL_HOPELESS = 29125 + SPELL_UNBALANCING_STRIKE = 26613, + SPELL_DISRUPTING_SHOUT = 29107, + SPELL_JAGGED_KNIFE = 55550, + SPELL_HOPELESS = 29125, + SPELL_UNDERSTUDY_TAUNT = 29060, + SPELL_UNDERSTUDY_BLOOD_STRIKE = 61696, + SPELL_FORCE_OBEDIENCE = 55479 }; enum Events { - EVENT_NONE, + EVENT_ATTACK = 1, EVENT_STRIKE, EVENT_SHOUT, - EVENT_KNIFE, - EVENT_COMMAND, + EVENT_KNIFE +}; + +enum SummonGroups +{ + SUMMON_GROUP_10MAN = 1, + SUMMON_GROUP_25MAN = 2 }; class boss_razuvious : public CreatureScript @@ -70,36 +67,60 @@ public: { boss_razuviousAI(Creature* creature) : BossAI(creature, BOSS_RAZUVIOUS) { } - void KilledUnit(Unit* /*victim*/) override + void SummonAdds() { - if (!(rand32() % 3)) - DoPlaySoundToSet(me, SOUND_SLAY); + me->SummonCreatureGroup(SUMMON_GROUP_10MAN); + if (Is25ManRaid()) + me->SummonCreatureGroup(SUMMON_GROUP_25MAN); } - void DamageTaken(Unit* pDone_by, uint32& uiDamage) override + void InitializeAI() override { - // Damage done by the controlled Death Knight understudies should also count toward damage done by players - if (pDone_by->GetTypeId() == TYPEID_UNIT && (pDone_by->GetEntry() == 16803 || pDone_by->GetEntry() == 29941)) + if (!me->isDead()) { - me->LowerPlayerDamageReq(uiDamage); + Reset(); + SummonAdds(); } } + void JustReachedHome() override + { + _JustReachedHome(); + SummonAdds(); + me->GetMotionMaster()->Initialize(); + } + + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER || (victim->GetTypeId() == TYPEID_UNIT && victim->GetEntry() == NPC_DK_UNDERSTUDY)) + Talk(SAY_SLAY); + } + + void SpellHit(Unit* caster, SpellInfo const* spell) override + { + if (spell->Id == SPELL_UNDERSTUDY_TAUNT) + Talk(SAY_TAUNTED, caster); + } + void JustDied(Unit* /*killer*/) override { - _JustDied(); - DoPlaySoundToSet(me, SOUND_DEATH); - me->CastSpell(me, SPELL_HOPELESS, true); /// @todo this may affect other creatures + Talk(SAY_DEATH); + DoCastAOE(SPELL_HOPELESS, true); + + events.Reset(); + instance->SetBossState(BOSS_RAZUVIOUS, DONE); } void EnterCombat(Unit* /*who*/) override { _EnterCombat(); - DoPlaySoundToSet(me, SOUND_AGGRO); - events.ScheduleEvent(EVENT_STRIKE, 30000); - events.ScheduleEvent(EVENT_SHOUT, 25000); - events.ScheduleEvent(EVENT_COMMAND, 40000); - events.ScheduleEvent(EVENT_KNIFE, 10000); + me->StopMoving(); + summons.DoZoneInCombat(); + Talk(SAY_AGGRO); + events.ScheduleEvent(EVENT_ATTACK, 7 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_STRIKE, 21 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_SHOUT, 16 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_KNIFE, 10 * IN_MILLISECONDS); } void UpdateAI(uint32 diff) override @@ -113,33 +134,112 @@ public: { switch (eventId) { + case EVENT_ATTACK: + SetCombatMovement(true); + if (Unit* victim = me->GetVictim()) + me->GetMotionMaster()->MoveChase(victim); + break; case EVENT_STRIKE: DoCastVictim(SPELL_UNBALANCING_STRIKE); - events.ScheduleEvent(EVENT_STRIKE, 30000); + events.ScheduleEvent(EVENT_STRIKE, 6 * IN_MILLISECONDS); return; case EVENT_SHOUT: DoCastAOE(SPELL_DISRUPTING_SHOUT); - events.ScheduleEvent(EVENT_SHOUT, 25000); + events.ScheduleEvent(EVENT_SHOUT, 16 * IN_MILLISECONDS); return; case EVENT_KNIFE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f)) DoCast(target, SPELL_JAGGED_KNIFE); - events.ScheduleEvent(EVENT_KNIFE, 10000); - return; - case EVENT_COMMAND: - DoPlaySoundToSet(me, SOUND_COMMND); - events.ScheduleEvent(EVENT_COMMAND, 40000); + events.ScheduleEvent(EVENT_KNIFE, urandms(10,15)); return; } } DoMeleeAttackIfReady(); } + + void Reset() override + { + SetCombatMovement(false); + _Reset(); + } }; }; +class npc_dk_understudy : public CreatureScript +{ + public: + npc_dk_understudy() : CreatureScript("npc_dk_understudy") { } + + struct npc_dk_understudyAI : public ScriptedAI + { + npc_dk_understudyAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), bloodStrikeTimer(0) { } + + void EnterCombat(Unit* /*who*/) override + { + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); + if (Creature* razuvious = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_RAZUVIOUS))) + razuvious->AI()->DoZoneInCombat(nullptr, 250.0f); + } + + void JustReachedHome() override + { + if (_instance->GetBossState(BOSS_RAZUVIOUS) == DONE) + me->DespawnOrUnsummon(); + else + ScriptedAI::JustReachedHome(); + } + + void UpdateAI(uint32 diff) override + { + if (!me->isPossessedByPlayer() && !UpdateVictim()) + return; + + if (!me->isPossessedByPlayer()) + { + if (diff < bloodStrikeTimer) + bloodStrikeTimer -= diff; + else + DoCastVictim(SPELL_UNDERSTUDY_BLOOD_STRIKE); + } + + DoMeleeAttackIfReady(); + } + + void OnCharmed(bool apply) override + { + ScriptedAI::OnCharmed(apply); + if (apply) + { + if (!me->IsInCombat()) + EnterCombat(nullptr); + me->StopMoving(); + me->SetReactState(REACT_PASSIVE); + _charmer = me->GetCharmerGUID(); + } + else + { + me->SetReactState(REACT_AGGRESSIVE); + if (Unit* charmer = ObjectAccessor::GetUnit(*me, _charmer)) + me->AddThreat(charmer, 100000.0f); + DoZoneInCombat(nullptr, 250.0f); + } + } + private: + InstanceScript* const _instance; + ObjectGuid _charmer; + uint32 bloodStrikeTimer; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<npc_dk_understudyAI>(creature); + } +}; + void AddSC_boss_razuvious() { new boss_razuvious(); + new npc_dk_understudy(); } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp index d74fd5a03f8..5d3b038d41d 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp @@ -19,48 +19,104 @@ #include "ScriptedCreature.h" #include "SpellScript.h" #include "Player.h" +#include "ObjectGuid.h" #include "naxxramas.h" -//Stalagg -enum StalaggYells + +enum Phases +{ + PHASE_NOT_ENGAGED = 1, + PHASE_PETS, + PHASE_TRANSITION, + PHASE_THADDIUS, + PHASE_RESETTING +}; + +enum AIActions { - SAY_STAL_AGGRO = 0, - SAY_STAL_SLAY = 1, - SAY_STAL_DEATH = 2 + ACTION_RESET_ENCOUNTER_TIMER = -1, // sent from instance AI + ACTION_BEGIN_RESET_ENCOUNTER = 0, // sent from thaddius to pets to trigger despawn and encounter reset + ACTION_RESET_ENCOUNTER, // sent from thaddius to pets to trigger respawn and full reset + ACTION_FEUGEN_DIED, // sent from respective pet to thaddius to indicate death + ACTION_STALAGG_DIED, // ^ + ACTION_FEUGEN_RESET, // pet to thaddius + ACTION_STALAGG_RESET, // ^ + ACTION_FEUGEN_AGGRO, // pet to thaddius on combat start + ACTION_STALAGG_AGGRO, // ^ + ACTION_FEUGEN_REVIVING_FX, // thaddius to pet when pet reports its death + ACTION_STALAGG_REVIVING_FX, // ^ + ACTION_FEUGEN_REVIVED, // thaddius to pet when pet should revive + ACTION_STALAGG_REVIVED, // ^ + ACTION_TRANSITION, // thaddius to pets when transition starts (coil overload anim) + ACTION_TRANSITION_2, // thaddius to pets to make the coils shock him + ACTION_TRANSITION_3, // thaddius to pets to disable coil GO after spawn + + ACTION_POLARITY_CROSSED // triggers achievement failure, sent from spellscript }; -enum StalagSpells +enum Events { - SPELL_POWERSURGE = 28134, - SPELL_MAGNETIC_PULL = 28338, - SPELL_STALAGG_TESLA = 28097 + EVENT_SHIFT = 1, // polarity shift + EVENT_SHIFT_TALK, // polarity shift yell (hack? couldn't find any event for cast finish) + EVENT_CHAIN, // chain lightning + EVENT_BERSERK, // enrage timer + EVENT_REVIVE_FEUGEN, // timer until feugen is revived (if stalagg still lives) + EVENT_REVIVE_STALAGG, // timer until stalagg is revived (if feugen still lives) + EVENT_TRANSITION_1, // timer until overload emote + EVENT_TRANSITION_2, // timer until thaddius gets zapped by the coils + EVENT_TRANSITION_3, // timer until thaddius engages + EVENT_ENABLE_BALL_LIGHTNING // grace period after thaddius aggro after which he starts being a baller (e.g. tossing ball lightning at out of range targets) }; -//Feugen -enum FeugenYells +enum Misc { - SAY_FEUG_AGGRO = 0, - SAY_FEUG_SLAY = 1, - SAY_FEUG_DEATH = 2 + MAX_POLARITY_10M = 5, + MAX_POLARITY_25M = 13, + + DATA_POLARITY_CROSSED = 1, +}; + +// Feugen & Stalagg +enum PetYells +{ + SAY_STALAGG_AGGRO = 0, + SAY_STALAGG_SLAY = 1, + SAY_STALAGG_DEATH = 2, + + SAY_FEUGEN_AGGRO = 0, + SAY_FEUGEN_SLAY = 1, + SAY_FEUGEN_DEATH = 2, + + EMOTE_FEIGN_DEATH = 3, + EMOTE_FEIGN_REVIVE = 4, + + EMOTE_TESLA_LINK_BREAKS = 0, + EMOTE_TESLA_OVERLOAD = 1 }; -enum FeugenSpells +enum PetSpells { - SPELL_STATICFIELD = 28135, - SPELL_FEUGEN_TESLA = 28109 + SPELL_STALAGG_POWERSURGE = 28134, + //SPELL_STALAGG_TESLA = 28097, + SPELL_STALAGG_TESLA_PERIODIC = 28098, + SPELL_STALAGG_CHAIN_VISUAL = 28096, + + SPELL_FEUGEN_STATICFIELD = 28135, + //SPELL_FEUGEN_TESLA = 28109, + SPELL_FEUGEN_TESLA_PERIODIC = 28110, + SPELL_FEUGEN_CHAIN_VISUAL = 28111, + + SPELL_MAGNETIC_PULL = 54517, + SPELL_MAGNETIC_PULL_EFFECT = 28337, + + SPELL_TESLA_SHOCK = 28099 }; -// Thaddius DoAction -enum ThaddiusActions +enum PetMisc { - ACTION_FEUGEN_RESET, - ACTION_FEUGEN_DIED, - ACTION_STALAGG_RESET, - ACTION_STALAGG_DIED + OVERLOAD_DISTANCE = 28 }; -//generic -#define C_TESLA_COIL 16218 //the coils (emotes "Tesla Coil overloads!") //Thaddius enum ThaddiusYells @@ -70,34 +126,31 @@ enum ThaddiusYells SAY_SLAY = 2, SAY_ELECT = 3, SAY_DEATH = 4, - SAY_SCREAM = 5 + SAY_SCREAM = 5, + + EMOTE_POLARITY_SHIFTED = 6 }; enum ThaddiusSpells { - SPELL_POLARITY_SHIFT = 28089, - SPELL_BALL_LIGHTNING = 28299, - SPELL_CHAIN_LIGHTNING = 28167, - SPELL_BERSERK = 27680, - SPELL_POSITIVE_CHARGE = 28062, - SPELL_POSITIVE_CHARGE_STACK = 29659, - SPELL_NEGATIVE_CHARGE = 28085, - SPELL_NEGATIVE_CHARGE_STACK = 29660, - SPELL_POSITIVE_POLARITY = 28059, - SPELL_NEGATIVE_POLARITY = 28084, -}; + SPELL_THADDIUS_INACTIVE_VISUAL = 28160, + SPELL_THADDIUS_SPARK_VISUAL = 28136, + SPELL_SHOCK_VISUAL = 28159, -enum Events -{ - EVENT_NONE, - EVENT_SHIFT, - EVENT_CHAIN, - EVENT_BERSERK, -}; + SPELL_BALL_LIGHTNING = 28299, + SPELL_CHAIN_LIGHTNING = 28167, + SPELL_BERSERK = 27680, -enum Achievement -{ - DATA_POLARITY_SWITCH = 76047605, + // polarity handling + SPELL_POLARITY_SHIFT = 28089, + + SPELL_POSITIVE_CHARGE_APPLY = 28059, + SPELL_POSITIVE_CHARGE_TICK = 28062, + SPELL_POSITIVE_CHARGE_AMP = 29659, + + SPELL_NEGATIVE_CHARGE_APPLY = 28084, + SPELL_NEGATIVE_CHARGE_TICK = 28085, + SPELL_NEGATIVE_CHARGE_AMP = 29660, }; class boss_thaddius : public CreatureScript @@ -112,166 +165,276 @@ public: struct boss_thaddiusAI : public BossAI { - boss_thaddiusAI(Creature* creature) : BossAI(creature, BOSS_THADDIUS) - { - // init is a bit tricky because thaddius shall track the life of both adds, but not if there was a wipe - // and, in particular, if there was a crash after both adds were killed (should not respawn) - - // Moreover, the adds may not yet be spawn. So just track down the status if mob is spawn - // and each mob will send its status at reset (meaning that it is alive) - checkFeugenAlive = false; - if (Creature* pFeugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) - checkFeugenAlive = pFeugen->IsAlive(); + public: + boss_thaddiusAI(Creature* creature) : BossAI(creature, BOSS_THADDIUS), stalaggAlive(true), feugenAlive(true), ballLightningEnabled(false), shockingEligibility(true) + { + if (instance->GetBossState(BOSS_THADDIUS) != DONE) + { + events.SetPhase(PHASE_NOT_ENGAGED); + SetCombatMovement(false); - checkStalaggAlive = false; - if (Creature* pStalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) - checkStalaggAlive = pStalagg->IsAlive(); + // initialize everything properly, and ensure that the coils are loaded by the time we initialize + BeginResetEncounter(true); + } + } - if (!checkFeugenAlive && !checkStalaggAlive) + void KilledUnit(Unit* victim) override { - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED); - me->SetReactState(REACT_AGGRESSIVE); + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); } - else + + void Reset() override { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED); - me->SetReactState(REACT_PASSIVE); + if (events.IsInPhase(PHASE_TRANSITION) || (events.IsInPhase(PHASE_THADDIUS) && me->IsAlive())) + BeginResetEncounter(); } - polaritySwitch = false; - uiAddsTimer = 0; - } - - bool checkStalaggAlive; - bool checkFeugenAlive; - bool polaritySwitch; - uint32 uiAddsTimer; - - void KilledUnit(Unit* /*victim*/) override - { - if (!(rand32() % 5)) - Talk(SAY_SLAY); - } - - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - Talk(SAY_DEATH); - } + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + me->setActive(false); + if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) + stalagg->setActive(false); + if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) + feugen->setActive(false); + Talk(SAY_DEATH); + } - void DoAction(int32 action) override - { - switch (action) + void DoAction(int32 action) override { - case ACTION_FEUGEN_RESET: - checkFeugenAlive = true; - break; - case ACTION_FEUGEN_DIED: - checkFeugenAlive = false; - break; - case ACTION_STALAGG_RESET: - checkStalaggAlive = true; - break; - case ACTION_STALAGG_DIED: - checkStalaggAlive = false; - break; + switch (action) + { + case ACTION_RESET_ENCOUNTER_TIMER: + if (events.IsInPhase(PHASE_RESETTING)) + ResetEncounter(); + break; + case ACTION_FEUGEN_RESET: + case ACTION_STALAGG_RESET: + if (!events.IsInPhase(PHASE_NOT_ENGAGED) && !events.IsInPhase(PHASE_RESETTING)) + BeginResetEncounter(); + break; + case ACTION_FEUGEN_AGGRO: + case ACTION_STALAGG_AGGRO: + if (events.IsInPhase(PHASE_RESETTING)) + return BeginResetEncounter(); + if (!events.IsInPhase(PHASE_NOT_ENGAGED)) + return; + events.SetPhase(PHASE_PETS); + + shockingEligibility = true; + + if (!instance->CheckRequiredBosses(BOSS_THADDIUS)) + return BeginResetEncounter(); + instance->SetBossState(BOSS_THADDIUS, IN_PROGRESS); + + me->setActive(true); + if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) + stalagg->setActive(true); + if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) + feugen->setActive(true); + break; + case ACTION_FEUGEN_DIED: + if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) + feugen->AI()->DoAction(ACTION_FEUGEN_REVIVING_FX); + feugenAlive = false; + if (stalaggAlive) + events.ScheduleEvent(EVENT_REVIVE_FEUGEN, 5 * IN_MILLISECONDS, 0, PHASE_PETS); + else + Transition(); + + break; + case ACTION_STALAGG_DIED: + if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) + stalagg->AI()->DoAction(ACTION_STALAGG_REVIVING_FX); + stalaggAlive = false; + if (feugenAlive) + events.ScheduleEvent(EVENT_REVIVE_STALAGG, 5 * IN_MILLISECONDS, 0, PHASE_PETS); + else + Transition(); + + break; + + case ACTION_POLARITY_CROSSED: + shockingEligibility = false; + break; + default: + break; + } } - if (!checkFeugenAlive && !checkStalaggAlive) + uint32 GetData(uint32 id) const override { - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED); - // REACT_AGGRESSIVE only reset when he takes damage. - DoZoneInCombat(); + return (id == DATA_POLARITY_CROSSED && shockingEligibility) ? 1u : 0u; } - else + + void Transition() // initiate transition between pet phase and thaddius phase { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED); - me->SetReactState(REACT_PASSIVE); + events.SetPhase(PHASE_TRANSITION); + + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + events.ScheduleEvent(EVENT_TRANSITION_1, 10 * IN_MILLISECONDS, 0, PHASE_TRANSITION); + events.ScheduleEvent(EVENT_TRANSITION_2, 12 * IN_MILLISECONDS, 0, PHASE_TRANSITION); + events.ScheduleEvent(EVENT_TRANSITION_3, 14 * IN_MILLISECONDS, 0, PHASE_TRANSITION); } - } - void EnterCombat(Unit* /*who*/) override - { - _EnterCombat(); - Talk(SAY_AGGRO); - events.ScheduleEvent(EVENT_SHIFT, 30000); - events.ScheduleEvent(EVENT_CHAIN, urand(10000, 20000)); - events.ScheduleEvent(EVENT_BERSERK, 360000); - } + void BeginResetEncounter(bool initial = false) + { + if (instance->GetBossState(BOSS_THADDIUS) == DONE) + return; + if (events.IsInPhase(PHASE_RESETTING)) + return; - void DamageTaken(Unit* /*pDoneBy*/, uint32 & /*uiDamage*/) override - { - me->SetReactState(REACT_AGGRESSIVE); - } + if (initial) // signal shorter spawn timer to instance script + instance->SetBossState(BOSS_THADDIUS, SPECIAL); + instance->ProcessEvent(me, EVENT_THADDIUS_BEGIN_RESET); + instance->SetBossState(BOSS_THADDIUS, NOT_STARTED); - void SetData(uint32 id, uint32 data) override - { - if (id == DATA_POLARITY_SWITCH) - polaritySwitch = data ? true : false; - } + // remove polarity shift debuffs on reset + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_CHARGE_APPLY); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_NEGATIVE_CHARGE_APPLY); - uint32 GetData(uint32 id) const override - { - if (id != DATA_POLARITY_SWITCH) - return 0; + me->DespawnOrUnsummon(); - return uint32(polaritySwitch); - } + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED); + events.SetPhase(PHASE_RESETTING); + if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) + feugen->AI()->DoAction(ACTION_BEGIN_RESET_ENCOUNTER); + if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) + stalagg->AI()->DoAction(ACTION_BEGIN_RESET_ENCOUNTER); - void UpdateAI(uint32 diff) override - { - if (checkFeugenAlive && checkStalaggAlive) - uiAddsTimer = 0; + me->setActive(false); + } - if (checkStalaggAlive != checkFeugenAlive) + void ResetEncounter() { - uiAddsTimer += diff; - if (uiAddsTimer > 5000) - { - if (!checkStalaggAlive) - { - if (Creature* pStalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) - pStalagg->Respawn(); - } - else - { - if (Creature* pFeugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) - pFeugen->Respawn(); - } - } - } + feugenAlive = true; + stalaggAlive = true; - if (!UpdateVictim()) - return; + me->Respawn(true); + _Reset(); + events.SetPhase(PHASE_NOT_ENGAGED); - events.Update(diff); + me->CastSpell(me, SPELL_THADDIUS_INACTIVE_VISUAL, true); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) + feugen->AI()->DoAction(ACTION_RESET_ENCOUNTER); + if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) + stalagg->AI()->DoAction(ACTION_RESET_ENCOUNTER); + } - while (uint32 eventId = events.ExecuteEvent()) + void UpdateAI(uint32 diff) override { - switch (eventId) + if (events.IsInPhase(PHASE_NOT_ENGAGED)) + return; + if (events.IsInPhase(PHASE_THADDIUS) && !UpdateVictim()) + return; + + events.Update(diff); + while (uint32 eventId = events.ExecuteEvent()) { - case EVENT_SHIFT: - DoCastAOE(SPELL_POLARITY_SHIFT); - events.ScheduleEvent(EVENT_SHIFT, 30000); - return; - case EVENT_CHAIN: - DoCastVictim(SPELL_CHAIN_LIGHTNING); - events.ScheduleEvent(EVENT_CHAIN, urand(10000, 20000)); - return; - case EVENT_BERSERK: - DoCast(me, SPELL_BERSERK); - return; + switch (eventId) + { + case EVENT_REVIVE_FEUGEN: + feugenAlive = true; + if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) + feugen->AI()->DoAction(ACTION_FEUGEN_REVIVED); + break; + case EVENT_REVIVE_STALAGG: + stalaggAlive = true; + if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) + stalagg->AI()->DoAction(ACTION_STALAGG_REVIVED); + break; + case EVENT_TRANSITION_1: // tesla coils overload + if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) + feugen->AI()->DoAction(ACTION_TRANSITION); + if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) + stalagg->AI()->DoAction(ACTION_TRANSITION); + break; + case EVENT_TRANSITION_2: // tesla coils shock thaddius + me->CastSpell(me, SPELL_THADDIUS_SPARK_VISUAL, true); + if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) + feugen->AI()->DoAction(ACTION_TRANSITION_2); + if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) + stalagg->AI()->DoAction(ACTION_TRANSITION_2); + break; + case EVENT_TRANSITION_3: // thaddius becomes active + me->CastSpell(me, SPELL_THADDIUS_SPARK_VISUAL, true); + ballLightningEnabled = false; + me->RemoveAura(SPELL_THADDIUS_INACTIVE_VISUAL); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + + DoZoneInCombat(); + if (Unit* closest = SelectTarget(SELECT_TARGET_NEAREST, 0, 500.0f)) + AttackStart(closest); + else // if there is no nearest target, then there is no target, meaning we should reset + return BeginResetEncounter(); + + if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) + feugen->AI()->DoAction(ACTION_TRANSITION_3); + if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) + stalagg->AI()->DoAction(ACTION_TRANSITION_3); + + events.SetPhase(PHASE_THADDIUS); + + Talk(SAY_AGGRO); + + events.ScheduleEvent(EVENT_ENABLE_BALL_LIGHTNING, 5 * IN_MILLISECONDS, 0, PHASE_THADDIUS); + events.ScheduleEvent(EVENT_SHIFT, 10 * IN_MILLISECONDS, 0, PHASE_THADDIUS); + events.ScheduleEvent(EVENT_CHAIN, urand(10, 20) * IN_MILLISECONDS, 0, PHASE_THADDIUS); + events.ScheduleEvent(EVENT_BERSERK, 6 * MINUTE * IN_MILLISECONDS, 0, PHASE_THADDIUS); + + break; + case EVENT_ENABLE_BALL_LIGHTNING: + ballLightningEnabled = true; + break; + case EVENT_SHIFT: + me->CastStop(); // shift overrides all other spells + DoCastAOE(SPELL_POLARITY_SHIFT); + events.ScheduleEvent(EVENT_SHIFT_TALK, 3 * IN_MILLISECONDS, PHASE_THADDIUS); + events.ScheduleEvent(EVENT_SHIFT, 30 * IN_MILLISECONDS, PHASE_THADDIUS); + break; + case EVENT_SHIFT_TALK: + Talk(SAY_ELECT); + Talk(EMOTE_POLARITY_SHIFTED); + break; + case EVENT_CHAIN: + if (me->FindCurrentSpellBySpellId(SPELL_POLARITY_SHIFT)) // delay until shift is over + events.ScheduleEvent(EVENT_CHAIN, 3 * IN_MILLISECONDS, 0, PHASE_THADDIUS); + else + { + me->CastStop(); + DoCastVictim(SPELL_CHAIN_LIGHTNING); + events.ScheduleEvent(EVENT_CHAIN, urand(10, 20) * IN_MILLISECONDS, PHASE_THADDIUS); + } + break; + case EVENT_BERSERK: + me->CastStop(); + DoCast(me, SPELL_BERSERK); + break; + default: + break; + } + } + + if (events.IsInPhase(PHASE_THADDIUS)) + { + if (me->IsWithinMeleeRange(me->GetVictim())) + DoMeleeAttackIfReady(); + else + if (ballLightningEnabled) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(target, SPELL_BALL_LIGHTNING); } } - if (events.GetTimer() > 15000 && !me->IsWithinMeleeRange(me->GetVictim())) - DoCastVictim(SPELL_BALL_LIGHTNING); - else - DoMeleeAttackIfReady(); - } + private: + bool stalaggAlive; + bool feugenAlive; + bool ballLightningEnabled; + bool shockingEligibility; }; }; @@ -288,88 +451,257 @@ public: struct npc_stalaggAI : public ScriptedAI { - npc_stalaggAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - instance = creature->GetInstanceScript(); - } + public: + npc_stalaggAI(Creature* creature) : ScriptedAI(creature), _myCoil(ObjectGuid::Empty), _myCoilGO(ObjectGuid::Empty), isOverloading(false), refreshBeam(false), isFeignDeath(false) + { + Initialize(); + instance = creature->GetInstanceScript(); + } - void Initialize() - { - powerSurgeTimer = urand(20000, 25000); - magneticPullTimer = 20000; - } + void Initialize() + { + if (GameObject* coil = myCoilGO()) + coil->SetGoState(GO_STATE_ACTIVE); - InstanceScript* instance; + // if the encounter reset while feigning death + me->SetStandState(UNIT_STAND_STATE_STAND); + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + isOverloading = false; + isFeignDeath = false; - uint32 powerSurgeTimer; - uint32 magneticPullTimer; + // force tesla coil state refresh + refreshBeam = true; - void Reset() override - { - if (Creature* pThaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS))) - if (pThaddius->AI()) - pThaddius->AI()->DoAction(ACTION_STALAGG_RESET); - Initialize(); - } + powerSurgeTimer = 10 * IN_MILLISECONDS; + } - void KilledUnit(Unit* /*victim*/) override - { - if (!(rand32() % 5)) - Talk(SAY_STAL_SLAY); - } + void Reset() override + { + if (isFeignDeath || !me->IsAlive()) + return; + if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS))) + thaddius->AI()->DoAction(ACTION_STALAGG_RESET); + } - void EnterCombat(Unit* /*who*/) override - { - Talk(SAY_STAL_AGGRO); - DoCast(SPELL_STALAGG_TESLA); - } + void BeginResetEncounter() + { + if (GameObject* coil = myCoilGO()) + coil->SetGoState(GO_STATE_READY); + me->DespawnOrUnsummon(); + me->setActive(false); + } - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_STAL_DEATH); - if (Creature* pThaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS))) - if (pThaddius->AI()) - pThaddius->AI()->DoAction(ACTION_STALAGG_DIED); - } + void ResetEncounter() + { + me->Respawn(true); + Initialize(); + } - void UpdateAI(uint32 uiDiff) override - { - if (!UpdateVictim()) - return; + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_BEGIN_RESET_ENCOUNTER: + BeginResetEncounter(); + break; + case ACTION_RESET_ENCOUNTER: + ResetEncounter(); + break; + case ACTION_STALAGG_REVIVING_FX: + break; + case ACTION_STALAGG_REVIVED: + if (!isFeignDeath) + break; + + me->SetFullHealth(); + me->SetStandState(UNIT_STAND_STATE_STAND); + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + Talk(EMOTE_FEIGN_REVIVE); + isFeignDeath = false; + + refreshBeam = true; // force beam refresh + + if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) + if (feugen->GetVictim()) + { + me->AddThreat(feugen->EnsureVictim(), 0.0f); + me->SetInCombatWith(feugen->EnsureVictim()); + } + break; + case ACTION_TRANSITION: + me->KillSelf(); // true death + me->DespawnOrUnsummon(); + + if (Creature* coil = myCoil()) + { + coil->CastStop(); + coil->AI()->Talk(EMOTE_TESLA_OVERLOAD); + } + break; + case ACTION_TRANSITION_2: + if (Creature* coil = myCoil()) + if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS))) + coil->CastSpell(thaddius, SPELL_SHOCK_VISUAL); + break; + case ACTION_TRANSITION_3: + if (GameObject* coil = myCoilGO()) + coil->SetGoState(GO_STATE_READY); + break; + default: + break; + } + } - if (magneticPullTimer <= uiDiff) + void KilledUnit(Unit* victim) override { - if (Creature* pFeugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_STALAGG_SLAY); + } + + void EnterCombat(Unit* who) override + { + Talk(SAY_STALAGG_AGGRO); + + if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS))) + thaddius->AI()->DoAction(ACTION_STALAGG_AGGRO); + + if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) + if (!feugen->IsInCombat()) + { + feugen->AddThreat(who, 0.0f); + feugen->SetInCombatWith(who); + } + } + + void DamageTaken(Unit* /*who*/, uint32& damage) override + { + if (damage < me->GetHealth()) + return; + + if (isFeignDeath) // don't take damage while feigning death { - Unit* pStalaggVictim = me->GetVictim(); - Unit* pFeugenVictim = pFeugen->GetVictim(); + damage = 0; + return; + } + + isFeignDeath = true; + isOverloading = false; + + Talk(EMOTE_FEIGN_DEATH); + if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS))) + thaddius->AI()->DoAction(ACTION_STALAGG_DIED); + + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->RemoveAllAuras(); + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + me->StopMoving(); + me->SetStandState(UNIT_STAND_STATE_DEAD); - if (pFeugenVictim && pStalaggVictim) + damage = 0; + + // force beam refresh as we just removed auras + refreshBeam = true; + } + + void SpellHit(Unit* caster, SpellInfo const* spell) override + { + if (!caster) + return; + if (spell->Id != SPELL_STALAGG_TESLA_PERIODIC) + return; + if (!isFeignDeath && me->IsInCombat() && !me->GetHomePosition().IsInDist(me, OVERLOAD_DISTANCE)) + { + if (!isOverloading) { - // magnetic pull is not working. So just jump. + isOverloading = true; + caster->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + if (Creature* creatureCaster = caster->ToCreature()) + creatureCaster->AI()->Talk(EMOTE_TESLA_LINK_BREAKS); + me->RemoveAura(SPELL_STALAGG_CHAIN_VISUAL); + } + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + { + caster->CastStop(SPELL_TESLA_SHOCK); + caster->CastSpell(target, SPELL_TESLA_SHOCK,true); + } + } + else if (isOverloading || refreshBeam) + { + isOverloading = false; + refreshBeam = false; + caster->CastStop(); + caster->CastSpell(me, SPELL_STALAGG_CHAIN_VISUAL, true); + caster->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + } + } - // reset aggro to be sure that feugen will not follow the jump - pFeugen->getThreatManager().modifyThreatPercent(pFeugenVictim, -100); - pFeugenVictim->JumpTo(me, 0.3f); + void UpdateAI(uint32 uiDiff) override + { + if (!isFeignDeath) + if (!UpdateVictim()) + return; - me->getThreatManager().modifyThreatPercent(pStalaggVictim, -100); - pStalaggVictim->JumpTo(pFeugen, 0.3f); + if (powerSurgeTimer <= uiDiff) + { + if (isFeignDeath) // delay until potential revive + powerSurgeTimer = 0u; + else + { + DoCast(me, SPELL_STALAGG_POWERSURGE); + powerSurgeTimer = urand(25, 30) * IN_MILLISECONDS; } } + else + powerSurgeTimer -= uiDiff; - magneticPullTimer = 20000; + if (!isFeignDeath) + DoMeleeAttackIfReady(); } - else magneticPullTimer -= uiDiff; - if (powerSurgeTimer <= uiDiff) + private: + Creature* myCoil() { - DoCast(me, SPELL_POWERSURGE); - powerSurgeTimer = urand(15000, 20000); - } else powerSurgeTimer -= uiDiff; + Creature* coil = nullptr; + if (_myCoil) + coil = ObjectAccessor::GetCreature(*me, _myCoil); + if (!coil) + { + coil = me->FindNearestCreature(NPC_TESLA, 1000.0f, true); + if (coil) + { + _myCoil = coil->GetGUID(); + coil->SetReactState(REACT_PASSIVE); + } + } + return coil; + } - DoMeleeAttackIfReady(); - } + GameObject* myCoilGO() + { + GameObject* coil = nullptr; + if (_myCoilGO) + coil = ObjectAccessor::GetGameObject(*me, _myCoilGO); + if (!coil) + { + coil = me->FindNearestGameObject(GO_CONS_NOX_TESLA_STALAGG, 1000.0f); + if (coil) + _myCoilGO = coil->GetGUID(); + } + return coil; + } + + InstanceScript* instance; + + uint32 powerSurgeTimer; + + ObjectGuid _myCoil; + ObjectGuid _myCoilGO; + bool isOverloading; + bool refreshBeam; + bool isFeignDeath; }; }; @@ -386,142 +718,381 @@ public: struct npc_feugenAI : public ScriptedAI { - npc_feugenAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - instance = creature->GetInstanceScript(); - } - - void Initialize() - { - staticFieldTimer = 5000; - } + public: + npc_feugenAI(Creature* creature) : ScriptedAI(creature), _myCoil(ObjectGuid::Empty), _myCoilGO(ObjectGuid::Empty), isOverloading(false), refreshBeam(false), isFeignDeath(false) + { + Initialize(); + instance = creature->GetInstanceScript(); + } - InstanceScript* instance; + void Initialize() + { + if (GameObject* coil = myCoilGO()) + coil->SetGoState(GO_STATE_ACTIVE); - uint32 staticFieldTimer; + // if the encounter reset while feigning death + me->SetStandState(UNIT_STAND_STATE_STAND); + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + isOverloading = false; + isFeignDeath = false; - void Reset() override - { - if (Creature* pThaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS))) - if (pThaddius->AI()) - pThaddius->AI()->DoAction(ACTION_FEUGEN_RESET); - Initialize(); - } + // force coil state to refresh + refreshBeam = true; - void KilledUnit(Unit* /*victim*/) override - { - if (!(rand32() % 5)) - Talk(SAY_FEUG_SLAY); - } + staticFieldTimer = 6 * IN_MILLISECONDS; + magneticPullTimer = 20 * IN_MILLISECONDS; + } - void EnterCombat(Unit* /*who*/) override - { - Talk(SAY_FEUG_AGGRO); - DoCast(SPELL_FEUGEN_TESLA); - } + void Reset() override + { + if (isFeignDeath || !me->IsAlive()) + return; + if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS))) + thaddius->AI()->DoAction(ACTION_FEUGEN_RESET); + } - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_FEUG_DEATH); - if (Creature* pThaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS))) - if (pThaddius->AI()) - pThaddius->AI()->DoAction(ACTION_FEUGEN_DIED); - } + void BeginResetEncounter() + { + if (GameObject* coil = myCoilGO()) + coil->SetGoState(GO_STATE_READY); + me->DespawnOrUnsummon(); + me->setActive(false); + } - void UpdateAI(uint32 uiDiff) override - { - if (!UpdateVictim()) - return; + void ResetEncounter() + { + me->Respawn(true); + Initialize(); + } - if (staticFieldTimer <= uiDiff) + void DoAction(int32 action) override { - DoCast(me, SPELL_STATICFIELD); - staticFieldTimer = 5000; - } else staticFieldTimer -= uiDiff; + switch (action) + { + case ACTION_BEGIN_RESET_ENCOUNTER: + BeginResetEncounter(); + break; + case ACTION_RESET_ENCOUNTER: + ResetEncounter(); + break; + case ACTION_FEUGEN_REVIVING_FX: + break; + case ACTION_FEUGEN_REVIVED: + if (!isFeignDeath) + break; + + me->SetFullHealth(); + me->SetStandState(UNIT_STAND_STATE_STAND); + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + Talk(EMOTE_FEIGN_REVIVE); + isFeignDeath = false; + + refreshBeam = true; // force beam refresh + + if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) + if (stalagg->GetVictim()) + { + me->AddThreat(stalagg->EnsureVictim(), 0.0f); + me->SetInCombatWith(stalagg->EnsureVictim()); + } + staticFieldTimer = 6 * IN_MILLISECONDS; + magneticPullTimer = 30 * IN_MILLISECONDS; + break; + case ACTION_TRANSITION: + me->KillSelf(); // true death this time around + me->DespawnOrUnsummon(); + + if (Creature* coil = myCoil()) + { + coil->CastStop(); + coil->AI()->Talk(EMOTE_TESLA_OVERLOAD); + } + break; + case ACTION_TRANSITION_2: + if (Creature* coil = myCoil()) + if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS))) + coil->CastSpell(thaddius, SPELL_SHOCK_VISUAL); + break; + case ACTION_TRANSITION_3: + if (GameObject* coil = myCoilGO()) + coil->SetGoState(GO_STATE_READY); + default: + break; + } + } - DoMeleeAttackIfReady(); - } - }; + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_FEUGEN_SLAY); + } -}; + void EnterCombat(Unit* who) override + { + Talk(SAY_FEUGEN_AGGRO); -class spell_thaddius_pos_neg_charge : public SpellScriptLoader -{ - public: - spell_thaddius_pos_neg_charge() : SpellScriptLoader("spell_thaddius_pos_neg_charge") { } + if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS))) + thaddius->AI()->DoAction(ACTION_STALAGG_AGGRO); - class spell_thaddius_pos_neg_charge_SpellScript : public SpellScript - { - PrepareSpellScript(spell_thaddius_pos_neg_charge_SpellScript); + if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) + if (!stalagg->IsInCombat()) + { + stalagg->AddThreat(who, 0.0f); + stalagg->SetInCombatWith(who); + } + } - bool Validate(SpellInfo const* /*spell*/) override + void DamageTaken(Unit* /*who*/, uint32& damage) override { - if (!sSpellMgr->GetSpellInfo(SPELL_POSITIVE_CHARGE)) - return false; - if (!sSpellMgr->GetSpellInfo(SPELL_POSITIVE_CHARGE_STACK)) - return false; - if (!sSpellMgr->GetSpellInfo(SPELL_NEGATIVE_CHARGE)) - return false; - if (!sSpellMgr->GetSpellInfo(SPELL_NEGATIVE_CHARGE_STACK)) - return false; - return true; + if (damage < me->GetHealth()) + return; + + if (isFeignDeath) // don't take damage while feigning death + { + damage = 0; + return; + } + + isFeignDeath = true; + isOverloading = false; + + Talk(EMOTE_FEIGN_DEATH); + if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS))) + thaddius->AI()->DoAction(ACTION_FEUGEN_DIED); + + me->RemoveAllAuras(); + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + me->StopMoving(); + me->SetStandState(UNIT_STAND_STATE_DEAD); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + damage = 0; + + // force beam refresh as we just removed auras + refreshBeam = true; } - bool Load() override + void SpellHit(Unit* caster, SpellInfo const* spell) override { - return GetCaster()->GetTypeId() == TYPEID_UNIT; + if (!caster) + return; + if (spell->Id != SPELL_FEUGEN_TESLA_PERIODIC) + return; + if (!isFeignDeath && me->IsInCombat() && !me->GetHomePosition().IsInDist(me, OVERLOAD_DISTANCE)) + { + if (!isOverloading) + { + isOverloading = true; + caster->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + if (Creature* creatureCaster = caster->ToCreature()) + creatureCaster->AI()->Talk(EMOTE_TESLA_LINK_BREAKS); + me->RemoveAura(SPELL_STALAGG_CHAIN_VISUAL); + } + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + { + caster->CastStop(SPELL_TESLA_SHOCK); + caster->CastSpell(target, SPELL_TESLA_SHOCK,true); + } + } + else if (isOverloading || refreshBeam) + { + isOverloading = false; + refreshBeam = false; + caster->CastStop(); + caster->CastSpell(me, SPELL_FEUGEN_CHAIN_VISUAL, true); + caster->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + } } - void HandleTargets(std::list<WorldObject*>& targets) + void UpdateAI(uint32 uiDiff) override { - uint8 count = 0; - for (std::list<WorldObject*>::iterator ihit = targets.begin(); ihit != targets.end(); ++ihit) - if ((*ihit)->GetGUID() != GetCaster()->GetGUID()) - if (Player* target = (*ihit)->ToPlayer()) - if (target->HasAura(GetTriggeringSpell()->Id)) - ++count; + if (isFeignDeath) + return; + if (!UpdateVictim()) + return; - if (count) + if (magneticPullTimer <= uiDiff) + { + DoCast(me, SPELL_MAGNETIC_PULL); + magneticPullTimer = 20 * IN_MILLISECONDS; + } + else magneticPullTimer -= uiDiff; + + if (staticFieldTimer <= uiDiff) { - uint32 spellId = 0; + DoCast(me, SPELL_FEUGEN_STATICFIELD); + staticFieldTimer = 6 * IN_MILLISECONDS; + } + else staticFieldTimer -= uiDiff; - if (GetSpellInfo()->Id == SPELL_POSITIVE_CHARGE) - spellId = SPELL_POSITIVE_CHARGE_STACK; - else // if (GetSpellInfo()->Id == SPELL_NEGATIVE_CHARGE) - spellId = SPELL_NEGATIVE_CHARGE_STACK; + DoMeleeAttackIfReady(); + } - GetCaster()->SetAuraStack(spellId, GetCaster(), count); + private: + Creature* myCoil() + { + Creature* coil = nullptr; + if (_myCoil) + coil = ObjectAccessor::GetCreature(*me, _myCoil); + if (!coil) + { + coil = me->FindNearestCreature(NPC_TESLA, 1000.0f, true); + if (coil) + { + _myCoil = coil->GetGUID(); + coil->SetReactState(REACT_PASSIVE); + } } + return coil; + } + + GameObject* myCoilGO() + { + GameObject* coil = nullptr; + if (_myCoilGO) + coil = ObjectAccessor::GetGameObject(*me, _myCoilGO); + if (!coil) + { + coil = me->FindNearestGameObject(GO_CONS_NOX_TESLA_FEUGEN, 1000.0f); + if (coil) + _myCoilGO = coil->GetGUID(); + } + return coil; + } + InstanceScript* instance; + + uint32 magneticPullTimer; + uint32 staticFieldTimer; + + ObjectGuid _myCoil; + ObjectGuid _myCoilGO; + + bool isOverloading; + bool refreshBeam; + bool isFeignDeath; + }; +}; + +class npc_tesla : public CreatureScript +{ +public: + npc_tesla() : CreatureScript("npc_tesla") { } + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<npc_teslaAI>(creature); + } + + struct npc_teslaAI : public ScriptedAI + { + npc_teslaAI(Creature* creature) : ScriptedAI(creature) { } + + void EnterEvadeMode() override { } // never stop casting due to evade + void UpdateAI(uint32 /*diff*/) override { } // never do anything unless told + void EnterCombat(Unit* /*who*/) override { } + void DamageTaken(Unit* /*who*/, uint32& damage) override { damage = 0; } // no, you can't kill it + }; +}; + +class spell_thaddius_polarity_charge : public SpellScriptLoader +{ + public: + spell_thaddius_polarity_charge() : SpellScriptLoader("spell_thaddius_polarity_charge") { } + + class spell_thaddius_polarity_charge_SpellScript : public SpellScript + { + PrepareSpellScript(spell_thaddius_polarity_charge_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + return ( + sSpellMgr->GetSpellInfo(SPELL_POLARITY_SHIFT) && + sSpellMgr->GetSpellInfo(SPELL_POSITIVE_CHARGE_APPLY) && + sSpellMgr->GetSpellInfo(SPELL_POSITIVE_CHARGE_TICK) && + sSpellMgr->GetSpellInfo(SPELL_POSITIVE_CHARGE_AMP) && + sSpellMgr->GetSpellInfo(SPELL_NEGATIVE_CHARGE_APPLY) && + sSpellMgr->GetSpellInfo(SPELL_NEGATIVE_CHARGE_TICK) && + sSpellMgr->GetSpellInfo(SPELL_NEGATIVE_CHARGE_AMP) + ); } - void HandleDamage(SpellEffIndex /*effIndex*/) + void HandleTargets(std::list<WorldObject*>& targetList) { if (!GetTriggeringSpell()) return; - Unit* target = GetHitUnit(); - Unit* caster = GetCaster(); + uint32 triggeringId = GetTriggeringSpell()->Id; + uint32 ampId; + switch (triggeringId) + { + case SPELL_POSITIVE_CHARGE_APPLY: + ampId = SPELL_POSITIVE_CHARGE_AMP; + break; + case SPELL_NEGATIVE_CHARGE_APPLY: + ampId = SPELL_NEGATIVE_CHARGE_AMP; + break; + default: + return; + } - if (target->HasAura(GetTriggeringSpell()->Id)) - SetHitDamage(0); - else + uint8 maxStacks = 0; + if (GetCaster()) + switch (GetCaster()->GetMap()->GetDifficulty()) + { + case RAID_DIFFICULTY_10MAN_NORMAL: + maxStacks = MAX_POLARITY_10M; + break; + case RAID_DIFFICULTY_25MAN_NORMAL: + maxStacks = MAX_POLARITY_25M; + break; + default: + break; + } + + uint8 stacksCount = 1; // do we get a stack for our own debuff? + std::list<WorldObject*>::iterator it = targetList.begin(); + while(it != targetList.end()) + { + if ((*it)->GetTypeId() != TYPEID_PLAYER) + { + it = targetList.erase(it); + continue; + } + if ((*it)->ToPlayer()->HasAura(triggeringId)) + { + it = targetList.erase(it); + if (stacksCount < maxStacks) + stacksCount++; + continue; + } + + // this guy will get hit - achievement failure trigger + if (Creature* thaddius = (*it)->FindNearestCreature(NPC_THADDIUS,200.0f)) + thaddius->AI()->DoAction(ACTION_POLARITY_CROSSED); + + ++it; + } + + if (GetCaster() && GetCaster()->ToPlayer()) { - if (target->GetTypeId() == TYPEID_PLAYER && caster->IsAIEnabled) - caster->ToCreature()->AI()->SetData(DATA_POLARITY_SWITCH, 1); + if (!GetCaster()->ToPlayer()->HasAura(ampId)) + GetCaster()->ToPlayer()->AddAura(ampId, GetCaster()); + GetCaster()->ToPlayer()->SetAuraStack(ampId, GetCaster(), stacksCount); } } void Register() override { - OnEffectHitTarget += SpellEffectFn(spell_thaddius_pos_neg_charge_SpellScript::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_thaddius_pos_neg_charge_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_thaddius_polarity_charge_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); } }; SpellScript* GetSpellScript() const override { - return new spell_thaddius_pos_neg_charge_SpellScript(); + return new spell_thaddius_polarity_charge_SpellScript; } }; @@ -536,16 +1107,33 @@ class spell_thaddius_polarity_shift : public SpellScriptLoader bool Validate(SpellInfo const* /*spell*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_POSITIVE_POLARITY) || !sSpellMgr->GetSpellInfo(SPELL_NEGATIVE_POLARITY)) - return false; - return true; + return ( + sSpellMgr->GetSpellInfo(SPELL_POLARITY_SHIFT) && + sSpellMgr->GetSpellInfo(SPELL_POSITIVE_CHARGE_APPLY) && + sSpellMgr->GetSpellInfo(SPELL_POSITIVE_CHARGE_TICK) && + sSpellMgr->GetSpellInfo(SPELL_POSITIVE_CHARGE_AMP) && + sSpellMgr->GetSpellInfo(SPELL_NEGATIVE_CHARGE_APPLY) && + sSpellMgr->GetSpellInfo(SPELL_NEGATIVE_CHARGE_TICK) && + sSpellMgr->GetSpellInfo(SPELL_NEGATIVE_CHARGE_AMP) + ); } - void HandleDummy(SpellEffIndex /* effIndex */) + void HandleDummy(SpellEffIndex /*effIndex*/) { - Unit* caster = GetCaster(); if (Unit* target = GetHitUnit()) - target->CastSpell(target, roll_chance_i(50) ? SPELL_POSITIVE_POLARITY : SPELL_NEGATIVE_POLARITY, true, NULL, NULL, caster->GetGUID()); + if (target->GetTypeId() == TYPEID_PLAYER) + { + if (roll_chance_i(50)) + { // positive + target->CastSpell(target, SPELL_POSITIVE_CHARGE_APPLY, true); + target->RemoveAura(SPELL_POSITIVE_CHARGE_AMP); + } + else + { // negative + target->CastSpell(target, SPELL_NEGATIVE_CHARGE_APPLY, true); + target->RemoveAura(SPELL_NEGATIVE_CHARGE_AMP); + } + } } void Register() override @@ -560,23 +1148,131 @@ class spell_thaddius_polarity_shift : public SpellScriptLoader } }; -class achievement_polarity_switch : public AchievementCriteriaScript +class spell_thaddius_magnetic_pull : public SpellScriptLoader { public: - achievement_polarity_switch() : AchievementCriteriaScript("achievement_polarity_switch") { } + spell_thaddius_magnetic_pull() : SpellScriptLoader("spell_thaddius_magnetic_pull") { }; + + class spell_thaddius_magnetic_pull_SpellScript : public SpellScript + { + PrepareSpellScript(spell_thaddius_magnetic_pull_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + return sSpellMgr->GetSpellInfo(SPELL_MAGNETIC_PULL) ? true : false; + } + + void HandleCast() // only feugen ever casts this according to wowhead data + { + Unit* feugen = GetCaster(); + if (!feugen || feugen->GetEntry() != NPC_FEUGEN) + return; + + Unit* stalagg = ObjectAccessor::GetCreature(*feugen, feugen->GetInstanceScript()->GetGuidData(DATA_STALAGG)); + if (!stalagg) + return; + + Unit* feugenTank = feugen->GetVictim(); + Unit* stalaggTank = stalagg->GetVictim(); + + if (!feugenTank || !stalaggTank) + return; + + ThreatManager& feugenThreat = feugen->getThreatManager(); + ThreatManager& stalaggThreat = stalagg->getThreatManager(); + + if (feugenTank == stalaggTank) // special behavior if the tanks are the same (taken from retail) + { + float feugenTankThreat = feugenThreat.getThreat(feugenTank); + float stalaggTankThreat = stalaggThreat.getThreat(stalaggTank); + + feugenThreat.addThreat(feugenTank, stalaggTankThreat - feugenTankThreat); + stalaggThreat.addThreat(stalaggTank, feugenTankThreat - stalaggTankThreat); + + feugen->CastSpell(stalaggTank, SPELL_MAGNETIC_PULL_EFFECT, true); + } + else // normal case, two tanks + { + float feugenTankThreat = feugenThreat.getThreat(feugenTank); + float feugenOtherThreat = feugenThreat.getThreat(stalaggTank); + float stalaggTankThreat = stalaggThreat.getThreat(stalaggTank); + float stalaggOtherThreat = stalaggThreat.getThreat(feugenTank); + + // set the two entries in feugen's threat table to be equal to the ones in stalagg's + feugenThreat.addThreat(stalaggTank, stalaggTankThreat - feugenOtherThreat); + feugenThreat.addThreat(feugenTank, stalaggOtherThreat - feugenTankThreat); + + // set the two entries in stalagg's threat table to be equal to the ones in feugen's + stalaggThreat.addThreat(feugenTank, feugenTankThreat - stalaggOtherThreat); + stalaggThreat.addThreat(stalaggTank, feugenOtherThreat - stalaggTankThreat); + + // pull the two tanks across + feugenTank->CastSpell(stalaggTank, SPELL_MAGNETIC_PULL_EFFECT, true); + stalaggTank->CastSpell(feugenTank, SPELL_MAGNETIC_PULL_EFFECT, true); + + // and make both attack their respective new tanks + if (feugen->GetAI()) + feugen->GetAI()->AttackStart(stalaggTank); + if (stalagg->GetAI()) + stalagg->GetAI()->AttackStart(feugenTank); + } + } + + void Register() override + { + OnCast += SpellCastFn(spell_thaddius_magnetic_pull_SpellScript::HandleCast); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_thaddius_magnetic_pull_SpellScript(); + } +}; + +class at_thaddius_entrance : public AreaTriggerScript +{ + public: + at_thaddius_entrance() : AreaTriggerScript("at_thaddius_entrance") { } + + bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override + { + InstanceScript* instance = player->GetInstanceScript(); + if (!instance || instance->GetData(DATA_HAD_THADDIUS_GREET) || instance->GetBossState(BOSS_THADDIUS) == DONE) + return true; + + if (Creature* thaddius = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_THADDIUS))) + thaddius->AI()->Talk(SAY_GREET); + instance->SetData(DATA_HAD_THADDIUS_GREET, 1u); + + return true; + } +}; + +class achievement_thaddius_shocking : public AchievementCriteriaScript +{ + public: + achievement_thaddius_shocking() : AchievementCriteriaScript("achievement_thaddius_shocking") { } bool OnCheck(Player* /*source*/, Unit* target) override { - return target && target->GetAI()->GetData(DATA_POLARITY_SWITCH); + return target && target->GetAI() && target->GetAI()->GetData(DATA_POLARITY_CROSSED); } }; + void AddSC_boss_thaddius() { new boss_thaddius(); new npc_stalagg(); new npc_feugen(); - new spell_thaddius_pos_neg_charge(); + new npc_tesla(); + + new spell_thaddius_polarity_charge(); new spell_thaddius_polarity_shift(); - new achievement_polarity_switch(); + new spell_thaddius_magnetic_pull(); + + new at_thaddius_entrance(); + + new achievement_thaddius_shocking(); } diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp index 9b10fab2d62..0e572835a51 100644 --- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp +++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp @@ -60,7 +60,6 @@ DoorData const doorData[] = MinionData const minionData[] = { - { NPC_DK_UNDERSTUDY, BOSS_RAZUVIOUS }, { NPC_SIR, BOSS_HORSEMEN }, { NPC_THANE, BOSS_HORSEMEN }, { NPC_LADY, BOSS_HORSEMEN }, @@ -127,6 +126,7 @@ class instance_naxxramas : public InstanceMapScript AbominationCount = 0; hadAnubRekhanGreet = false; hadFaerlinaGreet = false; + hadThaddiusGreet = false; CurrentWingTaunt = SAY_KELTHUZAD_FIRST_WING_TAUNT; playerDied = 0; @@ -142,6 +142,9 @@ class instance_naxxramas : public InstanceMapScript case NPC_FAERLINA: FaerlinaGUID = creature->GetGUID(); break; + case NPC_RAZUVIOUS: + RazuviousGUID = creature->GetGUID(); + break; case NPC_THANE: ThaneGUID = creature->GetGUID(); break; @@ -154,12 +157,12 @@ class instance_naxxramas : public InstanceMapScript case NPC_SIR: SirGUID = creature->GetGUID(); break; - case NPC_THADDIUS: - ThaddiusGUID = creature->GetGUID(); - break; case NPC_HEIGAN: HeiganGUID = creature->GetGUID(); break; + case NPC_THADDIUS: + ThaddiusGUID = creature->GetGUID(); + break; case NPC_FEUGEN: FeugenGUID = creature->GetGUID(); break; @@ -187,6 +190,19 @@ class instance_naxxramas : public InstanceMapScript AddMinion(creature, false); } + void ProcessEvent(WorldObject* /*source*/, uint32 eventId) override + { + switch (eventId) + { + case EVENT_THADDIUS_BEGIN_RESET: + if (GetBossState(BOSS_THADDIUS) == SPECIAL) // this is the initial spawn, we want a shorter spawn time + events.ScheduleEvent(EVENT_THADDIUS_RESET, 5 * IN_MILLISECONDS); + else + events.ScheduleEvent(EVENT_THADDIUS_RESET, 30 * IN_MILLISECONDS); + break; + } + } + void OnGameObjectCreate(GameObject* go) override { if (go->GetGOInfo()->displayId == 6785 || go->GetGOInfo()->displayId == 1287) @@ -329,6 +345,9 @@ class instance_naxxramas : public InstanceMapScript case DATA_HAD_FAERLINA_GREET: hadFaerlinaGreet = (value == 1u); break; + case DATA_HAD_THADDIUS_GREET: + hadThaddiusGreet = (value == 1u); + break; default: break; } @@ -341,9 +360,11 @@ class instance_naxxramas : public InstanceMapScript case DATA_ABOMINATION_KILLED: return AbominationCount; case DATA_HAD_ANUBREKHAN_GREET: - return (uint32)hadAnubRekhanGreet; + return hadAnubRekhanGreet ? 1u : 0u; case DATA_HAD_FAERLINA_GREET: - return (uint32)hadFaerlinaGreet; + return hadFaerlinaGreet ? 1u : 0u; + case DATA_HAD_THADDIUS_GREET: + return hadThaddiusGreet ? 1u : 0u; default: break; } @@ -359,6 +380,8 @@ class instance_naxxramas : public InstanceMapScript return AnubRekhanGUID; case DATA_FAERLINA: return FaerlinaGUID; + case DATA_RAZUVIOUS: + return RazuviousGUID; case DATA_THANE: return ThaneGUID; case DATA_LADY: @@ -367,14 +390,14 @@ class instance_naxxramas : public InstanceMapScript return BaronGUID; case DATA_SIR: return SirGUID; - case DATA_THADDIUS: - return ThaddiusGUID; case DATA_HEIGAN: return HeiganGUID; case DATA_FEUGEN: return FeugenGUID; case DATA_STALAGG: return StalaggGUID; + case DATA_THADDIUS: + return ThaddiusGUID; case DATA_KELTHUZAD: return KelthuzadGUID; case DATA_KELTHUZAD_PORTAL01: @@ -543,6 +566,11 @@ class instance_naxxramas : public InstanceMapScript kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD4); HandleGameObject(KelthuzadDoorGUID, true); break; + case EVENT_THADDIUS_RESET: + if (GetBossState(BOSS_THADDIUS) != DONE) + if (Creature* thaddius = instance->GetCreature(ThaddiusGUID)) + thaddius->AI()->DoAction(-1); + break; default: break; } @@ -628,6 +656,8 @@ class instance_naxxramas : public InstanceMapScript ObjectGuid HeiganGUID; /* The Military Quarter */ + // Instructor Razuvious + ObjectGuid RazuviousGUID; // Gothik the Harvester ObjectGuid GothikGateGUID; // The Four Horsemen @@ -657,6 +687,7 @@ class instance_naxxramas : public InstanceMapScript uint8 AbominationCount; bool hadAnubRekhanGreet; bool hadFaerlinaGreet; + bool hadThaddiusGreet; uint8 CurrentWingTaunt; /* The Immortal / The Undying */ diff --git a/src/server/scripts/Northrend/Naxxramas/naxxramas.h b/src/server/scripts/Northrend/Naxxramas/naxxramas.h index 6289b707411..e4d15cf84ba 100644 --- a/src/server/scripts/Northrend/Naxxramas/naxxramas.h +++ b/src/server/scripts/Northrend/Naxxramas/naxxramas.h @@ -47,8 +47,8 @@ enum Data DATA_GOTHIK_GATE, DATA_SAPPHIRON_BIRTH, DATA_HAD_ANUBREKHAN_GREET, - DATA_HAD_FAERLINA_GREET, + DATA_HAD_THADDIUS_GREET, DATA_HORSEMEN0, DATA_HORSEMEN1, @@ -66,6 +66,7 @@ enum Data64 { DATA_ANUBREKHAN, DATA_FAERLINA, + DATA_RAZUVIOUS, DATA_THANE, DATA_LADY, DATA_BARON, @@ -87,14 +88,16 @@ enum CreaturesIds { NPC_ANUBREKHAN = 15956, NPC_FAERLINA = 15953, + NPC_RAZUVIOUS = 16061, NPC_THANE = 16064, NPC_LADY = 16065, NPC_BARON = 30549, NPC_SIR = 16063, - NPC_THADDIUS = 15928, NPC_HEIGAN = 15936, + NPC_THADDIUS = 15928, NPC_FEUGEN = 15930, NPC_STALAGG = 15929, + NPC_TESLA = 16218, NPC_SAPPHIRON = 15989, NPC_KEL_THUZAD = 15990, NPC_CRYPT_GUARD = 16573, @@ -174,6 +177,10 @@ enum InstanceEvents EVENT_DIALOGUE_GOTHIK_KORTHAZZ2, EVENT_DIALOGUE_GOTHIK_RIVENDARE2, + // Thaddius AI requesting timed encounter (re-)spawn + EVENT_THADDIUS_BEGIN_RESET, + EVENT_THADDIUS_RESET, + // Dialogue that happens after each wing. EVENT_KELTHUZAD_WING_TAUNT, diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index cc9af9413e5..33ffea4993b 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -1244,8 +1244,9 @@ public: ++_wpCount; } else if (Vehicle* hoverDisk = me->GetVehicleKit()) - if (Unit* lordPassenger = hoverDisk->GetPassenger(0)) - lordPassenger->ToCreature()->AI()->DoAction(ACTION_SET_DISK_VICTIM_CHASE); + if (Unit* passenger = hoverDisk->GetPassenger(0)) + if (Creature* lordPassenger = passenger->ToCreature()) + lordPassenger->AI()->DoAction(ACTION_SET_DISK_VICTIM_CHASE); } private: diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp index bd4fee60c42..5c852cd7f26 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp @@ -701,7 +701,7 @@ class boss_leviathan_mk_ii : public CreatureScript { me->CastStop(); if (Unit* turret = me->GetVehicleKit()->GetPassenger(3)) - turret->Kill(turret); + turret->KillSelf(); me->SetSpeed(MOVE_RUN, 1.5f, true); me->GetMotionMaster()->MovePoint(WP_MKII_P1_IDLE, VehicleRelocation[WP_MKII_P1_IDLE]); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp index 6f07a88536d..8545d5b21eb 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp @@ -2423,7 +2423,7 @@ class spell_yogg_saron_squeeze : public SpellScriptLoader // 64125 { if (Unit* vehicle = GetTarget()->GetVehicleBase()) if (vehicle->IsAlive()) - vehicle->Kill(vehicle); // should tentacle die or just release its target? + vehicle->KillSelf(); // should tentacle die or just release its target? } void Register() override @@ -2905,7 +2905,7 @@ class spell_yogg_saron_insane : public SpellScriptLoader // 63120 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { if (GetTarget()->IsAlive()) - GetTarget()->Kill(GetTarget()); + GetTarget()->KillSelf(); } void Register() override diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp index 4cdfa653224..6ef9abe2267 100644 --- a/src/server/scripts/Northrend/zone_borean_tundra.cpp +++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp @@ -1326,7 +1326,7 @@ public: arlos->AI()->Talk(SAY_ARLOS_1); arlos->AI()->Talk(SAY_ARLOS_2); leryssa->AI()->Talk(SAY_LERYSSA_1); - arlos->Kill(arlos, false); + arlos->KillSelf(false); leryssa->RemoveAura(SPELL_STUN); leryssa->ClearUnitState(UNIT_STATE_STUNNED); leryssa->SetWalk(false); diff --git a/src/server/scripts/Northrend/zone_sholazar_basin.cpp b/src/server/scripts/Northrend/zone_sholazar_basin.cpp index 6e4a8df6f25..5d47e7fa4ec 100644 --- a/src/server/scripts/Northrend/zone_sholazar_basin.cpp +++ b/src/server/scripts/Northrend/zone_sholazar_basin.cpp @@ -778,7 +778,7 @@ public: wilhelm->AI()->Talk(SAY_WILHELM_MISS); drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS); - bird->Kill(bird); + bird->KillSelf(); crunchy->GetMotionMaster()->MovePoint(0, bird->GetPositionX(), bird->GetPositionY(), bird->GetMap()->GetWaterOrGroundLevel(bird->GetPositionX(), bird->GetPositionY(), bird->GetPositionZ())); /// @todo Make crunchy perform emote eat when he reaches the bird diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp index b16a9630335..04d3a20d945 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp @@ -257,7 +257,7 @@ class npc_voidtraveler : public CreatureScript { DoCastAOE(SPELL_EMPOWERING_SHADOWS, true); DoCast(me, SPELL_SHADOW_NOVA, true); - me->Kill(me); + me->KillSelf(); return; } me->GetMotionMaster()->MoveFollow(Vorpil, 0, 0); diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp index 787b191e23d..0292ed65697 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp @@ -633,7 +633,7 @@ public: } if (Creature* vashj = ObjectAccessor::GetCreature(*me, VashjGUID)) if (!vashj->IsInCombat() || ENSURE_AI(boss_lady_vashj::boss_lady_vashjAI, vashj->AI())->Phase != 2 || vashj->isDead()) - me->Kill(me); + me->KillSelf(); Move = 1000; } else Move -= diff; } diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp index 872269fd19f..2d99fd9bacf 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp @@ -1286,7 +1286,7 @@ class npc_kael_flamestrike : public CreatureScript DoCast(me, SPELL_FLAME_STRIKE_DMG); } else - me->Kill(me); + me->KillSelf(); KillSelf = true; Timer = 1000; diff --git a/src/server/scripts/Pet/pet_mage.cpp b/src/server/scripts/Pet/pet_mage.cpp index 0d6353cfb86..14d2687c298 100644 --- a/src/server/scripts/Pet/pet_mage.cpp +++ b/src/server/scripts/Pet/pet_mage.cpp @@ -24,11 +24,25 @@ #include "ScriptedCreature.h" #include "CombatAI.h" #include "Pet.h" +#include "PetAI.h" +#include "Cell.h" +#include "CellImpl.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" enum MageSpells { SPELL_MAGE_CLONE_ME = 45204, - SPELL_MAGE_MASTERS_THREAT_LIST = 58838 + SPELL_MAGE_MASTERS_THREAT_LIST = 58838, + SPELL_MAGE_FROST_BOLT = 59638, + SPELL_MAGE_FIRE_BLAST = 59637 +}; + +enum MirrorImageTimers +{ + TIMER_MIRROR_IMAGE_INIT = 0, + TIMER_MIRROR_IMAGE_FROST_BOLT = 4000, + TIMER_MIRROR_IMAGE_FIRE_BLAST = 6000 }; class npc_pet_mage_mirror_image : public CreatureScript @@ -40,20 +54,184 @@ class npc_pet_mage_mirror_image : public CreatureScript { npc_pet_mage_mirror_imageAI(Creature* creature) : CasterAI(creature) { } + void Init() + { + Unit* owner = me->GetCharmerOrOwner(); + + std::list<Unit*> targets; + Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(me, me, 30.0f); + Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(me, targets, u_check); + me->VisitNearbyObject(40.0f, searcher); + + Unit* highestThreatUnit = nullptr; + float highestThreat = 0.0f; + Unit* nearestPlayer = nullptr; + for (std::list<Unit*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter) + { + // Consider only units without CC + if (!(*iter)->HasBreakableByDamageCrowdControlAura((*iter))) + { + // Take first found unit + if (!highestThreatUnit && (*iter)->GetTypeId() != TYPEID_PLAYER) + { + highestThreatUnit = (*iter); + continue; + } + if (!nearestPlayer && ((*iter)->GetTypeId() == TYPEID_PLAYER)) + { + nearestPlayer = (*iter); + continue; + } + // else compare best fit unit with current unit + ThreatContainer::StorageType triggers = (*iter)->getThreatManager().getThreatList(); + for (ThreatContainer::StorageType::const_iterator trig_citr = triggers.begin(); trig_citr != triggers.end(); ++trig_citr) + { + // Try to find threat referenced to owner + if ((*trig_citr)->getTarget() == owner) + { + // Check if best fit hostile unit hs lower threat than this current unit + if (highestThreat < (*trig_citr)->getThreat()) + { + // If so, update best fit unit + highestThreat = (*trig_citr)->getThreat(); + highestThreatUnit = (*iter); + break; + } + } + } + // In case no unit with threat was found so far, always check for nearest unit (only for players) + if ((*iter)->GetTypeId() == TYPEID_PLAYER) + { + // If this player is closer than the previous one, update it + if (me->GetDistance((*iter)->GetPosition()) < me->GetDistance(nearestPlayer->GetPosition())) + nearestPlayer = (*iter); + } + } + } + // Prioritize units with threat referenced to owner + if (highestThreat > 0.0f && highestThreatUnit) + me->Attack(highestThreatUnit, false); + // If there is no such target, try to attack nearest hostile unit if such exists + else if (nearestPlayer) + me->Attack(nearestPlayer, false); + } + + bool IsInThreatList(Unit* target) + { + Unit* owner = me->GetCharmerOrOwner(); + + std::list<Unit*> targets; + Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(me, me, 30.0f); + Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(me, targets, u_check); + me->VisitNearbyObject(40.0f, searcher); + + for (std::list<Unit*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter) + { + if ((*iter) == target) + { + // Consider only units without CC + if (!(*iter)->HasBreakableByDamageCrowdControlAura((*iter))) + { + ThreatContainer::StorageType triggers = (*iter)->getThreatManager().getThreatList(); + for (ThreatContainer::StorageType::const_iterator trig_citr = triggers.begin(); trig_citr != triggers.end(); ++trig_citr) + { + // Try to find threat referenced to owner + if ((*trig_citr)->getTarget() == owner) + return true; + } + } + } + } + return false; + } + void InitializeAI() override { CasterAI::InitializeAI(); Unit* owner = me->GetOwner(); if (!owner) return; - // Inherit Master's Threat List (not yet implemented) - owner->CastSpell((Unit*)NULL, SPELL_MAGE_MASTERS_THREAT_LIST, true); + // here mirror image casts on summoner spell (not present in client dbc) 49866 // here should be auras (not present in client dbc): 35657, 35658, 35659, 35660 selfcast by mirror images (stats related?) // Clone Me! owner->CastSpell(me, SPELL_MAGE_CLONE_ME, false); } + void EnterCombat(Unit* who) override + { + if (me->GetVictim() && !me->GetVictim()->HasBreakableByDamageCrowdControlAura(me)) + { + me->CastSpell(who, SPELL_MAGE_FIRE_BLAST, false); + events.ScheduleEvent(SPELL_MAGE_FROST_BOLT, TIMER_MIRROR_IMAGE_INIT); + events.ScheduleEvent(SPELL_MAGE_FIRE_BLAST, TIMER_MIRROR_IMAGE_FIRE_BLAST); + } + else + EnterEvadeMode(); + } + + void Reset() override + { + events.Reset(); + } + + void UpdateAI(uint32 diff) override + { + Unit* owner = me->GetCharmerOrOwner(); + Unit* target = owner->getAttackerForHelper(); + + events.Update(diff); + + // prevent CC interrupts by images + if (me->GetVictim() && me->EnsureVictim()->HasBreakableByDamageCrowdControlAura(me)) + { + me->InterruptNonMeleeSpells(false); + return; + } + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + if (!owner) + return; + + // assign target if image doesnt have any or the target is not actual + if (!target || me->GetVictim() != target) + { + Unit* ownerTarget = nullptr; + if (Player* owner = me->GetCharmerOrOwner()->ToPlayer()) + ownerTarget = owner->GetSelectedUnit(); + + // recognize which victim will be choosen + if (ownerTarget && ownerTarget->GetTypeId() == TYPEID_PLAYER) + { + if (!ownerTarget->HasBreakableByDamageCrowdControlAura(ownerTarget)) + me->Attack(ownerTarget, false); + } + else if (ownerTarget && (ownerTarget->GetTypeId() != TYPEID_PLAYER) && IsInThreatList(ownerTarget)) + { + if (!ownerTarget->HasBreakableByDamageCrowdControlAura(ownerTarget)) + me->Attack(ownerTarget, false); + } + else + Init(); + } + + if (uint32 spellId = events.ExecuteEvent()) + { + if (spellId == SPELL_MAGE_FROST_BOLT) + { + events.ScheduleEvent(SPELL_MAGE_FROST_BOLT, TIMER_MIRROR_IMAGE_FROST_BOLT); + DoCastVictim(spellId); + } + else if (spellId == SPELL_MAGE_FIRE_BLAST) + { + DoCastVictim(spellId); + events.ScheduleEvent(SPELL_MAGE_FIRE_BLAST, TIMER_MIRROR_IMAGE_FIRE_BLAST); + } + } + } + // Do not reload Creature templates on evade mode enter - prevent visual lost void EnterEvadeMode() override { @@ -68,6 +246,7 @@ class npc_pet_mage_mirror_image : public CreatureScript me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle(), MOTION_SLOT_ACTIVE); } + Init(); } }; diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index cd0052c24bc..88271dc7139 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -1343,6 +1343,15 @@ class spell_dk_raise_dead : public SpellScriptLoader GetCaster()->CastSpell(targets, spellInfo, NULL, TRIGGERED_FULL_MASK); } + void OverrideCooldown() + { + // Because the ghoul is summoned by one of triggered spells SendCooldownEvent is not sent for this spell + // but the client has locked it by itself so we need some link between this spell and the real spell summoning. + // Luckily such link already exists - spell category + // This starts infinite category cooldown which can later be used by SendCooldownEvent to send packet for this spell + GetCaster()->GetSpellHistory()->StartCooldown(GetSpellInfo(), 0, nullptr, true); + } + void Register() override { OnCheckCast += SpellCheckCastFn(spell_dk_raise_dead_SpellScript::CheckCast); @@ -1351,6 +1360,7 @@ class spell_dk_raise_dead : public SpellScriptLoader OnCast += SpellCastFn(spell_dk_raise_dead_SpellScript::ConsumeReagents); OnEffectHitTarget += SpellEffectFn(spell_dk_raise_dead_SpellScript::HandleRaiseDead, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); OnEffectHitTarget += SpellEffectFn(spell_dk_raise_dead_SpellScript::HandleRaiseDead, EFFECT_2, SPELL_EFFECT_DUMMY); + AfterCast += SpellCastFn(spell_dk_raise_dead_SpellScript::OverrideCooldown); } private: diff --git a/src/server/scripts/Spells/spell_holiday.cpp b/src/server/scripts/Spells/spell_holiday.cpp index a1b218010aa..e29f87a5ff9 100644 --- a/src/server/scripts/Spells/spell_holiday.cpp +++ b/src/server/scripts/Spells/spell_holiday.cpp @@ -277,6 +277,86 @@ class spell_hallow_end_tricky_treat : public SpellScriptLoader } }; +// Hallowed wands +enum HallowendData +{ + //wand spells + SPELL_HALLOWED_WAND_PIRATE = 24717, + SPELL_HALLOWED_WAND_NINJA = 24718, + SPELL_HALLOWED_WAND_LEPER_GNOME = 24719, + SPELL_HALLOWED_WAND_RANDOM = 24720, + SPELL_HALLOWED_WAND_SKELETON = 24724, + SPELL_HALLOWED_WAND_WISP = 24733, + SPELL_HALLOWED_WAND_GHOST = 24737, + SPELL_HALLOWED_WAND_BAT = 24741 +}; + +class spell_hallow_end_wand : public SpellScriptLoader +{ +public: + spell_hallow_end_wand() : SpellScriptLoader("spell_hallow_end_wand") {} + + class spell_hallow_end_wand_SpellScript : public SpellScript + { + PrepareSpellScript(spell_hallow_end_wand_SpellScript); + + bool Validate(SpellInfo const* /*spellEntry*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_PIRATE_COSTUME_MALE) || + !sSpellMgr->GetSpellInfo(SPELL_PIRATE_COSTUME_FEMALE) || + !sSpellMgr->GetSpellInfo(SPELL_NINJA_COSTUME_MALE) || + !sSpellMgr->GetSpellInfo(SPELL_NINJA_COSTUME_FEMALE) || + !sSpellMgr->GetSpellInfo(SPELL_LEPER_GNOME_COSTUME_MALE) || + !sSpellMgr->GetSpellInfo(SPELL_LEPER_GNOME_COSTUME_FEMALE) || + !sSpellMgr->GetSpellInfo(SPELL_GHOST_COSTUME_MALE) || + !sSpellMgr->GetSpellInfo(SPELL_GHOST_COSTUME_FEMALE)) + return false; + return true; + } + + void HandleScriptEffect() + { + Unit* caster = GetCaster(); + Unit* target = GetHitUnit(); + + uint32 spellId = 0; + uint8 gender = target->getGender(); + + switch (GetSpellInfo()->Id) + { + case SPELL_HALLOWED_WAND_LEPER_GNOME: + spellId = gender ? SPELL_LEPER_GNOME_COSTUME_FEMALE : SPELL_LEPER_GNOME_COSTUME_MALE; + break; + case SPELL_HALLOWED_WAND_PIRATE: + spellId = gender ? SPELL_PIRATE_COSTUME_FEMALE : SPELL_PIRATE_COSTUME_MALE; + break; + case SPELL_HALLOWED_WAND_GHOST: + spellId = gender ? SPELL_GHOST_COSTUME_FEMALE : SPELL_GHOST_COSTUME_MALE; + break; + case SPELL_HALLOWED_WAND_NINJA: + spellId = gender ? SPELL_NINJA_COSTUME_FEMALE : SPELL_NINJA_COSTUME_MALE; + break; + case SPELL_HALLOWED_WAND_RANDOM: + spellId = RAND(SPELL_HALLOWED_WAND_PIRATE, SPELL_HALLOWED_WAND_NINJA, SPELL_HALLOWED_WAND_LEPER_GNOME, SPELL_HALLOWED_WAND_SKELETON, SPELL_HALLOWED_WAND_WISP, SPELL_HALLOWED_WAND_GHOST, SPELL_HALLOWED_WAND_BAT); + break; + default: + return; + } + caster->CastSpell(target, spellId, true); + } + + void Register() override + { + AfterHit += SpellHitFn(spell_hallow_end_wand_SpellScript::HandleScriptEffect); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_hallow_end_wand_SpellScript(); + } +}; + enum PilgrimsBountyBuffFood { // Pilgrims Bounty Buff Food @@ -886,6 +966,7 @@ void AddSC_holiday_spell_scripts() new spell_hallow_end_trick(); new spell_hallow_end_trick_or_treat(); new spell_hallow_end_tricky_treat(); + new spell_hallow_end_wand(); // Pilgrims Bounty new spell_pilgrims_bounty_buff_food("spell_gen_slow_roasted_turkey", SPELL_WELL_FED_AP_TRIGGER); new spell_pilgrims_bounty_buff_food("spell_gen_cranberry_chutney", SPELL_WELL_FED_ZM_TRIGGER); diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index f2871871c30..0ca4112b288 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -480,7 +480,7 @@ class spell_hun_misdirection : public SpellScriptLoader void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEFAULT) + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEFAULT || !GetTarget()->HasAura(SPELL_HUNTER_MISDIRECTION_PROC)) GetTarget()->ResetRedirectThreat(); } diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index 717382a0e36..f0b6c0945c2 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -2509,7 +2509,7 @@ class spell_item_chicken_cover : public SpellScriptLoader if (!target->HasAura(SPELL_CHICKEN_NET) && (caster->GetQuestStatus(QUEST_CHICKEN_PARTY) == QUEST_STATUS_INCOMPLETE || caster->GetQuestStatus(QUEST_FLOWN_THE_COOP) == QUEST_STATUS_INCOMPLETE)) { caster->CastSpell(caster, SPELL_CAPTURE_CHICKEN_ESCAPE, true); - target->Kill(target); + target->KillSelf(); } } } diff --git a/src/server/scripts/World/duel_reset.cpp b/src/server/scripts/World/duel_reset.cpp index f08469d5bd5..9e720455692 100644 --- a/src/server/scripts/World/duel_reset.cpp +++ b/src/server/scripts/World/duel_reset.cpp @@ -17,6 +17,8 @@ #include "ScriptMgr.h" #include "Player.h" +#include "Pet.h" +#include "SpellInfo.h" class DuelResetScript : public PlayerScript { @@ -26,28 +28,89 @@ class DuelResetScript : public PlayerScript // Called when a duel starts (after 3s countdown) void OnDuelStart(Player* player1, Player* player2) override { + // Cooldowns reset if (sWorld->getBoolConfig(CONFIG_RESET_DUEL_COOLDOWNS)) { player1->GetSpellHistory()->SaveCooldownStateBeforeDuel(); player2->GetSpellHistory()->SaveCooldownStateBeforeDuel(); - player1->RemoveArenaSpellCooldowns(true); - player2->RemoveArenaSpellCooldowns(true); + + ResetSpellCooldowns(player1); + ResetSpellCooldowns(player2); + } + + // Health and mana reset + if (sWorld->getBoolConfig(CONFIG_RESET_DUEL_HEALTH_MANA)) + { + player1->SaveHealthBeforeDuel(); + player1->SetHealth(player1->GetMaxHealth()); + + player2->SaveHealthBeforeDuel(); + player2->SetHealth(player2->GetMaxHealth()); + + // check if player1 class uses mana + if (player1->getPowerType() == POWER_MANA || player1->getClass() == CLASS_DRUID) + { + player1->SaveManaBeforeDuel(); + player1->SetPower(POWER_MANA, player1->GetMaxPower(POWER_MANA)); + } + + // check if player2 class uses mana + if (player2->getPowerType() == POWER_MANA || player2->getClass() == CLASS_DRUID) + { + player2->SaveManaBeforeDuel(); + player2->SetPower(POWER_MANA, player2->GetMaxPower(POWER_MANA)); + } } } // Called when a duel ends - void OnDuelEnd(Player* winner, Player* loser, DuelCompleteType /*type*/) override + void OnDuelEnd(Player* winner, Player* loser, DuelCompleteType type) override { - if (sWorld->getBoolConfig(CONFIG_RESET_DUEL_COOLDOWNS)) + // do not reset anything if DUEL_INTERRUPTED or DUEL_FLED + if (type == DUEL_WON) { - winner->RemoveArenaSpellCooldowns(true); - loser->RemoveArenaSpellCooldowns(true); + // Cooldown restore + if (sWorld->getBoolConfig(CONFIG_RESET_DUEL_COOLDOWNS)) + { + + ResetSpellCooldowns(winner); + ResetSpellCooldowns(loser); - winner->GetSpellHistory()->RestoreCooldownStateAfterDuel(); - loser->GetSpellHistory()->RestoreCooldownStateAfterDuel(); + winner->GetSpellHistory()->RestoreCooldownStateAfterDuel(); + loser->GetSpellHistory()->RestoreCooldownStateAfterDuel(); + } + + // Health and mana restore + if (sWorld->getBoolConfig(CONFIG_RESET_DUEL_HEALTH_MANA)) + { + winner->RestoreHealthAfterDuel(); + loser->RestoreHealthAfterDuel(); + + // check if player1 class uses mana + if (winner->getPowerType() == POWER_MANA || winner->getClass() == CLASS_DRUID) + winner->RestoreManaAfterDuel(); + + // check if player2 class uses mana + if (loser->getPowerType() == POWER_MANA || loser->getClass() == CLASS_DRUID) + loser->RestoreManaAfterDuel(); + } } } + + static void ResetSpellCooldowns(Player* player) + { + // remove cooldowns on spells that have < 10 min CD and has no onHold + player->GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr) -> bool + { + SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); + return spellInfo->RecoveryTime < 10 * MINUTE * IN_MILLISECONDS && spellInfo->CategoryRecoveryTime < 10 * MINUTE * IN_MILLISECONDS && !itr->second.OnHold; + }, true); + + // pet cooldowns + if (Pet* pet = player->GetPet()) + pet->GetSpellHistory()->ResetAllCooldowns(); + } }; void AddSC_duel_reset() diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index df2b2e73c1c..8619a864998 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -1142,11 +1142,11 @@ BirthdayTime = 1222964635 # DATABASE_CHARACTER = 2, // Character database # DATABASE_WORLD = 4, // World database # -# Default: 0 - (All Disabled) +# Default: 7 - (All enabled) # 4 - (Enable world only) -# 7 - (All enabled) +# 0 - (All disabled) -Updates.EnableDatabases = 0 +Updates.EnableDatabases = 7 # # Updates.SourcePath @@ -2640,6 +2640,13 @@ HonorPointsAfterDuel = 0 ResetDuelCooldowns = 0 +# ResetDuelHealthMana +# Description: Reset health and mana before duel starts and restore them when duel ends. +# Default: 0 - (Disabled) +# 1 - (Enabled) + +ResetDuelHealthMana = 0 + # # AlwaysMaxWeaponSkill # Description: Players will automatically gain max weapon/defense skill when logging in, diff --git a/src/tools/map_extractor/CMakeLists.txt b/src/tools/map_extractor/CMakeLists.txt index 87d68cc7a2f..b10956b3264 100644 --- a/src/tools/map_extractor/CMakeLists.txt +++ b/src/tools/map_extractor/CMakeLists.txt @@ -9,13 +9,16 @@ # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -file(GLOB_RECURSE sources *.cpp *.h) +file(GLOB_RECURSE mapextractor_SRCS *.cpp *.h) set(include_Dirs - ${CMAKE_SOURCE_DIR}/src/server/shared - ${CMAKE_SOURCE_DIR}/dep/libmpq - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/loadlib + ${CMAKE_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/dep/cppformat + ${CMAKE_SOURCE_DIR}/dep/libmpq + ${CMAKE_SOURCE_DIR}/src/common + ${CMAKE_SOURCE_DIR}/src/common/Utilities + ${CMAKE_SOURCE_DIR}/src/server/shared + ${CMAKE_CURRENT_SOURCE_DIR}/loadlib ) if( WIN32 ) @@ -28,13 +31,16 @@ endif() include_directories(${include_Dirs}) add_executable(mapextractor - ${sources} + ${mapextractor_SRCS} ) target_link_libraries(mapextractor + common + format mpq ${BZIP2_LIBRARIES} ${ZLIB_LIBRARIES} + ${Boost_LIBRARIES} ) if( UNIX ) diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index dcaa3ba0a76..c0497a1cefb 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -22,36 +22,17 @@ #include <deque> #include <set> #include <cstdlib> - -#ifdef _WIN32 -#include "direct.h" -#else -#include <sys/stat.h> -#include <unistd.h> -#endif +#include <fstream> #include "dbcfile.h" #include "mpq_libmpq04.h" +#include "StringFormat.h" #include "adt.h" #include "wdt.h" -#include <fcntl.h> - -#if defined( __GNUC__ ) - #define _open open - #define _close close - #ifndef O_BINARY - #define O_BINARY 0 - #endif -#else - #include <io.h> -#endif - -#ifdef O_LARGEFILE - #define OPEN_FLAGS (O_RDONLY | O_BINARY | O_LARGEFILE) -#else - #define OPEN_FLAGS (O_RDONLY | O_BINARY) -#endif + +#include <boost/filesystem.hpp> + extern ArchiveSet gOpenArchives; typedef struct @@ -106,37 +87,14 @@ const char *CONF_mpq_list[]={ static const char* const langs[] = {"enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" }; #define LANG_COUNT 12 -void CreateDir( const std::string& Path ) -{ - if(chdir(Path.c_str()) == 0) - { - chdir("../"); - return; - } - - int ret; - #ifdef _WIN32 - ret = _mkdir( Path.c_str()); - #else - ret = mkdir( Path.c_str(), 0777 ); - #endif - if (ret != 0) - { - printf("Fatal Error: Could not create directory %s check your permissions", Path.c_str()); - exit(1); - } -} - -bool FileExists( const char* FileName ) +void CreateDir(boost::filesystem::path const& path) { - int fp = _open(FileName, OPEN_FLAGS); - if(fp != -1) - { - _close(fp); - return true; - } + namespace fs = boost::filesystem; + if (fs::exists(path)) + return; - return false; + if (!fs::create_directory(path)) + throw new std::runtime_error("Unable to create directory" + path.string()); } void Usage(char* prg) @@ -207,7 +165,7 @@ void HandleArgs(int argc, char * arg[]) uint32 ReadBuild(int locale) { // include build info file also - std::string filename = std::string("component.wow-")+langs[locale]+".txt"; + std::string filename = Trinity::StringFormat("component.wow-%s.txt", langs[locale]); //printf("Read %s file... ", filename.c_str()); MPQFile m(filename.c_str()); @@ -269,7 +227,7 @@ uint32 ReadMapDBC() strncpy(map_ids[x].name, map_name, max_map_name_length); map_ids[x].name[max_map_name_length - 1] = '\0'; } - printf("Done! (%u maps loaded)\n", (uint32)map_count); + printf("Done! (" SZFMTD "maps loaded)\n", map_count); return map_count; } @@ -294,7 +252,7 @@ void ReadAreaTableDBC() maxAreaId = dbc.getMaxId(); - printf("Done! (%u areas loaded)\n", (uint32)area_count); + printf("Done! (" SZFMTD " areas loaded)\n", area_count); } void ReadLiquidTypeTableDBC() @@ -315,7 +273,7 @@ void ReadLiquidTypeTableDBC() for(uint32 x = 0; x < liqTypeCount; ++x) LiqType[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3); - printf("Done! (%u LiqTypes loaded)\n", (uint32)liqTypeCount); + printf("Done! (" SZFMTD " LiqTypes loaded)\n", liqTypeCount); } // @@ -414,17 +372,17 @@ uint8 liquid_flags[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]; bool liquid_show[ADT_GRID_SIZE][ADT_GRID_SIZE]; float liquid_height[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1]; -bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, uint32 build) +bool ConvertADT(std::string const& inputPath, std::string const& outputPath, int /*cell_y*/, int /*cell_x*/, uint32 build) { ADT_file adt; - if (!adt.loadFile(filename)) + if (!adt.loadFile(inputPath)) return false; adt_MCIN *cells = adt.a_grid->getMCIN(); if (!cells) { - printf("Can't find cells in '%s'\n", filename); + printf("Can't find cells in '%s'\n", inputPath.c_str()); return false; } @@ -434,8 +392,8 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, // Prepare map header map_fileheader map; - map.mapMagic = *(uint32 const*)MAP_MAGIC; - map.versionMagic = *(uint32 const*)MAP_VERSION_MAGIC; + map.mapMagic = *reinterpret_cast<uint32 const*>(MAP_MAGIC); + map.versionMagic = *reinterpret_cast<uint32 const*>(MAP_VERSION_MAGIC); map.buildMagic = build; // Get area flags data @@ -452,7 +410,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, area_flags[i][j] = areas[areaid]; continue; } - printf("File: %s\nCan't find area flag for areaid %u [%d, %d].\n", filename, areaid, cell->ix, cell->iy); + printf("File: %s\nCan't find area flag for areaid %u [%d, %d].\n", inputPath.c_str(), areaid, cell->ix, cell->iy); } area_flags[i][j] = 0xffff; } @@ -478,7 +436,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, map.areaMapSize = sizeof(map_areaHeader); map_areaHeader areaHeader; - areaHeader.fourcc = *(uint32 const*)MAP_AREA_MAGIC; + areaHeader.fourcc = *reinterpret_cast<uint32 const*>(MAP_AREA_MAGIC); areaHeader.flags = 0; if (fullAreaData) { @@ -488,7 +446,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, else { areaHeader.flags |= MAP_AREA_NO_AREA; - areaHeader.gridArea = (uint16)areaflag; + areaHeader.gridArea = static_cast<uint16>(areaflag); } // @@ -607,7 +565,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, map.heightMapSize = sizeof(map_heightHeader); map_heightHeader heightHeader; - heightHeader.fourcc = *(uint32 const*)MAP_HEIGHT_MAGIC; + heightHeader.fourcc = *reinterpret_cast<uint32 const*>(MAP_HEIGHT_MAGIC); heightHeader.flags = 0; heightHeader.gridHeight = minHeight; heightHeader.gridMaxHeight = maxHeight; @@ -763,7 +721,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, case LIQUID_TYPE_MAGMA: liquid_flags[i][j] |= MAP_LIQUID_TYPE_MAGMA; break; case LIQUID_TYPE_SLIME: liquid_flags[i][j] |= MAP_LIQUID_TYPE_SLIME; break; default: - printf("\nCan't find Liquid type %u for map %s\nchunk %d,%d\n", h->liquidType, filename, i, j); + printf("\nCan't find Liquid type %u for map %s\nchunk %d,%d\n", h->liquidType, inputPath.c_str(), i, j); break; } // Dark water detect @@ -848,7 +806,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, } map.liquidMapOffset = map.heightMapOffset + map.heightMapSize; map.liquidMapSize = sizeof(map_liquidHeader); - liquidHeader.fourcc = *(uint32 const*)MAP_LIQUID_MAGIC; + liquidHeader.fourcc = *reinterpret_cast<uint32 const*>(MAP_LIQUID_MAGIC); liquidHeader.flags = 0; liquidHeader.liquidType = 0; liquidHeader.offsetX = minX; @@ -906,69 +864,72 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, map.holesSize = 0; // Ok all data prepared - store it - FILE* output = fopen(filename2, "wb"); - if (!output) + + std::ofstream outFile(outputPath, std::ofstream::out | std::ofstream::binary); + if (!outFile) { - printf("Can't create the output file '%s'\n", filename2); + printf("Can't create the output file '%s'\n", outputPath.c_str()); return false; } - fwrite(&map, sizeof(map), 1, output); + + outFile.write(reinterpret_cast<const char*>(&map), sizeof(map)); // Store area data - fwrite(&areaHeader, sizeof(areaHeader), 1, output); + outFile.write(reinterpret_cast<const char*>(&areaHeader), sizeof(areaHeader)); if (!(areaHeader.flags&MAP_AREA_NO_AREA)) - fwrite(area_flags, sizeof(area_flags), 1, output); + outFile.write(reinterpret_cast<const char*>(area_flags), sizeof(area_flags)); // Store height data - fwrite(&heightHeader, sizeof(heightHeader), 1, output); + outFile.write(reinterpret_cast<const char*>(&heightHeader), sizeof(heightHeader)); if (!(heightHeader.flags & MAP_HEIGHT_NO_HEIGHT)) { if (heightHeader.flags & MAP_HEIGHT_AS_INT16) { - fwrite(uint16_V9, sizeof(uint16_V9), 1, output); - fwrite(uint16_V8, sizeof(uint16_V8), 1, output); + outFile.write(reinterpret_cast<const char*>(uint16_V9), sizeof(uint16_V9)); + outFile.write(reinterpret_cast<const char*>(uint16_V8), sizeof(uint16_V8)); } else if (heightHeader.flags & MAP_HEIGHT_AS_INT8) { - fwrite(uint8_V9, sizeof(uint8_V9), 1, output); - fwrite(uint8_V8, sizeof(uint8_V8), 1, output); + outFile.write(reinterpret_cast<const char*>(uint8_V9), sizeof(uint8_V9)); + outFile.write(reinterpret_cast<const char*>(uint8_V8), sizeof(uint8_V8)); } else { - fwrite(V9, sizeof(V9), 1, output); - fwrite(V8, sizeof(V8), 1, output); + outFile.write(reinterpret_cast<const char*>(V9), sizeof(V9)); + outFile.write(reinterpret_cast<const char*>(V8), sizeof(V8)); } } // Store liquid data if need if (map.liquidMapOffset) { - fwrite(&liquidHeader, sizeof(liquidHeader), 1, output); + outFile.write(reinterpret_cast<const char*>(&liquidHeader), sizeof(liquidHeader)); + if (!(liquidHeader.flags&MAP_LIQUID_NO_TYPE)) { - fwrite(liquid_entry, sizeof(liquid_entry), 1, output); - fwrite(liquid_flags, sizeof(liquid_flags), 1, output); + outFile.write(reinterpret_cast<const char*>(liquid_entry), sizeof(liquid_entry)); + outFile.write(reinterpret_cast<const char*>(liquid_flags), sizeof(liquid_flags)); } + if (!(liquidHeader.flags&MAP_LIQUID_NO_HEIGHT)) { - for (int y=0; y<liquidHeader.height;y++) - fwrite(&liquid_height[y+liquidHeader.offsetY][liquidHeader.offsetX], sizeof(float), liquidHeader.width, output); + for (int y = 0; y < liquidHeader.height; y++) + outFile.write(reinterpret_cast<const char*>(&liquid_height[y + liquidHeader.offsetY][liquidHeader.offsetX]), sizeof(float) * liquidHeader.width); } } // store hole data if (hasHoles) - fwrite(holes, map.holesSize, 1, output); - - fclose(output); + outFile.write(reinterpret_cast<const char*>(holes), map.holesSize); + outFile.close(); return true; } void ExtractMapsFromMpq(uint32 build) { - char mpq_filename[1024]; - char output_filename[1024]; - char mpq_map_name[1024]; + std::string mpqFileName; + std::string outputFileName; + std::string mpqMapName; printf("Extracting maps...\n"); @@ -986,9 +947,10 @@ void ExtractMapsFromMpq(uint32 build) { printf("Extract %s (%d/%u) \n", map_ids[z].name, z+1, map_count); // Loadup map grid data - sprintf(mpq_map_name, "World\\Maps\\%s\\%s.wdt", map_ids[z].name, map_ids[z].name); + + mpqMapName = Trinity::StringFormat("World\\Maps\\%s\\%s.wdt", map_ids[z].name, map_ids[z].name); WDT_file wdt; - if (!wdt.loadFile(mpq_map_name, false)) + if (!wdt.loadFile(mpqMapName, false)) { // printf("Error loading %s map wdt data\n", map_ids[z].name); continue; @@ -1000,9 +962,10 @@ void ExtractMapsFromMpq(uint32 build) { if (!wdt.main->adt_list[y][x].exist) continue; - sprintf(mpq_filename, "World\\Maps\\%s\\%s_%u_%u.adt", map_ids[z].name, map_ids[z].name, x, y); - sprintf(output_filename, "%s/maps/%03u%02u%02u.map", output_path, map_ids[z].id, y, x); - ConvertADT(mpq_filename, output_filename, y, x, build); + + mpqFileName = Trinity::StringFormat("World\\Maps\\%s\\%s_%u_%u.adt", map_ids[z].name, map_ids[z].name, x, y); + outputFileName = Trinity::StringFormat("%s/maps/%03u%02u%02u.map", output_path, map_ids[z].id, y, x); + ConvertADT(mpqFileName, outputFileName, y, x, build); } // draw progress bar printf("Processing........................%d%%\r", (100 * (y+1)) / WDT_MAP_SIZE); @@ -1038,9 +1001,9 @@ void ExtractDBCFiles(int locale, bool basicLocale) // get DBC file list for(ArchiveSet::iterator i = gOpenArchives.begin(); i != gOpenArchives.end();++i) { - vector<string> files; + std::vector<std::string> files; (*i)->GetFileListTo(files); - for (vector<string>::iterator iter = files.begin(); iter != files.end(); ++iter) + for (std::vector<std::string>::iterator iter = files.begin(); iter != files.end(); ++iter) if (iter->rfind(".dbc") == iter->length() - strlen(".dbc")) dbcfiles.insert(*iter); } @@ -1057,20 +1020,20 @@ void ExtractDBCFiles(int locale, bool basicLocale) // extract Build info file { - string mpq_name = std::string("component.wow-") + langs[locale] + ".txt"; - string filename = path + mpq_name; + std::string mpq_name = std::string("component.wow-") + langs[locale] + ".txt"; + std::string filename = path + mpq_name; ExtractFile(mpq_name.c_str(), filename); } // extract DBCs uint32 count = 0; - for (set<string>::iterator iter = dbcfiles.begin(); iter != dbcfiles.end(); ++iter) + for (std::set<std::string>::iterator iter = dbcfiles.begin(); iter != dbcfiles.end(); ++iter) { - string filename = path; + std::string filename = path; filename += (iter->c_str() + strlen("DBFilesClient\\")); - if(FileExists(filename.c_str())) + if (boost::filesystem::exists(filename)) continue; if (ExtractFile(iter->c_str(), filename)) @@ -1081,32 +1044,31 @@ void ExtractDBCFiles(int locale, bool basicLocale) void LoadLocaleMPQFiles(int const locale) { - char filename[512]; + std::string fileName = Trinity::StringFormat("%s/Data/%s/locale-%s.MPQ", input_path, langs[locale], langs[locale]); - sprintf(filename,"%s/Data/%s/locale-%s.MPQ", input_path, langs[locale], langs[locale]); - new MPQArchive(filename); + new MPQArchive(fileName.c_str()); for(int i = 1; i < 5; ++i) { - char ext[3] = ""; - if(i > 1) - sprintf(ext, "-%i", i); + std::string ext; + if (i > 1) + ext = Trinity::StringFormat("-%i", i); - sprintf(filename,"%s/Data/%s/patch-%s%s.MPQ", input_path, langs[locale], langs[locale], ext); - if(FileExists(filename)) - new MPQArchive(filename); + fileName = Trinity::StringFormat("%s/Data/%s/patch-%s%s.MPQ", input_path, langs[locale], langs[locale], ext.c_str()); + if (boost::filesystem::exists(fileName)) + new MPQArchive(fileName.c_str()); } } void LoadCommonMPQFiles() { - char filename[512]; + std::string fileName; int count = sizeof(CONF_mpq_list)/sizeof(char*); for(int i = 0; i < count; ++i) { - sprintf(filename, "%s/Data/%s", input_path, CONF_mpq_list[i]); - if(FileExists(filename)) - new MPQArchive(filename); + fileName = Trinity::StringFormat("%s/Data/%s", input_path, CONF_mpq_list[i]); + if (boost::filesystem::exists(fileName)) + new MPQArchive(fileName.c_str()); } } @@ -1128,9 +1090,8 @@ int main(int argc, char * arg[]) for (int i = 0; i < LANG_COUNT; i++) { - char tmp1[512]; - sprintf(tmp1, "%s/Data/%s/locale-%s.MPQ", input_path, langs[i], langs[i]); - if (FileExists(tmp1)) + std::string filename = Trinity::StringFormat("%s/Data/%s/locale-%s.MPQ", input_path, langs[i], langs[i]); + if (boost::filesystem::exists(filename)) { printf("Detected locale: %s\n", langs[i]); diff --git a/src/tools/map_extractor/loadlib.cpp b/src/tools/map_extractor/loadlib.cpp index 936cdb72cfd..2f31b472b56 100644 --- a/src/tools/map_extractor/loadlib.cpp +++ b/src/tools/map_extractor/loadlib.cpp @@ -38,14 +38,14 @@ FileLoader::~FileLoader() free(); } -bool FileLoader::loadFile(char *filename, bool log) +bool FileLoader::loadFile(std::string const& fileName, bool log) { free(); - MPQFile mf(filename); + MPQFile mf(fileName.c_str()); if(mf.isEof()) { if (log) - printf("No such file %s\n", filename); + printf("No such file %s\n", fileName.c_str()); return false; } @@ -57,7 +57,7 @@ bool FileLoader::loadFile(char *filename, bool log) if (prepareLoadedData()) return true; - printf("Error loading %s", filename); + printf("Error loading %s", fileName.c_str()); mf.close(); free(); return false; diff --git a/src/tools/map_extractor/loadlib/loadlib.h b/src/tools/map_extractor/loadlib/loadlib.h index a0b62a85983..6547704d885 100644 --- a/src/tools/map_extractor/loadlib/loadlib.h +++ b/src/tools/map_extractor/loadlib/loadlib.h @@ -19,31 +19,9 @@ #ifndef LOAD_LIB_H #define LOAD_LIB_H -#ifdef _WIN32 -typedef __int64 int64; -typedef __int32 int32; -typedef __int16 int16; -typedef __int8 int8; -typedef unsigned __int64 uint64; -typedef unsigned __int32 uint32; -typedef unsigned __int16 uint16; -typedef unsigned __int8 uint8; -#else -#include <stdint.h> -#ifndef uint64_t -#ifdef __linux__ -#include <linux/types.h> -#endif -#endif -typedef int64_t int64; -typedef int32_t int32; -typedef int16_t int16; -typedef int8_t int8; -typedef uint64_t uint64; -typedef uint32_t uint32; -typedef uint16_t uint16; -typedef uint8_t uint8; -#endif +#include "Define.h" + +#include <string> #define FILE_FORMAT_VERSION 18 @@ -79,7 +57,7 @@ public: file_MVER *version; FileLoader(); ~FileLoader(); - bool loadFile(char *filename, bool log = true); + bool loadFile(std::string const& fileName, bool log = true); virtual void free(); }; diff --git a/src/tools/map_extractor/mpq_libmpq04.h b/src/tools/map_extractor/mpq_libmpq04.h index c6fe36a8221..b9b332f95b0 100644 --- a/src/tools/map_extractor/mpq_libmpq04.h +++ b/src/tools/map_extractor/mpq_libmpq04.h @@ -27,8 +27,6 @@ #include <iostream> #include <deque> -using namespace std; - class MPQArchive { @@ -39,7 +37,7 @@ public: ~MPQArchive() { close(); } void close(); - void GetFileListTo(vector<string>& filelist) { + void GetFileListTo(std::vector<std::string>& filelist) { uint32_t filenum; if(libmpq__file_number(mpq_a, "(listfile)", &filenum)) return; libmpq__off_t size, transferred; @@ -58,7 +56,7 @@ public: while ((token != NULL) && (counter < size)) { //cout << token << endl; token[strlen(token) - 1] = 0; - string s = token; + std::string s = token; filelist.push_back(s); counter += strlen(token) + 2; token = strtok(NULL, seps); diff --git a/src/tools/mmaps_generator/IntermediateValues.h b/src/tools/mmaps_generator/IntermediateValues.h index 95a651a2df8..580e9e43139 100644 --- a/src/tools/mmaps_generator/IntermediateValues.h +++ b/src/tools/mmaps_generator/IntermediateValues.h @@ -22,7 +22,6 @@ #include "PathCommon.h" #include "TerrainBuilder.h" #include "Recast.h" -#include "DetourNavMesh.h" namespace MMAP { diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 69ca5297024..0c41be65cf7 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -15,17 +15,15 @@ * You should have received a copy of the GNU General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <limits.h> #include "PathCommon.h" #include "MapBuilder.h" - #include "MapTree.h" -#include "ModelInstance.h" - #include "DetourNavMeshBuilder.h" #include "DetourNavMesh.h" -#include "DetourCommon.h" +#include "IntermediateValues.h" + +#include <limits.h> #define MMAP_MAGIC 0x4d4d4150 // 'MMAP' #define MMAP_VERSION 5 @@ -164,7 +162,7 @@ namespace MMAP { while (1) { - uint32 mapId; + uint32 mapId = 0; _queue.WaitAndPop(mapId); @@ -215,12 +213,14 @@ namespace MMAP } /**************************************************************************/ - void MapBuilder::getGridBounds(uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY) + void MapBuilder::getGridBounds(uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY) const { - maxX = INT_MAX; - maxY = INT_MAX; - minX = INT_MIN; - minY = INT_MIN; + // min and max are initialized to invalid values so the caller iterating the [min, max] range + // will never enter the loop unless valid min/max values are found + maxX = 0; + maxY = 0; + minX = std::numeric_limits<uint32>::max(); + minY = std::numeric_limits<uint32>::max(); float bmin[3] = { 0, 0, 0 }; float bmax[3] = { 0, 0, 0 }; diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h index ced03d1dde8..432a0ee7489 100644 --- a/src/tools/mmaps_generator/MapBuilder.h +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -19,20 +19,18 @@ #ifndef _MAP_BUILDER_H #define _MAP_BUILDER_H -#include <vector> -#include <set> -#include <map> -#include <list> -#include <atomic> -#include <thread> - #include "TerrainBuilder.h" -#include "IntermediateValues.h" #include "Recast.h" #include "DetourNavMesh.h" #include "ProducerConsumerQueue.h" +#include <vector> +#include <set> +#include <list> +#include <atomic> +#include <thread> + using namespace VMAP; namespace MMAP @@ -120,7 +118,7 @@ namespace MMAP void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax); - void getGridBounds(uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY); + void getGridBounds(uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY) const; bool shouldSkipMap(uint32 mapID); bool isTransportMap(uint32 mapID); diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h index 9451e9d03ba..aa9591fba22 100644 --- a/src/tools/mmaps_generator/PathCommon.h +++ b/src/tools/mmaps_generator/PathCommon.h @@ -19,11 +19,10 @@ #ifndef _MMAP_COMMON_H #define _MMAP_COMMON_H -#include <string> -#include <vector> - #include "Common.h" +#include <vector> + #ifndef _WIN32 #include <stddef.h> #include <dirent.h> diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index 9043627994b..e525f24fced 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -764,12 +764,12 @@ namespace MMAP } uint32 liqOffset = meshData.liquidVerts.size() / 3; - for (uint32 i = 0; i < liqVerts.size(); ++i) - meshData.liquidVerts.append(liqVerts[i].y, liqVerts[i].z, liqVerts[i].x); + for (uint32 j = 0; j < liqVerts.size(); ++j) + meshData.liquidVerts.append(liqVerts[j].y, liqVerts[j].z, liqVerts[j].x); - for (uint32 i = 0; i < liqTris.size() / 3; ++i) + for (uint32 j = 0; j < liqTris.size() / 3; ++j) { - meshData.liquidTris.append(liqTris[i*3+1] + liqOffset, liqTris[i*3+2] + liqOffset, liqTris[i*3] + liqOffset); + meshData.liquidTris.append(liqTris[j*3+1] + liqOffset, liqTris[j*3+2] + liqOffset, liqTris[j*3] + liqOffset); meshData.liquidType.append(type); } } diff --git a/src/tools/mmaps_generator/TerrainBuilder.h b/src/tools/mmaps_generator/TerrainBuilder.h index 6c66ae45f46..f305bf0bd48 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.h +++ b/src/tools/mmaps_generator/TerrainBuilder.h @@ -81,11 +81,13 @@ namespace MMAP TerrainBuilder(bool skipLiquid); ~TerrainBuilder(); + TerrainBuilder(const TerrainBuilder &tb) = delete; + void loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData); bool loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData); void loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, const char* offMeshFilePath); - bool usesLiquids() { return !m_skipLiquid; } + bool usesLiquids() const { return !m_skipLiquid; } // vert and triangle methods static void transform(std::vector<G3D::Vector3> &original, std::vector<G3D::Vector3> &transformed, @@ -104,9 +106,6 @@ namespace MMAP /// Controls whether liquids are loaded bool m_skipLiquid; - /// Load the map terrain from file - bool loadHeightMap(uint32 mapID, uint32 tileX, uint32 tileY, G3D::Array<float> &vertices, G3D::Array<int> &triangles, Spot portion); - /// Get the vector coordinate for a specific position void getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v); @@ -121,10 +120,6 @@ namespace MMAP /// Get the liquid type for a specific position uint8 getLiquidType(int square, const uint8 liquid_type[16][16]); - - // hide parameterless and copy constructor - TerrainBuilder(); - TerrainBuilder(const TerrainBuilder &tb); }; } diff --git a/src/tools/vmap4_extractor/adtfile.cpp b/src/tools/vmap4_extractor/adtfile.cpp index 557511f6d1e..3a8b3495655 100644 --- a/src/tools/vmap4_extractor/adtfile.cpp +++ b/src/tools/vmap4_extractor/adtfile.cpp @@ -86,11 +86,11 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY) uint32 size; - string xMap; - string yMap; + std::string xMap; + std::string yMap; Adtfilename.erase(Adtfilename.find(".adt"),4); - string TempMapNumber; + std::string TempMapNumber; TempMapNumber = Adtfilename.substr(Adtfilename.length()-6,6); xMap = TempMapNumber.substr(TempMapNumber.find("_")+1,(TempMapNumber.find_last_of("_")-1) - (TempMapNumber.find("_"))); yMap = TempMapNumber.substr(TempMapNumber.find_last_of("_")+1,(TempMapNumber.length()) - (TempMapNumber.find_last_of("_"))); @@ -134,7 +134,7 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY) ADT.read(buf, size); char *p=buf; int t=0; - ModelInstansName = new string[size]; + ModelInstansName = new std::string[size]; while (p<buf+size) { fixnamen(p,strlen(p)); @@ -143,7 +143,7 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY) ModelInstansName[t++] = s; - string path(p); + std::string path(p); ExtractSingleModel(path); p = p+strlen(p)+1; diff --git a/src/tools/vmap4_extractor/mpq_libmpq04.h b/src/tools/vmap4_extractor/mpq_libmpq04.h index 6196285627d..4c8b4d376ca 100644 --- a/src/tools/vmap4_extractor/mpq_libmpq04.h +++ b/src/tools/vmap4_extractor/mpq_libmpq04.h @@ -21,14 +21,12 @@ #include "loadlib/loadlib.h" #include "libmpq/mpq.h" + #include <string.h> -#include <ctype.h> +#include <string> #include <vector> -#include <iostream> #include <deque> -using namespace std; - class MPQArchive { @@ -38,7 +36,7 @@ public: MPQArchive(const char* filename); ~MPQArchive() { close(); } - void GetFileListTo(vector<string>& filelist) { + void GetFileListTo(std::vector<std::string>& filelist) { uint32_t filenum; if(libmpq__file_number(mpq_a, "(listfile)", &filenum)) return; libmpq__off_t size, transferred; @@ -57,7 +55,7 @@ public: while ((token != NULL) && (counter < size)) { //cout << token << endl; token[strlen(token) - 1] = 0; - string s = token; + std::string s = token; filelist.push_back(s); counter += strlen(token) + 2; token = strtok(NULL, seps); @@ -78,9 +76,8 @@ class MPQFile char *buffer; libmpq__off_t pointer,size; - // disable copying - MPQFile(const MPQFile& /*f*/) {} - void operator=(const MPQFile& /*f*/) {} + MPQFile(const MPQFile& /*f*/) = delete; + void operator=(const MPQFile& /*f*/) = delete; public: MPQFile(const char* filename); // filenames are not case sensitive diff --git a/src/tools/vmap4_extractor/vmapexport.cpp b/src/tools/vmap4_extractor/vmapexport.cpp index 7a12897563e..78d6e86358f 100644 --- a/src/tools/vmap4_extractor/vmapexport.cpp +++ b/src/tools/vmap4_extractor/vmapexport.cpp @@ -17,14 +17,15 @@ */ #define _CRT_SECURE_NO_DEPRECATE -#include <cstdio> -#include <iostream> -#include <vector> -#include <list> -#include <errno.h> + +#include "adtfile.h" +#include "wdtfile.h" +#include "dbcfile.h" +#include "wmo.h" +#include "mpq_libmpq04.h" +#include "vmapexport.h" #ifdef WIN32 - #include <Windows.h> #include <sys/stat.h> #include <direct.h> #define mkdir _mkdir @@ -32,23 +33,14 @@ #include <sys/stat.h> #endif +#include <cstdio> +#include <iostream> +#include <vector> +#include <errno.h> + #undef min #undef max -//#pragma warning(disable : 4505) -//#pragma comment(lib, "Winmm.lib") - -#include <map> - -//From Extractor -#include "adtfile.h" -#include "wdtfile.h" -#include "dbcfile.h" -#include "wmo.h" -#include "mpq_libmpq04.h" - -#include "vmapexport.h" - //------------------------------------------------------------------------------ // Defines @@ -129,12 +121,12 @@ bool ExtractWmo() for (ArchiveSet::const_iterator ar_itr = gOpenArchives.begin(); ar_itr != gOpenArchives.end() && success; ++ar_itr) { - vector<string> filelist; + std::vector<std::string> filelist; (*ar_itr)->GetFileListTo(filelist); - for (vector<string>::iterator fname = filelist.begin(); fname != filelist.end() && success; ++fname) + for (std::vector<std::string>::iterator fname = filelist.begin(); fname != filelist.end() && success; ++fname) { - if (fname->find(".wmo") != string::npos) + if (fname->find(".wmo") != std::string::npos) success = ExtractSingleWmo(*fname); } } @@ -203,7 +195,7 @@ bool ExtractSingleWmo(std::string& fname) sprintf(groupFileName, "%s_%03u.wmo", temp, i); //printf("Trying to open groupfile %s\n",groupFileName); - string s = groupFileName; + std::string s = groupFileName; WMOGroup fgroup(s); if(!fgroup.open()) { @@ -305,7 +297,7 @@ bool fillArchiveNameVector(std::vector<std::string>& pArchiveNames) printf("\nGame path: %s\n", input_path); char path[512]; - string in_path(input_path); + std::string in_path(input_path); std::vector<std::string> locales, searchLocales; searchLocales.push_back("enGB"); @@ -345,10 +337,10 @@ bool fillArchiveNameVector(std::vector<std::string>& pArchiveNames) } // open expansion and common files - pArchiveNames.push_back(input_path + string("common.MPQ")); - pArchiveNames.push_back(input_path + string("common-2.MPQ")); - pArchiveNames.push_back(input_path + string("expansion.MPQ")); - pArchiveNames.push_back(input_path + string("lichking.MPQ")); + pArchiveNames.push_back(input_path + std::string("common.MPQ")); + pArchiveNames.push_back(input_path + std::string("common-2.MPQ")); + pArchiveNames.push_back(input_path + std::string("expansion.MPQ")); + pArchiveNames.push_back(input_path + std::string("lichking.MPQ")); // now, scan for the patch levels in the core dir printf("Scanning patch levels from data directory.\n"); diff --git a/src/tools/vmap4_extractor/wdtfile.cpp b/src/tools/vmap4_extractor/wdtfile.cpp index 877f49ce371..4e0b7b97705 100644 --- a/src/tools/vmap4_extractor/wdtfile.cpp +++ b/src/tools/vmap4_extractor/wdtfile.cpp @@ -19,6 +19,7 @@ #include "vmapexport.h" #include "wdtfile.h" #include "adtfile.h" + #include <cstdio> char * wdtGetPlainName(char * FileName) @@ -30,7 +31,7 @@ char * wdtGetPlainName(char * FileName) return FileName; } -WDTFile::WDTFile(char* file_name, char* file_name1) : WDT(file_name), gWmoInstansName(NULL), gnWMO(0) +WDTFile::WDTFile(char* file_name, char* file_name1) : gWmoInstansName(NULL), gnWMO(0), WDT(file_name) { filename.append(file_name1,strlen(file_name1)); } @@ -77,7 +78,7 @@ bool WDTFile::init(char* /*map_id*/, unsigned int mapID) WDT.read(buf, size); char *p=buf; int q = 0; - gWmoInstansName = new string[size]; + gWmoInstansName = new std::string[size]; while (p < buf + size) { char* s=wdtGetPlainName(p); diff --git a/src/tools/vmap4_extractor/wdtfile.h b/src/tools/vmap4_extractor/wdtfile.h index 22702133b95..81e84b36d1e 100644 --- a/src/tools/vmap4_extractor/wdtfile.h +++ b/src/tools/vmap4_extractor/wdtfile.h @@ -20,26 +20,25 @@ #define WDTFILE_H #include "mpq_libmpq04.h" -#include "wmo.h" #include <string> -#include "stdlib.h" class ADTFile; class WDTFile { -private: - MPQFile WDT; - string filename; public: WDTFile(char* file_name, char* file_name1); ~WDTFile(void); + bool init(char* map_id, unsigned int mapID); + ADTFile* GetMap(int x, int z); - string* gWmoInstansName; + std::string* gWmoInstansName; int gnWMO; - ADTFile* GetMap(int x, int z); +private: + MPQFile WDT; + std::string filename; }; #endif diff --git a/src/tools/vmap4_extractor/wmo.cpp b/src/tools/vmap4_extractor/wmo.cpp index f6f59bbc475..80dfbb97c5a 100644 --- a/src/tools/vmap4_extractor/wmo.cpp +++ b/src/tools/vmap4_extractor/wmo.cpp @@ -19,16 +19,14 @@ #include "vmapexport.h" #include "wmo.h" #include "vec3d.h" +#include "mpq_libmpq04.h" + #include <cstdio> #include <cstdlib> #include <cassert> -#include <map> -#include <fstream> #undef min #undef max -#include "mpq_libmpq04.h" -using namespace std; extern uint16 *LiqType; WMORoot::WMORoot(std::string &filename) |