Merge branch '3.3.5' into 4.3.4
Conflicts: .gitattributes dep/PackageList.txt sql/base/characters_database.sql sql/updates/world/2015_06_26_01_world_2015_05_15_00.sql sql/updates/world/2015_07_01_03_world_335.sql src/server/game/DungeonFinding/LFGMgr.cpp src/server/game/Entities/GameObject/GameObject.h src/server/game/Entities/Player/Player.cpp src/server/game/Entities/Unit/Unit.cpp src/server/game/Globals/ObjectMgr.cpp src/server/game/Handlers/QueryHandler.cpp src/server/game/Miscellaneous/Language.h src/server/game/Quests/QuestDef.cpp src/server/game/Spells/Spell.cpp src/server/game/Spells/SpellEffects.cpp src/server/game/Spells/SpellMgr.cpp src/server/scripts/Commands/cs_rbac.cpp src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp src/server/scripts/Spells/spell_quest.cpp src/server/shared/Database/Implementation/CharacterDatabase.cpp src/server/shared/Database/Implementation/WorldDatabase.cpp
This commit is contained in:
commit
293658fb13
100 files changed
+79037
-77341
No files matched your search
@@ -16,3 +16,4 @@ CMakeLists.txt.user
|
||||
*.BACKUP.*
|
||||
*.BASE.*
|
||||
*.LOCAL.*
|
||||
nbproject/*
|
||||
+1
-1
@@ -18,7 +18,7 @@ install:
|
||||
- mysql -uroot -e 'create database test_mysql;'
|
||||
- mkdir bin
|
||||
- cd bin
|
||||
- cmake ../ -DWITH_WARNINGS=1 -DWITH_COREDEBUG=0 -DUSE_COREPCH=1 -DUSE_SCRIPTPCH=1 -DTOOLS=1 -DSCRIPTS=1 -DSERVERS=1 -DNOJEM=1 -DCMAKE_BUILD_TYPE=Release
|
||||
- cmake ../ -DWITH_WARNINGS=1 -DWITH_COREDEBUG=0 -DUSE_COREPCH=1 -DUSE_SCRIPTPCH=1 -DTOOLS=1 -DSCRIPTS=1 -DSERVERS=1 -DNOJEM=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-Werror" -DCMAKE_CXX_FLAGS="-Werror"
|
||||
|
||||
script:
|
||||
- cd ..
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
|
||||
## Build Status
|
||||
|
||||
6.x | 4.3.4 | 3.3.5
|
||||
:------------: | :------------: | :------------:
|
||||
[](https://travis-ci.org/TrinityCore/TrinityCore) | [](https://travis-ci.org/TrinityCore/TrinityCore) | [](https://travis-ci.org/TrinityCore/TrinityCore)
|
||||
[](https://scan.coverity.com/projects/435) | | [](https://scan.coverity.com/projects/4656)
|
||||
6.x | 3.3.5
|
||||
:------------: | :------------:
|
||||
[](https://travis-ci.org/TrinityCore/TrinityCore) | [](https://travis-ci.org/TrinityCore/TrinityCore)
|
||||
[](https://scan.coverity.com/projects/435) | [](https://scan.coverity.com/projects/4656)
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -439,7 +439,6 @@ were extracted from old commits):
|
||||
- jorooo
|
||||
- joschiwald
|
||||
- Joshh
|
||||
- Joshiwald
|
||||
- joshwhedon
|
||||
- jotapdiez
|
||||
- jrkpote
|
||||
@@ -614,7 +613,6 @@ were extracted from old commits):
|
||||
- Necroo
|
||||
- Nefarion
|
||||
- nelegalno
|
||||
- nelgalno
|
||||
- Nemesis
|
||||
- neo0608
|
||||
- Neo2003
|
||||
@@ -684,7 +682,6 @@ were extracted from old commits):
|
||||
- pjasicek
|
||||
- PKX
|
||||
- Polkic
|
||||
- Portgas
|
||||
- Portgas D. Ace
|
||||
- Praetonus
|
||||
- Prince
|
||||
@@ -862,7 +859,6 @@ were extracted from old commits):
|
||||
- Tomatoes
|
||||
- Tome
|
||||
- Tommassino
|
||||
- tomrus88
|
||||
- TOM_RUS
|
||||
- toshik
|
||||
- totoro
|
||||
@@ -875,7 +871,6 @@ were extracted from old commits):
|
||||
- Trista
|
||||
- Trogvar
|
||||
- Trojan
|
||||
- Trond B Krokli
|
||||
- Troy
|
||||
- TrullyONE
|
||||
- Turk3y
|
||||
@@ -962,7 +957,6 @@ were extracted from old commits):
|
||||
- yesitsme
|
||||
- z0ldrax
|
||||
- Zabustak
|
||||
- ZackTsuna
|
||||
- Zakamurite
|
||||
- Zaphod
|
||||
- Zcuron
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
add_definitions(-D_BUILD_DIRECTIVE='"$(CONFIGURATION)"')
|
||||
|
||||
if(WITH_WARNINGS)
|
||||
set(WARNING_FLAGS "-W -Wall -Wextra -Winit-self -Wfatal-errors")
|
||||
set(WARNING_FLAGS "-W -Wall -Wextra -Winit-self -Wfatal-errors -Wno-mismatched-tags")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS} -Woverloaded-virtual")
|
||||
message(STATUS "Clang: All warnings enabled")
|
||||
|
||||
@@ -63,6 +63,19 @@ if( UNIX )
|
||||
endif( MYSQL_CONFIG )
|
||||
endif( UNIX )
|
||||
|
||||
if( WIN32 )
|
||||
# read environment variables and change \ to /
|
||||
SET(PROGRAM_FILES_32 $ENV{ProgramFiles})
|
||||
if (${PROGRAM_FILES_32})
|
||||
STRING(REPLACE "\\\\" "/" PROGRAM_FILES_32 ${PROGRAM_FILES_32})
|
||||
endif(${PROGRAM_FILES_32})
|
||||
|
||||
SET(PROGRAM_FILES_64 $ENV{ProgramW6432})
|
||||
if (${PROGRAM_FILES_64})
|
||||
STRING(REPLACE "\\\\" "/" PROGRAM_FILES_64 ${PROGRAM_FILES_64})
|
||||
endif(${PROGRAM_FILES_64})
|
||||
endif ( WIN32 )
|
||||
|
||||
find_path(MYSQL_INCLUDE_DIR
|
||||
NAMES
|
||||
mysql.h
|
||||
@@ -73,25 +86,13 @@ find_path(MYSQL_INCLUDE_DIR
|
||||
/usr/local/include
|
||||
/usr/local/include/mysql
|
||||
/usr/local/mysql/include
|
||||
"C:/Program Files/MySQL/MySQL Server 5.6/include"
|
||||
"C:/Program Files/MySQL/MySQL Server 5.5/include"
|
||||
"C:/Program Files/MySQL/MySQL Server 5.1/include"
|
||||
"C:/Program Files/MySQL/MySQL Server 5.0/include"
|
||||
"C:/Program Files/MySQL/include"
|
||||
"C:/Program Files (x86)/MySQL/MySQL Server 5.6/include"
|
||||
"C:/Program Files (x86)/MySQL/MySQL Server 5.5/include"
|
||||
"C:/Program Files (x86)/MySQL/MySQL Server 5.1/include"
|
||||
"C:/Program Files (x86)/MySQL/MySQL Server 5.0/include"
|
||||
"C:/Program Files (x86)/MySQL/include"
|
||||
"${PROGRAM_FILES_64}/MySQL/*/include"
|
||||
"${PROGRAM_FILES_64}/MySQL/include"
|
||||
"${PROGRAM_FILES_32}/MySQL/*/include"
|
||||
"${PROGRAM_FILES_32}/MySQL/include"
|
||||
"C:/MySQL/include"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.6;Location]/include"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.5;Location]/include"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.1;Location]/include"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.0;Location]/include"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.6;Location]/include"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.5;Location]/include"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.1;Location]/include"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.0;Location]/include"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\*;Location]/include"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\*;Location]/include"
|
||||
"$ENV{ProgramFiles}/MySQL/*/include"
|
||||
"$ENV{SystemDrive}/MySQL/*/include"
|
||||
"c:/msys/local/include"
|
||||
@@ -123,41 +124,17 @@ if( WIN32 )
|
||||
libmysql
|
||||
PATHS
|
||||
${MYSQL_ADD_LIBRARIES_PATH}
|
||||
"C:/Program Files/MySQL/MySQL Server 5.6/lib"
|
||||
"C:/Program Files/MySQL/MySQL Server 5.6/lib/opt"
|
||||
"C:/Program Files/MySQL/MySQL Server 5.5/lib"
|
||||
"C:/Program Files/MySQL/MySQL Server 5.5/lib/opt"
|
||||
"C:/Program Files/MySQL/MySQL Server 5.1/lib"
|
||||
"C:/Program Files/MySQL/MySQL Server 5.1/lib/opt"
|
||||
"C:/Program Files/MySQL/MySQL Server 5.0/lib"
|
||||
"C:/Program Files/MySQL/MySQL Server 5.0/lib/opt"
|
||||
"C:/Program Files/MySQL/lib"
|
||||
"C:/Program Files (x86)/MySQL/MySQL Server 5.6/lib"
|
||||
"C:/Program Files (x86)/MySQL/MySQL Server 5.6/lib/opt"
|
||||
"C:/Program Files (x86)/MySQL/MySQL Server 5.5/lib"
|
||||
"C:/Program Files (x86)/MySQL/MySQL Server 5.5/lib/opt"
|
||||
"C:/Program Files (x86)/MySQL/MySQL Server 5.1/lib"
|
||||
"C:/Program Files (x86)/MySQL/MySQL Server 5.1/lib/opt"
|
||||
"C:/Program Files (x86)/MySQL/MySQL Server 5.0/lib"
|
||||
"C:/Program Files (x86)/MySQL/MySQL Server 5.0/lib/opt"
|
||||
"C:/Program Files (x86)/MySQL/lib"
|
||||
"${PROGRAM_FILES_64}/MySQL/*/lib"
|
||||
"${PROGRAM_FILES_64}/MySQL/*/lib/opt"
|
||||
"${PROGRAM_FILES_64}/MySQL/lib"
|
||||
"${PROGRAM_FILES_32}/MySQL/*/lib"
|
||||
"${PROGRAM_FILES_32}/MySQL/*/lib/opt"
|
||||
"${PROGRAM_FILES_32}/MySQL/lib"
|
||||
"C:/MySQL/lib/debug"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.6;Location]/lib"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.6;Location]/lib/opt"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.5;Location]/lib"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.5;Location]/lib/opt"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.1;Location]/lib"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.1;Location]/lib/opt"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.0;Location]/lib"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.0;Location]/lib/opt"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.6;Location]/lib"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.6;Location]/lib/opt"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.5;Location]/lib"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.5;Location]/lib/opt"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.1;Location]/lib"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.1;Location]/lib/opt"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.0;Location]/lib"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.0;Location]/lib/opt"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\*;Location]/lib"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\*;Location]/lib/opt"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\*;Location]/lib"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\*;Location]/lib/opt"
|
||||
"$ENV{ProgramFiles}/MySQL/*/lib/opt"
|
||||
"$ENV{SystemDrive}/MySQL/*/lib/opt"
|
||||
"c:/msys/local/include"
|
||||
@@ -198,41 +175,17 @@ endif( UNIX )
|
||||
if( WIN32 )
|
||||
find_program(MYSQL_EXECUTABLE mysql
|
||||
PATHS
|
||||
"C:/Program Files/MySQL/MySQL Server 5.6/bin"
|
||||
"C:/Program Files/MySQL/MySQL Server 5.6/bin/opt"
|
||||
"C:/Program Files/MySQL/MySQL Server 5.5/bin"
|
||||
"C:/Program Files/MySQL/MySQL Server 5.5/bin/opt"
|
||||
"C:/Program Files/MySQL/MySQL Server 5.1/bin"
|
||||
"C:/Program Files/MySQL/MySQL Server 5.1/bin/opt"
|
||||
"C:/Program Files/MySQL/MySQL Server 5.0/bin"
|
||||
"C:/Program Files/MySQL/MySQL Server 5.0/bin/opt"
|
||||
"C:/Program Files/MySQL/bin"
|
||||
"C:/Program Files (x86)/MySQL/MySQL Server 5.6/bin"
|
||||
"C:/Program Files (x86)/MySQL/MySQL Server 5.6/bin/opt"
|
||||
"C:/Program Files (x86)/MySQL/MySQL Server 5.5/bin"
|
||||
"C:/Program Files (x86)/MySQL/MySQL Server 5.5/bin/opt"
|
||||
"C:/Program Files (x86)/MySQL/MySQL Server 5.1/bin"
|
||||
"C:/Program Files (x86)/MySQL/MySQL Server 5.1/bin/opt"
|
||||
"C:/Program Files (x86)/MySQL/MySQL Server 5.0/bin"
|
||||
"C:/Program Files (x86)/MySQL/MySQL Server 5.0/bin/opt"
|
||||
"C:/Program Files (x86)/MySQL/bin"
|
||||
"${PROGRAM_FILES_64}/MySQL/*/bin"
|
||||
"${PROGRAM_FILES_64}/MySQL/*/bin/opt"
|
||||
"${PROGRAM_FILES_64}/MySQL/bin"
|
||||
"${PROGRAM_FILES_32}/MySQL/*/bin"
|
||||
"${PROGRAM_FILES_32}/MySQL/*/bin/opt"
|
||||
"${PROGRAM_FILES_32}/MySQL/bin"
|
||||
"C:/MySQL/bin/debug"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.6;Location]/bin"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.6;Location]/bin/opt"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.5;Location]/bin"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.5;Location]/bin/opt"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.1;Location]/bin"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.1;Location]/bin/opt"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.0;Location]/bin"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.0;Location]/bin/opt"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.6;Location]/bin"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.6;Location]/bin/opt"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.5;Location]/bin"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.5;Location]/bin/opt"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.1;Location]/bin"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.1;Location]/bin/opt"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.0;Location]/bin"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.0;Location]/bin/opt"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\*;Location]/bin"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\*;Location]/bin/opt"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\*;Location]/bin"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\*;Location]/bin/opt"
|
||||
"$ENV{ProgramFiles}/MySQL/*/bin/opt"
|
||||
"$ENV{SystemDrive}/MySQL/*/bin/opt"
|
||||
"c:/msys/local/include"
|
||||
|
||||
@@ -106,6 +106,13 @@ if ( NOJEM )
|
||||
message(" *** jemalloc linking has been disabled!")
|
||||
message(" *** Please note that this is for DEBUGGING WITH VALGRIND only!")
|
||||
message(" *** DO NOT DISABLE IT UNLESS YOU KNOW WHAT YOU'RE DOING!")
|
||||
elseif ( VALGRIND )
|
||||
message("")
|
||||
message(" *** VALGRIND - WARNING!")
|
||||
message(" *** jemalloc will be configured to support Valgrind")
|
||||
message(" *** Please specify the valgrind include directory in VALGRIND_INCLUDE_DIR option if you get build errors")
|
||||
message(" *** Please note that this is for DEBUGGING WITH VALGRIND only!")
|
||||
add_definitions(-DJEMALLOC_VALGRIND)
|
||||
endif()
|
||||
|
||||
if ( HELGRIND )
|
||||
|
||||
@@ -105,3 +105,32 @@
|
||||
fun:_IO_file_xsputn@@GLIBC_2.2.5
|
||||
fun:fwrite
|
||||
}
|
||||
{
|
||||
[4] integer assignments
|
||||
Helgrind:Race
|
||||
fun:_ZN3Log14LoadFromConfigEv
|
||||
fun:_ZN5World18LoadConfigSettingsEb
|
||||
}
|
||||
{
|
||||
[4] integer assignments
|
||||
Helgrind:Race
|
||||
fun:_ZN3Log22CreateLoggerFromConfigERKSs
|
||||
fun:_ZN3Log21ReadLoggersFromConfigEv
|
||||
fun:_ZN3Log14LoadFromConfigEv
|
||||
fun:_ZN5World18LoadConfigSettingsEb
|
||||
}
|
||||
{
|
||||
[4] integer assignments
|
||||
Helgrind:Race
|
||||
fun:_ZN5World18LoadConfigSettingsEb
|
||||
}
|
||||
{
|
||||
[4] integer assignments
|
||||
Helgrind:Race
|
||||
fun:_ZNK5World12getIntConfigE15WorldIntConfigs
|
||||
}
|
||||
{
|
||||
[4] integer assignments
|
||||
Helgrind:Race
|
||||
fun:_ZNK3Log9ShouldLogERKSs8LogLevel
|
||||
}
|
||||
+3
-3
@@ -8,10 +8,10 @@
|
||||
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
if( CMAKE_COMPILER_IS_GNUCXX )
|
||||
add_definitions(--no-warnings)
|
||||
elseif( MSVC )
|
||||
if( MSVC )
|
||||
add_definitions(/W0)
|
||||
else()
|
||||
add_definitions(-w)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
|
||||
+2
-2
@@ -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: 1.1.0 fd53bb6fb88a23e38ec4fe331bfe95d7372d49c9
|
||||
Version: 7859f8123311c1b8f69856d3c5e1b8501fbdae11
|
||||
|
||||
G3D (a commercial-grade C++ 3D engine available as Open Source (BSD License)
|
||||
http://g3d.sourceforge.net/
|
||||
@@ -42,7 +42,7 @@ gSOAP (a portable development toolkit for C and C++ XML Web services and XML dat
|
||||
|
||||
recastnavigation (Recast is state of the art navigation mesh construction toolset for games)
|
||||
https://github.com/memononen/recastnavigation
|
||||
Version: 42b96b7306d39bb7680ddb0f89d480a8296c83ff
|
||||
Version: 1dd5cf1883d61e723fef3d4957cf758c50e7a52b
|
||||
|
||||
StormLib (a pack of modules, written in C++, which are able to read and also to write files from/to the MPQ archives)
|
||||
http://www.zezula.net/en/mpq/stormlib.html
|
||||
|
||||
@@ -6,12 +6,7 @@ set(FMT_SOURCES format.cc format.h)
|
||||
# Use variadic templates
|
||||
add_definitions(-DFMT_VARIADIC_TEMPLATES=1)
|
||||
|
||||
# Check if initializer lists are supported.
|
||||
check_cxx_source_compiles("
|
||||
#include <initializer_list>
|
||||
int main() {}" FMT_INITIALIZER_LIST)
|
||||
|
||||
# Use delete
|
||||
# Use deleted functions
|
||||
add_definitions(-DFMT_USE_DELETED_FUNCTIONS=1)
|
||||
|
||||
# Use static assert
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
`#96 <https://github.com/cppformat/cppformat/issues/96>`_ and
|
||||
`#114 <https://github.com/cppformat/cppformat/pull/114>`_).
|
||||
|
||||
* Added `changelog <https://github.com/cppformat/cppformat/edit/master/ChangeLog.rst>`_
|
||||
* Added `changelog <https://github.com/cppformat/cppformat/blob/master/ChangeLog.rst>`_
|
||||
(`#103 <https://github.com/cppformat/cppformat/issues/103>`_).
|
||||
|
||||
1.0.0 - 2015-02-05
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
Copyright (c) 2014 - 2015, Victor Zverovich
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+327
-217
@@ -35,11 +35,18 @@
|
||||
#include <cmath>
|
||||
#include <cstdarg>
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef __MINGW32__
|
||||
# include <cstring>
|
||||
#if defined(_WIN32) && defined(__MINGW32__)
|
||||
# include <cstring>
|
||||
#endif
|
||||
|
||||
#if FMT_USE_WINDOWS_H
|
||||
# if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
|
||||
# include <windows.h>
|
||||
# else
|
||||
# define NOMINMAX
|
||||
# include <windows.h>
|
||||
# undef NOMINMAX
|
||||
# endif
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
using fmt::internal::Arg;
|
||||
@@ -95,6 +102,7 @@ static inline fmt::internal::None<> strerror_s(char *, std::size_t, ...) {
|
||||
return fmt::internal::None<>();
|
||||
}
|
||||
|
||||
namespace fmt {
|
||||
namespace {
|
||||
|
||||
#ifndef _MSC_VER
|
||||
@@ -150,7 +158,7 @@ typedef void (*FormatFunc)(fmt::Writer &, int, fmt::StringRef);
|
||||
// Buffer should be at least of size 1.
|
||||
int safe_strerror(
|
||||
int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT {
|
||||
assert(buffer != 0 && buffer_size != 0);
|
||||
FMT_ASSERT(buffer != 0 && buffer_size != 0, "invalid buffer");
|
||||
|
||||
class StrError {
|
||||
private:
|
||||
@@ -199,7 +207,10 @@ int safe_strerror(
|
||||
StrError(int error_code, char *&buffer, std::size_t buffer_size)
|
||||
: error_code_(error_code), buffer_(buffer), buffer_size_(buffer_size) {}
|
||||
|
||||
int run() { return handle(strerror_r(error_code_, buffer_, buffer_size_)); }
|
||||
int run() {
|
||||
strerror_r(0, 0, ""); // Suppress a warning about unused strerror_r.
|
||||
return handle(strerror_r(error_code_, buffer_, buffer_size_));
|
||||
}
|
||||
};
|
||||
return StrError(error_code, buffer, buffer_size).run();
|
||||
}
|
||||
@@ -259,6 +270,11 @@ int parse_nonnegative_int(const Char *&s) {
|
||||
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 =
|
||||
@@ -379,24 +395,139 @@ class CharConverter : public fmt::internal::ArgVisitor<CharConverter, void> {
|
||||
arg_.int_value = static_cast<char>(value);
|
||||
}
|
||||
};
|
||||
|
||||
// This function template is used to prevent compile errors when handling
|
||||
// incompatible string arguments, e.g. handling a wide string in a narrow
|
||||
// string formatter.
|
||||
template <typename Char>
|
||||
Arg::StringValue<Char> ignore_incompatible_str(Arg::StringValue<wchar_t>);
|
||||
|
||||
template <>
|
||||
inline Arg::StringValue<char> ignore_incompatible_str(
|
||||
Arg::StringValue<wchar_t>) { return Arg::StringValue<char>(); }
|
||||
|
||||
template <>
|
||||
inline Arg::StringValue<wchar_t> ignore_incompatible_str(
|
||||
Arg::StringValue<wchar_t> s) { return s; }
|
||||
} // namespace
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <typename Impl, typename Char>
|
||||
class BasicArgFormatter : public ArgVisitor<Impl, void> {
|
||||
private:
|
||||
BasicWriter<Char> &writer_;
|
||||
FormatSpec &spec_;
|
||||
|
||||
FMT_DISALLOW_COPY_AND_ASSIGN(BasicArgFormatter);
|
||||
|
||||
protected:
|
||||
BasicWriter<Char> &writer() { return writer_; }
|
||||
const FormatSpec &spec() const { return spec_; }
|
||||
|
||||
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_); }
|
||||
|
||||
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_);
|
||||
}
|
||||
|
||||
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();
|
||||
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);
|
||||
} else {
|
||||
std::fill_n(out + 1, spec_.width_ - 1, fill);
|
||||
}
|
||||
} else {
|
||||
out = writer_.grow_buffer(1);
|
||||
}
|
||||
*out = internal::CharTraits<Char>::cast(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");
|
||||
spec_.flags_ = HASH_FLAG;
|
||||
spec_.type_ = 'x';
|
||||
writer_.write_int(reinterpret_cast<uintptr_t>(value), spec_);
|
||||
}
|
||||
};
|
||||
|
||||
// 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);
|
||||
}
|
||||
};
|
||||
} // namespace internal
|
||||
} // namespace fmt
|
||||
|
||||
FMT_FUNC void fmt::SystemError::init(
|
||||
int err_code, StringRef format_str, ArgList args) {
|
||||
int err_code, CStringRef format_str, ArgList args) {
|
||||
error_code_ = err_code;
|
||||
MemoryWriter w;
|
||||
internal::format_system_error(w, err_code, format(format_str, args));
|
||||
@@ -477,19 +608,20 @@ FMT_FUNC void fmt::internal::report_unknown_type(char code, const char *type) {
|
||||
static_cast<unsigned>(code), type)));
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#if FMT_USE_WINDOWS_H
|
||||
|
||||
FMT_FUNC fmt::internal::UTF8ToUTF16::UTF8ToUTF16(fmt::StringRef s) {
|
||||
int length = MultiByteToWideChar(
|
||||
CP_UTF8, MB_ERR_INVALID_CHARS, s.c_str(), -1, 0, 0);
|
||||
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 (length == 0)
|
||||
FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
|
||||
buffer_.resize(length);
|
||||
buffer_.resize(length + 1);
|
||||
length = MultiByteToWideChar(
|
||||
CP_UTF8, MB_ERR_INVALID_CHARS, s.c_str(), -1, &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;
|
||||
}
|
||||
|
||||
FMT_FUNC fmt::internal::UTF16ToUTF8::UTF16ToUTF8(fmt::WStringRef s) {
|
||||
@@ -500,19 +632,20 @@ 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.c_str(), -1, 0, 0, 0, 0);
|
||||
int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s.size(), 0, 0, 0, 0);
|
||||
if (length == 0)
|
||||
return GetLastError();
|
||||
buffer_.resize(length);
|
||||
buffer_.resize(length + 1);
|
||||
length = WideCharToMultiByte(
|
||||
CP_UTF8, 0, s.c_str(), -1, &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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
FMT_FUNC void fmt::WindowsError::init(
|
||||
int err_code, StringRef format_str, ArgList args) {
|
||||
int err_code, CStringRef format_str, ArgList args) {
|
||||
error_code_ = err_code;
|
||||
MemoryWriter w;
|
||||
internal::format_windows_error(w, err_code, format(format_str, args));
|
||||
@@ -520,30 +653,6 @@ FMT_FUNC void fmt::WindowsError::init(
|
||||
base = std::runtime_error(w.str());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
FMT_FUNC void fmt::internal::format_system_error(
|
||||
fmt::Writer &out, int error_code,
|
||||
fmt::StringRef message) FMT_NOEXCEPT {
|
||||
FMT_TRY {
|
||||
MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer;
|
||||
buffer.resize(INLINE_BUFFER_SIZE);
|
||||
for (;;) {
|
||||
char *system_message = &buffer[0];
|
||||
int result = safe_strerror(error_code, system_message, buffer.size());
|
||||
if (result == 0) {
|
||||
out << message << ": " << system_message;
|
||||
return;
|
||||
}
|
||||
if (result != ERANGE)
|
||||
break; // Can't get error message, report error code instead.
|
||||
buffer.resize(buffer.size() * 2);
|
||||
}
|
||||
} FMT_CATCH(...) {}
|
||||
format_error_code(out, error_code, message);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
FMT_FUNC void fmt::internal::format_windows_error(
|
||||
fmt::Writer &out, int error_code,
|
||||
fmt::StringRef message) FMT_NOEXCEPT {
|
||||
@@ -572,81 +681,74 @@ FMT_FUNC void fmt::internal::format_windows_error(
|
||||
} FMT_CATCH(...) {}
|
||||
format_error_code(out, error_code, message);
|
||||
}
|
||||
#endif
|
||||
|
||||
// An argument formatter.
|
||||
template <typename Char>
|
||||
class fmt::internal::ArgFormatter :
|
||||
public fmt::internal::ArgVisitor<fmt::internal::ArgFormatter<Char>, void> {
|
||||
private:
|
||||
fmt::BasicFormatter<Char> &formatter_;
|
||||
fmt::BasicWriter<Char> &writer_;
|
||||
fmt::FormatSpec &spec_;
|
||||
const Char *format_;
|
||||
#endif // FMT_USE_WINDOWS_H
|
||||
|
||||
FMT_DISALLOW_COPY_AND_ASSIGN(ArgFormatter);
|
||||
|
||||
public:
|
||||
ArgFormatter(
|
||||
fmt::BasicFormatter<Char> &f,fmt::FormatSpec &s, const Char *fmt)
|
||||
: formatter_(f), writer_(f.writer()), spec_(s), format_(fmt) {}
|
||||
|
||||
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_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 fmt::BasicWriter<Char>::CharPtr CharPtr;
|
||||
Char fill = static_cast<Char>(spec_.fill());
|
||||
if (spec_.precision_ == 0) {
|
||||
std::fill_n(writer_.grow_buffer(spec_.width_), spec_.width_, fill);
|
||||
return;
|
||||
}
|
||||
CharPtr out = CharPtr();
|
||||
if (spec_.width_ > 1) {
|
||||
out = writer_.grow_buffer(spec_.width_);
|
||||
if (spec_.align_ == fmt::ALIGN_RIGHT) {
|
||||
std::fill_n(out, spec_.width_ - 1, fill);
|
||||
out += spec_.width_ - 1;
|
||||
} else if (spec_.align_ == fmt::ALIGN_CENTER) {
|
||||
out = writer_.fill_padding(out, spec_.width_, 1, fill);
|
||||
} else {
|
||||
std::fill_n(out + 1, spec_.width_ - 1, fill);
|
||||
FMT_FUNC void fmt::internal::format_system_error(
|
||||
fmt::Writer &out, int error_code,
|
||||
fmt::StringRef message) FMT_NOEXCEPT {
|
||||
FMT_TRY {
|
||||
MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer;
|
||||
buffer.resize(INLINE_BUFFER_SIZE);
|
||||
for (;;) {
|
||||
char *system_message = &buffer[0];
|
||||
int result = safe_strerror(error_code, system_message, buffer.size());
|
||||
if (result == 0) {
|
||||
out << message << ": " << system_message;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
out = writer_.grow_buffer(1);
|
||||
if (result != ERANGE)
|
||||
break; // Can't get error message, report error code instead.
|
||||
buffer.resize(buffer.size() * 2);
|
||||
}
|
||||
*out = static_cast<Char>(value);
|
||||
}
|
||||
} FMT_CATCH(...) {}
|
||||
format_error_code(out, error_code, message);
|
||||
}
|
||||
|
||||
void visit_string(Arg::StringValue<char> value) {
|
||||
writer_.write_str(value, spec_);
|
||||
template <typename Char>
|
||||
void fmt::internal::ArgMap<Char>::init(const ArgList &args) {
|
||||
if (!map_.empty())
|
||||
return;
|
||||
typedef internal::NamedArg<Char> NamedArg;
|
||||
const NamedArg *named_arg = 0;
|
||||
bool use_values =
|
||||
args.type(ArgList::MAX_PACKED_ARGS - 1) == internal::Arg::NONE;
|
||||
if (use_values) {
|
||||
for (unsigned i = 0;/*nothing*/; ++i) {
|
||||
internal::Arg::Type arg_type = args.type(i);
|
||||
switch (arg_type) {
|
||||
case internal::Arg::NONE:
|
||||
return;
|
||||
case internal::Arg::NAMED_ARG:
|
||||
named_arg = static_cast<const NamedArg*>(args.values_[i].pointer);
|
||||
map_.insert(Pair(named_arg->name, *named_arg));
|
||||
break;
|
||||
default:
|
||||
/*nothing*/;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
void visit_wstring(Arg::StringValue<wchar_t> value) {
|
||||
writer_.write_str(ignore_incompatible_str<Char>(value), spec_);
|
||||
for (unsigned i = 0; i != ArgList::MAX_PACKED_ARGS; ++i) {
|
||||
internal::Arg::Type arg_type = args.type(i);
|
||||
if (arg_type == internal::Arg::NAMED_ARG) {
|
||||
named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
|
||||
map_.insert(Pair(named_arg->name, *named_arg));
|
||||
}
|
||||
}
|
||||
|
||||
void visit_pointer(const void *value) {
|
||||
if (spec_.type_ && spec_.type_ != 'p')
|
||||
fmt::internal::report_unknown_type(spec_.type_, "pointer");
|
||||
spec_.flags_ = fmt::HASH_FLAG;
|
||||
spec_.type_ = 'x';
|
||||
writer_.write_int(reinterpret_cast<uintptr_t>(value), spec_);
|
||||
for (unsigned i = ArgList::MAX_PACKED_ARGS;/*nothing*/; ++i) {
|
||||
switch (args.args_[i].type) {
|
||||
case internal::Arg::NONE:
|
||||
return;
|
||||
case internal::Arg::NAMED_ARG:
|
||||
named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
|
||||
map_.insert(Pair(named_arg->name, *named_arg));
|
||||
break;
|
||||
default:
|
||||
/*nothing*/;
|
||||
}
|
||||
}
|
||||
|
||||
void visit_custom(Arg::CustomValue c) {
|
||||
c.format(&formatter_, c.value, &format_);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
void fmt::internal::FixedBuffer<Char>::grow(std::size_t) {
|
||||
@@ -675,6 +777,19 @@ void fmt::BasicWriter<Char>::write_str(
|
||||
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;
|
||||
@@ -687,11 +802,33 @@ inline Arg fmt::BasicFormatter<Char>::parse_arg_index(const Char *&s) {
|
||||
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];
|
||||
if (arg.type == Arg::NONE)
|
||||
switch (arg.type) {
|
||||
case Arg::NONE:
|
||||
error = "argument index out of range";
|
||||
break;
|
||||
case Arg::NAMED_ARG:
|
||||
arg = *static_cast<const internal::Arg*>(arg.pointer);
|
||||
default:
|
||||
/*nothing*/;
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
|
||||
@@ -702,14 +839,19 @@ inline Arg fmt::internal::FormatterBase::next_arg(const char *&error) {
|
||||
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) {
|
||||
if (next_arg_index_ <= 0) {
|
||||
next_arg_index_ = -1;
|
||||
return do_get_arg(arg_index, error);
|
||||
}
|
||||
error = "cannot switch from automatic to manual argument indexing";
|
||||
return Arg();
|
||||
return check_no_auto_index(error) ? do_get_arg(arg_index, error) : Arg();
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
@@ -787,7 +929,7 @@ unsigned fmt::internal::PrintfFormatter<Char>::parse_header(
|
||||
|
||||
template <typename Char>
|
||||
void fmt::internal::PrintfFormatter<Char>::format(
|
||||
BasicWriter<Char> &writer, BasicStringRef<Char> format_str,
|
||||
BasicWriter<Char> &writer, BasicCStringRef<Char> format_str,
|
||||
const ArgList &args) {
|
||||
const Char *start = format_str.c_str();
|
||||
set_args(args);
|
||||
@@ -881,73 +1023,7 @@ void fmt::internal::PrintfFormatter<Char>::format(
|
||||
start = s;
|
||||
|
||||
// Format argument.
|
||||
switch (arg.type) {
|
||||
case Arg::INT:
|
||||
writer.write_int(arg.int_value, spec);
|
||||
break;
|
||||
case Arg::UINT:
|
||||
writer.write_int(arg.uint_value, spec);
|
||||
break;
|
||||
case Arg::LONG_LONG:
|
||||
writer.write_int(arg.long_long_value, spec);
|
||||
break;
|
||||
case Arg::ULONG_LONG:
|
||||
writer.write_int(arg.ulong_long_value, spec);
|
||||
break;
|
||||
case Arg::CHAR: {
|
||||
if (spec.type_ && spec.type_ != 'c')
|
||||
writer.write_int(arg.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>(arg.int_value);
|
||||
break;
|
||||
}
|
||||
case Arg::DOUBLE:
|
||||
writer.write_double(arg.double_value, spec);
|
||||
break;
|
||||
case Arg::LONG_DOUBLE:
|
||||
writer.write_double(arg.long_double_value, spec);
|
||||
break;
|
||||
case Arg::CSTRING:
|
||||
arg.string.size = 0;
|
||||
writer.write_str(arg.string, spec);
|
||||
break;
|
||||
case Arg::STRING:
|
||||
writer.write_str(arg.string, spec);
|
||||
break;
|
||||
case Arg::WSTRING:
|
||||
writer.write_str(ignore_incompatible_str<Char>(arg.wstring), spec);
|
||||
break;
|
||||
case Arg::POINTER:
|
||||
if (spec.type_ && spec.type_ != 'p')
|
||||
internal::report_unknown_type(spec.type_, "pointer");
|
||||
spec.flags_= HASH_FLAG;
|
||||
spec.type_ = 'x';
|
||||
writer.write_int(reinterpret_cast<uintptr_t>(arg.pointer), spec);
|
||||
break;
|
||||
case Arg::CUSTOM: {
|
||||
if (spec.type_)
|
||||
internal::report_unknown_type(spec.type_, "object");
|
||||
const void *str_format = "s";
|
||||
arg.custom.format(&writer, arg.custom.value, &str_format);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
internal::PrintfArgFormatter<Char>(writer, spec).visit(arg);
|
||||
}
|
||||
write(writer, start, s);
|
||||
}
|
||||
@@ -1019,16 +1095,47 @@ const Char *fmt::BasicFormatter<Char>::format(
|
||||
++s;
|
||||
}
|
||||
|
||||
// Parse width and zero flag.
|
||||
// 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') {
|
||||
if (*s == '0') {
|
||||
require_numeric_argument(arg, '0');
|
||||
spec.align_ = ALIGN_NUMERIC;
|
||||
spec.fill_ = '0';
|
||||
}
|
||||
// Zero may be parsed again as a part of the width, but it is simpler
|
||||
// and more efficient than checking if the next char is a digit.
|
||||
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.
|
||||
@@ -1039,7 +1146,8 @@ const Char *fmt::BasicFormatter<Char>::format(
|
||||
spec.precision_ = parse_nonnegative_int(s);
|
||||
} else if (*s == '{') {
|
||||
++s;
|
||||
const Arg &precision_arg = parse_arg_index(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;
|
||||
@@ -1069,7 +1177,7 @@ const Char *fmt::BasicFormatter<Char>::format(
|
||||
} else {
|
||||
FMT_THROW(FormatError("missing precision specifier"));
|
||||
}
|
||||
if (arg.type < Arg::LAST_INTEGER_TYPE || arg.type == Arg::POINTER) {
|
||||
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")));
|
||||
@@ -1092,7 +1200,7 @@ const Char *fmt::BasicFormatter<Char>::format(
|
||||
|
||||
template <typename Char>
|
||||
void fmt::BasicFormatter<Char>::format(
|
||||
BasicStringRef<Char> format_str, const ArgList &args) {
|
||||
BasicCStringRef<Char> format_str, const ArgList &args) {
|
||||
const Char *s = start_ = format_str.c_str();
|
||||
set_args(args);
|
||||
while (*s) {
|
||||
@@ -1106,7 +1214,7 @@ void fmt::BasicFormatter<Char>::format(
|
||||
if (c == '}')
|
||||
FMT_THROW(FormatError("unmatched '}' in format string"));
|
||||
write(writer_, start_, s - 1);
|
||||
Arg arg = parse_arg_index(s);
|
||||
Arg arg = is_name_start(*s) ? parse_arg_name(s) : parse_arg_index(s);
|
||||
s = format(s, arg);
|
||||
}
|
||||
write(writer_, start_, s);
|
||||
@@ -1117,30 +1225,30 @@ FMT_FUNC void fmt::report_system_error(
|
||||
report_error(internal::format_system_error, error_code, message);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#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);
|
||||
}
|
||||
#endif
|
||||
|
||||
FMT_FUNC void fmt::print(std::FILE *f, StringRef format_str, ArgList args) {
|
||||
FMT_FUNC void fmt::print(std::FILE *f, CStringRef format_str, ArgList args) {
|
||||
MemoryWriter w;
|
||||
w.write(format_str, args);
|
||||
std::fwrite(w.data(), 1, w.size(), f);
|
||||
}
|
||||
|
||||
FMT_FUNC void fmt::print(StringRef format_str, ArgList args) {
|
||||
FMT_FUNC void fmt::print(CStringRef format_str, ArgList args) {
|
||||
print(stdout, format_str, args);
|
||||
}
|
||||
|
||||
FMT_FUNC void fmt::print(std::ostream &os, StringRef format_str, ArgList args) {
|
||||
FMT_FUNC void fmt::print(std::ostream &os, CStringRef format_str, ArgList args) {
|
||||
MemoryWriter w;
|
||||
w.write(format_str, args);
|
||||
os.write(w.data(), w.size());
|
||||
}
|
||||
|
||||
FMT_FUNC void fmt::print_colored(Color c, StringRef format, 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);
|
||||
std::fputs(escape, stdout);
|
||||
@@ -1148,7 +1256,7 @@ FMT_FUNC void fmt::print_colored(Color c, StringRef format, ArgList args) {
|
||||
std::fputs(RESET_COLOR, stdout);
|
||||
}
|
||||
|
||||
FMT_FUNC int fmt::fprintf(std::FILE *f, StringRef format, ArgList args) {
|
||||
FMT_FUNC int fmt::fprintf(std::FILE *f, CStringRef format, ArgList args) {
|
||||
MemoryWriter w;
|
||||
printf(w, format, args);
|
||||
std::size_t size = w.size();
|
||||
@@ -1157,6 +1265,8 @@ FMT_FUNC int fmt::fprintf(std::FILE *f, StringRef format, ArgList args) {
|
||||
|
||||
#ifndef FMT_HEADER_ONLY
|
||||
|
||||
template struct fmt::internal::BasicData<void>;
|
||||
|
||||
// Explicit instantiations for char.
|
||||
|
||||
template void fmt::internal::FixedBuffer<char>::grow(std::size_t);
|
||||
@@ -1165,10 +1275,10 @@ template const char *fmt::BasicFormatter<char>::format(
|
||||
const char *&format_str, const fmt::internal::Arg &arg);
|
||||
|
||||
template void fmt::BasicFormatter<char>::format(
|
||||
BasicStringRef<char> format, const ArgList &args);
|
||||
CStringRef format, const ArgList &args);
|
||||
|
||||
template void fmt::internal::PrintfFormatter<char>::format(
|
||||
BasicWriter<char> &writer, BasicStringRef<char> format, const ArgList &args);
|
||||
BasicWriter<char> &writer, CStringRef format, const ArgList &args);
|
||||
|
||||
template int fmt::internal::CharTraits<char>::format_float(
|
||||
char *buffer, std::size_t size, const char *format,
|
||||
@@ -1186,10 +1296,10 @@ 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(
|
||||
BasicStringRef<wchar_t> format, const ArgList &args);
|
||||
BasicCStringRef<wchar_t> format, const ArgList &args);
|
||||
|
||||
template void fmt::internal::PrintfFormatter<wchar_t>::format(
|
||||
BasicWriter<wchar_t> &writer, BasicStringRef<wchar_t> format,
|
||||
BasicWriter<wchar_t> &writer, WCStringRef format,
|
||||
const ArgList &args);
|
||||
|
||||
template int fmt::internal::CharTraits<wchar_t>::format_float(
|
||||
|
||||
+412
-157
File diff suppressed because it is too large.
Load diff
@@ -83,7 +83,8 @@ fmt::BufferedFile::~BufferedFile() FMT_NOEXCEPT {
|
||||
fmt::report_system_error(errno, "cannot close file");
|
||||
}
|
||||
|
||||
fmt::BufferedFile::BufferedFile(fmt::StringRef filename, fmt::StringRef mode) {
|
||||
fmt::BufferedFile::BufferedFile(
|
||||
fmt::CStringRef filename, fmt::CStringRef mode) {
|
||||
FMT_RETRY_VAL(file_, FMT_SYSTEM(fopen(filename.c_str(), mode.c_str())), 0);
|
||||
if (!file_)
|
||||
throw SystemError(errno, "cannot open file {}", filename);
|
||||
@@ -108,7 +109,7 @@ int fmt::BufferedFile::fileno() const {
|
||||
return fd;
|
||||
}
|
||||
|
||||
fmt::File::File(fmt::StringRef path, int oflag) {
|
||||
fmt::File::File(fmt::CStringRef path, int oflag) {
|
||||
int mode = S_IRUSR | S_IWUSR;
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
fd_ = -1;
|
||||
@@ -151,8 +152,8 @@ fmt::LongLong fmt::File::size() const {
|
||||
if (error != NO_ERROR)
|
||||
throw WindowsError(GetLastError(), "cannot get file size");
|
||||
}
|
||||
fmt::ULongLong size = size_upper;
|
||||
return (size << sizeof(DWORD) * CHAR_BIT) | size_lower;
|
||||
fmt::ULongLong long_size = size_upper;
|
||||
return (long_size << sizeof(DWORD) * CHAR_BIT) | size_lower;
|
||||
#else
|
||||
typedef struct stat Stat;
|
||||
Stat file_stat = Stat();
|
||||
|
||||
@@ -41,10 +41,6 @@
|
||||
|
||||
#include "format.h"
|
||||
|
||||
#ifdef FMT_INCLUDE_POSIX_TEST
|
||||
# include "test/posix-test.h"
|
||||
#endif
|
||||
|
||||
#ifndef FMT_POSIX
|
||||
# if defined(_WIN32) && !defined(__MINGW32__)
|
||||
// Fix warnings about deprecated symbols.
|
||||
@@ -185,7 +181,7 @@ public:
|
||||
#endif
|
||||
|
||||
// Opens a file.
|
||||
BufferedFile(fmt::StringRef filename, fmt::StringRef mode);
|
||||
BufferedFile(CStringRef filename, CStringRef mode);
|
||||
|
||||
// Closes the file.
|
||||
void close();
|
||||
@@ -197,10 +193,10 @@ public:
|
||||
// of MinGW that define fileno as a macro.
|
||||
int (fileno)() const;
|
||||
|
||||
void print(fmt::StringRef format_str, const ArgList &args) {
|
||||
void print(CStringRef format_str, const ArgList &args) {
|
||||
fmt::print(file_, format_str, args);
|
||||
}
|
||||
FMT_VARIADIC(void, print, fmt::StringRef)
|
||||
FMT_VARIADIC(void, print, CStringRef)
|
||||
};
|
||||
|
||||
// A file. Closed file is represented by a File object with descriptor -1.
|
||||
@@ -228,7 +224,7 @@ class File {
|
||||
File() FMT_NOEXCEPT : fd_(-1) {}
|
||||
|
||||
// Opens a file and constructs a File object representing this file.
|
||||
File(fmt::StringRef path, int oflag);
|
||||
File(CStringRef path, int oflag);
|
||||
|
||||
#if !FMT_USE_RVALUE_REFERENCES
|
||||
// Emulate a move constructor and a move assignment operator if rvalue
|
||||
@@ -300,7 +296,7 @@ class File {
|
||||
void close();
|
||||
|
||||
// Returns the file size.
|
||||
fmt::LongLong size() const;
|
||||
LongLong size() const;
|
||||
|
||||
// Attempts to read count bytes from the file into the specified buffer.
|
||||
std::size_t read(void *buffer, std::size_t count);
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
dep/g3dlite/Readme.txt | 3 ++-
|
||||
dep/g3dlite/include/G3D/Log.h | 2 +-
|
||||
dep/g3dlite/include/G3D/Rect2D.h | 2 +-
|
||||
dep/g3dlite/source/FileSystem.cpp | 3 +++
|
||||
dep/g3dlite/source/debugAssert.cpp | 2 ++
|
||||
dep/g3dlite/source/fileutils.cpp | 10 ++++++++++
|
||||
dep/g3dlite/source/prompt.cpp | 2 ++
|
||||
7 files changed, 21 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dep/g3dlite/Readme.txt b/dep/g3dlite/Readme.txt
|
||||
index 7fab7f8..7439943 100644
|
||||
--- a/dep/g3dlite/Readme.txt
|
||||
+++ b/dep/g3dlite/Readme.txt
|
||||
@@ -11,4 +11,5 @@ G3D-v8.0_hotfix7.diff - 2013-08-31 - fix typo in Matrix4 == operator
|
||||
G3D-v8.0_hotfix8.diff - 2013-09-01 - fix typo in Vector3int32 += operator
|
||||
G3D-v8.0_hotfix9.diff - 2014-06-01 - only VS < 10 don't ship inttypes.h
|
||||
G3D-v9.0 hotfix1.diff - 2014-08-22 - updated to G3D9, reapplied previous patches and removed unneeded changes
|
||||
-G3D-v9.0 hotfix2.diff - 2014-08-23 - fix some -Wconversion warnings
|
||||
\ No newline at end of file
|
||||
+G3D-v9.0 hotfix2.diff - 2014-08-23 - fix some -Wconversion warnings
|
||||
+G3D-v9.0 hotfix3.diff - 2015-06-28 - fix some warnings
|
||||
diff --git a/dep/g3dlite/include/G3D/Log.h b/dep/g3dlite/include/G3D/Log.h
|
||||
index 2aedb13..c8a5d53 100644
|
||||
--- a/dep/g3dlite/include/G3D/Log.h
|
||||
+++ b/dep/g3dlite/include/G3D/Log.h
|
||||
@@ -57,9 +57,9 @@ private:
|
||||
|
||||
static Log* commonLog;
|
||||
|
||||
+public:
|
||||
int stripFromStackBottom;
|
||||
|
||||
-public:
|
||||
|
||||
/**
|
||||
@param stripFromStackBottom Number of call stacks to strip from the
|
||||
diff --git a/dep/g3dlite/include/G3D/Rect2D.h b/dep/g3dlite/include/G3D/Rect2D.h
|
||||
index f72dd08..93dd0e6 100644
|
||||
--- a/dep/g3dlite/include/G3D/Rect2D.h
|
||||
+++ b/dep/g3dlite/include/G3D/Rect2D.h
|
||||
@@ -118,7 +118,7 @@ private:
|
||||
}
|
||||
|
||||
/** Uninitialized constructor */
|
||||
- Rect2D(bool b) {}
|
||||
+ Rect2D(bool /*b*/) {}
|
||||
public:
|
||||
|
||||
/** \param any Must either Rect2D::xywh(#, #, #, #) or Rect2D::xyxy(#, #, #, #)*/
|
||||
diff --git a/dep/g3dlite/source/FileSystem.cpp b/dep/g3dlite/source/FileSystem.cpp
|
||||
index 32a84e7..06e6ff0 100644
|
||||
--- a/dep/g3dlite/source/FileSystem.cpp
|
||||
+++ b/dep/g3dlite/source/FileSystem.cpp
|
||||
@@ -137,6 +137,9 @@ void FileSystem::Dir::computeZipListing(const std::string& zipfile, const std::s
|
||||
|
||||
zip_close(z);
|
||||
z = NULL;
|
||||
+#else
|
||||
+ (void)zipfile;
|
||||
+ (void)_pathInsideZipfile;
|
||||
#endif
|
||||
}
|
||||
|
||||
diff --git a/dep/g3dlite/source/debugAssert.cpp b/dep/g3dlite/source/debugAssert.cpp
|
||||
index 92ce237..cfccf9a 100644
|
||||
--- a/dep/g3dlite/source/debugAssert.cpp
|
||||
+++ b/dep/g3dlite/source/debugAssert.cpp
|
||||
@@ -121,6 +121,8 @@ static void createErrorMessage(
|
||||
const char* moduleName = strrchr(modulePath, '\\');
|
||||
outTitle = outTitle + string(" - ") + string(moduleName ? (moduleName + 1) : modulePath);
|
||||
|
||||
+ #else
|
||||
+ (void)outTitle;
|
||||
#endif
|
||||
|
||||
// Build the message.
|
||||
diff --git a/dep/g3dlite/source/fileutils.cpp b/dep/g3dlite/source/fileutils.cpp
|
||||
index 966cca7..2788ada 100644
|
||||
--- a/dep/g3dlite/source/fileutils.cpp
|
||||
+++ b/dep/g3dlite/source/fileutils.cpp
|
||||
@@ -396,6 +396,10 @@ bool zipfileExists(const std::string& filename, std::string& outZipfile,
|
||||
}
|
||||
|
||||
}
|
||||
+#else
|
||||
+ (void)filename;
|
||||
+ (void)outZipfile;
|
||||
+ (void)outInternalFile;
|
||||
#endif
|
||||
// not a valid directory structure ever,
|
||||
// obviously no .zip was found within the path
|
||||
@@ -756,6 +760,12 @@ static void getFileOrDirListZip(const std::string& path,
|
||||
zip_close( z );
|
||||
|
||||
fileSet.getMembers(files);
|
||||
+#else
|
||||
+ (void)path;
|
||||
+ (void)prefix;
|
||||
+ (void)files;
|
||||
+ (void)wantFiles;
|
||||
+ (void)includePath;
|
||||
#endif
|
||||
}
|
||||
|
||||
diff --git a/dep/g3dlite/source/prompt.cpp b/dep/g3dlite/source/prompt.cpp
|
||||
index ee520d8..6927fd0 100644
|
||||
--- a/dep/g3dlite/source/prompt.cpp
|
||||
+++ b/dep/g3dlite/source/prompt.cpp
|
||||
@@ -572,6 +572,8 @@ int prompt(
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
+#else
|
||||
+ (void)useGui;
|
||||
#endif /* G3DFIX: exclude GUI prompt code */
|
||||
return textPrompt(windowTitle, prompt, choice, numChoices);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
dep/g3dlite/source/Matrix4.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dep/g3dlite/source/Matrix4.cpp b/dep/g3dlite/source/Matrix4.cpp
|
||||
index f3b25ad..0588cb6 100644
|
||||
--- a/dep/g3dlite/source/Matrix4.cpp
|
||||
+++ b/dep/g3dlite/source/Matrix4.cpp
|
||||
@@ -606,7 +606,7 @@ bool Matrix4float64::operator==(const Matrix4float64& other) const {
|
||||
// If the bit patterns are identical, they must be
|
||||
// the same matrix. If not, they *might* still have
|
||||
// equal elements due to floating point weirdness.
|
||||
- if (memcmp(this, &other, sizeof(Matrix4float64) == 0)) {
|
||||
+ if (memcmp(this, &other, sizeof(Matrix4float64)) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ set(jemalloc_STAT_SRC
|
||||
include_directories(
|
||||
${BUILDDIR}/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
${VALGRIND_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
add_definitions(-D_GNU_SOURCE -D_REENTRANT)
|
||||
|
||||
@@ -483,22 +483,22 @@ DROP TABLE IF EXISTS `character_aura`;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `character_aura` (
|
||||
`guid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier',
|
||||
`caster_guid` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'Full Global Unique Identifier',
|
||||
`item_guid` bigint(20) unsigned NOT NULL DEFAULT '0',
|
||||
`casterGuid` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'Full Global Unique Identifier',
|
||||
`itemGuid` bigint(20) unsigned NOT NULL DEFAULT '0',
|
||||
`spell` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
`effect_mask` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`recalculate_mask` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`stackcount` tinyint(3) unsigned NOT NULL DEFAULT '1',
|
||||
`effectMask` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`recalculateMask` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`stackCount` tinyint(3) unsigned NOT NULL DEFAULT '1',
|
||||
`amount0` int(11) NOT NULL DEFAULT '0',
|
||||
`amount1` int(11) NOT NULL DEFAULT '0',
|
||||
`amount2` int(11) NOT NULL DEFAULT '0',
|
||||
`base_amount0` int(11) NOT NULL DEFAULT '0',
|
||||
`base_amount1` int(11) NOT NULL DEFAULT '0',
|
||||
`base_amount2` int(11) NOT NULL DEFAULT '0',
|
||||
`maxduration` int(11) NOT NULL DEFAULT '0',
|
||||
`remaintime` int(11) NOT NULL DEFAULT '0',
|
||||
`remaincharges` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`guid`,`caster_guid`,`item_guid`,`spell`,`effect_mask`)
|
||||
`maxDuration` int(11) NOT NULL DEFAULT '0',
|
||||
`remainTime` int(11) NOT NULL DEFAULT '0',
|
||||
`remainCharges` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`guid`,`casterGuid`,`itemGuid`,`spell`,`effectMask`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Player System';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
@@ -763,7 +763,7 @@ DROP TABLE IF EXISTS `character_glyphs`;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `character_glyphs` (
|
||||
`guid` int(10) unsigned NOT NULL,
|
||||
`spec` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`talentGroup` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`glyph1` smallint(5) unsigned DEFAULT '0',
|
||||
`glyph2` smallint(5) unsigned DEFAULT '0',
|
||||
`glyph3` smallint(5) unsigned DEFAULT '0',
|
||||
@@ -1276,8 +1276,8 @@ DROP TABLE IF EXISTS `character_talent`;
|
||||
CREATE TABLE `character_talent` (
|
||||
`guid` int(10) unsigned NOT NULL,
|
||||
`spell` mediumint(8) unsigned NOT NULL,
|
||||
`spec` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`guid`,`spell`,`spec`)
|
||||
`talentGroup` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`guid`,`spell`,`talentGroup`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
@@ -1383,8 +1383,8 @@ CREATE TABLE `characters` (
|
||||
`power4` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`power5` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`latency` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
`speccount` tinyint(3) unsigned NOT NULL DEFAULT '1',
|
||||
`activespec` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`talentGroupsCount` tinyint(3) unsigned NOT NULL DEFAULT '1',
|
||||
`activeTalentGroup` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`exploredZones` longtext,
|
||||
`equipmentCache` longtext,
|
||||
`knownTitles` longtext,
|
||||
@@ -1575,68 +1575,68 @@ LOCK TABLES `gameobject_respawn` WRITE;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `gm_subsurveys`
|
||||
-- Table structure for table `gm_subsurvey`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `gm_subsurveys`;
|
||||
DROP TABLE IF EXISTS `gm_subsurvey`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `gm_subsurveys` (
|
||||
CREATE TABLE `gm_subsurvey` (
|
||||
`surveyId` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`subsurveyId` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`rank` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`comment` text NOT NULL,
|
||||
PRIMARY KEY (`surveyId`,`subsurveyId`)
|
||||
`questionId` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`answer` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`answerComment` text NOT NULL,
|
||||
PRIMARY KEY (`surveyId`,`questionId`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Player System';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `gm_subsurveys`
|
||||
-- Dumping data for table `gm_subsurvey`
|
||||
--
|
||||
|
||||
LOCK TABLES `gm_subsurveys` WRITE;
|
||||
/*!40000 ALTER TABLE `gm_subsurveys` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `gm_subsurveys` ENABLE KEYS */;
|
||||
LOCK TABLES `gm_subsurvey` WRITE;
|
||||
/*!40000 ALTER TABLE `gm_subsurvey` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `gm_subsurvey` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `gm_surveys`
|
||||
-- Table structure for table `gm_survey`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `gm_surveys`;
|
||||
DROP TABLE IF EXISTS `gm_survey`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `gm_surveys` (
|
||||
CREATE TABLE `gm_survey` (
|
||||
`surveyId` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`guid` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`mainSurvey` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`overallComment` longtext NOT NULL,
|
||||
`comment` longtext NOT NULL,
|
||||
`createTime` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`surveyId`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Player System';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `gm_surveys`
|
||||
-- Dumping data for table `gm_survey`
|
||||
--
|
||||
|
||||
LOCK TABLES `gm_surveys` WRITE;
|
||||
/*!40000 ALTER TABLE `gm_surveys` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `gm_surveys` ENABLE KEYS */;
|
||||
LOCK TABLES `gm_survey` WRITE;
|
||||
/*!40000 ALTER TABLE `gm_survey` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `gm_survey` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `gm_tickets`
|
||||
-- Table structure for table `gm_ticket`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `gm_tickets`;
|
||||
DROP TABLE IF EXISTS `gm_ticket`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `gm_tickets` (
|
||||
`ticketId` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`guid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier of ticket creator',
|
||||
CREATE TABLE `gm_ticket` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`playerGuid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier of ticket creator',
|
||||
`name` varchar(12) NOT NULL COMMENT 'Name of ticket creator',
|
||||
`message` text NOT NULL,
|
||||
`description` text NOT NULL,
|
||||
`createTime` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`mapId` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
`posX` float NOT NULL DEFAULT '0',
|
||||
@@ -1650,18 +1650,18 @@ CREATE TABLE `gm_tickets` (
|
||||
`completed` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`escalated` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`viewed` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`haveTicket` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`ticketId`)
|
||||
`needMoreHelp` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Player System';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `gm_tickets`
|
||||
-- Dumping data for table `gm_ticket`
|
||||
--
|
||||
|
||||
LOCK TABLES `gm_tickets` WRITE;
|
||||
/*!40000 ALTER TABLE `gm_tickets` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `gm_tickets` ENABLE KEYS */;
|
||||
LOCK TABLES `gm_ticket` WRITE;
|
||||
/*!40000 ALTER TABLE `gm_ticket` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `gm_ticket` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
@@ -1738,7 +1738,7 @@ CREATE TABLE `groups` (
|
||||
`icon8` bigint(20) unsigned NOT NULL,
|
||||
`groupType` tinyint(3) unsigned NOT NULL,
|
||||
`difficulty` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`raiddifficulty` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`raidDifficulty` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`masterLooterGuid` int(10) unsigned NOT NULL,
|
||||
PRIMARY KEY (`guid`),
|
||||
KEY `leaderGuid` (`leaderGuid`)
|
||||
@@ -2476,21 +2476,21 @@ DROP TABLE IF EXISTS `pet_aura`;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `pet_aura` (
|
||||
`guid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier',
|
||||
`caster_guid` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'Full Global Unique Identifier',
|
||||
`casterGuid` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'Full Global Unique Identifier',
|
||||
`spell` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
`effect_mask` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`recalculate_mask` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`stackcount` tinyint(3) unsigned NOT NULL DEFAULT '1',
|
||||
`effectMask` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`recalculateMask` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`stackCount` tinyint(3) unsigned NOT NULL DEFAULT '1',
|
||||
`amount0` mediumint(8) NOT NULL,
|
||||
`amount1` mediumint(8) NOT NULL,
|
||||
`amount2` mediumint(8) NOT NULL,
|
||||
`base_amount0` mediumint(8) NOT NULL,
|
||||
`base_amount1` mediumint(8) NOT NULL,
|
||||
`base_amount2` mediumint(8) NOT NULL,
|
||||
`maxduration` int(11) NOT NULL DEFAULT '0',
|
||||
`remaintime` int(11) NOT NULL DEFAULT '0',
|
||||
`remaincharges` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`guid`,`spell`,`effect_mask`)
|
||||
`maxDuration` int(11) NOT NULL DEFAULT '0',
|
||||
`remainTime` int(11) NOT NULL DEFAULT '0',
|
||||
`remainCharges` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`guid`,`spell`,`effectMask`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Pet System';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
@@ -2761,7 +2761,7 @@ CREATE TABLE `updates` (
|
||||
|
||||
LOCK TABLES `updates` WRITE;
|
||||
/*!40000 ALTER TABLE `updates` DISABLE KEYS */;
|
||||
INSERT INTO `updates` VALUES ('2015_03_20_00_characters.sql','B761760804EA73BD297F296C5C1919687DF7191C','ARCHIVED','2015-03-21 21:44:15',0),('2015_03_20_01_characters.sql','894F08B70449A5481FFAF394EE5571D7FC4D8A3A','ARCHIVED','2015-03-21 21:44:15',0),('2015_03_20_02_characters.sql','97D7BE0CAADC79F3F11B9FD296B8C6CD40FE593B','ARCHIVED','2015-03-21 21:44:51',0);
|
||||
INSERT INTO `updates` VALUES ('2015_03_20_00_characters.sql','B761760804EA73BD297F296C5C1919687DF7191C','ARCHIVED','2015-03-21 21:44:15',0),('2015_03_20_01_characters.sql','894F08B70449A5481FFAF394EE5571D7FC4D8A3A','ARCHIVED','2015-03-21 21:44:15',0),('2015_03_20_02_characters.sql','97D7BE0CAADC79F3F11B9FD296B8C6CD40FE593B','ARCHIVED','2015-03-21 21:44:51',0), ('2015_06_26_00_characters_335.sql','f8230a59a9e878a6f54f421d6621f1595bd93861','RELEASED','2015-03-21 21:44:51',0);
|
||||
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
@@ -2846,4 +2846,4 @@ UNLOCK TABLES;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
|
||||
-- Dump completed on 2015-03-21 21:48:11
|
||||
-- Dump completed on 2015-06-25 17:43:13
|
||||
+75416
-75416
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,57 @@
|
||||
-- `character_aura`
|
||||
ALTER TABLE `character_aura`
|
||||
CHANGE `caster_guid` `casterGuid` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'Full Global Unique Identifier',
|
||||
CHANGE `item_guid` `itemGuid` bigint(20) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `effect_mask` `effectMask` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `recalculate_mask` `recalculateMask` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `stackcount` `stackCount` tinyint(3) unsigned NOT NULL DEFAULT '1',
|
||||
CHANGE `maxduration` `maxDuration` int(11) NOT NULL DEFAULT '0',
|
||||
CHANGE `remaintime` `remainTime` int(11) NOT NULL DEFAULT '0',
|
||||
CHANGE `remaincharges` `remainCharges` tinyint(3) unsigned NOT NULL DEFAULT '0';
|
||||
|
||||
-- `character_glyphs`
|
||||
ALTER TABLE `character_glyphs`
|
||||
CHANGE `spec` `talentGroup` tinyint(3) unsigned NOT NULL DEFAULT '0';
|
||||
|
||||
-- `character_talent`
|
||||
ALTER TABLE `character_talent`
|
||||
CHANGE `spec` `talentGroup` tinyint(3) unsigned NOT NULL DEFAULT '0';
|
||||
|
||||
-- `characters`
|
||||
ALTER TABLE `characters`
|
||||
CHANGE `speccount` `talentGroupsCount` tinyint(3) unsigned NOT NULL DEFAULT '1',
|
||||
CHANGE `activespec` `activeTalentGroup` tinyint(3) unsigned NOT NULL DEFAULT '0';
|
||||
|
||||
-- `gm_subsurveys` -> `gm_subsurvey`
|
||||
RENAME TABLE `gm_subsurveys` TO `gm_subsurvey`;
|
||||
ALTER TABLE `gm_subsurvey`
|
||||
CHANGE `subsurveyId` `questionId` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `rank` `answer` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `comment` `answerComment` text NOT NULL;
|
||||
|
||||
-- `gm_surveys` -> `gm_survey`
|
||||
RENAME TABLE `gm_surveys` TO `gm_survey`;
|
||||
ALTER TABLE `gm_survey`
|
||||
CHANGE `overallComment` `comment` longtext NOT NULL;
|
||||
|
||||
-- `gm_tickets` -> `gm_ticket`
|
||||
RENAME TABLE `gm_tickets` TO `gm_ticket`;
|
||||
ALTER TABLE `gm_ticket`
|
||||
CHANGE `ticketId` `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
CHANGE `guid` `playerGuid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier of ticket creator',
|
||||
CHANGE `message` `description` text NOT NULL,
|
||||
CHANGE `haveTicket` `needMoreHelp` tinyint(3) unsigned NOT NULL DEFAULT '0';
|
||||
|
||||
-- `groups`
|
||||
ALTER TABLE `groups`
|
||||
CHANGE `raiddifficulty` `raidDifficulty` tinyint(3) unsigned NOT NULL DEFAULT '0';
|
||||
|
||||
-- `pet_aura`
|
||||
ALTER TABLE `pet_aura`
|
||||
CHANGE `caster_guid` `casterGuid` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'Full Global Unique Identifier',
|
||||
CHANGE `effect_mask` `effectMask` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `recalculate_mask` `recalculateMask` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `stackcount` `stackCount` tinyint(3) unsigned NOT NULL DEFAULT '1',
|
||||
CHANGE `maxduration` `maxDuration` int(11) NOT NULL DEFAULT '0',
|
||||
CHANGE `remaintime` `remainTime` int(11) NOT NULL DEFAULT '0',
|
||||
CHANGE `remaincharges` `remainCharges` tinyint(3) unsigned NOT NULL DEFAULT '0';
|
||||
@@ -0,0 +1,176 @@
|
||||
-- areatrigger_teleport
|
||||
ALTER TABLE `areatrigger_teleport`
|
||||
CHANGE `id` `ID` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `name` `Name` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL;
|
||||
|
||||
-- battleground_template
|
||||
ALTER TABLE `battleground_template`
|
||||
CHANGE `id` `ID` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0';
|
||||
|
||||
-- creature_equip_template
|
||||
ALTER TABLE `creature_equip_template`
|
||||
CHANGE `entry` `CreatureID` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `id` `ID` TINYINT(3) UNSIGNED NOT NULL DEFAULT '1',
|
||||
CHANGE `itemEntry1` `ItemID1` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `itemEntry2` `ItemID2` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `itemEntry3` `ItemID3` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0';
|
||||
|
||||
-- creature_formations
|
||||
ALTER TABLE `creature_formations`
|
||||
CHANGE `leaderGUID` `leaderGUID` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `memberGUID` `memberGUID` INT(10) UNSIGNED NOT NULL DEFAULT '0';
|
||||
|
||||
-- creature_model_info
|
||||
ALTER TABLE `creature_model_info`
|
||||
CHANGE `modelid` `DisplayID` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `bounding_radius` `BoundingRadius` FLOAT NOT NULL DEFAULT '0',
|
||||
CHANGE `combat_reach` `CombatReach` FLOAT NOT NULL DEFAULT '0',
|
||||
CHANGE `gender` `Gender` TINYINT(3) UNSIGNED NOT NULL DEFAULT '2',
|
||||
CHANGE `modelid_other_gender` `DisplayID_Other_Gender` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0';
|
||||
|
||||
-- gameobject_template
|
||||
ALTER TABLE `gameobject_template`
|
||||
CHANGE `data0` `Data0` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data1` `Data1` INT(11) NOT NULL DEFAULT '0',
|
||||
CHANGE `data2` `Data2` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data3` `Data3` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data4` `Data4` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data5` `Data5` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data6` `Data6` INT(11) NOT NULL DEFAULT '0',
|
||||
CHANGE `data7` `Data7` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data8` `Data8` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data9` `Data9` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data10` `Data10` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data11` `Data11` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data12` `Data12` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data13` `Data13` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data14` `Data14` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data15` `Data15` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data16` `Data16` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data17` `Data17` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data18` `Data18` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data19` `Data19` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data20` `Data20` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data21` `Data21` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data22` `Data22` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data23` `Data23` INT(10) UNSIGNED NOT NULL DEFAULT '0';
|
||||
|
||||
-- lfg_entrances -> lfg_dungeon_template
|
||||
RENAME TABLE `lfg_entrances` TO `lfg_dungeon_template`;
|
||||
|
||||
-- npc_text
|
||||
ALTER TABLE `npc_text`
|
||||
CHANGE `prob0` `Probability0` FLOAT NOT NULL DEFAULT '0',
|
||||
CHANGE `prob1` `Probability1` FLOAT NOT NULL DEFAULT '0',
|
||||
CHANGE `prob2` `Probability2` FLOAT NOT NULL DEFAULT '0',
|
||||
CHANGE `prob3` `Probability3` FLOAT NOT NULL DEFAULT '0',
|
||||
CHANGE `prob4` `Probability4` FLOAT NOT NULL DEFAULT '0',
|
||||
CHANGE `prob5` `Probability5` FLOAT NOT NULL DEFAULT '0',
|
||||
CHANGE `prob6` `Probability6` FLOAT NOT NULL DEFAULT '0',
|
||||
CHANGE `prob7` `Probability7` FLOAT NOT NULL DEFAULT '0';
|
||||
|
||||
-- npc_trainer
|
||||
ALTER TABLE `npc_trainer`
|
||||
CHANGE `entry` `ID` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `spell` `SpellID` MEDIUMINT(8) NOT NULL DEFAULT '0',
|
||||
CHANGE `spellcost` `MoneyCost` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `reqskill` `ReqSkillLine` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `reqskillvalue` `ReqSkillRank` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `reqlevel` `ReqLevel` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0';
|
||||
|
||||
-- page_text
|
||||
ALTER TABLE `page_text`
|
||||
CHANGE `entry` `ID` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `text` `Text` LONGTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
|
||||
CHANGE `next_page` `NextPageID` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `VerifiedBuild` `VerifiedBuild` SMALLINT(5) NULL DEFAULT '0';
|
||||
|
||||
-- player_xp_for_level
|
||||
ALTER TABLE `player_xp_for_level`
|
||||
CHANGE `lvl` `Level` TINYINT(3) UNSIGNED NOT NULL,
|
||||
CHANGE `xp_for_next_level` `Experience` INT(10) UNSIGNED NOT NULL;
|
||||
|
||||
-- points_of_interest
|
||||
ALTER TABLE `points_of_interest`
|
||||
CHANGE `entry` `ID` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `x` `PositionX` FLOAT NOT NULL DEFAULT '0',
|
||||
CHANGE `y` `PositionY` FLOAT NOT NULL DEFAULT '0',
|
||||
CHANGE `icon` `Icon` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `flags` `Flags` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `data` `Data` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `icon_name` `Name` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;
|
||||
|
||||
-- quest_poi
|
||||
ALTER TABLE `quest_poi`
|
||||
CHANGE `questId` `QuestID` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `objIndex` `ObjectiveIndex` INT(11) NOT NULL DEFAULT '0',
|
||||
CHANGE `mapid` `MapID` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `FloorId` `Floor` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `unk3` `Priority` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `unk4` `Flags` INT(10) UNSIGNED NOT NULL DEFAULT '0';
|
||||
|
||||
-- quest_poi_points
|
||||
ALTER TABLE `quest_poi_points`
|
||||
CHANGE `questId` `QuestID` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `id` `Idx1` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `idx` `Idx2` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `x` `X` INT(11) NOT NULL DEFAULT '0',
|
||||
CHANGE `y` `Y` INT(11) NOT NULL DEFAULT '0';
|
||||
|
||||
-- quest_template
|
||||
ALTER TABLE `quest_template`
|
||||
CHANGE `Id` `ID` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `Level` `QuestLevel` smallint(3) NOT NULL DEFAULT '1',
|
||||
CHANGE `ZoneOrSort` `QuestSortID` smallint(6) NOT NULL DEFAULT '0',
|
||||
CHANGE `Type` `QuestType` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `SuggestedPlayers` `SuggestedGroupNum` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardTitleId` `RewardTitle` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardItemId1` `RewardItem1` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardItemId2` `RewardItem2` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardItemId3` `RewardItem3` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardItemId4` `RewardItem4` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardItemCount1` `RewardAmount1` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardItemCount2` `RewardAmount2` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardItemCount3` `RewardAmount3` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardItemCount4` `RewardAmount4` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardChoiceItemId1` `RewardChoiceItemID1` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardChoiceItemId2` `RewardChoiceItemID2` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardChoiceItemId3` `RewardChoiceItemID3` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardChoiceItemId4` `RewardChoiceItemID4` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardChoiceItemId5` `RewardChoiceItemID5` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardChoiceItemId6` `RewardChoiceItemID6` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardChoiceItemCount1` `RewardChoiceItemQuantity1` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardChoiceItemCount2` `RewardChoiceItemQuantity2` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardChoiceItemCount3` `RewardChoiceItemQuantity3` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardChoiceItemCount4` `RewardChoiceItemQuantity4` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardChoiceItemCount5` `RewardChoiceItemQuantity5` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardChoiceItemCount6` `RewardChoiceItemQuantity6` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardFactionId1` `RewardFactionID1` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'faction id from Faction.dbc in this case',
|
||||
CHANGE `RewardFactionId2` `RewardFactionID2` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'faction id from Faction.dbc in this case',
|
||||
CHANGE `RewardFactionId3` `RewardFactionID3` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'faction id from Faction.dbc in this case',
|
||||
CHANGE `RewardFactionId4` `RewardFactionID4` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'faction id from Faction.dbc in this case',
|
||||
CHANGE `RewardFactionId5` `RewardFactionID5` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'faction id from Faction.dbc in this case',
|
||||
CHANGE `RewardFactionValueId1` `RewardFactionValue1` mediumint(8) NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardFactionValueId2` `RewardFactionValue2` mediumint(8) NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardFactionValueId3` `RewardFactionValue3` mediumint(8) NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardFactionValueId4` `RewardFactionValue4` mediumint(8) NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardFactionValueId5` `RewardFactionValue5` mediumint(8) NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardFactionValueIdOverride1` `RewardFactionOverride1` mediumint(8) NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardFactionValueIdOverride2` `RewardFactionOverride2` mediumint(8) NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardFactionValueIdOverride3` `RewardFactionOverride3` mediumint(8) NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardFactionValueIdOverride4` `RewardFactionOverride4` mediumint(8) NOT NULL DEFAULT '0',
|
||||
CHANGE `RewardFactionValueIdOverride5` `RewardFactionOverride5` mediumint(8) NOT NULL DEFAULT '0',
|
||||
CHANGE `Title` `LogTitle` text,
|
||||
CHANGE `Objectives` `LogDescription` text,
|
||||
CHANGE `Details` `QuestDescription` text,
|
||||
CHANGE `CompletedText` `QuestCompletionLog` text;
|
||||
|
||||
-- spell_target_position
|
||||
ALTER TABLE `spell_target_position`
|
||||
CHANGE `id` `ID` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Identifier',
|
||||
CHANGE `effIndex` `EffectIndex` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `target_map` `MapID` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE `target_position_x` `PositionX` FLOAT NOT NULL DEFAULT '0',
|
||||
CHANGE `target_position_y` `PositionY` FLOAT NOT NULL DEFAULT '0',
|
||||
CHANGE `target_position_z` `PositionZ` FLOAT NOT NULL DEFAULT '0',
|
||||
CHANGE `target_orientation` `Orientation` FLOAT NOT NULL DEFAULT '0';
|
||||
@@ -0,0 +1,44 @@
|
||||
DROP TABLE IF EXISTS `creature_questitem`;
|
||||
CREATE TABLE `creature_questitem` (
|
||||
`CreatureEntry` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`Idx` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`ItemId` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`CreatureEntry`,`Idx`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
DROP TABLE IF EXISTS `gameobject_questitem`;
|
||||
CREATE TABLE `gameobject_questitem` (
|
||||
`GameObjectEntry` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`Idx` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`ItemId` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`GameObjectEntry`,`Idx`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
INSERT INTO gameobject_questitem (`GameObjectEntry`, `Idx`, `ItemId`)
|
||||
(SELECT gameobject_template.entry, 0, gameobject_template.questItem1 FROM gameobject_template WHERE gameobject_template.questItem1 != 0);
|
||||
INSERT INTO gameobject_questitem (`GameObjectEntry`, `Idx`, `ItemId`)
|
||||
(SELECT gameobject_template.entry, 1, gameobject_template.questItem2 FROM gameobject_template WHERE gameobject_template.questItem2 != 0);
|
||||
INSERT INTO gameobject_questitem (`GameObjectEntry`, `Idx`, `ItemId`)
|
||||
(SELECT gameobject_template.entry, 2, gameobject_template.questItem3 FROM gameobject_template WHERE gameobject_template.questItem3 != 0);
|
||||
INSERT INTO gameobject_questitem (`GameObjectEntry`, `Idx`, `ItemId`)
|
||||
(SELECT gameobject_template.entry, 3, gameobject_template.questItem4 FROM gameobject_template WHERE gameobject_template.questItem4 != 0);
|
||||
INSERT INTO gameobject_questitem (`GameObjectEntry`, `Idx`, `ItemId`)
|
||||
(SELECT gameobject_template.entry, 4, gameobject_template.questItem5 FROM gameobject_template WHERE gameobject_template.questItem5 != 0);
|
||||
INSERT INTO gameobject_questitem (`GameObjectEntry`, `Idx`, `ItemId`)
|
||||
(SELECT gameobject_template.entry, 5, gameobject_template.questItem6 FROM gameobject_template WHERE gameobject_template.questItem6 != 0);
|
||||
|
||||
INSERT INTO creature_questitem (`CreatureEntry`, `Idx`, `ItemId`)
|
||||
(SELECT creature_template.entry, 0, creature_template.questItem1 FROM creature_template WHERE creature_template.questItem1 != 0);
|
||||
INSERT INTO creature_questitem (`CreatureEntry`, `Idx`, `ItemId`)
|
||||
(SELECT creature_template.entry, 1, creature_template.questItem2 FROM creature_template WHERE creature_template.questItem2 != 0);
|
||||
INSERT INTO creature_questitem (`CreatureEntry`, `Idx`, `ItemId`)
|
||||
(SELECT creature_template.entry, 2, creature_template.questItem3 FROM creature_template WHERE creature_template.questItem3 != 0);
|
||||
INSERT INTO creature_questitem (`CreatureEntry`, `Idx`, `ItemId`)
|
||||
(SELECT creature_template.entry, 3, creature_template.questItem4 FROM creature_template WHERE creature_template.questItem4 != 0);
|
||||
INSERT INTO creature_questitem (`CreatureEntry`, `Idx`, `ItemId`)
|
||||
(SELECT creature_template.entry, 4, creature_template.questItem5 FROM creature_template WHERE creature_template.questItem5 != 0);
|
||||
INSERT INTO creature_questitem (`CreatureEntry`, `Idx`, `ItemId`)
|
||||
(SELECT creature_template.entry, 5, creature_template.questItem6 FROM creature_template WHERE creature_template.questItem6 != 0);
|
||||
|
||||
ALTER TABLE `creature_template` DROP `questItem1`, DROP `questItem2`, DROP `questItem3`, DROP `questItem4`, DROP `questItem5`, DROP `questItem6`;
|
||||
ALTER TABLE `gameobject_template` DROP `questItem1`, DROP `questItem2`, DROP `questItem3`, DROP `questItem4`, DROP `questItem5`, DROP `questItem6`;
|
||||
@@ -79,8 +79,8 @@ int main(int argc, char** argv)
|
||||
std::string configFile = _TRINITY_REALM_CONFIG;
|
||||
std::string configService;
|
||||
auto vm = GetConsoleArguments(argc, argv, configFile, configService);
|
||||
// exit if help is enabled
|
||||
if (vm.count("help"))
|
||||
// exit if help or version is enabled
|
||||
if (vm.count("help") || vm.count("version"))
|
||||
return 0;
|
||||
|
||||
#if PLATFORM == PLATFORM_WINDOWS
|
||||
@@ -262,6 +262,7 @@ variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile
|
||||
options_description all("Allowed options");
|
||||
all.add_options()
|
||||
("help,h", "print usage message")
|
||||
("version,v", "print version build info")
|
||||
("config,c", value<std::string>(&configFile)->default_value(_TRINITY_REALM_CONFIG), "use <arg> as configuration file")
|
||||
;
|
||||
#if PLATFORM == PLATFORM_WINDOWS
|
||||
@@ -271,6 +272,8 @@ variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile
|
||||
;
|
||||
|
||||
all.add(win);
|
||||
#else
|
||||
(void)configService;
|
||||
#endif
|
||||
variables_map variablesMap;
|
||||
try
|
||||
@@ -285,6 +288,8 @@ variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile
|
||||
|
||||
if (variablesMap.count("help"))
|
||||
std::cout << all << "\n";
|
||||
else if (variablesMap.count("version"))
|
||||
std::cout << _FULLVERSION << "\n";
|
||||
|
||||
return variablesMap;
|
||||
}
|
||||
@@ -186,12 +186,12 @@ bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool Sto
|
||||
return hit;
|
||||
}
|
||||
|
||||
bool GameObjectModel::Relocate(const GameObject& go)
|
||||
bool GameObjectModel::UpdatePosition()
|
||||
{
|
||||
if (!iModel)
|
||||
return false;
|
||||
|
||||
ModelList::const_iterator it = model_list.find(go.GetDisplayId());
|
||||
ModelList::const_iterator it = model_list.find(owner->GetDisplayId());
|
||||
if (it == model_list.end())
|
||||
return false;
|
||||
|
||||
@@ -203,9 +203,9 @@ bool GameObjectModel::Relocate(const GameObject& go)
|
||||
return false;
|
||||
}
|
||||
|
||||
iPos = Vector3(go.GetPositionX(), go.GetPositionY(), go.GetPositionZ());
|
||||
iPos = Vector3(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ());
|
||||
|
||||
G3D::Matrix3 iRotation = G3D::Matrix3::fromEulerAnglesZYX(go.GetOrientation(), 0, 0);
|
||||
G3D::Matrix3 iRotation = G3D::Matrix3::fromEulerAnglesZYX(owner->GetOrientation(), 0, 0);
|
||||
iInvRot = iRotation.inverse();
|
||||
// transform bounding box:
|
||||
mdl_box = AABox(mdl_box.low() * iScale, mdl_box.high() * iScale);
|
||||
@@ -219,7 +219,7 @@ bool GameObjectModel::Relocate(const GameObject& go)
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
Vector3 pos(iBound.corner(i));
|
||||
go.SummonCreature(1, pos.x, pos.y, pos.z, 0, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
owner->SummonCreature(1, pos.x, pos.y, pos.z, 0, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
|
||||
static GameObjectModel* Create(const GameObject& go);
|
||||
|
||||
bool Relocate(GameObject const& go);
|
||||
bool UpdatePosition();
|
||||
};
|
||||
|
||||
#endif // _GAMEOBJECT_MODEL_H
|
||||
@@ -763,6 +763,9 @@ void SmartAI::SetCombatMove(bool on)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (me->HasUnitState(UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE))
|
||||
return;
|
||||
|
||||
me->GetMotionMaster()->MovementExpired();
|
||||
me->GetMotionMaster()->Clear(true);
|
||||
me->StopMoving();
|
||||
|
||||
@@ -247,7 +247,14 @@ class SmartScript
|
||||
DecPhase(abs(p));
|
||||
}
|
||||
|
||||
void DecPhase(int32 p = 1) { mEventPhase -= (mEventPhase < (uint32)p ? (uint32)p - mEventPhase : (uint32)p); }
|
||||
void DecPhase(int32 p = 1)
|
||||
{
|
||||
if(mEventPhase > (uint32)p)
|
||||
mEventPhase -= (uint32)p;
|
||||
else
|
||||
mEventPhase = 0;
|
||||
}
|
||||
|
||||
bool IsInPhase(uint32 p) const { return ((1 << (mEventPhase - 1)) & p) != 0; }
|
||||
void SetPhase(uint32 p = 0) { mEventPhase = p; }
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ void BattlegroundWS::PostUpdateImpl(uint32 diff)
|
||||
player->CastSpell(player, WS_SPELL_FOCUSED_ASSAULT, true);
|
||||
_flagDebuffState = 1;
|
||||
}
|
||||
else if (_flagDebuffState == 1 && _flagSpellForceTimer >= 900000) //15 minutes
|
||||
else if (_flagDebuffState == 1 && _flagSpellForceTimer >= 15*MINUTE*IN_MILLISECONDS) //15 minutes
|
||||
{
|
||||
if (Player* player = ObjectAccessor::FindPlayer(m_FlagKeepers[0]))
|
||||
{
|
||||
|
||||
@@ -78,6 +78,7 @@ ChatCommand* ChatHandler::getCommandTable()
|
||||
|
||||
// cache top-level commands
|
||||
size_t added = 0;
|
||||
free(commandTableCache);
|
||||
commandTableCache = (ChatCommand*)malloc(sizeof(ChatCommand) * total);
|
||||
ASSERT(commandTableCache);
|
||||
memset(commandTableCache, 0, sizeof(ChatCommand) * total);
|
||||
|
||||
@@ -1548,6 +1548,9 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
||||
if (!((1 << i) & cond->SourceGroup))
|
||||
continue;
|
||||
|
||||
if (spellInfo->Effects[i].ChainTarget > 0)
|
||||
continue;
|
||||
|
||||
switch (spellInfo->Effects[i].TargetA.GetSelectionCategory())
|
||||
{
|
||||
case TARGET_SELECT_CATEGORY_NEARBY:
|
||||
@@ -1568,7 +1571,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
||||
break;
|
||||
}
|
||||
|
||||
TC_LOG_ERROR("sql.sql", "SourceEntry %u SourceGroup %u in `condition` table - spell %u does not have implicit targets of types: _AREA_, _CONE_, _NEARBY_ for effect %u, SourceGroup needs correction, ignoring.", cond->SourceEntry, origGroup, cond->SourceEntry, uint32(i));
|
||||
TC_LOG_ERROR("sql.sql", "SourceEntry %u SourceGroup %u in `condition` table - spell %u does not have implicit targets of types: _AREA_, _CONE_, _NEARBY_, __CHAIN__ for effect %u, SourceGroup needs correction, ignoring.", cond->SourceEntry, origGroup, cond->SourceEntry, uint32(i));
|
||||
cond->SourceGroup &= ~(1 << i);
|
||||
}
|
||||
// all effects were removed, no need to add the condition at all
|
||||
|
||||
@@ -1388,6 +1388,12 @@ bool Creature::CanStartAttack(Unit const* who, bool force) const
|
||||
if (IsCivilian())
|
||||
return false;
|
||||
|
||||
// This set of checks is should be done only for creatures
|
||||
if ((HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC) && who->GetTypeId() != TYPEID_PLAYER) // flag is valid only for non player characters
|
||||
|| (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC) && who->GetTypeId() == TYPEID_PLAYER) // immune to PC and target is a player, return false
|
||||
|| (who->GetOwner() && who->GetOwner()->GetTypeId() == TYPEID_PLAYER && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC))) // player pets are immune to pc as well
|
||||
return false;
|
||||
|
||||
// Do not attack non-combat pets
|
||||
if (who->GetTypeId() == TYPEID_UNIT && who->GetCreatureType() == CREATURE_TYPE_NON_COMBAT_PET)
|
||||
return false;
|
||||
@@ -1525,9 +1531,9 @@ void Creature::setDeathState(DeathState s)
|
||||
SetUInt32Value(UNIT_NPC_FLAGS, cinfo->npcflag);
|
||||
ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~UNIT_STATE_IGNORE_PATHFINDING));
|
||||
SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool));
|
||||
LoadCreaturesAddon(true);
|
||||
Motion_Initialize();
|
||||
Unit::setDeathState(ALIVE);
|
||||
LoadCreaturesAddon(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -134,7 +134,6 @@ struct CreatureTemplate
|
||||
float ModDamage;
|
||||
float ModExperience;
|
||||
bool RacialLeader;
|
||||
uint32 questItems[MAX_CREATURE_QUEST_ITEMS];
|
||||
uint32 movementId;
|
||||
bool RegenHealth;
|
||||
uint32 MechanicImmuneMask;
|
||||
@@ -171,6 +170,9 @@ struct CreatureTemplate
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<uint32> CreatureQuestItemList;
|
||||
typedef std::unordered_map<uint32, CreatureQuestItemList> CreatureQuestItemMap;
|
||||
|
||||
// Benchmarked: Faster than std::map (insert/find)
|
||||
typedef std::unordered_map<uint32, CreatureTemplate> CreatureTemplateContainer;
|
||||
|
||||
|
||||
@@ -1797,6 +1797,9 @@ void GameObject::Use(Unit* user)
|
||||
return;
|
||||
}
|
||||
|
||||
if (Player* player = user->ToPlayer())
|
||||
sOutdoorPvPMgr->HandleCustomSpell(player, spellId, this);
|
||||
|
||||
if (spellCaster)
|
||||
spellCaster->CastSpell(user, spellInfo, triggered);
|
||||
else
|
||||
@@ -2408,7 +2411,7 @@ void GameObject::UpdateModelPosition()
|
||||
if (GetMap()->ContainsGameObjectModel(*m_model))
|
||||
{
|
||||
GetMap()->RemoveGameObjectModel(*m_model);
|
||||
m_model->Relocate(*this);
|
||||
m_model->UpdatePosition();
|
||||
GetMap()->InsertGameObjectModel(*m_model);
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,6 @@ struct GameObjectTemplate
|
||||
uint32 faction;
|
||||
uint32 flags;
|
||||
float size;
|
||||
uint32 questItems[MAX_GAMEOBJECT_QUEST_ITEMS];
|
||||
int32 unkInt32;
|
||||
union // different GO types have different data field
|
||||
{
|
||||
@@ -634,6 +633,9 @@ struct GameObjectData
|
||||
bool dbData;
|
||||
};
|
||||
|
||||
typedef std::vector<uint32> GameObjectQuestItemList;
|
||||
typedef std::unordered_map<uint32, GameObjectQuestItemList> GameObjectQuestItemMap;
|
||||
|
||||
// For containers: [GO_NOT_READY]->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED->GO_READY -> ...
|
||||
// For bobber: GO_NOT_READY ->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED-><deleted>
|
||||
// For door(closed):[GO_NOT_READY]->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED->GO_READY(close) -> ...
|
||||
|
||||
@@ -9802,13 +9802,9 @@ void Player::SendBattlefieldWorldStates()
|
||||
{
|
||||
if (Battlefield* wg = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG))
|
||||
{
|
||||
if (wg->IsWarTime())
|
||||
SendUpdateWorldState(ClockWorldState[1], uint32(time(NULL)));
|
||||
else // Time to next battle
|
||||
{
|
||||
uint32 timer = wg->GetTimer() / 1000;
|
||||
SendUpdateWorldState(ClockWorldState[1], time(NULL) + timer);
|
||||
}
|
||||
SendUpdateWorldState(BATTLEFIELD_WG_WORLD_STATE_ACTIVE, wg->IsWarTime() ? 0 : 1);
|
||||
uint32 timer = wg->IsWarTime() ? 0 : (wg->GetTimer() / 1000); // 0 - Time to next battle
|
||||
SendUpdateWorldState(ClockWorldState[1], uint32(time(NULL) + timer));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17968,9 +17964,9 @@ void Player::_LoadAuras(PreparedQueryResult result, uint32 timediff)
|
||||
TC_LOG_DEBUG("entities.player.loading", "Loading auras for player %u", GetGUIDLow());
|
||||
|
||||
/* 0 1 2 3 4 5 6 7 8 9 10
|
||||
QueryResult* result = CharacterDatabase.PQuery("SELECT caster_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2,
|
||||
QueryResult* result = CharacterDatabase.PQuery("SELECT casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2,
|
||||
11 12 13
|
||||
maxduration, remaintime, remaincharges FROM character_aura WHERE guid = '%u'", GetGUIDLow());
|
||||
maxDuration, remainTime, remainCharges FROM character_aura WHERE guid = '%u'", GetGUIDLow());
|
||||
*/
|
||||
|
||||
if (result)
|
||||
@@ -23191,15 +23187,17 @@ void Player::SendTransferAborted(uint32 mapid, TransferAbortReason reason, uint8
|
||||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
void Player::SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time)
|
||||
void Player::SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time, bool welcome)
|
||||
{
|
||||
// type of warning, based on the time remaining until reset
|
||||
uint32 type;
|
||||
if (time > 3600)
|
||||
if (welcome)
|
||||
type = RAID_INSTANCE_WELCOME;
|
||||
else if (time > 900 && time <= 3600)
|
||||
else if (time > 21600)
|
||||
type = RAID_INSTANCE_WELCOME;
|
||||
else if (time > 3600)
|
||||
type = RAID_INSTANCE_WARNING_HOURS;
|
||||
else if (time > 300 && time <= 900)
|
||||
else if (time > 300)
|
||||
type = RAID_INSTANCE_WARNING_MIN;
|
||||
else
|
||||
type = RAID_INSTANCE_WARNING_MIN_SOON;
|
||||
@@ -24224,6 +24222,9 @@ bool Player::IsAtGroupRewardDistance(WorldObject const* pRewardSource) const
|
||||
if (player->GetMapId() != pRewardSource->GetMapId() || player->GetInstanceId() != pRewardSource->GetInstanceId())
|
||||
return false;
|
||||
|
||||
if (player->GetMap()->IsDungeon())
|
||||
return true;
|
||||
|
||||
return pRewardSource->GetDistance(player) <= sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE);
|
||||
}
|
||||
|
||||
@@ -26292,7 +26293,7 @@ void Player::SetMap(Map* map)
|
||||
|
||||
void Player::_LoadGlyphs(PreparedQueryResult result)
|
||||
{
|
||||
// SELECT spec, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6, glyph7, glyph8, glyph9 FROM character_glyphs WHERE guid = '%u'
|
||||
// SELECT talentGroup, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6 from character_glyphs WHERE guid = '%u'
|
||||
if (!result)
|
||||
return;
|
||||
|
||||
@@ -26335,7 +26336,7 @@ void Player::_SaveGlyphs(SQLTransaction& trans)
|
||||
|
||||
void Player::_LoadTalents(PreparedQueryResult result)
|
||||
{
|
||||
// SetPQuery(PLAYER_LOGIN_QUERY_LOADTALENTS, "SELECT spell, spec FROM character_talent WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||
// SetPQuery(PLAYER_LOGIN_QUERY_LOADTALENTS, "SELECT spell, talentGroup FROM character_talent WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||
if (result)
|
||||
{
|
||||
do
|
||||
|
||||
@@ -1279,7 +1279,7 @@ class Player : public Unit, public GridObject<Player>
|
||||
void SendInitialPacketsAfterAddToMap();
|
||||
void SendSupercededSpell(uint32 oldSpell, uint32 newSpell);
|
||||
void SendTransferAborted(uint32 mapid, TransferAbortReason reason, uint8 arg = 0);
|
||||
void SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time);
|
||||
void SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time, bool welcome);
|
||||
|
||||
bool CanInteractWithQuestGiver(Object* questGiver);
|
||||
Creature* GetNPCIfCanInteractWith(ObjectGuid guid, uint32 npcflagmask);
|
||||
|
||||
@@ -1706,6 +1706,13 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe
|
||||
{
|
||||
// We're going to call functions which can modify content of the list during iteration over it's elements
|
||||
// Let's copy the list so we can prevent iterator invalidation
|
||||
// check if caster is immune to damage
|
||||
if (caster->IsImmunedToDamage(schoolMask))
|
||||
{
|
||||
victim->SendSpellMiss(caster, (*itr)->GetSpellInfo()->Id, SPELL_MISS_IMMUNE);
|
||||
continue;
|
||||
}
|
||||
|
||||
AuraEffectList vSplitDamagePctCopy(victim->GetAuraEffectsByType(SPELL_AURA_SPLIT_DAMAGE_PCT));
|
||||
for (AuraEffectList::iterator itr = vSplitDamagePctCopy.begin(); itr != vSplitDamagePctCopy.end() && dmgInfo.GetDamage() > 0; ++itr)
|
||||
{
|
||||
@@ -1731,6 +1738,14 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe
|
||||
splitDamage = RoundToInterval(splitDamage, uint32(0), uint32(dmgInfo.GetDamage()));
|
||||
|
||||
dmgInfo.AbsorbDamage(splitDamage);
|
||||
|
||||
// check if caster is immune to damage
|
||||
if (caster->IsImmunedToDamage(schoolMask))
|
||||
{
|
||||
victim->SendSpellMiss(caster, (*itr)->GetSpellInfo()->Id, SPELL_MISS_IMMUNE);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32 split_absorb = 0;
|
||||
DealDamageMods(caster, splitDamage, &split_absorb);
|
||||
|
||||
@@ -9567,6 +9582,26 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo) const
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 Unit::GetSchoolImmunityMask() const
|
||||
{
|
||||
uint32 mask = 0;
|
||||
SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_SCHOOL];
|
||||
for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
|
||||
mask |= itr->type;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
uint32 Unit::GetMechanicImmunityMask() const
|
||||
{
|
||||
uint32 mask = 0;
|
||||
SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
|
||||
for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
|
||||
mask |= (1 << itr->type);
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const
|
||||
{
|
||||
if (!spellInfo || !spellInfo->Effects[index].IsEffect())
|
||||
@@ -10709,6 +10744,13 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
|
||||
/// @todo possible affect only on MOVE_RUN
|
||||
if (int32 normalization = GetMaxPositiveAuraModifier(SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED))
|
||||
{
|
||||
if (Creature* creature = ToCreature())
|
||||
{
|
||||
uint32 immuneMask = creature->GetCreatureTemplate()->MechanicImmuneMask;
|
||||
if (immuneMask & (1 << MECHANIC_SNARE) || immuneMask & (1 << MECHANIC_DAZE))
|
||||
break;
|
||||
}
|
||||
|
||||
// Use speed from aura
|
||||
float max_speed = normalization / (IsControlledByPlayer() ? playerBaseMoveSpeed[mtype] : baseMoveSpeed[mtype]);
|
||||
if (speed > max_speed)
|
||||
@@ -10730,15 +10772,15 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
|
||||
// Apply strongest slow aura mod to speed
|
||||
int32 slow = GetMaxNegativeAuraModifier(SPELL_AURA_MOD_DECREASE_SPEED);
|
||||
if (slow)
|
||||
{
|
||||
AddPct(speed, slow);
|
||||
if (float minSpeedMod = (float)GetMaxPositiveAuraModifier(SPELL_AURA_MOD_MINIMUM_SPEED))
|
||||
{
|
||||
float min_speed = minSpeedMod / 100.0f;
|
||||
if (speed < min_speed)
|
||||
speed = min_speed;
|
||||
}
|
||||
|
||||
if (float minSpeedMod = (float)GetMaxPositiveAuraModifier(SPELL_AURA_MOD_MINIMUM_SPEED))
|
||||
{
|
||||
float min_speed = minSpeedMod / 100.0f;
|
||||
if (speed < min_speed)
|
||||
speed = min_speed;
|
||||
}
|
||||
|
||||
SetSpeed(mtype, speed, forced);
|
||||
}
|
||||
|
||||
@@ -14846,7 +14888,7 @@ void Unit::KnockbackFrom(float x, float y, float speedXY, float speedZ)
|
||||
float vcos, vsin;
|
||||
GetSinCos(x, y, vsin, vcos);
|
||||
SendMoveKnockBack(player, speedXY, -speedZ, vcos, vsin);
|
||||
|
||||
|
||||
if (player->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) || player->HasAuraType(SPELL_AURA_FLY))
|
||||
player->SetCanFly(true, true);
|
||||
}
|
||||
|
||||
@@ -1972,6 +1972,8 @@ class Unit : public WorldObject
|
||||
void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply);
|
||||
void ApplySpellDispelImmunity(const SpellInfo* spellProto, DispelType type, bool apply);
|
||||
virtual bool IsImmunedToSpell(SpellInfo const* spellInfo) const; // redefined in Creature
|
||||
uint32 GetSchoolImmunityMask() const;
|
||||
uint32 GetMechanicImmunityMask() const;
|
||||
|
||||
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const;
|
||||
bool IsImmunedToDamage(SpellInfo const* spellInfo) const;
|
||||
|
||||
@@ -547,7 +547,7 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields)
|
||||
creatureTemplate.ModExperience = fields[72].GetFloat();
|
||||
creatureTemplate.RacialLeader = fields[73].GetBool();
|
||||
|
||||
for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
|
||||
creatureTemplate.movementId = fields[70].GetUInt32();
|
||||
creatureTemplate.questItems[i] = fields[74 + i].GetUInt32();
|
||||
|
||||
creatureTemplate.movementId = fields[80].GetUInt32();
|
||||
@@ -3899,10 +3899,12 @@ void ObjectMgr::LoadQuests()
|
||||
QueryResult result = WorldDatabase.Query("SELECT "
|
||||
//0 1 2 3 4 5 6 7 8 9 10 11 12
|
||||
"ID, Method, QuestLevel, MinLevel, MaxLevel, QuestSortID, QuestType, SuggestedGroupNum, LimitTime, RequiredClasses, RequiredRaces, RequiredSkillId, RequiredSkillPoints, "
|
||||
// 13 14 15 16 17 18 19 20
|
||||
"RequiredFactionId1, RequiredFactionId2, RequiredFactionValue1, RequiredFactionValue2, RequiredMinRepFaction, RequiredMaxRepFaction, RequiredMinRepValue, RequiredMaxRepValue, "
|
||||
// 21 22 23 24 25 26 27 28 29 30 31
|
||||
"PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestIdChain, RewardXPId, RewardOrRequiredMoney, RewardMoneyMaxLevel, RewardSpell, RewardSpellCast, RewardHonor, RewardHonorMultiplier, "
|
||||
// 9 10 11 12
|
||||
"RequiredFactionId1, RequiredFactionId2, RequiredFactionValue1, RequiredFactionValue2, "
|
||||
// 13 14 15 16 17 18 19 20
|
||||
"NextQuestIdChain, RewardXPId, RewardOrRequiredMoney, RewardMoneyMaxLevel, RewardSpell, RewardSpellCast, RewardHonor, RewardHonorMultiplier, "
|
||||
// 21 22 23 24 25 26
|
||||
"SourceItemId, Flags, RewardTitle, RequiredPlayerKills, RewardTalents, RewardArenaPoints, "
|
||||
// 32 33 34 35 36 37 38 39 40 41 42 43
|
||||
"RewardMailTemplateId, RewardMailDelay, SourceItemId, SourceItemCount, SourceSpellId, Flags, SpecialFlags, MinimapTargetMark, RewardTitle, RequiredPlayerKills, RewardTalents, RewardArenaPoints, "
|
||||
// 44 45 46 47 48 49 50 51 52 53 54 55 56
|
||||
@@ -3951,6 +3953,31 @@ void ObjectMgr::LoadQuests()
|
||||
|
||||
std::map<uint32, uint32> usedMailTemplates;
|
||||
|
||||
// Load `quest_template_addon`
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
result = WorldDatabase.Query("SELECT ID, MaxLevel, AllowableClasses, SourceSpellID, PrevQuestID, NextQuestID, ExclusiveGroup, RewardMailTemplateID, RewardMailDelay, "
|
||||
//9 10 11 12 13 14 15 16
|
||||
"RequiredSkillID, RequiredSkillPoints, RequiredMinRepFaction, RequiredMaxRepFaction, RequiredMinRepValue, RequiredMaxRepValue, ProvidedItemCount, SpecialFlags FROM quest_template_addon");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
TC_LOG_ERROR("server.loading", ">> Loaded 0 quest template addons. DB table `quest_template_addon` is empty.");
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
uint32 questId = fields[0].GetUInt32();
|
||||
|
||||
auto itr = _questTemplates.find(questId);
|
||||
if (itr != _questTemplates.end())
|
||||
itr->second->LoadQuestTemplateAddon(fields);
|
||||
else
|
||||
TC_LOG_ERROR("server.loading", "Table `quest_template_addon` has data for quest %u but such quest does not exist", questId);
|
||||
} while (result->NextRow());
|
||||
}
|
||||
|
||||
// Post processing
|
||||
for (QuestMap::iterator iter = _questTemplates.begin(); iter != _questTemplates.end(); ++iter)
|
||||
{
|
||||
@@ -5247,7 +5274,7 @@ void ObjectMgr::LoadPageTexts()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
// 0 1 2
|
||||
// 0 1 2
|
||||
QueryResult result = WorldDatabase.Query("SELECT ID, Text, NextPageID FROM page_text");
|
||||
|
||||
if (!result)
|
||||
@@ -6242,7 +6269,7 @@ void ObjectMgr::LoadAreaTriggerTeleports()
|
||||
|
||||
_areaTriggerStore.clear(); // need for reload case
|
||||
|
||||
// 0 1 2 3 4 5
|
||||
// 0 1 2 3 4 5
|
||||
QueryResult result = WorldDatabase.Query("SELECT ID, target_map, target_position_x, target_position_y, target_position_z, target_orientation FROM areatrigger_teleport");
|
||||
if (!result)
|
||||
{
|
||||
@@ -7319,7 +7346,7 @@ void ObjectMgr::LoadPointsOfInterest()
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
// 0 1 2 3 4 5 6
|
||||
// 0 1 2 3 4 5 6
|
||||
QueryResult result = WorldDatabase.Query("SELECT ID, PositionX, PositionY, Icon, Flags, Data, Name FROM points_of_interest");
|
||||
|
||||
if (!result)
|
||||
@@ -7365,7 +7392,7 @@ void ObjectMgr::LoadQuestPOI()
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
// 0 1 2 3 4 5 6 7
|
||||
// 0 1 2 3 4 5 6 7
|
||||
QueryResult result = WorldDatabase.Query("SELECT QuestID, id, ObjectiveIndex, MapID, WorldMapAreaId, Floor, Priority, Flags FROM quest_poi order by QuestID");
|
||||
|
||||
if (!result)
|
||||
@@ -7374,7 +7401,7 @@ void ObjectMgr::LoadQuestPOI()
|
||||
return;
|
||||
}
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3
|
||||
QueryResult points = WorldDatabase.Query("SELECT QuestID, Idx1, X, Y FROM quest_poi_points ORDER BY QuestID DESC, Idx2");
|
||||
|
||||
std::vector<std::vector<std::vector<QuestPOIPoint> > > POIs;
|
||||
@@ -9491,3 +9518,63 @@ PlayerInfo const* ObjectMgr::GetPlayerInfo(uint32 race, uint32 class_) const
|
||||
return NULL;
|
||||
return info;
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadGameObjectQuestItems()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
// 0 1
|
||||
QueryResult result = WorldDatabase.Query("SELECT GameObjectEntry, ItemId FROM gameobject_questitem ORDER BY Idx ASC");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
TC_LOG_INFO("server.loading", ">> Loaded 0 gameobject quest items. DB table `gameobject_questitem` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 count = 0;
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
uint32 entry = fields[0].GetUInt32();
|
||||
uint32 item = fields[1].GetUInt32();
|
||||
|
||||
_gameObjectQuestItemStore[entry].push_back(item);
|
||||
|
||||
++count;
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
TC_LOG_INFO("server.loading", ">> Loaded %u gameobject quest items in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadCreatureQuestItems()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
// 0 1
|
||||
QueryResult result = WorldDatabase.Query("SELECT CreatureEntry, ItemId FROM creature_questitem ORDER BY Idx ASC");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
TC_LOG_INFO("server.loading", ">> Loaded 0 creature quest items. DB table `creature_questitem` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 count = 0;
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
uint32 entry = fields[0].GetUInt32();
|
||||
uint32 item = fields[1].GetUInt32();
|
||||
|
||||
_creatureQuestItemStore[entry].push_back(item);
|
||||
|
||||
++count;
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
TC_LOG_INFO("server.loading", ">> Loaded %u creature quest items in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "ObjectDefines.h"
|
||||
#include "VehicleDefines.h"
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <map>
|
||||
#include <limits>
|
||||
#include "ConditionMgr.h"
|
||||
@@ -66,8 +67,8 @@ struct TempSummonGroupKey
|
||||
|
||||
bool operator<(TempSummonGroupKey const& rhs) const
|
||||
{
|
||||
// memcmp is only reliable if struct doesn't have any padding (packed)
|
||||
return memcmp(this, &rhs, sizeof(TempSummonGroupKey)) < 0;
|
||||
return std::tie(_summonerEntry, _summonerType, _summonGroup) <
|
||||
std::tie(rhs._summonerEntry, rhs._summonerType, rhs._summonGroup);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -750,6 +751,24 @@ class ObjectMgr
|
||||
|
||||
ObjectGuid GetPlayerGUIDByName(std::string const& name) const;
|
||||
|
||||
GameObjectQuestItemList const* GetGameObjectQuestItemList(uint32 id) const
|
||||
{
|
||||
GameObjectQuestItemMap::const_iterator itr = _gameObjectQuestItemStore.find(id);
|
||||
if (itr != _gameObjectQuestItemStore.end())
|
||||
return &itr->second;
|
||||
return NULL;
|
||||
}
|
||||
GameObjectQuestItemMap const* GetGameObjectQuestItemMap() const { return &_gameObjectQuestItemStore; }
|
||||
|
||||
CreatureQuestItemList const* GetCreatureQuestItemList(uint32 id) const
|
||||
{
|
||||
CreatureQuestItemMap::const_iterator itr = _creatureQuestItemStore.find(id);
|
||||
if (itr != _creatureQuestItemStore.end())
|
||||
return &itr->second;
|
||||
return NULL;
|
||||
}
|
||||
CreatureQuestItemMap const* GetCreatureQuestItemMap() const { return &_creatureQuestItemStore; }
|
||||
|
||||
/**
|
||||
* Retrieves the player name by guid.
|
||||
*
|
||||
@@ -958,6 +977,8 @@ class ObjectMgr
|
||||
void LoadCreatureTemplateAddons();
|
||||
void LoadCreatureTemplate(Field* fields);
|
||||
void CheckCreatureTemplate(CreatureTemplate const* cInfo);
|
||||
void LoadGameObjectQuestItems();
|
||||
void LoadCreatureQuestItems();
|
||||
void LoadTempSummons();
|
||||
void LoadCreatures();
|
||||
void LoadLinkedRespawn();
|
||||
@@ -1444,6 +1465,8 @@ class ObjectMgr
|
||||
CreatureAddonContainer _creatureAddonStore;
|
||||
CreatureAddonContainer _creatureTemplateAddonStore;
|
||||
GameObjectAddonContainer _gameObjectAddonStore;
|
||||
GameObjectQuestItemMap _gameObjectQuestItemStore;
|
||||
CreatureQuestItemMap _creatureQuestItemStore;
|
||||
EquipmentInfoContainer _equipmentInfoStore;
|
||||
LinkedRespawnContainer _linkedRespawnStore;
|
||||
CreatureLocaleContainer _creatureLocaleStore;
|
||||
|
||||
@@ -969,7 +969,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject)
|
||||
continue;
|
||||
if (i->AllowedForPlayer(member))
|
||||
{
|
||||
if (member->IsWithinDistInMap(pLootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
|
||||
if (member->IsAtGroupRewardDistance(pLootedObject))
|
||||
{
|
||||
r->totalPlayersRolling++;
|
||||
|
||||
@@ -1054,7 +1054,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject)
|
||||
|
||||
if (i->AllowedForPlayer(member))
|
||||
{
|
||||
if (member->IsWithinDistInMap(pLootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
|
||||
if (member->IsAtGroupRewardDistance(pLootedObject))
|
||||
{
|
||||
r->totalPlayersRolling++;
|
||||
r->playerVote[member->GetGUID()] = NOT_EMITED_YET;
|
||||
@@ -1113,7 +1113,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject)
|
||||
continue;
|
||||
|
||||
bool allowedForPlayer = i->AllowedForPlayer(playerToRoll);
|
||||
if (allowedForPlayer && playerToRoll->IsWithinDistInMap(lootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
|
||||
if (allowedForPlayer && playerToRoll->IsAtGroupRewardDistance(lootedObject))
|
||||
{
|
||||
r->totalPlayersRolling++;
|
||||
if (playerToRoll->GetPassOnGroupLoot())
|
||||
@@ -1188,7 +1188,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject)
|
||||
continue;
|
||||
|
||||
bool allowedForPlayer = i->AllowedForPlayer(playerToRoll);
|
||||
if (allowedForPlayer && playerToRoll->IsWithinDistInMap(lootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
|
||||
if (allowedForPlayer && playerToRoll->IsAtGroupRewardDistance(lootedObject))
|
||||
{
|
||||
r->totalPlayersRolling++;
|
||||
r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET;
|
||||
@@ -1264,7 +1264,7 @@ void Group::MasterLoot(Loot* loot, WorldObject* pLootedObject)
|
||||
if (!looter->IsInWorld())
|
||||
continue;
|
||||
|
||||
if (looter->IsWithinDistInMap(pLootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
|
||||
if (looter->IsAtGroupRewardDistance(pLootedObject))
|
||||
{
|
||||
data << uint64(looter->GetGUID());
|
||||
++real_count;
|
||||
@@ -1276,7 +1276,7 @@ void Group::MasterLoot(Loot* loot, WorldObject* pLootedObject)
|
||||
for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
Player* looter = itr->GetSource();
|
||||
if (looter->IsWithinDistInMap(pLootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
|
||||
if (looter->IsAtGroupRewardDistance(pLootedObject))
|
||||
looter->GetSession()->SendPacket(&data);
|
||||
}
|
||||
}
|
||||
@@ -1791,7 +1791,7 @@ void Group::UpdateLooterGuid(WorldObject* pLootedObject, bool ifneed)
|
||||
{
|
||||
// not update if only update if need and ok
|
||||
Player* looter = ObjectAccessor::FindPlayer(guid_itr->guid);
|
||||
if (looter && looter->IsWithinDistInMap(pLootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
|
||||
if (looter && looter->IsAtGroupRewardDistance(pLootedObject))
|
||||
return;
|
||||
}
|
||||
++guid_itr;
|
||||
@@ -1802,7 +1802,7 @@ void Group::UpdateLooterGuid(WorldObject* pLootedObject, bool ifneed)
|
||||
for (member_citerator itr = guid_itr; itr != m_memberSlots.end(); ++itr)
|
||||
{
|
||||
if (Player* player = ObjectAccessor::FindPlayer(itr->guid))
|
||||
if (player->IsWithinDistInMap(pLootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
|
||||
if (player->IsAtGroupRewardDistance(pLootedObject))
|
||||
{
|
||||
pNewLooter = player;
|
||||
break;
|
||||
@@ -1815,7 +1815,7 @@ void Group::UpdateLooterGuid(WorldObject* pLootedObject, bool ifneed)
|
||||
for (member_citerator itr = m_memberSlots.begin(); itr != guid_itr; ++itr)
|
||||
{
|
||||
if (Player* player = ObjectAccessor::FindPlayer(itr->guid))
|
||||
if (player->IsWithinDistInMap(pLootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
|
||||
if (player->IsAtGroupRewardDistance(pLootedObject))
|
||||
{
|
||||
pNewLooter = player;
|
||||
break;
|
||||
|
||||
@@ -124,7 +124,7 @@ void GroupMgr::LoadGroups()
|
||||
// 0 1 2 3 4 5 6 7 8 9
|
||||
QueryResult result = CharacterDatabase.Query("SELECT g.leaderGuid, g.lootMethod, g.looterGuid, g.lootThreshold, g.icon1, g.icon2, g.icon3, g.icon4, g.icon5, g.icon6"
|
||||
// 10 11 12 13 14 15 16 17 18
|
||||
", g.icon7, g.icon8, g.groupType, g.difficulty, g.raiddifficulty, g.masterLooterGuid, g.guid, lfg.dungeon, lfg.state FROM groups g LEFT JOIN lfg_data lfg ON lfg.guid = g.guid ORDER BY g.guid ASC");
|
||||
", g.icon7, g.icon8, g.groupType, g.difficulty, g.raidDifficulty, g.masterLooterGuid, g.guid, lfg.dungeon, lfg.state FROM groups g LEFT JOIN lfg_data lfg ON lfg.guid = g.guid ORDER BY g.guid ASC");
|
||||
if (!result)
|
||||
{
|
||||
TC_LOG_INFO("server.loading", ">> Loaded 0 group definitions. DB table `groups` is empty!");
|
||||
|
||||
@@ -177,7 +177,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/)
|
||||
if (!member)
|
||||
continue;
|
||||
|
||||
if (player->IsWithinDistInMap(member, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
|
||||
if (player->IsAtGroupRewardDistance(member))
|
||||
playersNear.push_back(member);
|
||||
}
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ void WorldSession::HandleMoveWorldportAckOpcode()
|
||||
if (time_t timeReset = sInstanceSaveMgr->GetResetTimeFor(mEntry->MapID, diff))
|
||||
{
|
||||
uint32 timeleft = uint32(timeReset - time(NULL));
|
||||
GetPlayer()->SendInstanceResetWarning(mEntry->MapID, diff, timeleft);
|
||||
GetPlayer()->SendInstanceResetWarning(mEntry->MapID, diff, timeleft, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPacket& recvData)
|
||||
data << info->unk1; // 2.0.3, string
|
||||
data.append(info->raw.data, MAX_GAMEOBJECT_DATA);
|
||||
data << float(info->size); // go size
|
||||
for (uint32 i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i)
|
||||
|
||||
data << uint32(info->questItems[i]); // itemId[6], quest drop
|
||||
data << int32(info->unkInt32); // 4.x, unknown
|
||||
SendPacket(&data);
|
||||
|
||||
@@ -642,10 +642,10 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, b
|
||||
|
||||
if (warn)
|
||||
{
|
||||
if (now <= resetTime)
|
||||
if (now >= resetTime)
|
||||
timeLeft = 0;
|
||||
else
|
||||
timeLeft = uint32(now - resetTime);
|
||||
timeLeft = uint32(resetTime - now);
|
||||
|
||||
((InstanceMap*)map2)->SendResetWarnings(timeLeft);
|
||||
}
|
||||
|
||||
@@ -151,14 +151,8 @@ uint32 LootStore::LoadLootTable()
|
||||
bool needsquest = fields[4].GetBool();
|
||||
uint16 lootmode = fields[5].GetUInt16();
|
||||
uint8 groupid = fields[6].GetUInt8();
|
||||
int32 mincount = fields[7].GetUInt8();
|
||||
int32 maxcount = fields[8].GetUInt8();
|
||||
|
||||
if (maxcount > std::numeric_limits<uint8>::max())
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d Item %d: MaxCount value (%u) to large. must be less %u - skipped", GetName(), entry, item, maxcount, std::numeric_limits<uint8>::max());
|
||||
continue; // error already printed to log/console.
|
||||
}
|
||||
uint8 mincount = fields[7].GetUInt8();
|
||||
uint8 maxcount = fields[8].GetUInt8();
|
||||
|
||||
if (groupid >= 1 << 7) // it stored in 7 bit field
|
||||
{
|
||||
|
||||
@@ -3201,7 +3201,7 @@ void InstanceMap::UnloadAll()
|
||||
void InstanceMap::SendResetWarnings(uint32 timeLeft) const
|
||||
{
|
||||
for (MapRefManager::const_iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr)
|
||||
itr->GetSource()->SendInstanceResetWarning(GetId(), itr->GetSource()->GetDifficulty(IsRaid()), timeLeft);
|
||||
itr->GetSource()->SendInstanceResetWarning(GetId(), itr->GetSource()->GetDifficulty(IsRaid()), timeLeft, false);
|
||||
}
|
||||
|
||||
void InstanceMap::SetResetSchedule(bool on)
|
||||
|
||||
@@ -973,15 +973,14 @@ enum TrinityStrings
|
||||
LANG_GUILD_INFO_MOTD = 1182,
|
||||
LANG_GUILD_INFO_EXTRA_INFO = 1183,
|
||||
LANG_GUILD_INFO_LEVEL = 1184,
|
||||
// Room for more level 3 1184-1199 not used
|
||||
|
||||
// Debug commands
|
||||
LANG_DO_NOT_USE_6X_DEBUG_AREATRIGGER_LEFT = 1999,
|
||||
LANG_CINEMATIC_NOT_EXIST = 1200,
|
||||
LANG_MOVIE_NOT_EXIST = 1201,
|
||||
LANG_DEBUG_AREATRIGGER_ON = 1202,
|
||||
LANG_DEBUG_AREATRIGGER_OFF = 1203,
|
||||
LANG_DEBUG_AREATRIGGER_REACHED = 1204,
|
||||
// Room for more debug 1205-1299 not used
|
||||
|
||||
// Isle of Conquest
|
||||
LANG_BG_IC_START_TWO_MINUTES = 1205,
|
||||
|
||||
@@ -925,6 +925,7 @@ void PathGenerator::ReducePathLenghtByDist(float dist)
|
||||
float step = dist / len;
|
||||
// same as nextVec
|
||||
_pathPoints[i + 1] -= diffVec * step;
|
||||
_sourceUnit->UpdateAllowedPositionZ(_pathPoints[i + 1].x, _pathPoints[i + 1].y, _pathPoints[i + 1].z);
|
||||
_pathPoints.resize(i + 2);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -207,6 +207,8 @@ class Quest
|
||||
friend class ObjectMgr;
|
||||
public:
|
||||
Quest(Field* questRecord);
|
||||
void LoadQuestTemplateAddon(Field* fields);
|
||||
|
||||
uint32 XPValue(Player* player) const;
|
||||
|
||||
bool HasFlag(uint32 flag) const { return (Flags & flag) != 0; }
|
||||
@@ -352,21 +354,13 @@ class Quest
|
||||
uint32 Method;
|
||||
int32 ZoneOrSort;
|
||||
uint32 MinLevel;
|
||||
uint32 MaxLevel;
|
||||
int32 Level;
|
||||
uint32 Type;
|
||||
uint32 RequiredClasses;
|
||||
uint32 RequiredRaces;
|
||||
uint32 RequiredSkillId;
|
||||
uint32 RequiredSkillPoints;
|
||||
uint32 RequiredFactionId1;
|
||||
int32 RequiredFactionValue1;
|
||||
uint32 RequiredFactionId2;
|
||||
int32 RequiredFactionValue2;
|
||||
uint32 RequiredMinRepFaction;
|
||||
int32 RequiredMinRepValue;
|
||||
uint32 RequiredMaxRepFaction;
|
||||
int32 RequiredMaxRepValue;
|
||||
uint32 SuggestedPlayers;
|
||||
uint32 LimitTime;
|
||||
uint32 Flags;
|
||||
@@ -374,14 +368,9 @@ class Quest
|
||||
uint32 RequiredPlayerKills;
|
||||
uint32 RewardTalents;
|
||||
int32 RewardArenaPoints;
|
||||
int32 PrevQuestId;
|
||||
int32 NextQuestId;
|
||||
int32 ExclusiveGroup;
|
||||
uint32 NextQuestIdChain;
|
||||
uint32 RewardXPId;
|
||||
uint32 SourceItemId;
|
||||
uint32 SourceItemIdCount;
|
||||
uint32 SourceSpellid;
|
||||
std::string Title;
|
||||
std::string Details;
|
||||
std::string Objectives;
|
||||
@@ -395,8 +384,6 @@ class Quest
|
||||
uint32 RewardMoneyMaxLevel;
|
||||
uint32 RewardSpell;
|
||||
int32 RewardSpellCast;
|
||||
uint32 RewardMailTemplateId;
|
||||
uint32 RewardMailDelay;
|
||||
uint32 PointMapId;
|
||||
float PointX;
|
||||
float PointY;
|
||||
@@ -418,7 +405,23 @@ class Quest
|
||||
uint32 SoundAccept;
|
||||
uint32 SoundTurnIn;
|
||||
|
||||
uint32 SpecialFlags; // custom flags, not sniffed/WDB
|
||||
// quest_template_addon table (custom data)
|
||||
uint32 MaxLevel = 0;
|
||||
uint32 RequiredClasses = 0;
|
||||
uint32 SourceSpellid = 0;
|
||||
int32 PrevQuestId = 0;
|
||||
int32 NextQuestId = 0;
|
||||
int32 ExclusiveGroup = 0;
|
||||
uint32 RewardMailTemplateId = 0;
|
||||
uint32 RewardMailDelay = 0;
|
||||
uint32 RequiredSkillId = 0;
|
||||
uint32 RequiredSkillPoints = 0;
|
||||
uint32 RequiredMinRepFaction = 0;
|
||||
int32 RequiredMinRepValue = 0;
|
||||
uint32 RequiredMaxRepFaction = 0;
|
||||
int32 RequiredMaxRepValue = 0;
|
||||
uint32 SourceItemIdCount = 0;
|
||||
uint32 SpecialFlags = 0; // custom flags, not sniffed/WDB
|
||||
};
|
||||
|
||||
struct QuestStatusData
|
||||
|
||||
@@ -3093,6 +3093,10 @@ void AuraEffect::HandleModStateImmunityMask(AuraApplication const* aurApp, uint8
|
||||
|
||||
switch (miscVal)
|
||||
{
|
||||
case 27:
|
||||
target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SILENCE, apply);
|
||||
aura_immunity_list.push_back(SPELL_AURA_MOD_SILENCE);
|
||||
break;
|
||||
case 96:
|
||||
case 1615:
|
||||
{
|
||||
|
||||
@@ -1310,6 +1310,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
|
||||
if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 3790, 0))
|
||||
{
|
||||
uint32 damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), GetEffect(0)->GetAmount(), DOT);
|
||||
damage *= caster->SpellDamagePctDone(target, GetSpellInfo(), SPELL_DIRECT_DAMAGE);
|
||||
damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT);
|
||||
int32 basepoints0 = aurEff->GetAmount() * GetEffect(0)->GetTotalTicks() * int32(damage) / 100;
|
||||
int32 heal = int32(CalculatePct(basepoints0, 15));
|
||||
|
||||
@@ -3762,6 +3762,10 @@ void Spell::SendSpellStart()
|
||||
//TC_LOG_DEBUG("spells", "Sending SMSG_SPELL_START id=%u", m_spellInfo->Id);
|
||||
|
||||
uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
|
||||
uint32 schoolImmunityMask = m_caster->GetSchoolImmunityMask();
|
||||
uint32 mechanicImmunityMask = m_caster->GetMechanicImmunityMask();
|
||||
if (schoolImmunityMask || mechanicImmunityMask)
|
||||
castFlags |= CAST_FLAG_IMMUNITY;
|
||||
|
||||
if ((IsTriggered() && !m_spellInfo->IsAutoRepeatRangedSpell()) || m_triggeredByAuraSpell)
|
||||
castFlags |= CAST_FLAG_PENDING;
|
||||
@@ -3818,8 +3822,8 @@ void Spell::SendSpellStart()
|
||||
|
||||
if (castFlags & CAST_FLAG_PROJECTILE)
|
||||
{
|
||||
data << uint32(0); // Ammo display ID
|
||||
data << uint32(0); // Inventory Type
|
||||
data << uint32(schoolImmunityMask);
|
||||
data << uint32(mechanicImmunityMask);
|
||||
}
|
||||
|
||||
if (castFlags & CAST_FLAG_IMMUNITY)
|
||||
@@ -4472,8 +4476,11 @@ void Spell::TakeRunePower(bool didHit)
|
||||
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
|
||||
}
|
||||
|
||||
// Let's say we use a skill that requires a Frost rune. This is the order:
|
||||
// - Frost rune
|
||||
// - Death rune, originally a Frost rune
|
||||
// - Death rune, any kind
|
||||
runeCost[RUNE_DEATH] = 0; // calculated later
|
||||
|
||||
for (uint32 i = 0; i < MAX_RUNES; ++i)
|
||||
{
|
||||
RuneType rune = player->GetCurrentRune(i);
|
||||
@@ -4485,8 +4492,32 @@ void Spell::TakeRunePower(bool didHit)
|
||||
}
|
||||
}
|
||||
|
||||
// Find a Death rune where the base rune matches the one we need
|
||||
runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
|
||||
if (runeCost[RUNE_DEATH] > 0)
|
||||
{
|
||||
for (uint32 i = 0; i < MAX_RUNES; ++i)
|
||||
{
|
||||
RuneType rune = player->GetCurrentRune(i);
|
||||
RuneType baseRune = player->GetBaseRune(i);
|
||||
if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH && runeCost[baseRune] > 0)
|
||||
{
|
||||
player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i) : uint32(RUNE_MISS_COOLDOWN), true);
|
||||
player->SetLastUsedRune(rune);
|
||||
runeCost[baseRune]--;
|
||||
runeCost[rune]--;
|
||||
|
||||
// keep Death Rune type if missed
|
||||
if (didHit)
|
||||
player->RestoreBaseRune(i);
|
||||
|
||||
if (runeCost[RUNE_DEATH] == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Grab any Death rune
|
||||
if (runeCost[RUNE_DEATH] > 0)
|
||||
{
|
||||
for (uint32 i = 0; i < MAX_RUNES; ++i)
|
||||
@@ -5123,15 +5154,15 @@ SpellCastResult Spell::CheckCast(bool strict)
|
||||
|
||||
m_preGeneratedPath.SetPathLengthLimit(range);
|
||||
// first try with raycast, if it fails fall back to normal path
|
||||
bool result = m_preGeneratedPath.CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + target->GetObjectSize(), false, true);
|
||||
bool result = m_preGeneratedPath.CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + target->GetObjectSize() / 2.f, false, true);
|
||||
if (m_preGeneratedPath.GetPathType() & PATHFIND_SHORT)
|
||||
return SPELL_FAILED_OUT_OF_RANGE;
|
||||
else if (!result || m_preGeneratedPath.GetPathType() & PATHFIND_NOPATH)
|
||||
else if (!result || m_preGeneratedPath.GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
|
||||
{
|
||||
result = m_preGeneratedPath.CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + target->GetObjectSize(), false, false);
|
||||
result = m_preGeneratedPath.CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + target->GetObjectSize() / 2.f, false, false);
|
||||
if (m_preGeneratedPath.GetPathType() & PATHFIND_SHORT)
|
||||
return SPELL_FAILED_OUT_OF_RANGE;
|
||||
else if (!result || m_preGeneratedPath.GetPathType() & PATHFIND_NOPATH)
|
||||
else if (!result || m_preGeneratedPath.GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
|
||||
return SPELL_FAILED_NOPATH;
|
||||
}
|
||||
|
||||
|
||||
@@ -2861,19 +2861,18 @@ void Spell::EffectTaunt(SpellEffIndex /*effIndex*/)
|
||||
return;
|
||||
}
|
||||
|
||||
// Also use this effect to set the taunter's threat to the taunted creature's highest value
|
||||
if (unitTarget->getThreatManager().getCurrentVictim())
|
||||
{
|
||||
float myThreat = unitTarget->getThreatManager().getThreat(m_caster);
|
||||
float itsThreat = unitTarget->getThreatManager().getCurrentVictim()->getThreat();
|
||||
if (itsThreat > myThreat)
|
||||
unitTarget->getThreatManager().addThreat(m_caster, itsThreat - myThreat);
|
||||
}
|
||||
|
||||
//Set aggro victim to caster
|
||||
if (!unitTarget->getThreatManager().getOnlineContainer().empty())
|
||||
{
|
||||
// Also use this effect to set the taunter's threat to the taunted creature's highest value
|
||||
float myThreat = unitTarget->getThreatManager().getThreat(m_caster);
|
||||
float topThreat = unitTarget->getThreatManager().getOnlineContainer().getMostHated()->getThreat();
|
||||
if (topThreat > myThreat)
|
||||
unitTarget->getThreatManager().doAddThreat(m_caster, topThreat - myThreat);
|
||||
|
||||
//Set aggro victim to caster
|
||||
if (HostileReference* forcedVictim = unitTarget->getThreatManager().getOnlineContainer().getReferenceByTarget(m_caster))
|
||||
unitTarget->getThreatManager().setCurrentVictim(forcedVictim);
|
||||
}
|
||||
|
||||
if (unitTarget->ToCreature()->IsAIEnabled && !unitTarget->ToCreature()->HasReactState(REACT_PASSIVE))
|
||||
unitTarget->ToCreature()->AI()->AttackStart(m_caster);
|
||||
|
||||
@@ -1665,6 +1665,7 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a
|
||||
return SPELL_FAILED_NOT_HERE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1664,7 +1664,7 @@ void SpellMgr::LoadSpellTargetPositions()
|
||||
|
||||
mSpellTargetPositions.clear(); // need for reload case
|
||||
|
||||
// 0 1 2 3 4 5 6
|
||||
// 0 1 2 3 4 5 6
|
||||
QueryResult result = WorldDatabase.Query("SELECT ID, EffectIndex, MapID, PositionX, PositionY, PositionZ, Orientation FROM spell_target_position");
|
||||
if (!result)
|
||||
{
|
||||
|
||||
@@ -641,8 +641,8 @@ SpellValue const* SpellScript::GetSpellValue()
|
||||
bool AuraScript::_Validate(SpellInfo const* entry)
|
||||
{
|
||||
for (std::list<CheckAreaTargetHandler>::iterator itr = DoCheckAreaTarget.begin(); itr != DoCheckAreaTarget.end(); ++itr)
|
||||
if (!entry->HasAreaAuraEffect() && !entry->HasEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
|
||||
TC_LOG_ERROR("scripts", "Spell `%u` of script `%s` does not have area aura effect - handler bound to hook `DoCheckAreaTarget` of AuraScript won't be executed", entry->Id, m_scriptName->c_str());
|
||||
if (!entry->HasAreaAuraEffect() && !entry->HasEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) && !entry->HasEffect(SPELL_EFFECT_APPLY_AURA))
|
||||
TC_LOG_ERROR("scripts", "Spell `%u` of script `%s` does not have apply aura effect - handler bound to hook `DoCheckAreaTarget` of AuraScript won't be executed", entry->Id, m_scriptName->c_str());
|
||||
|
||||
for (std::list<AuraDispelHandler>::iterator itr = OnDispel.begin(); itr != OnDispel.end(); ++itr)
|
||||
if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
|
||||
|
||||
@@ -301,7 +301,7 @@ void TicketMgr::LoadTickets()
|
||||
PreparedQueryResult result = CharacterDatabase.Query(stmt);
|
||||
if (!result)
|
||||
{
|
||||
TC_LOG_INFO("server.loading", ">> Loaded 0 GM tickets. DB table `gm_tickets` is empty!");
|
||||
TC_LOG_INFO("server.loading", ">> Loaded 0 GM tickets. DB table `gm_ticket` is empty!");
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -338,7 +338,7 @@ void TicketMgr::LoadSurveys()
|
||||
_lastSurveyId = 0;
|
||||
|
||||
uint32 oldMSTime = getMSTime();
|
||||
if (QueryResult result = CharacterDatabase.Query("SELECT MAX(surveyId) FROM gm_surveys"))
|
||||
if (QueryResult result = CharacterDatabase.Query("SELECT MAX(surveyId) FROM gm_survey"))
|
||||
_lastSurveyId = (*result)[0].GetUInt32();
|
||||
|
||||
TC_LOG_INFO("server.loading", ">> Loaded GM Survey count from database in %u ms", GetMSTimeDiffToNow(oldMSTime));
|
||||
|
||||
@@ -147,7 +147,7 @@ bool CharacterDatabaseCleaner::TalentCheck(uint32 talent_id)
|
||||
|
||||
void CharacterDatabaseCleaner::CleanCharacterTalent()
|
||||
{
|
||||
CharacterDatabase.DirectPExecute("DELETE FROM character_talent WHERE spec > %u", MAX_TALENT_SPECS);
|
||||
CharacterDatabase.DirectPExecute("DELETE FROM character_talent WHERE talentGroup > %u", MAX_TALENT_SPECS);
|
||||
CheckUnique("spell", "character_talent", &TalentCheck);
|
||||
}
|
||||
|
||||
|
||||
@@ -1575,6 +1575,12 @@ void World::SetInitialWorldSettings()
|
||||
TC_LOG_INFO("server.loading", "Loading GameObject Addon Data...");
|
||||
sObjectMgr->LoadGameObjectAddons(); // must be after LoadGameObjectTemplate() and LoadGameobjects()
|
||||
|
||||
TC_LOG_INFO("server.loading", "Loading GameObject Quest Items...");
|
||||
sObjectMgr->LoadGameObjectQuestItems();
|
||||
|
||||
TC_LOG_INFO("server.loading", "Loading Creature Quest Items...");
|
||||
sObjectMgr->LoadCreatureQuestItems();
|
||||
|
||||
TC_LOG_INFO("server.loading", "Loading Creature Linked Respawn...");
|
||||
sObjectMgr->LoadLinkedRespawn(); // must be after LoadCreatures(), LoadGameObjects()
|
||||
|
||||
@@ -1782,6 +1788,9 @@ void World::SetInitialWorldSettings()
|
||||
TC_LOG_INFO("server.loading", "Loading faction change spell pairs...");
|
||||
sObjectMgr->LoadFactionChangeSpells();
|
||||
|
||||
TC_LOG_INFO("server.loading", "Loading faction change quest pairs...");
|
||||
sObjectMgr->LoadFactionChangeQuests();
|
||||
|
||||
TC_LOG_INFO("server.loading", "Loading faction change item pairs...");
|
||||
sObjectMgr->LoadFactionChangeItems();
|
||||
|
||||
|
||||
@@ -87,6 +87,10 @@ public:
|
||||
if (para && strcmp(para, "true") == 0)
|
||||
useStraightPath = true;
|
||||
|
||||
bool useStraightLine = false;
|
||||
if (para && strcmp(para, "line") == 0)
|
||||
useStraightLine = true;
|
||||
|
||||
// unit locations
|
||||
float x, y, z;
|
||||
player->GetPosition(x, y, z);
|
||||
@@ -94,11 +98,11 @@ public:
|
||||
// path
|
||||
PathGenerator path(target);
|
||||
path.SetUseStraightPath(useStraightPath);
|
||||
bool result = path.CalculatePath(x, y, z);
|
||||
bool result = path.CalculatePath(x, y, z, false, useStraightLine);
|
||||
|
||||
Movement::PointsArray const& pointPath = path.GetPath();
|
||||
handler->PSendSysMessage("%s's path to %s:", target->GetName().c_str(), player->GetName().c_str());
|
||||
handler->PSendSysMessage("Building: %s", useStraightPath ? "StraightPath" : "SmoothPath");
|
||||
handler->PSendSysMessage("Building: %s", useStraightPath ? "StraightPath" : useStraightLine ? "Raycast" : "SmoothPath");
|
||||
handler->PSendSysMessage("Result: %s - Length: %zu - Type: %u", (result ? "true" : "false"), pointPath.size(), path.GetPathType());
|
||||
|
||||
G3D::Vector3 const &start = path.GetStartPosition();
|
||||
|
||||
@@ -319,7 +319,7 @@ public:
|
||||
}
|
||||
|
||||
MapEntry const* map = sMapStore.LookupEntry(tele->mapId);
|
||||
if (!map || map->IsBattlegroundOrArena())
|
||||
if (!map || (map->IsBattlegroundOrArena() && (me->GetMapId() != tele->mapId || !me->IsGameMaster())))
|
||||
{
|
||||
handler->SendSysMessage(LANG_CANNOT_TELE_TO_BG);
|
||||
handler->SetSentErrorMessage(true);
|
||||
|
||||
@@ -111,6 +111,7 @@ public:
|
||||
instance_zulfarrak_InstanceMapScript(Map* map) : InstanceScript(map)
|
||||
{
|
||||
SetHeaders(DataHeader);
|
||||
GahzRillaEncounter = NOT_STARTED;
|
||||
PyramidPhase = 0;
|
||||
major_wave_Timer = 0;
|
||||
minor_wave_Timer = 0;
|
||||
|
||||
@@ -25,14 +25,6 @@
|
||||
#include "ruby_sanctum.h"
|
||||
#include "Player.h"
|
||||
|
||||
/* ScriptData
|
||||
SDName: ruby_sanctum
|
||||
SDAuthors: Kaelima, Warpten
|
||||
SD%Complete: 90%
|
||||
SDComment: Based on Kaelima's initial work (half of it). Corporeality handling is a pure guess, we lack info.
|
||||
SDCategory: Chamber of Aspects
|
||||
EndScriptData */
|
||||
|
||||
enum Texts
|
||||
{
|
||||
// Shared
|
||||
@@ -86,6 +78,8 @@ enum Spells
|
||||
|
||||
// Living Inferno
|
||||
SPELL_BLAZING_AURA = 75885,
|
||||
SPELL_SPAWN_LIVING_EMBERS = 75880,
|
||||
SPELL_SUMMON_LIVING_EMBER = 75881,
|
||||
|
||||
// Halion Controller
|
||||
SPELL_COSMETIC_FIRE_PILLAR = 76006,
|
||||
@@ -142,7 +136,7 @@ enum Events
|
||||
EVENT_CHECK_CORPOREALITY = 14,
|
||||
EVENT_SHADOW_PULSARS_SHOOT = 15,
|
||||
EVENT_TRIGGER_BERSERK = 16,
|
||||
EVENT_TWILIGHT_MENDING = 17
|
||||
EVENT_TWILIGHT_MENDING = 17,
|
||||
};
|
||||
|
||||
enum Actions
|
||||
@@ -155,7 +149,13 @@ enum Actions
|
||||
ACTION_MONITOR_CORPOREALITY = 3,
|
||||
|
||||
// Orb Carrier
|
||||
ACTION_SHOOT = 4
|
||||
ACTION_SHOOT = 4,
|
||||
|
||||
// Living Inferno
|
||||
ACTION_SUMMON_LIVING_EMBERS = 5,
|
||||
|
||||
// Meteor Flame
|
||||
ACTION_SUMMON_FLAME = 6
|
||||
};
|
||||
|
||||
enum Phases
|
||||
@@ -173,7 +173,8 @@ enum Misc
|
||||
DATA_MATERIAL_DAMAGE_TAKEN = 2,
|
||||
DATA_STACKS_DISPELLED = 3,
|
||||
DATA_FIGHT_PHASE = 4,
|
||||
DATA_EVADE_METHOD = 5
|
||||
DATA_EVADE_METHOD = 5,
|
||||
DATA_SPAWNED_FLAMES = 6,
|
||||
};
|
||||
|
||||
enum OrbCarrierSeats
|
||||
@@ -702,7 +703,7 @@ class npc_halion_controller : public CreatureScript
|
||||
// The IsInCombat() check is needed because that check should be false when Halion is
|
||||
// not engaged, while it would return true without as UpdateVictim() checks for
|
||||
// combat state.
|
||||
if (!(_events.IsInPhase(PHASE_INTRO)) && me->IsInCombat() && !UpdateVictim())
|
||||
if (!_events.IsInPhase(PHASE_INTRO) && me->IsInCombat() && !UpdateVictim())
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
@@ -893,8 +894,6 @@ class npc_halion_controller : public CreatureScript
|
||||
}
|
||||
};
|
||||
|
||||
typedef npc_halion_controller::npc_halion_controllerAI controllerAI;
|
||||
|
||||
class npc_orb_carrier : public CreatureScript
|
||||
{
|
||||
public:
|
||||
@@ -996,7 +995,7 @@ class npc_meteor_strike_initial : public CreatureScript
|
||||
if (!owner)
|
||||
return;
|
||||
|
||||
// Let Halion Controller count as summoner
|
||||
// Let Controller count as summoner
|
||||
if (Creature* controller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_HALION_CONTROLLER)))
|
||||
controller->AI()->JustSummoned(me);
|
||||
|
||||
@@ -1006,11 +1005,13 @@ class npc_meteor_strike_initial : public CreatureScript
|
||||
if (HalionAI* halionAI = CAST_AI(HalionAI, owner->AI()))
|
||||
{
|
||||
Position const* ownerPos = halionAI->GetMeteorStrikePosition();
|
||||
// Adjust randomness between 0 and pi.
|
||||
float randomAdjustment = frand(static_cast<float>(M_PI / 14), static_cast<float>(13 * M_PI / 14));
|
||||
float angle[4];
|
||||
angle[0] = me->GetAngle(ownerPos);
|
||||
angle[1] = me->GetAngle(ownerPos) - static_cast<float>(M_PI/2);
|
||||
angle[2] = me->GetAngle(ownerPos) - static_cast<float>(-M_PI/2);
|
||||
angle[3] = me->GetAngle(ownerPos) - static_cast<float>(M_PI);
|
||||
angle[1] = angle[0] + randomAdjustment;
|
||||
angle[2] = angle[0] + static_cast<float>(M_PI);
|
||||
angle[3] = angle[2] + randomAdjustment;
|
||||
|
||||
_meteorList.clear();
|
||||
for (uint8 i = 0; i < 4; i++)
|
||||
@@ -1019,7 +1020,10 @@ class npc_meteor_strike_initial : public CreatureScript
|
||||
me->SetOrientation(angle[i]);
|
||||
Position newPos = me->GetNearPosition(10.0f, 0.0f); // Exact distance
|
||||
if (Creature* meteor = me->SummonCreature(NPC_METEOR_STRIKE_NORTH + i, newPos, TEMPSUMMON_TIMED_DESPAWN, 30000))
|
||||
{
|
||||
meteor->SetOrientation(angle[i]);
|
||||
_meteorList.push_back(meteor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1045,11 +1049,8 @@ class npc_meteor_strike : public CreatureScript
|
||||
struct npc_meteor_strikeAI : public ScriptedAI
|
||||
{
|
||||
npc_meteor_strikeAI(Creature* creature) : ScriptedAI(creature),
|
||||
_instance(creature->GetInstanceScript())
|
||||
_instance(creature->GetInstanceScript()), _spawnCount(0)
|
||||
{
|
||||
_range = 5.0f;
|
||||
_spawnCount = 0;
|
||||
|
||||
SetCombatMovement(false);
|
||||
}
|
||||
|
||||
@@ -1070,34 +1071,38 @@ class npc_meteor_strike : public CreatureScript
|
||||
controller->AI()->JustSummoned(me);
|
||||
}
|
||||
|
||||
void SetData(uint32 dataType, uint32 dataCount) override
|
||||
{
|
||||
if (dataType == DATA_SPAWNED_FLAMES)
|
||||
_spawnCount += dataCount;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 dataType) const override
|
||||
{
|
||||
if (dataType == DATA_SPAWNED_FLAMES)
|
||||
return _spawnCount;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (_spawnCount > 5)
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
if (_events.ExecuteEvent() == EVENT_SPAWN_METEOR_FLAME)
|
||||
{
|
||||
Position pos = me->GetNearPosition( _range, 0.0f);
|
||||
|
||||
Position pos = me->GetNearPosition(5.0f, 0.0f);
|
||||
if (Creature* flame = me->SummonCreature(NPC_METEOR_STRIKE_FLAME, pos, TEMPSUMMON_TIMED_DESPAWN, 25000))
|
||||
{
|
||||
if (Creature* controller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_HALION_CONTROLLER)))
|
||||
controller->AI()->JustSummoned(flame);
|
||||
flame->SetOrientation(me->GetOrientation());
|
||||
|
||||
flame->CastSpell(flame, SPELL_METEOR_STRIKE_FIRE_AURA_2, true);
|
||||
++_spawnCount;
|
||||
flame->AI()->SetGUID(GetGUID());
|
||||
flame->AI()->DoAction(ACTION_SUMMON_FLAME);
|
||||
}
|
||||
_range += 5.0f;
|
||||
_events.ScheduleEvent(EVENT_SPAWN_METEOR_FLAME, 800);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
InstanceScript* _instance;
|
||||
EventMap _events;
|
||||
float _range;
|
||||
uint8 _spawnCount;
|
||||
};
|
||||
|
||||
@@ -1107,6 +1112,67 @@ class npc_meteor_strike : public CreatureScript
|
||||
}
|
||||
};
|
||||
|
||||
class npc_meteor_strike_flame : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_meteor_strike_flame() : CreatureScript("npc_meteor_strike_flame") { }
|
||||
|
||||
struct npc_meteor_strike_flameAI : public ScriptedAI
|
||||
{
|
||||
npc_meteor_strike_flameAI(Creature* creature) : ScriptedAI(creature),
|
||||
_instance(creature->GetInstanceScript())
|
||||
{
|
||||
SetCombatMovement(false);
|
||||
}
|
||||
|
||||
void SetGUID(ObjectGuid guid, int32 /*id = 0 */) override
|
||||
{
|
||||
_rootOwnerGuid = guid;
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
if (action != ACTION_SUMMON_FLAME || _rootOwnerGuid.IsEmpty())
|
||||
return;
|
||||
|
||||
me->CastSpell(me, SPELL_METEOR_STRIKE_FIRE_AURA_2, true);
|
||||
|
||||
Creature* meteorStrike = ObjectAccessor::GetCreature(*me, _rootOwnerGuid);
|
||||
if (!meteorStrike || meteorStrike->AI()->GetData(DATA_SPAWNED_FLAMES) > 5)
|
||||
return;
|
||||
|
||||
me->SetOrientation(me->GetOrientation() + frand(static_cast<float>(-M_PI / 16), static_cast<float>(M_PI / 16)));
|
||||
Position pos = me->GetNearPosition(5.0f, 0.0f);
|
||||
|
||||
if (Creature* flame = me->SummonCreature(NPC_METEOR_STRIKE_FLAME, pos, TEMPSUMMON_TIMED_DESPAWN, 25000))
|
||||
{
|
||||
flame->AI()->SetGUID(_rootOwnerGuid);
|
||||
meteorStrike->AI()->SetData(DATA_SPAWNED_FLAMES, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void IsSummonedBy(Unit* /*summoner*/) override
|
||||
{
|
||||
// Let Halion Controller count as summoner.
|
||||
if (Creature* controller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_HALION_CONTROLLER)))
|
||||
controller->AI()->JustSummoned(me);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 /*diff*/) override { }
|
||||
void EnterEvadeMode() override { }
|
||||
|
||||
private:
|
||||
InstanceScript* _instance;
|
||||
EventMap _events;
|
||||
ObjectGuid _rootOwnerGuid = ObjectGuid::Empty;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetRubySanctumAI<npc_meteor_strike_flameAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_combustion_consumption : public CreatureScript
|
||||
{
|
||||
public:
|
||||
@@ -1119,26 +1185,23 @@ class npc_combustion_consumption : public CreatureScript
|
||||
{
|
||||
SetCombatMovement(false);
|
||||
|
||||
switch (me->GetEntry())
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_COMBUSTION:
|
||||
_explosionSpell = SPELL_FIERY_COMBUSTION_EXPLOSION;
|
||||
_damageSpell = SPELL_COMBUSTION_DAMAGE_AURA;
|
||||
me->SetPhaseMask(0x01, true);
|
||||
creature->SetPhaseMask(IsHeroic() ? 0x21 : 0x01, true);
|
||||
break;
|
||||
case NPC_CONSUMPTION:
|
||||
_explosionSpell = SPELL_SOUL_CONSUMPTION_EXPLOSION;
|
||||
_damageSpell = SPELL_CONSUMPTION_DAMAGE_AURA;
|
||||
me->SetPhaseMask(0x20, true);
|
||||
creature->SetPhaseMask(IsHeroic() ? 0x21 : 0x20, true);
|
||||
break;
|
||||
default: // Should never happen
|
||||
_explosionSpell = 0;
|
||||
_damageSpell = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (IsHeroic())
|
||||
me->SetPhaseMask(0x01 | 0x20, true);
|
||||
}
|
||||
|
||||
void IsSummonedBy(Unit* summoner) override
|
||||
@@ -1160,7 +1223,7 @@ class npc_combustion_consumption : public CreatureScript
|
||||
me->CastCustomSpell(SPELL_SCALE_AURA, SPELLVALUE_AURA_STACK, stackAmount, me);
|
||||
DoCast(me, _damageSpell);
|
||||
|
||||
int32 damage = 1200 + (stackAmount * 1290); // Needs more researches.
|
||||
int32 damage = 1200 + (stackAmount * 1290); // Needs more research.
|
||||
summoner->CastCustomSpell(_explosionSpell, SPELLVALUE_BASE_POINT0, damage, summoner);
|
||||
}
|
||||
|
||||
@@ -1193,6 +1256,10 @@ class npc_living_inferno : public CreatureScript
|
||||
me->SetInCombatWithZone();
|
||||
me->CastSpell(me, SPELL_BLAZING_AURA, true);
|
||||
|
||||
// SMSG_SPELL_GO for the living ember stuff isn't even sent to the client - Blizzard on drugs.
|
||||
if (me->GetMap()->GetDifficulty() == RAID_DIFFICULTY_25MAN_HEROIC)
|
||||
me->CastSpell(me, SPELL_SPAWN_LIVING_EMBERS, true);
|
||||
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HALION_CONTROLLER)))
|
||||
controller->AI()->JustSummoned(me);
|
||||
@@ -1210,7 +1277,6 @@ class npc_living_inferno : public CreatureScript
|
||||
}
|
||||
};
|
||||
|
||||
//! Need sniff data
|
||||
class npc_living_ember : public CreatureScript
|
||||
{
|
||||
public:
|
||||
@@ -1738,12 +1804,46 @@ class spell_halion_summon_exit_portals : public SpellScriptLoader
|
||||
}
|
||||
};
|
||||
|
||||
class spell_halion_spawn_living_embers : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_halion_spawn_living_embers() : SpellScriptLoader("spell_halion_spawn_living_embers") { }
|
||||
|
||||
class spell_halion_spawn_living_embers_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_halion_spawn_living_embers_SpellScript);
|
||||
|
||||
void SelectMeteorFlames(std::list<WorldObject*>& unitList)
|
||||
{
|
||||
if (!unitList.empty())
|
||||
Trinity::Containers::RandomResizeList(unitList, 10);
|
||||
}
|
||||
|
||||
void HandleScript(SpellEffIndex /* effIndex */)
|
||||
{
|
||||
GetHitUnit()->CastSpell(GetHitUnit(), SPELL_SUMMON_LIVING_EMBER, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_halion_spawn_living_embers_SpellScript::SelectMeteorFlames, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_halion_spawn_living_embers_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_halion_spawn_living_embers_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_halion()
|
||||
{
|
||||
new boss_halion();
|
||||
new boss_twilight_halion();
|
||||
|
||||
new npc_halion_controller();
|
||||
new npc_meteor_strike_flame();
|
||||
new npc_meteor_strike_initial();
|
||||
new npc_meteor_strike();
|
||||
new npc_combustion_consumption();
|
||||
@@ -1765,4 +1865,5 @@ void AddSC_boss_halion()
|
||||
new spell_halion_twilight_phasing();
|
||||
new spell_halion_twilight_cutter();
|
||||
new spell_halion_clear_debuffs();
|
||||
new spell_halion_spawn_living_embers();
|
||||
}
|
||||
@@ -1530,15 +1530,14 @@ public:
|
||||
{
|
||||
npc_wyrmrest_skytalonAI(Creature* creature) : VehicleAI(creature)
|
||||
{
|
||||
_summoner = NULL;
|
||||
}
|
||||
|
||||
void IsSummonedBy(Unit* summoner) override
|
||||
{
|
||||
_summoner = NULL;
|
||||
_summoner.Clear();
|
||||
if (Player* player = summoner->ToPlayer())
|
||||
{
|
||||
_summoner = player;
|
||||
_summoner = player->GetGUID();
|
||||
_events.ScheduleEvent(EVENT_CAST_RIDE_SPELL, 2*IN_MILLISECONDS);
|
||||
}
|
||||
}
|
||||
@@ -1553,7 +1552,8 @@ public:
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_CAST_RIDE_SPELL:
|
||||
me->CastSpell(_summoner, SPELL_RIDE_RED_DRAGON_TRIGGERED, true);
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*me, _summoner))
|
||||
me->CastSpell(player, SPELL_RIDE_RED_DRAGON_TRIGGERED, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1575,7 +1575,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Player* _summoner;
|
||||
ObjectGuid _summoner;
|
||||
EventMap _events;
|
||||
};
|
||||
|
||||
|
||||
@@ -77,9 +77,9 @@ public:
|
||||
|
||||
/// @todo this should be handled in map, maybe add a summon function in map
|
||||
// There is no other way afaik...
|
||||
void SpawnGameObject(uint32 entry, Position& pos)
|
||||
void SpawnGameObject(uint32 entry, Position const& pos)
|
||||
{
|
||||
GameObject* go = new GameObject;
|
||||
GameObject* go = new GameObject();
|
||||
if (!go->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), entry, instance,
|
||||
PHASEMASK_NORMAL, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(),
|
||||
0, 0, 0, 0, 120, GO_STATE_READY))
|
||||
@@ -98,30 +98,19 @@ public:
|
||||
platformGUID = go->GetGUID();
|
||||
break;
|
||||
case GO_FOCUSING_IRIS_10:
|
||||
if (instance->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)
|
||||
{
|
||||
irisGUID = go->GetGUID();
|
||||
focusingIrisPosition = go->GetPosition();
|
||||
}
|
||||
break;
|
||||
case GO_FOCUSING_IRIS_25:
|
||||
if (instance->GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
|
||||
{
|
||||
irisGUID = go->GetGUID();
|
||||
focusingIrisPosition = go->GetPosition();
|
||||
}
|
||||
irisGUID = go->GetGUID();
|
||||
focusingIrisPosition = go->GetPosition();
|
||||
break;
|
||||
case GO_EXIT_PORTAL:
|
||||
exitPortalGUID = go->GetGUID();
|
||||
exitPortalPosition = go->GetPosition();
|
||||
break;
|
||||
case GO_HEART_OF_MAGIC_10:
|
||||
if (instance->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)
|
||||
heartOfMagicGUID = go->GetGUID();
|
||||
break;
|
||||
case GO_HEART_OF_MAGIC_25:
|
||||
if (instance->GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
|
||||
heartOfMagicGUID = go->GetGUID();
|
||||
heartOfMagicGUID = go->GetGUID();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -166,10 +155,10 @@ public:
|
||||
if (eventId == EVENT_FOCUSING_IRIS)
|
||||
{
|
||||
if (Creature* alexstraszaBunny = instance->GetCreature(alexstraszaBunnyGUID))
|
||||
{
|
||||
alexstraszaBunny->CastSpell(alexstraszaBunny, SPELL_IRIS_OPENED);
|
||||
instance->GetGameObject(irisGUID)->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE);
|
||||
}
|
||||
|
||||
if (GameObject* iris = instance->GetGameObject(irisGUID))
|
||||
iris->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE);
|
||||
|
||||
if (Creature* malygos = instance->GetCreature(malygosGUID))
|
||||
malygos->AI()->DoAction(0); // ACTION_LAND_ENCOUNTER_START
|
||||
@@ -183,17 +172,17 @@ public:
|
||||
{
|
||||
if (Creature* malygos = instance->GetCreature(malygosGUID))
|
||||
{
|
||||
std::list<HostileReference*> m_threatlist = malygos->getThreatManager().getThreatList();
|
||||
ThreatContainer::StorageType const& threatList = malygos->getThreatManager().getThreatList();
|
||||
for (GuidList::const_iterator itr_vortex = vortexTriggers.begin(); itr_vortex != vortexTriggers.end(); ++itr_vortex)
|
||||
{
|
||||
if (m_threatlist.empty())
|
||||
if (threatList.empty())
|
||||
return;
|
||||
|
||||
uint8 counter = 0;
|
||||
if (Creature* trigger = instance->GetCreature(*itr_vortex))
|
||||
{
|
||||
// each trigger have to cast the spell to 5 players.
|
||||
for (std::list<HostileReference*>::const_iterator itr = m_threatlist.begin(); itr!= m_threatlist.end(); ++itr)
|
||||
for (ThreatContainer::StorageType::const_iterator itr = threatList.begin(); itr != threatList.end(); ++itr)
|
||||
{
|
||||
if (counter >= 5)
|
||||
break;
|
||||
|
||||
@@ -229,6 +229,21 @@ class instance_oculus : public InstanceMapScript
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const override
|
||||
{
|
||||
if (type == DATA_CONSTRUCTS)
|
||||
{
|
||||
if (CentrifugueConstructCounter == 0)
|
||||
return KILL_NO_CONSTRUCT;
|
||||
else if (CentrifugueConstructCounter == 1)
|
||||
return KILL_ONE_CONSTRUCT;
|
||||
else if (CentrifugueConstructCounter > 1)
|
||||
return KILL_MORE_CONSTRUCT;
|
||||
}
|
||||
|
||||
return KILL_NO_CONSTRUCT;
|
||||
}
|
||||
|
||||
ObjectGuid GetGuidData(uint32 type) const override
|
||||
{
|
||||
switch (type)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "ScriptedGossip.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "CombatAI.h"
|
||||
#include "Player.h"
|
||||
#include "Vehicle.h"
|
||||
@@ -76,6 +77,11 @@ enum Drakes
|
||||
SPELL_EMERALD_TOUCH_THE_NIGHTMARE = 50341, // (60 yds) - Instant - Consumes 30% of the caster's max health to inflict 25, 000 nature damage to an enemy dragon and reduce the damage it deals by 25% for 30 sec.
|
||||
// you do not have access to until you kill the Mage-Lord Urom
|
||||
SPELL_EMERALD_DREAM_FUNNEL = 50344, // (60 yds) - Channeled - Transfers 5% of the caster's max health to a friendly drake every second for 10 seconds as long as the caster channels.
|
||||
/*
|
||||
* All Drakes
|
||||
* GPS System
|
||||
*/
|
||||
SPELL_GPS = 53389,
|
||||
|
||||
// Misc
|
||||
POINT_LAND = 2,
|
||||
@@ -101,7 +107,13 @@ enum Says
|
||||
WHISPER_DRAKES_WELCOME = 1,
|
||||
WHISPER_DRAKES_ABILITIES = 2,
|
||||
WHISPER_DRAKES_SPECIAL = 3,
|
||||
WHISPER_DRAKES_LOWHEALTH = 4
|
||||
WHISPER_DRAKES_LOWHEALTH = 4,
|
||||
WHISPER_GPS_10_CONSTRUCTS = 5,
|
||||
WHISPER_GPS_1_CONSTRUCT = 6,
|
||||
WHISPER_GPS_VAROS = 7,
|
||||
WHISPER_GPS_UROM = 8,
|
||||
WHISPER_GPS_EREGOS = 9,
|
||||
WHISPER_GPS_END = 10
|
||||
};
|
||||
|
||||
class npc_verdisa_beglaristrasz_eternos : public CreatureScript
|
||||
@@ -250,6 +262,26 @@ class npc_ruby_emerald_amber_drake : public CreatureScript
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, const SpellInfo* spell) override
|
||||
{
|
||||
if (Unit* creator = ObjectAccessor::GetUnit(*me, me->GetCreatorGUID()))
|
||||
if (spell->Id == SPELL_GPS)
|
||||
{
|
||||
if (_instance->GetBossState(DATA_EREGOS) == DONE)
|
||||
Talk(WHISPER_GPS_END, creator);
|
||||
else if (_instance->GetBossState(DATA_UROM) == DONE)
|
||||
Talk(WHISPER_GPS_EREGOS, creator);
|
||||
else if (_instance->GetBossState(DATA_VAROS) == DONE)
|
||||
Talk(WHISPER_GPS_UROM, creator);
|
||||
else if (_instance->GetData(DATA_CONSTRUCTS) == KILL_NO_CONSTRUCT)
|
||||
Talk(WHISPER_GPS_VAROS, creator);
|
||||
else if (_instance->GetData(DATA_CONSTRUCTS) == KILL_ONE_CONSTRUCT)
|
||||
Talk(WHISPER_GPS_1_CONSTRUCT, creator);
|
||||
else if (_instance->GetData(DATA_CONSTRUCTS) == KILL_MORE_CONSTRUCT)
|
||||
Talk(WHISPER_GPS_10_CONSTRUCTS, creator);
|
||||
}
|
||||
}
|
||||
|
||||
void IsSummonedBy(Unit* summoner) override
|
||||
{
|
||||
if (_instance->GetBossState(DATA_EREGOS) == IN_PROGRESS)
|
||||
|
||||
@@ -29,7 +29,9 @@ enum DataTypes
|
||||
DATA_DRAKOS = 0,
|
||||
DATA_VAROS = 1,
|
||||
DATA_UROM = 2,
|
||||
DATA_EREGOS = 3
|
||||
DATA_EREGOS = 3,
|
||||
// GPS System
|
||||
DATA_CONSTRUCTS = 4
|
||||
};
|
||||
|
||||
enum CreatureIds
|
||||
@@ -91,6 +93,13 @@ enum InstanceEvents
|
||||
EVENT_EREGOS_INTRO
|
||||
};
|
||||
|
||||
enum ConstructKillState
|
||||
{
|
||||
KILL_NO_CONSTRUCT = 0,
|
||||
KILL_ONE_CONSTRUCT = 1,
|
||||
KILL_MORE_CONSTRUCT = 2
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
POINT_MOVE_OUT = 1
|
||||
|
||||
@@ -690,22 +690,7 @@ class instance_ulduar : public InstanceMapScript
|
||||
{
|
||||
case BOSS_LEVIATHAN:
|
||||
if (state == DONE)
|
||||
{
|
||||
// Eject all players from vehicles and make them untargetable.
|
||||
// They will be despawned after a while
|
||||
for (auto const& vehicleGuid : LeviathanVehicleGUIDs)
|
||||
{
|
||||
if (Creature* vehicleCreature = instance->GetCreature(vehicleGuid))
|
||||
{
|
||||
if (Vehicle* vehicle = vehicleCreature->GetVehicleKit())
|
||||
{
|
||||
vehicle->RemoveAllPassengers();
|
||||
vehicleCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
vehicleCreature->DespawnOrUnsummon(5 * MINUTE * IN_MILLISECONDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_events.ScheduleEvent(EVENT_DESPAWN_LEVIATHAN_VEHICLES, 5 * IN_MILLISECONDS);
|
||||
break;
|
||||
case BOSS_IGNIS:
|
||||
case BOSS_RAZORSCALE:
|
||||
@@ -1164,6 +1149,22 @@ class instance_ulduar : public InstanceMapScript
|
||||
algalon->AI()->DoAction(EVENT_DESPAWN_ALGALON);
|
||||
}
|
||||
break;
|
||||
case EVENT_DESPAWN_LEVIATHAN_VEHICLES:
|
||||
// Eject all players from vehicles and make them untargetable.
|
||||
// They will be despawned after a while
|
||||
for (auto const& vehicleGuid : LeviathanVehicleGUIDs)
|
||||
{
|
||||
if (Creature* vehicleCreature = instance->GetCreature(vehicleGuid))
|
||||
{
|
||||
if (Vehicle* vehicle = vehicleCreature->GetVehicleKit())
|
||||
{
|
||||
vehicle->RemoveAllPassengers();
|
||||
vehicleCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
vehicleCreature->DespawnOrUnsummon(5 * MINUTE * IN_MILLISECONDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,6 +404,7 @@ enum UlduarEvents
|
||||
EVENT_DESPAWN_ALGALON = 1,
|
||||
EVENT_UPDATE_ALGALON_TIMER = 2,
|
||||
ACTION_INIT_ALGALON = 6,
|
||||
EVENT_DESPAWN_LEVIATHAN_VEHICLES = 7
|
||||
};
|
||||
|
||||
enum YoggSaronIllusions
|
||||
|
||||
@@ -23,12 +23,9 @@ enum Spells
|
||||
{
|
||||
SPELL_ARCANE_VACUUM = 58694,
|
||||
SPELL_BLIZZARD = 58693,
|
||||
H_SPELL_BLIZZARD = 59369,
|
||||
SPELL_MANA_DESTRUCTION = 59374,
|
||||
SPELL_TAIL_SWEEP = 58690,
|
||||
H_SPELL_TAIL_SWEEP = 59283,
|
||||
SPELL_UNCONTROLLABLE_ENERGY = 58688,
|
||||
H_SPELL_UNCONTROLLABLE_ENERGY = 59281,
|
||||
SPELL_TRANSFORM = 58668
|
||||
};
|
||||
|
||||
@@ -48,17 +45,11 @@ class boss_cyanigosa : public CreatureScript
|
||||
public:
|
||||
boss_cyanigosa() : CreatureScript("boss_cyanigosa") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
struct boss_cyanigosaAI : public BossAI
|
||||
{
|
||||
return GetInstanceAI<boss_cyanigosaAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_cyanigosaAI : public ScriptedAI
|
||||
{
|
||||
boss_cyanigosaAI(Creature* creature) : ScriptedAI(creature)
|
||||
boss_cyanigosaAI(Creature* creature) : BossAI(creature, DATA_CYANIGOSA)
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
@@ -76,24 +67,20 @@ public:
|
||||
uint32 uiTailSweepTimer;
|
||||
uint32 uiUncontrollableEnergyTimer;
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
instance->SetData(DATA_CYANIGOSA_EVENT, NOT_STARTED);
|
||||
BossAI::Reset();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
void EnterCombat(Unit* who) override
|
||||
{
|
||||
BossAI::EnterCombat(who);
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
instance->SetData(DATA_CYANIGOSA_EVENT, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override { }
|
||||
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (instance->GetData(DATA_REMOVE_NPC) == 1)
|
||||
@@ -102,13 +89,12 @@ public:
|
||||
instance->SetData(DATA_REMOVE_NPC, 0);
|
||||
}
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (uiArcaneVacuumTimer <= diff)
|
||||
{
|
||||
DoCast(SPELL_ARCANE_VACUUM);
|
||||
DoCastAOE(SPELL_ARCANE_VACUUM);
|
||||
uiArcaneVacuumTimer = 10000;
|
||||
} else uiArcaneVacuumTimer -= diff;
|
||||
|
||||
@@ -121,7 +107,7 @@ public:
|
||||
|
||||
if (uiTailSweepTimer <= diff)
|
||||
{
|
||||
DoCast(SPELL_TAIL_SWEEP);
|
||||
DoCastVictim(SPELL_TAIL_SWEEP);
|
||||
uiTailSweepTimer = 20000;
|
||||
} else uiTailSweepTimer -= diff;
|
||||
|
||||
@@ -144,22 +130,23 @@ public:
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
instance->SetData(DATA_CYANIGOSA_EVENT, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<boss_cyanigosaAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_defenseless : public AchievementCriteriaScript
|
||||
|
||||
@@ -24,12 +24,11 @@ enum Spells
|
||||
SPELL_BLOODLUST = 54516,
|
||||
SPELL_BREAK_BONDS = 59463,
|
||||
SPELL_CHAIN_HEAL = 54481,
|
||||
H_SPELL_CHAIN_HEAL = 59473,
|
||||
SPELL_EARTH_SHIELD = 54479,
|
||||
H_SPELL_EARTH_SHIELD = 59471,
|
||||
SPELL_EARTH_SHOCK = 54511,
|
||||
SPELL_LIGHTNING_BOLT = 53044,
|
||||
SPELL_STORMSTRIKE = 51876
|
||||
SPELL_STORMSTRIKE = 51876,
|
||||
SPELL_WINDFURY = 54493
|
||||
};
|
||||
|
||||
enum Yells
|
||||
@@ -42,6 +41,17 @@ enum Yells
|
||||
SAY_BOTH_ADDS_KILLED = 5
|
||||
};
|
||||
|
||||
enum ErekemEvents
|
||||
{
|
||||
EVENT_EARTH_SHIELD = 1,
|
||||
EVENT_CHAIN_HEAL,
|
||||
EVENT_BLOODLUST,
|
||||
EVENT_LIGHTNING_BOLT,
|
||||
EVENT_EARTH_SHOCK,
|
||||
EVENT_WINDFURY,
|
||||
EVENT_STORMSTRIKE
|
||||
};
|
||||
|
||||
class boss_erekem : public CreatureScript
|
||||
{
|
||||
public:
|
||||
@@ -62,39 +72,50 @@ public:
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
uiBloodlustTimer = 15000;
|
||||
uiChainHealTimer = 0;
|
||||
uiEarthShockTimer = urand(2000, 8000);
|
||||
uiLightningBoltTimer = urand(5000, 10000);
|
||||
uiEarthShieldTimer = 20000;
|
||||
phase = 0;
|
||||
breakBondsCd = 0;
|
||||
}
|
||||
|
||||
uint32 uiBloodlustTimer;
|
||||
uint32 uiChainHealTimer;
|
||||
uint32 uiEarthShockTimer;
|
||||
uint32 uiLightningBoltTimer;
|
||||
uint32 uiEarthShieldTimer;
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
if (instance->GetData(DATA_WAVE_COUNT) == 6)
|
||||
instance->SetData(DATA_1ST_BOSS_EVENT, NOT_STARTED);
|
||||
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
|
||||
instance->SetData(DATA_2ND_BOSS_EVENT, NOT_STARTED);
|
||||
|
||||
if (instance->GetData(DATA_WAVE_COUNT) == 6)
|
||||
instance->SetBossState(DATA_1ST_BOSS_EVENT, NOT_STARTED);
|
||||
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
|
||||
instance->SetBossState(DATA_2ND_BOSS_EVENT, NOT_STARTED);
|
||||
|
||||
if (instance->GetData(DATA_MAIN_EVENT_PHASE) == IN_PROGRESS)
|
||||
{
|
||||
if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
|
||||
pGuard1->DespawnOrUnsummon();
|
||||
if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
|
||||
pGuard2->DespawnOrUnsummon();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
|
||||
{
|
||||
if (!pGuard1->IsAlive())
|
||||
pGuard1->Respawn();
|
||||
}
|
||||
if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
|
||||
{
|
||||
if (!pGuard2->IsAlive())
|
||||
pGuard2->Respawn();
|
||||
}
|
||||
}
|
||||
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
|
||||
{
|
||||
if (!pGuard1->IsAlive())
|
||||
pGuard1->Respawn();
|
||||
}
|
||||
pGuard1->Respawn();
|
||||
|
||||
if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
|
||||
{
|
||||
if (!pGuard2->IsAlive())
|
||||
pGuard2->Respawn();
|
||||
}
|
||||
pGuard2->Respawn();
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
@@ -111,13 +132,13 @@ public:
|
||||
|
||||
if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
|
||||
{
|
||||
pGuard1->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
|
||||
pGuard1->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
|
||||
if (!pGuard1->GetVictim() && pGuard1->AI())
|
||||
pGuard1->AI()->AttackStart(who);
|
||||
}
|
||||
if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
|
||||
{
|
||||
pGuard2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
|
||||
pGuard2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
|
||||
if (!pGuard2->GetVictim() && pGuard2->AI())
|
||||
pGuard2->AI()->AttackStart(who);
|
||||
}
|
||||
@@ -129,81 +150,24 @@ public:
|
||||
Talk(SAY_AGGRO);
|
||||
DoCast(me, SPELL_EARTH_SHIELD);
|
||||
|
||||
if (GameObject* pDoor = instance->instance->GetGameObject(instance->GetGuidData(DATA_EREKEM_CELL)))
|
||||
if (pDoor->GetGoState() == GO_STATE_READY)
|
||||
if (GameObject* door = instance->GetGameObject(DATA_EREKEM_CELL))
|
||||
if (door->GetGoState() == GO_STATE_READY)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (instance->GetData(DATA_WAVE_COUNT) == 6)
|
||||
instance->SetData(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
|
||||
instance->SetBossState(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
|
||||
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
|
||||
instance->SetData(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
|
||||
}
|
||||
instance->SetBossState(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override { }
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//spam stormstrike in hc mode if spawns are dead
|
||||
if (IsHeroic())
|
||||
{
|
||||
if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
|
||||
{
|
||||
if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
|
||||
{
|
||||
if (!pGuard1->IsAlive() && !pGuard2->IsAlive())
|
||||
DoCastVictim(SPELL_STORMSTRIKE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (uiEarthShieldTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_EARTH_SHIELD);
|
||||
uiEarthShieldTimer = 20000;
|
||||
} else uiEarthShieldTimer -= diff;
|
||||
|
||||
if (uiChainHealTimer <= diff)
|
||||
{
|
||||
if (ObjectGuid TargetGUID = GetChainHealTargetGUID())
|
||||
{
|
||||
if (Creature* target = ObjectAccessor::GetCreature(*me, TargetGUID))
|
||||
DoCast(target, SPELL_CHAIN_HEAL);
|
||||
|
||||
//If one of the adds is dead spawn heals faster
|
||||
Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1));
|
||||
Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2));
|
||||
uiChainHealTimer = ((pGuard1 && !pGuard1->IsAlive()) || (pGuard2 && !pGuard2->IsAlive()) ? 3000 : 8000) + rand32() % 3000;
|
||||
}
|
||||
} else uiChainHealTimer -= diff;
|
||||
|
||||
if (uiBloodlustTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_BLOODLUST);
|
||||
uiBloodlustTimer = urand(35000, 45000);
|
||||
} else uiBloodlustTimer -= diff;
|
||||
|
||||
if (uiEarthShockTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_EARTH_SHOCK);
|
||||
uiEarthShockTimer = urand(8000, 13000);
|
||||
} else uiEarthShockTimer -= diff;
|
||||
|
||||
if (uiLightningBoltTimer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_LIGHTNING_BOLT);
|
||||
uiLightningBoltTimer = urand(18000, 24000);
|
||||
} else uiLightningBoltTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
events.ScheduleEvent(EVENT_EARTH_SHIELD, 20000);
|
||||
events.ScheduleEvent(EVENT_BLOODLUST, 15000);
|
||||
events.ScheduleEvent(EVENT_CHAIN_HEAL, 10000);
|
||||
events.ScheduleEvent(EVENT_LIGHTNING_BOLT, 2000);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
@@ -212,41 +176,134 @@ public:
|
||||
|
||||
if (instance->GetData(DATA_WAVE_COUNT) == 6)
|
||||
{
|
||||
instance->SetData(DATA_1ST_BOSS_EVENT, DONE);
|
||||
instance->SetBossState(DATA_1ST_BOSS_EVENT, DONE);
|
||||
instance->SetData(DATA_WAVE_COUNT, 7);
|
||||
}
|
||||
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
|
||||
{
|
||||
instance->SetData(DATA_2ND_BOSS_EVENT, DONE);
|
||||
instance->SetBossState(DATA_2ND_BOSS_EVENT, DONE);
|
||||
instance->SetData(DATA_WAVE_COUNT, 13);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() != TYPEID_PLAYER)
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
if (phase == 0)
|
||||
if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
|
||||
{
|
||||
if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
|
||||
{
|
||||
if (!pGuard1->IsAlive() && !pGuard2->IsAlive())
|
||||
{
|
||||
phase = 1;
|
||||
DoCastVictim(SPELL_STORMSTRIKE);
|
||||
DoCast(SPELL_WINDFURY);
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_EARTH_SHOCK, urand(2000, 8000));
|
||||
events.ScheduleEvent(EVENT_WINDFURY, urand(1500, 2000));
|
||||
events.ScheduleEvent(EVENT_STORMSTRIKE, urand(1500, 2000));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
if (breakBondsCd <= 0)
|
||||
{
|
||||
if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
|
||||
{
|
||||
if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
|
||||
{
|
||||
if (pGuard1->IsAlive())
|
||||
{
|
||||
if (pGuard1->HasAuraType(SPELL_AURA_MOD_STUN) || pGuard1->HasAuraType(SPELL_AURA_MOD_ROOT)
|
||||
|| pGuard1->HasAuraType(SPELL_AURA_MOD_CONFUSE) || pGuard1->HasAuraType(SPELL_AURA_MOD_PACIFY)
|
||||
|| pGuard1->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED))
|
||||
{
|
||||
DoCast(SPELL_BREAK_BONDS);
|
||||
breakBondsCd = 10000;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (pGuard2->IsAlive())
|
||||
{
|
||||
if (pGuard2->HasAuraType(SPELL_AURA_MOD_STUN) || pGuard2->HasAuraType(SPELL_AURA_MOD_ROOT)
|
||||
|| pGuard2->HasAuraType(SPELL_AURA_MOD_CONFUSE) || pGuard2->HasAuraType(SPELL_AURA_MOD_PACIFY)
|
||||
|| pGuard2->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED))
|
||||
{
|
||||
DoCast(SPELL_BREAK_BONDS);
|
||||
breakBondsCd = 10000;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
breakBondsCd -= diff;
|
||||
|
||||
switch (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_EARTH_SHIELD:
|
||||
if (Unit* ally = DoSelectLowestHpFriendly(30.0f))
|
||||
DoCast(ally, SPELL_EARTH_SHIELD);
|
||||
events.ScheduleEvent(EVENT_EARTH_SHIELD, 20000);
|
||||
break;
|
||||
case EVENT_BLOODLUST:
|
||||
DoCast(SPELL_BLOODLUST);
|
||||
events.ScheduleEvent(EVENT_BLOODLUST, urand(35000, 45000));
|
||||
break;
|
||||
case EVENT_LIGHTNING_BOLT:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_LIGHTNING_BOLT);
|
||||
events.ScheduleEvent(EVENT_LIGHTNING_BOLT, 2500);
|
||||
break;
|
||||
case EVENT_CHAIN_HEAL:
|
||||
if (Unit* ally = DoSelectLowestHpFriendly(40.0f))
|
||||
DoCast(ally, SPELL_CHAIN_HEAL);
|
||||
{
|
||||
Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1));
|
||||
Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2));
|
||||
events.ScheduleEvent(EVENT_CHAIN_HEAL, ((pGuard1 && !pGuard1->IsAlive()) || (pGuard2 && !pGuard2->IsAlive()) ? 3000 : 8000 + rand() % 3000));
|
||||
}
|
||||
break;
|
||||
case EVENT_EARTH_SHOCK:
|
||||
DoCastVictim(SPELL_EARTH_SHOCK);
|
||||
events.ScheduleEvent(EVENT_EARTH_SHOCK, urand(8000, 13000));
|
||||
break;
|
||||
case EVENT_WINDFURY:
|
||||
DoCast(SPELL_WINDFURY);
|
||||
events.ScheduleEvent(EVENT_WINDFURY, urand(1500, 2000));
|
||||
break;
|
||||
case EVENT_STORMSTRIKE:
|
||||
DoCastVictim(SPELL_STORMSTRIKE);
|
||||
events.ScheduleEvent(EVENT_STORMSTRIKE, urand(1500, 2000));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
ObjectGuid GetChainHealTargetGUID()
|
||||
{
|
||||
if (HealthBelowPct(85))
|
||||
return me->GetGUID();
|
||||
|
||||
Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1));
|
||||
if (pGuard1 && pGuard1->IsAlive() && !pGuard1->HealthAbovePct(75))
|
||||
return pGuard1->GetGUID();
|
||||
|
||||
Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2));
|
||||
if (pGuard2 && pGuard2->IsAlive() && !pGuard2->HealthAbovePct(75))
|
||||
return pGuard2->GetGUID();
|
||||
|
||||
return ObjectGuid::Empty;
|
||||
}
|
||||
private:
|
||||
EventMap events;
|
||||
InstanceScript* instance;
|
||||
uint8 phase;
|
||||
int32 breakBondsCd;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
enum GuardSpells
|
||||
@@ -290,6 +347,9 @@ public:
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
@@ -308,7 +368,6 @@ public:
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override { }
|
||||
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
@@ -335,7 +394,6 @@ public:
|
||||
} else uiGushingWoundTimer -= diff;
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_erekem()
|
||||
|
||||
@@ -23,19 +23,20 @@ enum Spells
|
||||
{
|
||||
SPELL_DRAINED = 59820,
|
||||
SPELL_FRENZY = 54312,
|
||||
SPELL_FRENZY_H = 59522,
|
||||
SPELL_PROTECTIVE_BUBBLE = 54306,
|
||||
SPELL_WATER_BLAST = 54237,
|
||||
SPELL_WATER_BLAST_H = 59520,
|
||||
SPELL_WATER_BOLT_VOLLEY = 54241,
|
||||
SPELL_WATER_BOLT_VOLLEY_H = 59521,
|
||||
SPELL_SPLASH = 59516,
|
||||
SPELL_WATER_GLOBULE = 54268
|
||||
SPELL_BURST = 54379,
|
||||
SPELL_WATER_GLOBULE = 54268,
|
||||
SPELL_MERGE = 54269,
|
||||
SPELL_WATER_GLOBULE_VISUAL = 54260
|
||||
};
|
||||
|
||||
enum IchoronCreatures
|
||||
{
|
||||
NPC_ICHOR_GLOBULE = 29321,
|
||||
NPC_ICHORON_SUMMON_TARGET = 29326
|
||||
};
|
||||
|
||||
enum Yells
|
||||
@@ -51,75 +52,83 @@ enum Yells
|
||||
|
||||
enum Actions
|
||||
{
|
||||
ACTION_WATER_ELEMENT_HIT = 1,
|
||||
ACTION_WATER_ELEMENT_KILLED = 2,
|
||||
ACTION_WATER_ELEMENT_HIT = 1
|
||||
};
|
||||
|
||||
/// @todo get those positions from spawn of creature 29326
|
||||
#define MAX_SPAWN_LOC 5
|
||||
static Position SpawnLoc[MAX_SPAWN_LOC]=
|
||||
enum IchoronEvents
|
||||
{
|
||||
{1840.64f, 795.407f, 44.079f, 1.676f},
|
||||
{1886.24f, 757.733f, 47.750f, 5.201f},
|
||||
{1877.91f, 845.915f, 43.417f, 3.560f},
|
||||
{1918.97f, 850.645f, 47.225f, 4.136f},
|
||||
{1935.50f, 796.224f, 52.492f, 4.224f},
|
||||
EVENT_WATER_BLAST = 1,
|
||||
EVENT_WATER_BOLT_VOLLEY
|
||||
};
|
||||
|
||||
enum GlobuleEvents
|
||||
{
|
||||
EVENT_GLOBULE_MOVE = 1
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
DATA_GLOBULE_PATH = 0,
|
||||
DATA_DEHYDRATION = 1
|
||||
};
|
||||
|
||||
|
||||
#define MAX_GLOBULE_PATHS 10
|
||||
|
||||
Position const globulePaths[MAX_GLOBULE_PATHS] =
|
||||
{
|
||||
// first target
|
||||
{ 1861.357f, 804.039f, 44.008f, 6.268f },
|
||||
{ 1869.375f, 803.976f, 38.781f, 0.009f },
|
||||
// second target
|
||||
{ 1888.063f, 763.488f, 47.667f, 1.744f },
|
||||
{ 1882.865f, 776.385f, 38.824f, 1.882f },
|
||||
// third target
|
||||
{ 1935.140f, 817.752f, 52.181f, 1.885f },
|
||||
{ 1916.642f, 826.337f, 39.139f, 2.851f },
|
||||
// fourth target
|
||||
{ 1930.257f, 833.053f, 46.906f, 4.579f },
|
||||
{ 1916.642f, 826.337f, 39.139f, 2.851f },
|
||||
// fifth target
|
||||
{ 1878.248f, 841.883f, 43.334f, 4.717f },
|
||||
{ 1879.438f, 834.443f, 38.699f, 4.831f }
|
||||
};
|
||||
|
||||
class boss_ichoron : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_ichoron() : CreatureScript("boss_ichoron") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<boss_ichoronAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_ichoronAI : public ScriptedAI
|
||||
{
|
||||
boss_ichoronAI(Creature* creature) : ScriptedAI(creature), m_waterElements(creature)
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
bIsExploded = false;
|
||||
bIsFrenzy = false;
|
||||
bIsDrained = false;
|
||||
dehydration = true;
|
||||
uiBubbleCheckerTimer = 1000;
|
||||
uiWaterBoltVolleyTimer = urand(10000, 15000);
|
||||
drainedTimer = 50;
|
||||
burstTimer = 15000;
|
||||
}
|
||||
|
||||
bool bIsExploded;
|
||||
bool bIsFrenzy;
|
||||
bool dehydration;
|
||||
|
||||
uint32 uiBubbleCheckerTimer;
|
||||
uint32 uiWaterBoltVolleyTimer;
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
SummonList m_waterElements;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
|
||||
events.Reset();
|
||||
me->SetVisible(true);
|
||||
DespawnWaterElements();
|
||||
|
||||
if (instance->GetData(DATA_WAVE_COUNT) == 6)
|
||||
instance->SetData(DATA_1ST_BOSS_EVENT, NOT_STARTED);
|
||||
instance->SetBossState(DATA_1ST_BOSS_EVENT, NOT_STARTED);
|
||||
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
|
||||
instance->SetData(DATA_2ND_BOSS_EVENT, NOT_STARTED);
|
||||
instance->SetBossState(DATA_2ND_BOSS_EVENT, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
@@ -128,16 +137,20 @@ public:
|
||||
|
||||
DoCast(me, SPELL_PROTECTIVE_BUBBLE);
|
||||
|
||||
if (GameObject* pDoor = instance->instance->GetGameObject(instance->GetGuidData(DATA_ICHORON_CELL)))
|
||||
if (pDoor->GetGoState() == GO_STATE_READY)
|
||||
if (GameObject* door = instance->GetGameObject(DATA_ICHORON_CELL))
|
||||
if (door->GetGoState() == GO_STATE_READY)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (instance->GetData(DATA_WAVE_COUNT) == 6)
|
||||
instance->SetData(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
|
||||
instance->SetBossState(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
|
||||
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
|
||||
instance->SetData(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
|
||||
instance->SetBossState(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
|
||||
|
||||
events.ScheduleEvent(EVENT_WATER_BOLT_VOLLEY, urand(10000, 15000));
|
||||
events.ScheduleEvent(EVENT_WATER_BLAST, urand(6000, 9000));
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
@@ -162,18 +175,14 @@ public:
|
||||
switch (param)
|
||||
{
|
||||
case ACTION_WATER_ELEMENT_HIT:
|
||||
me->ModifyHealth(int32(me->CountPctFromMaxHealth(1)));
|
||||
|
||||
{
|
||||
if (bIsExploded)
|
||||
DoExplodeCompleted();
|
||||
|
||||
me->SetHealth(me->GetHealth() + me->CountPctFromMaxHealth(3));
|
||||
dehydration = false;
|
||||
break;
|
||||
case ACTION_WATER_ELEMENT_KILLED:
|
||||
uint32 damage = me->CountPctFromMaxHealth(3);
|
||||
me->ModifyHealth(-int32(damage));
|
||||
me->LowerPlayerDamageReq(damage);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,6 +196,7 @@ public:
|
||||
void DoExplodeCompleted()
|
||||
{
|
||||
bIsExploded = false;
|
||||
bIsDrained = false;
|
||||
|
||||
if (!HealthBelowPct(25))
|
||||
{
|
||||
@@ -206,75 +216,24 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override { }
|
||||
|
||||
|
||||
void UpdateAI(uint32 uiDiff) override
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
if (!who->ToCreature())
|
||||
return;
|
||||
|
||||
if (!bIsFrenzy && HealthBelowPct(25) && !bIsExploded)
|
||||
{
|
||||
Talk(SAY_ENRAGE);
|
||||
DoCast(me, SPELL_FRENZY, true);
|
||||
bIsFrenzy = true;
|
||||
}
|
||||
if (who->GetEntry() != NPC_ICHOR_GLOBULE)
|
||||
return;
|
||||
|
||||
if (!bIsFrenzy)
|
||||
{
|
||||
if (uiBubbleCheckerTimer <= uiDiff)
|
||||
{
|
||||
if (!bIsExploded)
|
||||
{
|
||||
if (!me->HasAura(SPELL_PROTECTIVE_BUBBLE))
|
||||
{
|
||||
Talk(SAY_SHATTER);
|
||||
DoCast(me, SPELL_WATER_BLAST);
|
||||
DoCast(me, SPELL_DRAINED);
|
||||
bIsExploded = true;
|
||||
me->AttackStop();
|
||||
me->SetVisible(false);
|
||||
for (uint8 i = 0; i < 10; i++)
|
||||
{
|
||||
int tmp = urand(0, MAX_SPAWN_LOC-1);
|
||||
me->SummonCreature(NPC_ICHOR_GLOBULE, SpawnLoc[tmp], TEMPSUMMON_CORPSE_DESPAWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool bIsWaterElementsAlive = false;
|
||||
if (!m_waterElements.empty())
|
||||
{
|
||||
for (SummonList::const_iterator itr = m_waterElements.begin(); itr != m_waterElements.end(); ++itr)
|
||||
if (Creature* temp = ObjectAccessor::GetCreature(*me, *itr))
|
||||
if (temp->IsAlive())
|
||||
{
|
||||
bIsWaterElementsAlive = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!me->IsWithinDist(who, 4.0f, false))
|
||||
return;
|
||||
|
||||
if (!bIsWaterElementsAlive)
|
||||
DoExplodeCompleted();
|
||||
}
|
||||
uiBubbleCheckerTimer = 1000;
|
||||
}
|
||||
else uiBubbleCheckerTimer -= uiDiff;
|
||||
}
|
||||
if (who->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
|
||||
return;
|
||||
|
||||
if (!bIsExploded)
|
||||
{
|
||||
if (uiWaterBoltVolleyTimer <= uiDiff)
|
||||
{
|
||||
DoCast(me, SPELL_WATER_BOLT_VOLLEY);
|
||||
uiWaterBoltVolleyTimer = urand(10000, 15000);
|
||||
}
|
||||
else uiWaterBoltVolleyTimer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
who->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
who->CastSpell(who, SPELL_MERGE);
|
||||
DoAction(ACTION_WATER_ELEMENT_HIT);
|
||||
who->ToCreature()->DespawnOrUnsummon(1000);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
@@ -291,45 +250,187 @@ public:
|
||||
|
||||
if (instance->GetData(DATA_WAVE_COUNT) == 6)
|
||||
{
|
||||
instance->SetData(DATA_1ST_BOSS_EVENT, DONE);
|
||||
instance->SetBossState(DATA_1ST_BOSS_EVENT, DONE);
|
||||
instance->SetData(DATA_WAVE_COUNT, 7);
|
||||
}
|
||||
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
|
||||
{
|
||||
instance->SetData(DATA_2ND_BOSS_EVENT, DONE);
|
||||
instance->SetBossState(DATA_2ND_BOSS_EVENT, DONE);
|
||||
instance->SetData(DATA_WAVE_COUNT, 13);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned) override
|
||||
{
|
||||
if (summoned)
|
||||
{
|
||||
summoned->SetSpeed(MOVE_RUN, 0.3f);
|
||||
summoned->GetMotionMaster()->MoveFollow(me, 0, 0);
|
||||
m_waterElements.Summon(summoned);
|
||||
instance->SetGuidData(DATA_ADD_TRASH_MOB, summoned->GetGUID());
|
||||
}
|
||||
summoned->SetSpeed(MOVE_RUN, 0.3f);
|
||||
m_waterElements.Summon(summoned);
|
||||
|
||||
instance->SetGuidData(DATA_ADD_TRASH_MOB, summoned->GetGUID());
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* summoned) override
|
||||
{
|
||||
if (summoned)
|
||||
m_waterElements.Despawn(summoned);
|
||||
|
||||
if (m_waterElements.empty() && bIsExploded)
|
||||
{
|
||||
m_waterElements.Despawn(summoned);
|
||||
instance->SetGuidData(DATA_DEL_TRASH_MOB, summoned->GetGUID());
|
||||
me->RemoveAllAuras();
|
||||
DoExplodeCompleted();
|
||||
}
|
||||
|
||||
instance->SetGuidData(DATA_DEL_TRASH_MOB, summoned->GetGUID());
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() != TYPEID_PLAYER)
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
if (!bIsFrenzy && HealthBelowPct(25) && !bIsExploded)
|
||||
{
|
||||
Talk(SAY_ENRAGE);
|
||||
DoCast(me, SPELL_FRENZY, true);
|
||||
bIsFrenzy = true;
|
||||
}
|
||||
|
||||
if (!bIsFrenzy)
|
||||
{
|
||||
if (!bIsExploded)
|
||||
{
|
||||
if (!me->HasAura(SPELL_PROTECTIVE_BUBBLE))
|
||||
{
|
||||
bIsExploded = true;
|
||||
Talk(SAY_SHATTER);
|
||||
DoCast(SPELL_BURST);
|
||||
me->RemoveAllAuras();
|
||||
burstTimer = 15000;
|
||||
|
||||
std::list<Creature*> summonTargets;
|
||||
GetCreatureListWithEntryInGrid(summonTargets, me, NPC_ICHORON_SUMMON_TARGET, 200.0f);
|
||||
std::list<Creature*>::iterator itr = summonTargets.begin();
|
||||
|
||||
for (uint8 i = 0; i < MAX_GLOBULE_PATHS; i++)
|
||||
{
|
||||
std::advance(itr, urand(0, summonTargets.size() - 1)); // I take a random minion in the list
|
||||
Position targetPos = (*itr)->GetRandomNearPosition(10.0f);
|
||||
itr = summonTargets.begin();
|
||||
TempSummon* globule = me->SummonCreature(NPC_ICHOR_GLOBULE, targetPos, TEMPSUMMON_CORPSE_DESPAWN);
|
||||
DoCast(globule, SPELL_WATER_GLOBULE_VISUAL);
|
||||
|
||||
float minDistance = 1000.0f;
|
||||
uint8 nextPath = 0;
|
||||
// I move the globules to next position. the 10 positions are in couples, defined in globulePaths, so i have to increase by 2.
|
||||
for (uint8 gpath = 0; gpath < MAX_GLOBULE_PATHS; gpath += 2)
|
||||
{
|
||||
if (globule->GetDistance(globulePaths[gpath]) < minDistance)
|
||||
{
|
||||
minDistance = globule->GetDistance(globulePaths[gpath]);
|
||||
nextPath = gpath;
|
||||
}
|
||||
}
|
||||
|
||||
globule->GetAI()->SetData(DATA_GLOBULE_PATH, nextPath);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
switch (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_WATER_BLAST:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_WATER_BLAST);
|
||||
events.ScheduleEvent(EVENT_WATER_BLAST, urand(6000, 9000));
|
||||
break;
|
||||
case EVENT_WATER_BOLT_VOLLEY:
|
||||
DoCast(SPELL_WATER_BOLT_VOLLEY);
|
||||
events.ScheduleEvent(EVENT_WATER_BOLT_VOLLEY, urand(10000, 15000));
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
else if (!bIsDrained)
|
||||
{
|
||||
if (drainedTimer <= 0)
|
||||
{
|
||||
bIsDrained = true;
|
||||
drainedTimer = 50;
|
||||
uint32 damage = me->CountPctFromMaxHealth(30);
|
||||
if (me->GetHealth() < damage)
|
||||
me->SetHealth(me->CountPctFromMaxHealth(1));
|
||||
else
|
||||
{
|
||||
me->SetHealth(me->GetHealth() - damage);
|
||||
me->LowerPlayerDamageReq(damage);
|
||||
}
|
||||
DoCast(SPELL_DRAINED);
|
||||
me->SetVisible(false);
|
||||
me->AttackStop();
|
||||
}
|
||||
else
|
||||
drainedTimer -= diff;
|
||||
}
|
||||
else if (bIsDrained)
|
||||
{
|
||||
if (burstTimer <= 0)
|
||||
{
|
||||
DoExplodeCompleted();
|
||||
}
|
||||
else
|
||||
burstTimer -= diff;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
switch (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_WATER_BLAST:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_WATER_BLAST);
|
||||
events.ScheduleEvent(EVENT_WATER_BLAST, urand(6000, 9000));
|
||||
break;
|
||||
case EVENT_WATER_BOLT_VOLLEY:
|
||||
DoCast(SPELL_WATER_BOLT_VOLLEY);
|
||||
events.ScheduleEvent(EVENT_WATER_BOLT_VOLLEY, urand(10000, 15000));
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
InstanceScript* instance;
|
||||
SummonList m_waterElements;
|
||||
EventMap events;
|
||||
bool bIsExploded;
|
||||
bool bIsFrenzy;
|
||||
bool bIsDrained;
|
||||
bool dehydration;
|
||||
int32 drainedTimer;
|
||||
int32 burstTimer;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<boss_ichoronAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_ichor_globule : public CreatureScript
|
||||
@@ -337,11 +438,6 @@ class npc_ichor_globule : public CreatureScript
|
||||
public:
|
||||
npc_ichor_globule() : CreatureScript("npc_ichor_globule") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_ichor_globuleAI>(creature);
|
||||
}
|
||||
|
||||
struct npc_ichor_globuleAI : public ScriptedAI
|
||||
{
|
||||
npc_ichor_globuleAI(Creature* creature) : ScriptedAI(creature)
|
||||
@@ -352,51 +448,74 @@ public:
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
uiRangeCheck_Timer = 1000;
|
||||
pathId = 0;
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 uiRangeCheck_Timer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
DoCast(me, SPELL_WATER_GLOBULE);
|
||||
events.Reset();
|
||||
DoCast(SPELL_WATER_GLOBULE);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
|
||||
void AttackStart(Unit* /*who*/) override
|
||||
void SetData(uint32 id, uint32 data) override
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 uiDiff) override
|
||||
{
|
||||
if (uiRangeCheck_Timer < uiDiff)
|
||||
if (id == DATA_GLOBULE_PATH)
|
||||
{
|
||||
if (Creature* pIchoron = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_ICHORON)))
|
||||
{
|
||||
if (me->IsWithinDist(pIchoron, 2.0f, false))
|
||||
{
|
||||
if (pIchoron->AI())
|
||||
pIchoron->AI()->DoAction(ACTION_WATER_ELEMENT_HIT);
|
||||
me->DespawnOrUnsummon();
|
||||
}
|
||||
}
|
||||
uiRangeCheck_Timer = 1000;
|
||||
pathId = data;
|
||||
me->GetMotionMaster()->MovePoint(0, globulePaths[pathId]);
|
||||
}
|
||||
else uiRangeCheck_Timer -= uiDiff;
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
void MovementInform(uint32 type, uint32 id) override
|
||||
{
|
||||
DoCast(me, SPELL_SPLASH);
|
||||
if (Creature* pIchoron = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_ICHORON)))
|
||||
if (pIchoron->AI())
|
||||
pIchoron->AI()->DoAction(ACTION_WATER_ELEMENT_KILLED);
|
||||
if (type != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case 0:
|
||||
me->GetMotionMaster()->Clear();
|
||||
events.ScheduleEvent(EVENT_GLOBULE_MOVE, 500);
|
||||
break;
|
||||
case 1:
|
||||
me->GetMotionMaster()->Clear();
|
||||
if (Creature* ichoron = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_ICHORON)))
|
||||
me->GetMotionMaster()->MoveFollow(ichoron, 0.0f, 0.0f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// on retail spell casted on a creature's death are not casted after death but keeping mob at 1 health, casting it and then letting the mob die.
|
||||
// this feature should be still implemented
|
||||
void DamageTaken(Unit* /*attacker*/, uint32 &damage) override
|
||||
{
|
||||
int32 actualHp = me->GetHealth();
|
||||
actualHp -= damage;
|
||||
|
||||
if (actualHp <= 0)
|
||||
DoCast(SPELL_SPLASH);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
if (events.ExecuteEvent() == EVENT_GLOBULE_MOVE)
|
||||
me->GetMotionMaster()->MovePoint(1, globulePaths[pathId + 1]);
|
||||
}
|
||||
|
||||
private:
|
||||
InstanceScript* instance;
|
||||
EventMap events;
|
||||
uint8 pathId;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_ichor_globuleAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_dehydration : public AchievementCriteriaScript
|
||||
|
||||
@@ -21,13 +21,18 @@
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CAUTERIZING_FLAMES = 59466, //Only in heroic
|
||||
SPELL_FIREBOLT = 54235,
|
||||
H_SPELL_FIREBOLT = 59468,
|
||||
SPELL_FLAME_BREATH = 54282,
|
||||
H_SPELL_FLAME_BREATH = 59469,
|
||||
SPELL_LAVA_BURN = 54249,
|
||||
H_SPELL_LAVA_BURN = 59594
|
||||
SPELL_CAUTERIZING_FLAMES = 59466, // Only in heroic
|
||||
SPELL_FIREBOLT = 54235,
|
||||
SPELL_FLAME_BREATH = 54282,
|
||||
SPELL_LAVA_BURN = 54249
|
||||
};
|
||||
|
||||
enum LavanthorEvents
|
||||
{
|
||||
EVENT_CAUTERIZING_FLAMES = 1,
|
||||
EVENT_FIREBOLT,
|
||||
EVENT_FLAME_BREATH,
|
||||
EVENT_LAVA_BURN
|
||||
};
|
||||
|
||||
class boss_lavanthor : public CreatureScript
|
||||
@@ -44,46 +49,37 @@ public:
|
||||
{
|
||||
boss_lavanthorAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
uiFireboltTimer = 1000;
|
||||
uiFlameBreathTimer = 5000;
|
||||
uiLavaBurnTimer = 10000;
|
||||
uiCauterizingFlamesTimer = 3000;
|
||||
}
|
||||
|
||||
uint32 uiFireboltTimer;
|
||||
uint32 uiFlameBreathTimer;
|
||||
uint32 uiLavaBurnTimer;
|
||||
uint32 uiCauterizingFlamesTimer;
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
if (instance->GetData(DATA_WAVE_COUNT) == 6)
|
||||
instance->SetData(DATA_1ST_BOSS_EVENT, NOT_STARTED);
|
||||
instance->SetBossState(DATA_1ST_BOSS_EVENT, NOT_STARTED);
|
||||
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
|
||||
instance->SetData(DATA_2ND_BOSS_EVENT, NOT_STARTED);
|
||||
instance->SetBossState(DATA_2ND_BOSS_EVENT, NOT_STARTED);
|
||||
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
if (GameObject* pDoor = instance->instance->GetGameObject(instance->GetGuidData(DATA_LAVANTHOR_CELL)))
|
||||
if (pDoor->GetGoState() == GO_STATE_READY)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
if (instance->GetData(DATA_WAVE_COUNT) == 6)
|
||||
instance->SetData(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
|
||||
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
|
||||
instance->SetData(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
|
||||
if (GameObject* door = instance->GetGameObject(DATA_LAVANTHOR_CELL))
|
||||
if (door->GetGoState() == GO_STATE_READY)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
if (instance->GetData(DATA_WAVE_COUNT) == 6)
|
||||
instance->SetBossState(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
|
||||
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
|
||||
instance->SetBossState(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
|
||||
|
||||
events.ScheduleEvent(EVENT_FIREBOLT, 1000);
|
||||
events.ScheduleEvent(EVENT_FLAME_BREATH, 5000);
|
||||
events.ScheduleEvent(EVENT_LAVA_BURN, 10000);
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_CAUTERIZING_FLAMES, 3000);
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
@@ -100,40 +96,38 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override { }
|
||||
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (uiFireboltTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_FIREBOLT);
|
||||
uiFireboltTimer = urand(5000, 13000);
|
||||
} else uiFireboltTimer -= diff;
|
||||
events.Update(diff);
|
||||
|
||||
if (uiFlameBreathTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_FLAME_BREATH);
|
||||
uiFlameBreathTimer = urand(10000, 15000);
|
||||
} else uiFlameBreathTimer -= diff;
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
if (uiLavaBurnTimer <= diff)
|
||||
switch (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
DoCastVictim(SPELL_LAVA_BURN);
|
||||
uiLavaBurnTimer = urand(15000, 23000);
|
||||
}
|
||||
|
||||
if (IsHeroic())
|
||||
{
|
||||
if (uiCauterizingFlamesTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_CAUTERIZING_FLAMES);
|
||||
uiCauterizingFlamesTimer = urand(10000, 16000);
|
||||
} else uiCauterizingFlamesTimer -= diff;
|
||||
case EVENT_FIREBOLT:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_FIREBOLT);
|
||||
events.ScheduleEvent(EVENT_FIREBOLT, urand(5000, 13000));
|
||||
break;
|
||||
case EVENT_FLAME_BREATH:
|
||||
DoCast(SPELL_FLAME_BREATH);
|
||||
events.ScheduleEvent(EVENT_FLAME_BREATH, urand(10000, 15000));
|
||||
break;
|
||||
case EVENT_LAVA_BURN:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_LAVA_BURN);
|
||||
events.ScheduleEvent(EVENT_LAVA_BURN, urand(15000, 23000));
|
||||
break;
|
||||
case EVENT_CAUTERIZING_FLAMES:
|
||||
DoCast(SPELL_CAUTERIZING_FLAMES);
|
||||
events.ScheduleEvent(EVENT_CAUTERIZING_FLAMES, urand(10000, 16000));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
@@ -143,17 +137,20 @@ public:
|
||||
{
|
||||
if (instance->GetData(DATA_WAVE_COUNT) == 6)
|
||||
{
|
||||
instance->SetData(DATA_1ST_BOSS_EVENT, DONE);
|
||||
instance->SetBossState(DATA_1ST_BOSS_EVENT, DONE);
|
||||
instance->SetData(DATA_WAVE_COUNT, 7);
|
||||
}
|
||||
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
|
||||
{
|
||||
instance->SetData(DATA_2ND_BOSS_EVENT, DONE);
|
||||
instance->SetBossState(DATA_2ND_BOSS_EVENT, DONE);
|
||||
instance->SetData(DATA_WAVE_COUNT, 13);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
InstanceScript* instance;
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_boss_lavanthor()
|
||||
|
||||
@@ -17,13 +17,27 @@
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "violet_hold.h"
|
||||
|
||||
//Spells
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CORROSIVE_SALIVA = 54527,
|
||||
SPELL_OPTIC_LINK = 54396
|
||||
SPELL_OPTIC_LINK = 54396,
|
||||
SPELL_RAY_OF_PAIN = 54438, // NYI missing spelldifficulty
|
||||
SPELL_RAY_OF_SUFFERING = 54442, // NYI missing spelldifficulty
|
||||
|
||||
// Visual
|
||||
SPELL_OPTIC_LINK_LEVEL_1 = 54393,
|
||||
SPELL_OPTIC_LINK_LEVEL_2 = 54394,
|
||||
SPELL_OPTIC_LINK_LEVEL_3 = 54395
|
||||
};
|
||||
|
||||
enum MoraggEvents
|
||||
{
|
||||
EVENT_CORROSIVE_SALIVA = 1,
|
||||
EVENT_OPTIC_LINK
|
||||
};
|
||||
|
||||
class boss_moragg : public CreatureScript
|
||||
@@ -31,52 +45,43 @@ class boss_moragg : public CreatureScript
|
||||
public:
|
||||
boss_moragg() : CreatureScript("boss_moragg") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<boss_moraggAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_moraggAI : public ScriptedAI
|
||||
{
|
||||
boss_moraggAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
uiOpticLinkTimer = 10000;
|
||||
uiCorrosiveSalivaTimer = 5000;
|
||||
}
|
||||
|
||||
uint32 uiOpticLinkTimer;
|
||||
uint32 uiCorrosiveSalivaTimer;
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
events.Reset();
|
||||
|
||||
if (instance->GetData(DATA_WAVE_COUNT) == 6)
|
||||
instance->SetData(DATA_1ST_BOSS_EVENT, NOT_STARTED);
|
||||
instance->SetBossState(DATA_1ST_BOSS_EVENT, NOT_STARTED);
|
||||
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
|
||||
instance->SetData(DATA_2ND_BOSS_EVENT, NOT_STARTED);
|
||||
instance->SetBossState(DATA_2ND_BOSS_EVENT, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
if (GameObject* pDoor = instance->instance->GetGameObject(instance->GetGuidData(DATA_MORAGG_CELL)))
|
||||
if (pDoor->GetGoState() == GO_STATE_READY)
|
||||
if (GameObject* door = instance->GetGameObject(DATA_MORAGG_CELL))
|
||||
if (door->GetGoState() == GO_STATE_READY)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (instance->GetData(DATA_WAVE_COUNT) == 6)
|
||||
instance->SetData(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
|
||||
instance->SetBossState(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
|
||||
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
|
||||
instance->SetData(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
|
||||
instance->SetBossState(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
|
||||
|
||||
me->SetInCombatWithZone();
|
||||
|
||||
DoCast(SPELL_RAY_OF_PAIN);
|
||||
DoCast(SPELL_RAY_OF_SUFFERING);
|
||||
events.ScheduleEvent(EVENT_OPTIC_LINK, 15000);
|
||||
events.ScheduleEvent(EVENT_CORROSIVE_SALIVA, 5000);
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
@@ -93,48 +98,202 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override { }
|
||||
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (uiOpticLinkTimer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_OPTIC_LINK);
|
||||
uiOpticLinkTimer = 15000;
|
||||
} else uiOpticLinkTimer -= diff;
|
||||
events.Update(diff);
|
||||
|
||||
if (uiCorrosiveSalivaTimer <= diff)
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
DoCastVictim(SPELL_CORROSIVE_SALIVA);
|
||||
uiCorrosiveSalivaTimer = 10000;
|
||||
} else uiCorrosiveSalivaTimer -= diff;
|
||||
case EVENT_OPTIC_LINK:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_OPTIC_LINK);
|
||||
events.ScheduleEvent(EVENT_OPTIC_LINK, 25000);
|
||||
break;
|
||||
case EVENT_CORROSIVE_SALIVA:
|
||||
DoCastVictim(SPELL_CORROSIVE_SALIVA);
|
||||
events.ScheduleEvent(EVENT_CORROSIVE_SALIVA, 10000);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (instance->GetData(DATA_WAVE_COUNT) == 6)
|
||||
{
|
||||
instance->SetData(DATA_1ST_BOSS_EVENT, DONE);
|
||||
instance->SetBossState(DATA_1ST_BOSS_EVENT, DONE);
|
||||
instance->SetData(DATA_WAVE_COUNT, 7);
|
||||
}
|
||||
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
|
||||
{
|
||||
instance->SetData(DATA_2ND_BOSS_EVENT, DONE);
|
||||
instance->SetBossState(DATA_2ND_BOSS_EVENT, DONE);
|
||||
instance->SetData(DATA_WAVE_COUNT, 13);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
InstanceScript* instance;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<boss_moraggAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_moragg_ray_of_suffering : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_moragg_ray_of_suffering() : SpellScriptLoader("spell_moragg_ray_of_suffering") { }
|
||||
|
||||
class spell_moragg_ray_of_suffering_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_moragg_ray_of_suffering_AuraScript);
|
||||
|
||||
void OnPeriodic(AuraEffect const* aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
std::list<HostileReference*> players = GetTarget()->getThreatManager().getThreatList();
|
||||
if (!players.empty())
|
||||
{
|
||||
std::list<HostileReference*>::iterator itr = players.begin();
|
||||
std::advance(itr, urand(0, players.size() - 1));
|
||||
|
||||
uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell;
|
||||
GetTarget()->CastCustomSpell(triggerSpell, SPELLVALUE_MAX_TARGETS, 1, (*itr)->getTarget(), TRIGGERED_FULL_MASK, NULL, aurEff);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_moragg_ray_of_suffering_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_moragg_ray_of_suffering_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_moragg_ray_of_pain : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_moragg_ray_of_pain() : SpellScriptLoader("spell_moragg_ray_of_pain") { }
|
||||
|
||||
class spell_moragg_ray_of_pain_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_moragg_ray_of_pain_AuraScript);
|
||||
|
||||
void OnPeriodic(AuraEffect const* aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
std::list<HostileReference*> players = GetTarget()->getThreatManager().getThreatList();
|
||||
if (!players.empty())
|
||||
{
|
||||
std::list<HostileReference*>::iterator itr = players.begin();
|
||||
std::advance(itr, urand(0, players.size() - 1));
|
||||
|
||||
uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell;
|
||||
GetTarget()->CastCustomSpell(triggerSpell, SPELLVALUE_MAX_TARGETS, 1, (*itr)->getTarget(), TRIGGERED_FULL_MASK, NULL, aurEff);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_moragg_ray_of_pain_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_moragg_ray_of_pain_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_moragg_optic_link : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_moragg_optic_link() : SpellScriptLoader("spell_moragg_optic_link") { }
|
||||
|
||||
class spell_moragg_optic_link_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_moragg_optic_link_AuraScript);
|
||||
|
||||
void OnPeriodic(AuraEffect const* aurEff)
|
||||
{
|
||||
switch (aurEff->GetTickNumber()) // Different visual based on tick
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
GetTarget()->CastCustomSpell(SPELL_OPTIC_LINK_LEVEL_1, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff);
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
GetTarget()->CastCustomSpell(SPELL_OPTIC_LINK_LEVEL_1, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff);
|
||||
GetTarget()->CastCustomSpell(SPELL_OPTIC_LINK_LEVEL_2, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff);
|
||||
break;
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
GetTarget()->CastCustomSpell(SPELL_OPTIC_LINK_LEVEL_1, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff);
|
||||
GetTarget()->CastCustomSpell(SPELL_OPTIC_LINK_LEVEL_2, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff);
|
||||
GetTarget()->CastCustomSpell(SPELL_OPTIC_LINK_LEVEL_3, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnUpdate(AuraEffect* aurEff)
|
||||
{
|
||||
switch (aurEff->GetTickNumber())
|
||||
{
|
||||
case 1:
|
||||
aurEff->SetAmount(aurEff->GetAmount() + 250); // base amount is 500
|
||||
break;
|
||||
case 4:
|
||||
aurEff->SetAmount(aurEff->GetAmount() * 2); // goes to 1500
|
||||
break;
|
||||
case 8:
|
||||
aurEff->SetAmount(aurEff->GetAmount() * 2); // goes to 3000
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_moragg_optic_link_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
|
||||
OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_moragg_optic_link_AuraScript::OnUpdate, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_moragg_optic_link_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_moragg()
|
||||
{
|
||||
new boss_moragg();
|
||||
new spell_moragg_ray_of_suffering();
|
||||
new spell_moragg_ray_of_pain();
|
||||
new spell_moragg_optic_link();
|
||||
}
|
||||
@@ -17,24 +17,24 @@
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "violet_hold.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "SpellScript.h"
|
||||
#include "Player.h"
|
||||
#include "violet_hold.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_ARCANE_BARRAGE_VOLLEY = 54202,
|
||||
SPELL_ARCANE_BARRAGE_VOLLEY_H = 59483,
|
||||
SPELL_ARCANE_BUFFET = 54226,
|
||||
SPELL_ARCANE_BUFFET_H = 59485,
|
||||
SPELL_SUMMON_ETHEREAL_SPHERE_1 = 54102,
|
||||
SPELL_SUMMON_ETHEREAL_SPHERE_2 = 54137,
|
||||
SPELL_SUMMON_ETHEREAL_SPHERE_2 = 61337,
|
||||
SPELL_SUMMON_ETHEREAL_SPHERE_3 = 54138
|
||||
};
|
||||
|
||||
enum NPCs
|
||||
{
|
||||
NPC_ETHEREAL_SPHERE = 29271,
|
||||
//NPC_ETHEREAL_SPHERE2 = 32582, // heroic only?
|
||||
NPC_ETHEREAL_SPHERE2 = 32582
|
||||
};
|
||||
|
||||
enum CreatureSpells
|
||||
@@ -42,7 +42,8 @@ enum CreatureSpells
|
||||
SPELL_ARCANE_POWER = 54160,
|
||||
H_SPELL_ARCANE_POWER = 59474,
|
||||
SPELL_SUMMON_PLAYERS = 54164,
|
||||
SPELL_POWER_BALL_VISUAL = 54141
|
||||
SPELL_POWER_BALL_VISUAL = 54141,
|
||||
SPELL_POWER_BALL_DAMAGE_TRIGGER = 54207
|
||||
};
|
||||
|
||||
enum Yells
|
||||
@@ -56,52 +57,50 @@ enum Yells
|
||||
SAY_SUMMON_ENERGY = 6
|
||||
};
|
||||
|
||||
enum XevozzEvents
|
||||
{
|
||||
EVENT_ARCANE_BARRAGE = 1,
|
||||
EVENT_ARCANE_BUFFET,
|
||||
EVENT_SUMMON_SPHERE,
|
||||
EVENT_SUMMON_SPHERE_2,
|
||||
EVENT_RANGE_CHECK,
|
||||
EVENT_SUMMON_PLAYERS,
|
||||
EVENT_DESPAWN_SPHERE
|
||||
};
|
||||
|
||||
enum SphereActions
|
||||
{
|
||||
ACTION_SUMMON = 1,
|
||||
};
|
||||
|
||||
class boss_xevozz : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_xevozz() : CreatureScript("boss_xevozz") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<boss_xevozzAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_xevozzAI : public ScriptedAI
|
||||
{
|
||||
boss_xevozzAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
uiSummonEtherealSphere_Timer = urand(10000, 12000);
|
||||
uiArcaneBarrageVolley_Timer = urand(20000, 22000);
|
||||
uiArcaneBuffet_Timer = uiSummonEtherealSphere_Timer + urand(5000, 6000);
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 uiSummonEtherealSphere_Timer;
|
||||
uint32 uiArcaneBarrageVolley_Timer;
|
||||
uint32 uiArcaneBuffet_Timer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
if (instance->GetData(DATA_WAVE_COUNT) == 6)
|
||||
instance->SetData(DATA_1ST_BOSS_EVENT, NOT_STARTED);
|
||||
instance->SetBossState(DATA_1ST_BOSS_EVENT, NOT_STARTED);
|
||||
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
|
||||
instance->SetData(DATA_2ND_BOSS_EVENT, NOT_STARTED);
|
||||
instance->SetBossState(DATA_2ND_BOSS_EVENT, NOT_STARTED);
|
||||
|
||||
Initialize();
|
||||
DespawnSphere();
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void DespawnSphere()
|
||||
{
|
||||
std::list<Creature*> assistList;
|
||||
GetCreatureListWithEntryInGrid(assistList, me, NPC_ETHEREAL_SPHERE, 150.0f);
|
||||
GetCreatureListWithEntryInGrid(assistList, me, NPC_ETHEREAL_SPHERE2, 150.0f);
|
||||
|
||||
if (assistList.empty())
|
||||
return;
|
||||
@@ -116,11 +115,7 @@ public:
|
||||
void JustSummoned(Creature* summoned) override
|
||||
{
|
||||
summoned->SetSpeed(MOVE_RUN, 0.5f);
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
summoned->AddThreat(target, 0.00f);
|
||||
summoned->AI()->AttackStart(target);
|
||||
}
|
||||
summoned->GetMotionMaster()->MoveFollow(me, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
@@ -139,58 +134,23 @@ public:
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
if (GameObject* pDoor = instance->instance->GetGameObject(instance->GetGuidData(DATA_XEVOZZ_CELL)))
|
||||
if (pDoor->GetGoState() == GO_STATE_READY)
|
||||
if (GameObject* door = instance->GetGameObject(DATA_XEVOZZ_CELL))
|
||||
if (door->GetGoState() == GO_STATE_READY)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
if (instance->GetData(DATA_WAVE_COUNT) == 6)
|
||||
instance->SetData(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
|
||||
instance->SetBossState(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
|
||||
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
|
||||
instance->SetData(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
|
||||
}
|
||||
instance->SetBossState(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override { }
|
||||
|
||||
|
||||
void UpdateAI(uint32 uiDiff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (uiArcaneBarrageVolley_Timer < uiDiff)
|
||||
{
|
||||
DoCast(me, SPELL_ARCANE_BARRAGE_VOLLEY);
|
||||
uiArcaneBarrageVolley_Timer = urand(20000, 22000);
|
||||
}
|
||||
else uiArcaneBarrageVolley_Timer -= uiDiff;
|
||||
|
||||
if (uiArcaneBuffet_Timer)
|
||||
{
|
||||
if (uiArcaneBuffet_Timer < uiDiff)
|
||||
{
|
||||
DoCastVictim(SPELL_ARCANE_BUFFET);
|
||||
uiArcaneBuffet_Timer = 0;
|
||||
}
|
||||
else uiArcaneBuffet_Timer -= uiDiff;
|
||||
}
|
||||
|
||||
if (uiSummonEtherealSphere_Timer < uiDiff)
|
||||
{
|
||||
Talk(SAY_SPAWN);
|
||||
DoCast(me, SPELL_SUMMON_ETHEREAL_SPHERE_1);
|
||||
if (IsHeroic()) // extra one for heroic
|
||||
me->SummonCreature(NPC_ETHEREAL_SPHERE, me->GetPositionX() - 5 + rand32() % 10, me->GetPositionY() - 5 + rand32() % 10, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 40000);
|
||||
|
||||
uiSummonEtherealSphere_Timer = urand(45000, 47000);
|
||||
uiArcaneBuffet_Timer = urand(5000, 6000);
|
||||
}
|
||||
else uiSummonEtherealSphere_Timer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
events.ScheduleEvent(EVENT_SUMMON_SPHERE, 5000);
|
||||
events.ScheduleEvent(EVENT_ARCANE_BARRAGE, urand(8000, 10000));
|
||||
events.ScheduleEvent(EVENT_ARCANE_BUFFET, urand(10000, 11000));
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
@@ -201,24 +161,86 @@ public:
|
||||
|
||||
if (instance->GetData(DATA_WAVE_COUNT) == 6)
|
||||
{
|
||||
instance->SetData(DATA_1ST_BOSS_EVENT, DONE);
|
||||
instance->SetBossState(DATA_1ST_BOSS_EVENT, DONE);
|
||||
instance->SetData(DATA_WAVE_COUNT, 7);
|
||||
}
|
||||
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
|
||||
{
|
||||
instance->SetData(DATA_2ND_BOSS_EVENT, NOT_STARTED);
|
||||
instance->SetBossState(DATA_2ND_BOSS_EVENT, NOT_STARTED);
|
||||
instance->SetData(DATA_WAVE_COUNT, 13);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() != TYPEID_PLAYER)
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* who, const SpellInfo* spell) override
|
||||
{
|
||||
if (!who->ToCreature())
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
if ((spell->Id == SPELL_ARCANE_POWER) || (spell->Id == H_SPELL_ARCANE_POWER))
|
||||
Talk(SAY_SUMMON_ENERGY);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_ARCANE_BARRAGE:
|
||||
DoCast(SPELL_ARCANE_BARRAGE_VOLLEY);
|
||||
events.ScheduleEvent(EVENT_ARCANE_BARRAGE, urand(8000, 10000));
|
||||
break;
|
||||
case EVENT_ARCANE_BUFFET:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_ARCANE_BUFFET);
|
||||
events.ScheduleEvent(EVENT_ARCANE_BUFFET, urand(15000, 20000));
|
||||
break;
|
||||
case EVENT_SUMMON_SPHERE:
|
||||
Talk(SAY_REPEAT_SUMMON);
|
||||
DoCast(SPELL_SUMMON_ETHEREAL_SPHERE_1);
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_SUMMON_SPHERE_2, 2500);
|
||||
events.ScheduleEvent(EVENT_SUMMON_PLAYERS, urand(33000, 35000));
|
||||
events.ScheduleEvent(EVENT_SUMMON_SPHERE, urand(45000, 47000));
|
||||
break;
|
||||
case EVENT_SUMMON_SPHERE_2:
|
||||
Talk(SAY_REPEAT_SUMMON);
|
||||
DoCast(SPELL_SUMMON_ETHEREAL_SPHERE_2);
|
||||
break;
|
||||
case EVENT_SUMMON_PLAYERS:
|
||||
if (Creature* sphere = me->FindNearestCreature(NPC_ETHEREAL_SPHERE, 150.0f))
|
||||
sphere->GetAI()->DoAction(ACTION_SUMMON);
|
||||
else if (Creature* sphere = me->FindNearestCreature(NPC_ETHEREAL_SPHERE2, 150.0f))
|
||||
sphere->GetAI()->DoAction(ACTION_SUMMON);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
InstanceScript* instance;
|
||||
EventMap events;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<boss_xevozzAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_ethereal_sphere : public CreatureScript
|
||||
@@ -226,83 +248,149 @@ class npc_ethereal_sphere : public CreatureScript
|
||||
public:
|
||||
npc_ethereal_sphere() : CreatureScript("npc_ethereal_sphere") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_ethereal_sphereAI>(creature);
|
||||
}
|
||||
|
||||
struct npc_ethereal_sphereAI : public ScriptedAI
|
||||
{
|
||||
npc_ethereal_sphereAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
uiSummonPlayers_Timer = urand(33000, 35000);
|
||||
uiRangeCheck_Timer = 1000;
|
||||
arcanePower = false;
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 uiSummonPlayers_Timer;
|
||||
uint32 uiRangeCheck_Timer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
events.Reset();
|
||||
DoCast(SPELL_POWER_BALL_VISUAL);
|
||||
DoCast(SPELL_POWER_BALL_DAMAGE_TRIGGER);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->setFaction(16);
|
||||
events.ScheduleEvent(EVENT_DESPAWN_SPHERE, 40000);
|
||||
events.ScheduleEvent(EVENT_RANGE_CHECK, 1000);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 uiDiff) override
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
if (action == ACTION_SUMMON)
|
||||
DoCast(SPELL_SUMMON_PLAYERS);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
if (!me->HasAura(SPELL_POWER_BALL_VISUAL))
|
||||
DoCast(me, SPELL_POWER_BALL_VISUAL);
|
||||
|
||||
if (uiRangeCheck_Timer < uiDiff)
|
||||
switch (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
if (Creature* pXevozz = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_XEVOZZ)))
|
||||
{
|
||||
float fDistance = me->GetDistance2d(pXevozz);
|
||||
if (fDistance <= 3)
|
||||
DoCast(pXevozz, SPELL_ARCANE_POWER);
|
||||
else
|
||||
DoCast(me, 35845); //Is it blizzlike?
|
||||
}
|
||||
uiRangeCheck_Timer = 1000;
|
||||
case EVENT_RANGE_CHECK:
|
||||
if (Creature* xevozz = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_XEVOZZ)))
|
||||
{
|
||||
if (me->IsWithinDist(xevozz, 3.0f) && !arcanePower)
|
||||
{
|
||||
DoCast(SPELL_ARCANE_POWER);
|
||||
arcanePower = true;
|
||||
events.ScheduleEvent(EVENT_DESPAWN_SPHERE, 8000);
|
||||
}
|
||||
}
|
||||
events.ScheduleEvent(EVENT_RANGE_CHECK, 1000);
|
||||
break;
|
||||
case EVENT_DESPAWN_SPHERE:
|
||||
me->DespawnOrUnsummon();
|
||||
break;
|
||||
}
|
||||
else uiRangeCheck_Timer -= uiDiff;
|
||||
}
|
||||
|
||||
if (uiSummonPlayers_Timer < uiDiff)
|
||||
private:
|
||||
InstanceScript* instance;
|
||||
EventMap events;
|
||||
bool arcanePower;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_ethereal_sphereAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_xevozz_summon_players : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_xevozz_summon_players() : SpellScriptLoader("spell_xevozz_summon_players") { }
|
||||
|
||||
class spell_xevozz_summon_players_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_xevozz_summon_players_SpellScript);
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Unit* target = GetHitUnit();
|
||||
|
||||
if (target)
|
||||
{
|
||||
DoCast(me, SPELL_SUMMON_PLAYERS); // not working right
|
||||
Position pos = GetOriginalCaster()->GetPosition();
|
||||
|
||||
Map* map = me->GetMap();
|
||||
if (map && map->IsDungeon())
|
||||
{
|
||||
Map::PlayerList const &PlayerList = map->GetPlayers();
|
||||
|
||||
if (!PlayerList.isEmpty())
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
if (i->GetSource()->IsAlive())
|
||||
DoTeleportPlayer(i->GetSource(), me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), i->GetSource()->GetOrientation());
|
||||
}
|
||||
|
||||
uiSummonPlayers_Timer = urand(33000, 35000);
|
||||
target->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation());
|
||||
}
|
||||
else uiSummonPlayers_Timer -= uiDiff;
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_xevozz_summon_players_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_xevozz_summon_players_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_xevozz_summon_ethereal_sphere : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_xevozz_summon_ethereal_sphere() : SpellScriptLoader("spell_xevozz_summon_ethereal_sphere") { }
|
||||
|
||||
class spell_xevozz_summon_ethereal_sphere_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_xevozz_summon_ethereal_sphere_SpellScript);
|
||||
|
||||
void HandleScript(SpellDestination& target)
|
||||
{
|
||||
Unit* caster = GetOriginalCaster();
|
||||
Position pos;
|
||||
float distance = 0.0f;
|
||||
|
||||
while (distance < 20.0f)
|
||||
{
|
||||
pos = caster->GetRandomNearPosition(60.0f);
|
||||
distance = caster->GetDistance(pos);
|
||||
}
|
||||
|
||||
target.Relocate(pos);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_xevozz_summon_ethereal_sphere_SpellScript::HandleScript, EFFECT_0, TARGET_DEST_DB);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_xevozz_summon_ethereal_sphere_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_xevozz()
|
||||
{
|
||||
new boss_xevozz();
|
||||
new npc_ethereal_sphere();
|
||||
new spell_xevozz_summon_players();
|
||||
new spell_xevozz_summon_ethereal_sphere();
|
||||
}
|
||||
@@ -22,20 +22,14 @@
|
||||
enum Spells
|
||||
{
|
||||
SPELL_SHROUD_OF_DARKNESS = 54524,
|
||||
H_SPELL_SHROUD_OF_DARKNESS = 59745,
|
||||
SPELL_SUMMON_VOID_SENTRY = 54369,
|
||||
SPELL_VOID_SHIFT = 54361,
|
||||
H_SPELL_VOID_SHIFT = 59743,
|
||||
SPELL_VOID_SHIFTED = 54343,
|
||||
|
||||
SPELL_ZURAMAT_ADD_2 = 54342,
|
||||
H_SPELL_ZURAMAT_ADD_2 = 59747
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
NPC_VOID_SENTRY = 29364
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
@@ -51,19 +45,21 @@ enum Misc
|
||||
DATA_VOID_DANCE = 2153
|
||||
};
|
||||
|
||||
enum ZuramatEvents
|
||||
{
|
||||
EVENT_VOID_SHIFT = 1,
|
||||
EVENT_SUMMON_VOID,
|
||||
EVENT_SHROUD_OF_DARKNESS
|
||||
};
|
||||
|
||||
class boss_zuramat : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_zuramat() : CreatureScript("boss_zuramat") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<boss_zuramatAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_zuramatAI : public ScriptedAI
|
||||
{
|
||||
boss_zuramatAI(Creature* creature) : ScriptedAI(creature)
|
||||
boss_zuramatAI(Creature* creature) : ScriptedAI(creature), sentries(me)
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
@@ -71,18 +67,18 @@ public:
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
SpellShroudOfDarknessTimer = 22000;
|
||||
SpellVoidShiftTimer = 15000;
|
||||
SpellSummonVoidTimer = 12000;
|
||||
voidDance = true;
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 SpellVoidShiftTimer;
|
||||
uint32 SpellSummonVoidTimer;
|
||||
uint32 SpellShroudOfDarknessTimer;
|
||||
bool voidDance;
|
||||
void DespawnSentries()
|
||||
{
|
||||
sentries.DespawnAll();
|
||||
std::list<Creature*> sentrylist;
|
||||
GetCreatureListWithEntryInGrid(sentrylist, me, NPC_VOID_SENTRY_BALL, 200.0f);
|
||||
if (!sentrylist.empty())
|
||||
for (std::list<Creature*>::const_iterator itr = sentrylist.begin(); itr != sentrylist.end(); ++itr)
|
||||
(*itr)->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
@@ -92,6 +88,8 @@ public:
|
||||
instance->SetData(DATA_2ND_BOSS_EVENT, NOT_STARTED);
|
||||
|
||||
Initialize();
|
||||
events.Reset();
|
||||
DespawnSentries();
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
@@ -110,48 +108,29 @@ public:
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
if (GameObject* pDoor = instance->instance->GetGameObject(instance->GetGuidData(DATA_ZURAMAT_CELL)))
|
||||
if (pDoor->GetGoState() == GO_STATE_READY)
|
||||
if (GameObject* door = instance->GetGameObject(DATA_ZURAMAT_CELL))
|
||||
if (door->GetGoState() == GO_STATE_READY)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
if (instance->GetData(DATA_WAVE_COUNT) == 6)
|
||||
instance->SetData(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
|
||||
instance->SetBossState(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
|
||||
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
|
||||
instance->SetData(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
|
||||
|
||||
me->SetInCombatWithZone();
|
||||
events.ScheduleEvent(EVENT_SHROUD_OF_DARKNESS, urand(18000, 20000));
|
||||
events.ScheduleEvent(EVENT_VOID_SHIFT, 9000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_VOID, 4000);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override { }
|
||||
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (SpellSummonVoidTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SUMMON_VOID_SENTRY, false);
|
||||
SpellSummonVoidTimer = 20000;
|
||||
} else SpellSummonVoidTimer -=diff;
|
||||
|
||||
if (SpellVoidShiftTimer <= diff)
|
||||
{
|
||||
if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(unit, SPELL_VOID_SHIFT);
|
||||
SpellVoidShiftTimer = 20000;
|
||||
} else SpellVoidShiftTimer -=diff;
|
||||
|
||||
if (SpellShroudOfDarknessTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SHROUD_OF_DARKNESS);
|
||||
SpellShroudOfDarknessTimer = 20000;
|
||||
} else SpellShroudOfDarknessTimer -=diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
sentries.Summon(summon);
|
||||
}
|
||||
|
||||
void SummonedCreatureDies(Creature* summoned, Unit* /*who*/) override
|
||||
@@ -170,37 +149,73 @@ public:
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
instance->SetData(DATA_ZURAMAT, 1);
|
||||
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
DespawnSentries();
|
||||
|
||||
if (instance->GetData(DATA_WAVE_COUNT) == 6)
|
||||
{
|
||||
instance->SetData(DATA_1ST_BOSS_EVENT, DONE);
|
||||
instance->SetBossState(DATA_1ST_BOSS_EVENT, DONE);
|
||||
instance->SetData(DATA_WAVE_COUNT, 7);
|
||||
}
|
||||
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
|
||||
{
|
||||
instance->SetData(DATA_2ND_BOSS_EVENT, DONE);
|
||||
instance->SetBossState(DATA_2ND_BOSS_EVENT, DONE);
|
||||
instance->SetData(DATA_WAVE_COUNT, 13);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() != TYPEID_PLAYER)
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SUMMON_VOID:
|
||||
DoCast(SPELL_SUMMON_VOID_SENTRY);
|
||||
events.ScheduleEvent(EVENT_SUMMON_VOID, urand(7000, 10000));
|
||||
break;
|
||||
case EVENT_VOID_SHIFT:
|
||||
if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(unit, SPELL_VOID_SHIFT);
|
||||
events.ScheduleEvent(EVENT_VOID_SHIFT, 15000);
|
||||
break;
|
||||
case EVENT_SHROUD_OF_DARKNESS:
|
||||
DoCast(SPELL_SHROUD_OF_DARKNESS);
|
||||
events.ScheduleEvent(EVENT_SHROUD_OF_DARKNESS, urand(18000, 20000));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summon->AI()->AttackStart(me->GetVictim());
|
||||
summon->CastSpell((Unit*)NULL, SPELL_ZURAMAT_ADD_2);
|
||||
summon->SetInPhase(169, true, true); // Normal phase
|
||||
summon->SetInPhase(173, true, true); // Void phase
|
||||
}
|
||||
private:
|
||||
InstanceScript* instance;
|
||||
EventMap events;
|
||||
SummonList sentries;
|
||||
bool voidDance;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<boss_zuramatAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_void_dance : public AchievementCriteriaScript
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
#include "Player.h"
|
||||
#include "TemporarySummon.h"
|
||||
|
||||
#define MAX_ENCOUNTER 3
|
||||
|
||||
/* Violet Hold encounters:
|
||||
0 - First boss
|
||||
1 - Second boss
|
||||
@@ -38,21 +36,6 @@
|
||||
6 - Zuramat
|
||||
7 - Cyanigosa */
|
||||
|
||||
enum GameObjects
|
||||
{
|
||||
GO_MAIN_DOOR = 191723,
|
||||
GO_XEVOZZ_DOOR = 191556,
|
||||
GO_LAVANTHOR_DOOR = 191566,
|
||||
GO_ICHORON_DOOR = 191722,
|
||||
GO_ZURAMAT_DOOR = 191565,
|
||||
GO_EREKEM_DOOR = 191564,
|
||||
GO_EREKEM_GUARD_1_DOOR = 191563,
|
||||
GO_EREKEM_GUARD_2_DOOR = 191562,
|
||||
GO_MORAGG_DOOR = 191606,
|
||||
GO_INTRO_ACTIVATION_CRYSTAL = 193615,
|
||||
GO_ACTIVATION_CRYSTAL = 193611
|
||||
};
|
||||
|
||||
enum AzureSaboteurSpells
|
||||
{
|
||||
SABOTEUR_SHIELD_DISRUPTION = 58291,
|
||||
@@ -64,7 +47,7 @@ enum CrystalSpells
|
||||
SPELL_ARCANE_LIGHTNING = 57930
|
||||
};
|
||||
|
||||
const Position PortalLocation[] =
|
||||
Position const PortalLocation[] =
|
||||
{
|
||||
{1877.51f, 850.104f, 44.6599f, 4.7822f }, // WP 1
|
||||
{1918.37f, 853.437f, 47.1624f, 4.12294f}, // WP 2
|
||||
@@ -74,21 +57,21 @@ const Position PortalLocation[] =
|
||||
{1908.31f, 809.657f, 38.7037f, 3.08701f} // WP 6
|
||||
};
|
||||
|
||||
const Position ArcaneSphere = {1887.060059f, 806.151001f, 61.321602f, 0.0f};
|
||||
const Position BossStartMove1 = {1894.684448f, 739.390503f, 47.668003f, 0.0f};
|
||||
const Position BossStartMove2 = {1875.173950f, 860.832703f, 43.333565f, 0.0f};
|
||||
const Position BossStartMove21 = {1858.854614f, 855.071411f, 43.333565f, 0.0f};
|
||||
const Position BossStartMove22 = {1891.926636f, 863.388977f, 43.333565f, 0.0f};
|
||||
const Position BossStartMove3 = {1916.138062f, 778.152222f, 35.772308f, 0.0f};
|
||||
const Position BossStartMove4 = {1853.618286f, 758.557617f, 38.657505f, 0.0f};
|
||||
const Position BossStartMove5 = {1906.683960f, 842.348022f, 38.637459f, 0.0f};
|
||||
const Position BossStartMove6 = {1928.207031f, 852.864441f, 47.200813f, 0.0f};
|
||||
Position const ArcaneSphere = {1887.060059f, 806.151001f, 61.321602f, 0.0f};
|
||||
Position const BossStartMove1 = {1894.684448f, 739.390503f, 47.668003f, 0.0f};
|
||||
Position const BossStartMove2 = {1875.173950f, 860.832703f, 43.333565f, 0.0f};
|
||||
Position const BossStartMove21 = {1858.854614f, 855.071411f, 43.333565f, 0.0f};
|
||||
Position const BossStartMove22 = {1891.926636f, 863.388977f, 43.333565f, 0.0f};
|
||||
Position const BossStartMove3 = {1916.138062f, 778.152222f, 35.772308f, 0.0f};
|
||||
Position const BossStartMove4 = {1853.618286f, 758.557617f, 38.657505f, 0.0f};
|
||||
Position const BossStartMove5 = {1906.683960f, 842.348022f, 38.637459f, 0.0f};
|
||||
Position const BossStartMove6 = {1928.207031f, 852.864441f, 47.200813f, 0.0f};
|
||||
|
||||
const Position CyanigosasSpawnLocation = {1930.281250f, 804.407715f, 52.410946f, 3.139621f};
|
||||
const Position MiddleRoomLocation = {1892.291260f, 805.696838f, 38.438862f, 3.139621f};
|
||||
const Position MiddleRoomPortalSaboLocation = {1896.622925f, 804.854126f, 38.504772f, 3.139621f};
|
||||
Position const CyanigosasSpawnLocation = {1930.281250f, 804.407715f, 52.410946f, 3.139621f};
|
||||
Position const MiddleRoomLocation = {1892.291260f, 805.696838f, 38.438862f, 3.139621f};
|
||||
Position const MiddleRoomPortalSaboLocation = {1896.622925f, 804.854126f, 38.504772f, 3.139621f};
|
||||
|
||||
//Cyanigosa's prefight event data
|
||||
// Cyanigosa's prefight event data
|
||||
enum Yells
|
||||
{
|
||||
CYANIGOSA_SAY_SPAWN = 0
|
||||
@@ -100,21 +83,45 @@ enum Spells
|
||||
CYANIGOSA_BLUE_AURA = 47759,
|
||||
};
|
||||
|
||||
ObjectData const creatureData[] =
|
||||
{
|
||||
{ NPC_XEVOZZ, DATA_XEVOZZ },
|
||||
{ NPC_LAVANTHOR, DATA_LAVANTHOR },
|
||||
{ NPC_ICHORON, DATA_ICHORON },
|
||||
{ NPC_ZURAMAT, DATA_ZURAMAT },
|
||||
{ NPC_EREKEM, DATA_EREKEM },
|
||||
{ NPC_MORAGG, DATA_MORAGG },
|
||||
{ NPC_CYANIGOSA, DATA_CYANIGOSA },
|
||||
{ NPC_SINCLARI, DATA_SINCLARI },
|
||||
{ 0, 0 } // END
|
||||
};
|
||||
|
||||
ObjectData const gameObjectData[] =
|
||||
{
|
||||
{ GO_EREKEM_GUARD_1_DOOR, DATA_EREKEM_LEFT_GUARD_CELL },
|
||||
{ GO_EREKEM_GUARD_2_DOOR, DATA_EREKEM_RIGHT_GUARD_CELL },
|
||||
{ GO_EREKEM_DOOR, DATA_EREKEM_CELL },
|
||||
{ GO_ZURAMAT_DOOR, DATA_ZURAMAT_CELL },
|
||||
{ GO_LAVANTHOR_DOOR, DATA_LAVANTHOR_CELL },
|
||||
{ GO_MORAGG_DOOR, DATA_MORAGG_CELL },
|
||||
{ GO_ICHORON_DOOR, DATA_ICHORON_CELL },
|
||||
{ GO_XEVOZZ_DOOR, DATA_XEVOZZ_CELL },
|
||||
{ GO_MAIN_DOOR, DATA_MAIN_DOOR },
|
||||
{ 0, 0 } // END
|
||||
};
|
||||
|
||||
class instance_violet_hold : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_violet_hold() : InstanceMapScript("instance_violet_hold", 608) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
||||
{
|
||||
return new instance_violet_hold_InstanceMapScript(map);
|
||||
}
|
||||
|
||||
struct instance_violet_hold_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_violet_hold_InstanceMapScript(Map* map) : InstanceScript(map)
|
||||
{
|
||||
SetHeaders(DataHeader);
|
||||
SetBossNumber(EncounterCount);
|
||||
LoadObjectData(creatureData, gameObjectData);
|
||||
|
||||
uiRemoveNpc = 0;
|
||||
|
||||
@@ -138,29 +145,11 @@ public:
|
||||
bCrystalActivated = false;
|
||||
defenseless = true;
|
||||
uiMainEventPhase = NOT_STARTED;
|
||||
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
zuramatDead = false;
|
||||
}
|
||||
|
||||
ObjectGuid uiMoragg;
|
||||
ObjectGuid uiErekem;
|
||||
ObjectGuid uiErekemGuard[2];
|
||||
ObjectGuid uiIchoron;
|
||||
ObjectGuid uiLavanthor;
|
||||
ObjectGuid uiXevozz;
|
||||
ObjectGuid uiZuramat;
|
||||
ObjectGuid uiCyanigosa;
|
||||
ObjectGuid uiSinclari;
|
||||
|
||||
ObjectGuid uiMoraggCell;
|
||||
ObjectGuid uiErekemCell;
|
||||
ObjectGuid uiErekemLeftGuardCell;
|
||||
ObjectGuid uiErekemRightGuardCell;
|
||||
ObjectGuid uiIchoronCell;
|
||||
ObjectGuid uiLavanthorCell;
|
||||
ObjectGuid uiXevozzCell;
|
||||
ObjectGuid uiZuramatCell;
|
||||
ObjectGuid uiMainDoor;
|
||||
ObjectGuid uiTeleportationPortal;
|
||||
ObjectGuid uiSaboteurPortal;
|
||||
|
||||
@@ -180,7 +169,6 @@ public:
|
||||
|
||||
uint8 uiDoorIntegrity;
|
||||
|
||||
uint16 m_auiEncounter[MAX_ENCOUNTER];
|
||||
uint8 uiCountErekemGuards;
|
||||
uint8 uiCountActivationCrystals;
|
||||
uint8 uiCyanigosaEventPhase;
|
||||
@@ -191,132 +179,93 @@ public:
|
||||
bool bIsDoorSpellCast;
|
||||
bool bCrystalActivated;
|
||||
bool defenseless;
|
||||
bool zuramatDead;
|
||||
|
||||
std::list<uint8> NpcAtDoorCastingList;
|
||||
|
||||
std::string str_data;
|
||||
|
||||
bool IsEncounterInProgress() const override
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature) override
|
||||
{
|
||||
InstanceScript::OnCreatureCreate(creature);
|
||||
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case CREATURE_XEVOZZ:
|
||||
uiXevozz = creature->GetGUID();
|
||||
break;
|
||||
case CREATURE_LAVANTHOR:
|
||||
uiLavanthor = creature->GetGUID();
|
||||
break;
|
||||
case CREATURE_ICHORON:
|
||||
uiIchoron = creature->GetGUID();
|
||||
break;
|
||||
case CREATURE_ZURAMAT:
|
||||
uiZuramat = creature->GetGUID();
|
||||
break;
|
||||
case CREATURE_EREKEM:
|
||||
uiErekem = creature->GetGUID();
|
||||
break;
|
||||
case CREATURE_EREKEM_GUARD:
|
||||
case NPC_EREKEM_GUARD:
|
||||
if (uiCountErekemGuards < 2)
|
||||
{
|
||||
uiErekemGuard[uiCountErekemGuards++] = creature->GetGUID();
|
||||
creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
|
||||
creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
|
||||
}
|
||||
break;
|
||||
case CREATURE_MORAGG:
|
||||
uiMoragg = creature->GetGUID();
|
||||
case NPC_CYANIGOSA:
|
||||
creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
|
||||
break;
|
||||
case CREATURE_CYANIGOSA:
|
||||
uiCyanigosa = creature->GetGUID();
|
||||
creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
|
||||
default:
|
||||
break;
|
||||
case CREATURE_SINCLARI:
|
||||
uiSinclari = creature->GetGUID();
|
||||
case NPC_VOID_SENTRY:
|
||||
if (zuramatDead)
|
||||
{
|
||||
creature->DespawnOrUnsummon();
|
||||
zuramatDead = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
BEWARE - SHIT.
|
||||
if (creature->GetGUID() == uiFirstBoss || creature->GetGUID() == uiSecondBoss)
|
||||
{
|
||||
creature->AllLootRemovedFromCorpse();
|
||||
creature->RemoveLootMode(1);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go) override
|
||||
{
|
||||
InstanceScript::OnGameObjectCreate(go);
|
||||
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_EREKEM_GUARD_1_DOOR:
|
||||
uiErekemLeftGuardCell = go->GetGUID();
|
||||
break;
|
||||
case GO_EREKEM_GUARD_2_DOOR:
|
||||
uiErekemRightGuardCell = go->GetGUID();
|
||||
break;
|
||||
case GO_EREKEM_DOOR:
|
||||
uiErekemCell = go->GetGUID();
|
||||
break;
|
||||
case GO_ZURAMAT_DOOR:
|
||||
uiZuramatCell = go->GetGUID();
|
||||
break;
|
||||
case GO_LAVANTHOR_DOOR:
|
||||
uiLavanthorCell = go->GetGUID();
|
||||
break;
|
||||
case GO_MORAGG_DOOR:
|
||||
uiMoraggCell = go->GetGUID();
|
||||
break;
|
||||
case GO_ICHORON_DOOR:
|
||||
uiIchoronCell = go->GetGUID();
|
||||
break;
|
||||
case GO_XEVOZZ_DOOR:
|
||||
uiXevozzCell = go->GetGUID();
|
||||
break;
|
||||
case GO_MAIN_DOOR:
|
||||
uiMainDoor = go->GetGUID();
|
||||
break;
|
||||
case GO_ACTIVATION_CRYSTAL:
|
||||
if (uiCountActivationCrystals < 4)
|
||||
uiActivationCrystal[uiCountActivationCrystals++] = go->GetGUID();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool SetBossState(uint32 type, EncounterState state) override
|
||||
{
|
||||
if (!InstanceScript::SetBossState(type, state))
|
||||
return false;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DATA_1ST_BOSS_EVENT:
|
||||
if (state == DONE)
|
||||
UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, NPC_EREKEM, nullptr);
|
||||
break;
|
||||
case DATA_2ND_BOSS_EVENT:
|
||||
if (state == DONE)
|
||||
UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, NPC_MORAGG, nullptr);
|
||||
break;
|
||||
case DATA_CYANIGOSA:
|
||||
if (state == DONE)
|
||||
{
|
||||
uiMainEventPhase = DONE;
|
||||
if (GameObject* mainDoor = GetGameObject(DATA_MAIN_DOOR))
|
||||
mainDoor->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data) override
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_1ST_BOSS_EVENT:
|
||||
UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, CREATURE_EREKEM, NULL);
|
||||
m_auiEncounter[0] = data;
|
||||
if (data == DONE)
|
||||
SaveToDB();
|
||||
break;
|
||||
case DATA_2ND_BOSS_EVENT:
|
||||
UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, CREATURE_MORAGG, NULL);
|
||||
m_auiEncounter[1] = data;
|
||||
if (data == DONE)
|
||||
SaveToDB();
|
||||
break;
|
||||
case DATA_CYANIGOSA_EVENT:
|
||||
m_auiEncounter[2] = data;
|
||||
if (data == DONE)
|
||||
{
|
||||
SaveToDB();
|
||||
uiMainEventPhase = DONE;
|
||||
if (GameObject* pMainDoor = instance->GetGameObject(uiMainDoor))
|
||||
pMainDoor->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case DATA_WAVE_COUNT:
|
||||
uiWaveCount = data;
|
||||
bActive = true;
|
||||
@@ -340,21 +289,8 @@ public:
|
||||
NpcAtDoorCastingList.pop_back();
|
||||
break;
|
||||
case DATA_MAIN_DOOR:
|
||||
if (GameObject* pMainDoor = instance->GetGameObject(uiMainDoor))
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case GO_STATE_ACTIVE:
|
||||
pMainDoor->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_STATE_READY:
|
||||
pMainDoor->SetGoState(GO_STATE_READY);
|
||||
break;
|
||||
case GO_STATE_ACTIVE_ALTERNATIVE:
|
||||
pMainDoor->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (GameObject* mainDoor = GetGameObject(type))
|
||||
mainDoor->SetGoState(GOState(data));
|
||||
break;
|
||||
case DATA_START_BOSS_ENCOUNTER:
|
||||
switch (uiWaveCount)
|
||||
@@ -374,7 +310,7 @@ public:
|
||||
uiMainEventPhase = data;
|
||||
if (data == IN_PROGRESS) // Start event
|
||||
{
|
||||
if (GameObject* mainDoor = instance->GetGameObject(uiMainDoor))
|
||||
if (GameObject* mainDoor = GetGameObject(DATA_MAIN_DOOR))
|
||||
mainDoor->SetGoState(GO_STATE_READY);
|
||||
uiWaveCount = 1;
|
||||
bActive = true;
|
||||
@@ -384,6 +320,9 @@ public:
|
||||
uiRemoveNpc = 0; // might not have been reset after a wipe on a boss.
|
||||
}
|
||||
break;
|
||||
case DATA_ZURAMAT:
|
||||
zuramatDead = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,9 +343,6 @@ public:
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_1ST_BOSS_EVENT: return m_auiEncounter[0];
|
||||
case DATA_2ND_BOSS_EVENT: return m_auiEncounter[1];
|
||||
case DATA_CYANIGOSA_EVENT: return m_auiEncounter[2];
|
||||
case DATA_WAVE_COUNT: return uiWaveCount;
|
||||
case DATA_REMOVE_NPC: return uiRemoveNpc;
|
||||
case DATA_PORTAL_LOCATION: return uiLocation;
|
||||
@@ -421,125 +357,114 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
ObjectGuid GetGuidData(uint32 identifier) const override
|
||||
ObjectGuid GetGuidData(uint32 type) const override
|
||||
{
|
||||
switch (identifier)
|
||||
switch (type)
|
||||
{
|
||||
case DATA_MORAGG: return uiMoragg;
|
||||
case DATA_EREKEM: return uiErekem;
|
||||
case DATA_EREKEM_GUARD_1: return uiErekemGuard[0];
|
||||
case DATA_EREKEM_GUARD_2: return uiErekemGuard[1];
|
||||
case DATA_ICHORON: return uiIchoron;
|
||||
case DATA_LAVANTHOR: return uiLavanthor;
|
||||
case DATA_XEVOZZ: return uiXevozz;
|
||||
case DATA_ZURAMAT: return uiZuramat;
|
||||
case DATA_CYANIGOSA: return uiCyanigosa;
|
||||
case DATA_MORAGG_CELL: return uiMoraggCell;
|
||||
case DATA_EREKEM_CELL: return uiErekemCell;
|
||||
case DATA_EREKEM_RIGHT_GUARD_CELL: return uiErekemRightGuardCell;
|
||||
case DATA_EREKEM_LEFT_GUARD_CELL: return uiErekemLeftGuardCell;
|
||||
case DATA_ICHORON_CELL: return uiIchoronCell;
|
||||
case DATA_LAVANTHOR_CELL: return uiLavanthorCell;
|
||||
case DATA_XEVOZZ_CELL: return uiXevozzCell;
|
||||
case DATA_ZURAMAT_CELL: return uiZuramatCell;
|
||||
case DATA_MAIN_DOOR: return uiMainDoor;
|
||||
case DATA_SINCLARI: return uiSinclari;
|
||||
case DATA_TELEPORTATION_PORTAL: return uiTeleportationPortal;
|
||||
case DATA_SABOTEUR_PORTAL: return uiSaboteurPortal;
|
||||
}
|
||||
|
||||
return ObjectGuid::Empty;
|
||||
return InstanceScript::GetGuidData(type);
|
||||
}
|
||||
|
||||
void SpawnPortal()
|
||||
{
|
||||
SetData(DATA_PORTAL_LOCATION, (GetData(DATA_PORTAL_LOCATION) + urand(1, 5))%6);
|
||||
if (Creature* pSinclari = instance->GetCreature(uiSinclari))
|
||||
if (Creature* portal = pSinclari->SummonCreature(CREATURE_TELEPORTATION_PORTAL, PortalLocation[GetData(DATA_PORTAL_LOCATION)], TEMPSUMMON_CORPSE_DESPAWN))
|
||||
if (Creature* sinclari = GetCreature(DATA_SINCLARI))
|
||||
if (Creature* portal = sinclari->SummonCreature(NPC_TELEPORTATION_PORTAL, PortalLocation[GetData(DATA_PORTAL_LOCATION)], TEMPSUMMON_CORPSE_DESPAWN))
|
||||
uiTeleportationPortal = portal->GetGUID();
|
||||
}
|
||||
|
||||
void StartBossEncounter(uint8 uiBoss, bool bForceRespawn = true)
|
||||
{
|
||||
Creature* pBoss = NULL;
|
||||
Creature* boss = nullptr;
|
||||
|
||||
switch (uiBoss)
|
||||
{
|
||||
case BOSS_MORAGG:
|
||||
HandleGameObject(uiMoraggCell, bForceRespawn);
|
||||
pBoss = instance->GetCreature(uiMoragg);
|
||||
if (pBoss)
|
||||
pBoss->GetMotionMaster()->MovePoint(0, BossStartMove1);
|
||||
HandleGameObject(GetObjectGuid(DATA_MORAGG_CELL), bForceRespawn);
|
||||
boss = GetCreature(DATA_MORAGG);
|
||||
if (boss)
|
||||
boss->GetMotionMaster()->MovePoint(0, BossStartMove1);
|
||||
break;
|
||||
case BOSS_EREKEM:
|
||||
HandleGameObject(uiErekemCell, bForceRespawn);
|
||||
HandleGameObject(uiErekemRightGuardCell, bForceRespawn);
|
||||
HandleGameObject(uiErekemLeftGuardCell, bForceRespawn);
|
||||
HandleGameObject(GetObjectGuid(DATA_EREKEM_CELL), bForceRespawn);
|
||||
HandleGameObject(GetObjectGuid(DATA_EREKEM_LEFT_GUARD_CELL), bForceRespawn);
|
||||
HandleGameObject(GetObjectGuid(DATA_EREKEM_RIGHT_GUARD_CELL), bForceRespawn);
|
||||
|
||||
pBoss = instance->GetCreature(uiErekem);
|
||||
|
||||
if (pBoss)
|
||||
pBoss->GetMotionMaster()->MovePoint(0, BossStartMove2);
|
||||
boss = GetCreature(DATA_EREKEM);
|
||||
if (boss)
|
||||
boss->GetMotionMaster()->MovePoint(0, BossStartMove2);
|
||||
|
||||
if (Creature* pGuard1 = instance->GetCreature(uiErekemGuard[0]))
|
||||
{
|
||||
if (bForceRespawn)
|
||||
pGuard1->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
|
||||
{
|
||||
pGuard1->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
|
||||
pGuard1->GetMotionMaster()->MovePoint(0, BossStartMove21);
|
||||
}
|
||||
else
|
||||
pGuard1->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
|
||||
pGuard1->GetMotionMaster()->MovePoint(0, BossStartMove21);
|
||||
}
|
||||
|
||||
if (Creature* pGuard2 = instance->GetCreature(uiErekemGuard[1]))
|
||||
{
|
||||
if (bForceRespawn)
|
||||
{
|
||||
pGuard2->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
|
||||
pGuard2->GetMotionMaster()->MovePoint(0, BossStartMove22);
|
||||
}
|
||||
else
|
||||
pGuard2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
|
||||
pGuard2->GetMotionMaster()->MovePoint(0, BossStartMove22);
|
||||
}
|
||||
break;
|
||||
case BOSS_ICHORON:
|
||||
HandleGameObject(uiIchoronCell, bForceRespawn);
|
||||
pBoss = instance->GetCreature(uiIchoron);
|
||||
if (pBoss)
|
||||
pBoss->GetMotionMaster()->MovePoint(0, BossStartMove3);
|
||||
HandleGameObject(GetObjectGuid(DATA_ICHORON_CELL), bForceRespawn);
|
||||
boss = GetCreature(DATA_ICHORON);
|
||||
if (boss)
|
||||
boss->GetMotionMaster()->MovePoint(0, BossStartMove3);
|
||||
break;
|
||||
case BOSS_LAVANTHOR:
|
||||
HandleGameObject(uiLavanthorCell, bForceRespawn);
|
||||
pBoss = instance->GetCreature(uiLavanthor);
|
||||
if (pBoss)
|
||||
pBoss->GetMotionMaster()->MovePoint(0, BossStartMove4);
|
||||
HandleGameObject(GetObjectGuid(DATA_LAVANTHOR_CELL), bForceRespawn);
|
||||
boss = GetCreature(DATA_LAVANTHOR);
|
||||
if (boss)
|
||||
boss->GetMotionMaster()->MovePoint(0, BossStartMove4);
|
||||
break;
|
||||
case BOSS_XEVOZZ:
|
||||
HandleGameObject(uiXevozzCell, bForceRespawn);
|
||||
pBoss = instance->GetCreature(uiXevozz);
|
||||
if (pBoss)
|
||||
pBoss->GetMotionMaster()->MovePoint(0, BossStartMove5);
|
||||
HandleGameObject(GetObjectGuid(DATA_XEVOZZ_CELL), bForceRespawn);
|
||||
boss = GetCreature(DATA_XEVOZZ);
|
||||
if (boss)
|
||||
boss->GetMotionMaster()->MovePoint(0, BossStartMove5);
|
||||
break;
|
||||
case BOSS_ZURAMAT:
|
||||
HandleGameObject(uiZuramatCell, bForceRespawn);
|
||||
pBoss = instance->GetCreature(uiZuramat);
|
||||
if (pBoss)
|
||||
pBoss->GetMotionMaster()->MovePoint(0, BossStartMove6);
|
||||
HandleGameObject(GetObjectGuid(DATA_ZURAMAT_CELL), bForceRespawn);
|
||||
boss = GetCreature(DATA_ZURAMAT);
|
||||
if (boss)
|
||||
boss->GetMotionMaster()->MovePoint(0, BossStartMove6);
|
||||
break;
|
||||
}
|
||||
|
||||
// generic boss state changes
|
||||
if (pBoss)
|
||||
if (boss)
|
||||
{
|
||||
pBoss->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
|
||||
pBoss->SetReactState(REACT_AGGRESSIVE);
|
||||
boss->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
|
||||
boss->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
if (!bForceRespawn)
|
||||
{
|
||||
if (pBoss->isDead())
|
||||
if (boss->isDead())
|
||||
{
|
||||
// respawn but avoid to be looted again
|
||||
pBoss->Respawn();
|
||||
pBoss->RemoveLootMode(1);
|
||||
boss->Respawn();
|
||||
boss->RemoveLootMode(1);
|
||||
}
|
||||
pBoss->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
|
||||
else
|
||||
boss->GetMotionMaster()->MoveTargetedHome();
|
||||
|
||||
boss->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
|
||||
uiWaveCount = 0;
|
||||
}
|
||||
}
|
||||
@@ -555,12 +480,12 @@ public:
|
||||
case 6:
|
||||
if (uiFirstBoss == 0)
|
||||
uiFirstBoss = urand(1, 6);
|
||||
if (Creature* pSinclari = instance->GetCreature(uiSinclari))
|
||||
if (Creature* sinclari = GetCreature(DATA_SINCLARI))
|
||||
{
|
||||
if (Creature* pPortal = pSinclari->SummonCreature(CREATURE_TELEPORTATION_PORTAL, MiddleRoomPortalSaboLocation, TEMPSUMMON_CORPSE_DESPAWN))
|
||||
uiSaboteurPortal = pPortal->GetGUID();
|
||||
if (Creature* pAzureSaboteur = pSinclari->SummonCreature(CREATURE_SABOTEOUR, MiddleRoomLocation, TEMPSUMMON_DEAD_DESPAWN))
|
||||
pAzureSaboteur->CastSpell(pAzureSaboteur, SABOTEUR_SHIELD_EFFECT, false);
|
||||
if (Creature* portal = sinclari->SummonCreature(NPC_TELEPORTATION_PORTAL, MiddleRoomPortalSaboLocation, TEMPSUMMON_CORPSE_DESPAWN))
|
||||
uiSaboteurPortal = portal->GetGUID();
|
||||
if (Creature* azureSaboteur = sinclari->SummonCreature(NPC_SABOTEOUR, MiddleRoomLocation, TEMPSUMMON_DEAD_DESPAWN))
|
||||
azureSaboteur->CastSpell(azureSaboteur, SABOTEUR_SHIELD_EFFECT, false);
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
@@ -569,25 +494,22 @@ public:
|
||||
{
|
||||
uiSecondBoss = urand(1, 6);
|
||||
} while (uiSecondBoss == uiFirstBoss);
|
||||
if (Creature* pSinclari = instance->GetCreature(uiSinclari))
|
||||
if (Creature* sinclari = GetCreature(DATA_SINCLARI))
|
||||
{
|
||||
if (Creature* pPortal = pSinclari->SummonCreature(CREATURE_TELEPORTATION_PORTAL, MiddleRoomPortalSaboLocation, TEMPSUMMON_CORPSE_DESPAWN))
|
||||
if (Creature* pPortal = sinclari->SummonCreature(NPC_TELEPORTATION_PORTAL, MiddleRoomPortalSaboLocation, TEMPSUMMON_CORPSE_DESPAWN))
|
||||
uiSaboteurPortal = pPortal->GetGUID();
|
||||
if (Creature* pAzureSaboteur = pSinclari->SummonCreature(CREATURE_SABOTEOUR, MiddleRoomLocation, TEMPSUMMON_DEAD_DESPAWN))
|
||||
if (Creature* pAzureSaboteur = sinclari->SummonCreature(NPC_SABOTEOUR, MiddleRoomLocation, TEMPSUMMON_DEAD_DESPAWN))
|
||||
pAzureSaboteur->CastSpell(pAzureSaboteur, SABOTEUR_SHIELD_EFFECT, false);
|
||||
}
|
||||
break;
|
||||
case 18:
|
||||
{
|
||||
Creature* pSinclari = instance->GetCreature(uiSinclari);
|
||||
if (pSinclari)
|
||||
pSinclari->SummonCreature(CREATURE_CYANIGOSA, CyanigosasSpawnLocation, TEMPSUMMON_DEAD_DESPAWN);
|
||||
if (Creature* sinclari = GetCreature(DATA_SINCLARI))
|
||||
sinclari->SummonCreature(NPC_CYANIGOSA, CyanigosasSpawnLocation, TEMPSUMMON_DEAD_DESPAWN);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (GameObject* pMainDoor = instance->GetGameObject(uiMainDoor))
|
||||
pMainDoor->SetGoState(GO_STATE_READY);
|
||||
if (GameObject* mainDoor = GetGameObject(DATA_MAIN_DOOR))
|
||||
mainDoor->SetGoState(GO_STATE_READY);
|
||||
DoUpdateWorldState(WORLD_STATE_VH_PRISON_STATE, 100);
|
||||
// no break
|
||||
}
|
||||
@@ -597,54 +519,15 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetSaveData() override
|
||||
void WriteSaveDataMore(std::ostringstream& data) override
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "V H " << (uint16)m_auiEncounter[0]
|
||||
<< ' ' << (uint16)m_auiEncounter[1]
|
||||
<< ' ' << (uint16)m_auiEncounter[2]
|
||||
<< ' ' << (uint16)uiFirstBoss
|
||||
<< ' ' << (uint16)uiSecondBoss;
|
||||
|
||||
str_data = saveStream.str();
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return str_data;
|
||||
data << uiFirstBoss << ' ' << uiSecondBoss;
|
||||
}
|
||||
|
||||
void Load(const char* in) override
|
||||
void ReadSaveDataMore(std::istringstream& data) override
|
||||
{
|
||||
if (!in)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
uint16 data0, data1, data2, data3, data4;
|
||||
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3 >> data4;
|
||||
|
||||
if (dataHead1 == 'V' && dataHead2 == 'H')
|
||||
{
|
||||
m_auiEncounter[0] = data0;
|
||||
m_auiEncounter[1] = data1;
|
||||
m_auiEncounter[2] = data2;
|
||||
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
|
||||
uiFirstBoss = uint8(data3);
|
||||
uiSecondBoss = uint8(data4);
|
||||
} else OUT_LOAD_INST_DATA_FAIL;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
data >> uiFirstBoss;
|
||||
data >> uiSecondBoss;
|
||||
}
|
||||
|
||||
bool CheckWipe()
|
||||
@@ -660,6 +543,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
zuramatDead = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -690,59 +574,57 @@ public:
|
||||
SetData(DATA_MAIN_DOOR, GO_STATE_ACTIVE);
|
||||
SetData(DATA_WAVE_COUNT, 0);
|
||||
uiMainEventPhase = NOT_STARTED;
|
||||
uiActivationTimer = 5000;
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
if (GameObject* crystal = instance->GetGameObject(uiActivationCrystal[i]))
|
||||
crystal->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
|
||||
if (Creature* pSinclari = instance->GetCreature(uiSinclari))
|
||||
if (Creature* sinclari = GetCreature(DATA_SINCLARI))
|
||||
{
|
||||
pSinclari->SetVisible(true);
|
||||
sinclari->SetVisible(true);
|
||||
|
||||
std::list<Creature*> GuardList;
|
||||
pSinclari->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f);
|
||||
sinclari->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f);
|
||||
if (!GuardList.empty())
|
||||
{
|
||||
for (std::list<Creature*>::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr)
|
||||
for (Creature* guard : GuardList)
|
||||
{
|
||||
if (Creature* pGuard = *itr)
|
||||
{
|
||||
pGuard->SetVisible(true);
|
||||
pGuard->SetReactState(REACT_AGGRESSIVE);
|
||||
pGuard->GetMotionMaster()->MovePoint(1, pGuard->GetHomePosition());
|
||||
}
|
||||
guard->SetVisible(true);
|
||||
guard->SetReactState(REACT_AGGRESSIVE);
|
||||
guard->GetMotionMaster()->MovePoint(1, guard->GetHomePosition());
|
||||
}
|
||||
}
|
||||
pSinclari->GetMotionMaster()->MovePoint(1, pSinclari->GetHomePosition());
|
||||
pSinclari->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
sinclari->GetMotionMaster()->MovePoint(1, sinclari->GetHomePosition());
|
||||
sinclari->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
}
|
||||
|
||||
// Cyanigosa is spawned but not tranformed, prefight event
|
||||
Creature* pCyanigosa = instance->GetCreature(uiCyanigosa);
|
||||
if (pCyanigosa && !pCyanigosa->HasAura(CYANIGOSA_SPELL_TRANSFORM))
|
||||
Creature* cyanigosa = GetCreature(DATA_CYANIGOSA);
|
||||
if (cyanigosa && !cyanigosa->HasAura(CYANIGOSA_SPELL_TRANSFORM))
|
||||
{
|
||||
if (uiCyanigosaEventTimer <= diff)
|
||||
{
|
||||
switch (uiCyanigosaEventPhase)
|
||||
{
|
||||
case 1:
|
||||
pCyanigosa->CastSpell(pCyanigosa, CYANIGOSA_BLUE_AURA, false);
|
||||
pCyanigosa->AI()->Talk(CYANIGOSA_SAY_SPAWN);
|
||||
cyanigosa->CastSpell(cyanigosa, CYANIGOSA_BLUE_AURA, false);
|
||||
cyanigosa->AI()->Talk(CYANIGOSA_SAY_SPAWN);
|
||||
uiCyanigosaEventTimer = 7*IN_MILLISECONDS;
|
||||
++uiCyanigosaEventPhase;
|
||||
break;
|
||||
case 2:
|
||||
pCyanigosa->GetMotionMaster()->MoveJump(MiddleRoomLocation.GetPositionX(), MiddleRoomLocation.GetPositionY(), MiddleRoomLocation.GetPositionZ(), 10.0f, 20.0f);
|
||||
pCyanigosa->CastSpell(pCyanigosa, CYANIGOSA_BLUE_AURA, false);
|
||||
cyanigosa->GetMotionMaster()->MoveJump(MiddleRoomLocation.GetPositionX(), MiddleRoomLocation.GetPositionY(), MiddleRoomLocation.GetPositionZ(), 10.0f, 20.0f);
|
||||
cyanigosa->CastSpell(cyanigosa, CYANIGOSA_BLUE_AURA, false);
|
||||
uiCyanigosaEventTimer = 7*IN_MILLISECONDS;
|
||||
++uiCyanigosaEventPhase;
|
||||
break;
|
||||
case 3:
|
||||
pCyanigosa->RemoveAurasDueToSpell(CYANIGOSA_BLUE_AURA);
|
||||
pCyanigosa->CastSpell(pCyanigosa, CYANIGOSA_SPELL_TRANSFORM, 0);
|
||||
pCyanigosa->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
|
||||
pCyanigosa->SetReactState(REACT_AGGRESSIVE);
|
||||
cyanigosa->RemoveAurasDueToSpell(CYANIGOSA_BLUE_AURA);
|
||||
cyanigosa->CastSpell(cyanigosa, CYANIGOSA_SPELL_TRANSFORM, 0);
|
||||
cyanigosa->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
|
||||
cyanigosa->SetReactState(REACT_AGGRESSIVE);
|
||||
uiCyanigosaEventTimer = 2*IN_MILLISECONDS;
|
||||
++uiCyanigosaEventPhase;
|
||||
break;
|
||||
@@ -815,6 +697,11 @@ public:
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
||||
{
|
||||
return new instance_violet_hold_InstanceMapScript(map);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_instance_violet_hold()
|
||||
|
||||
@@ -28,22 +28,23 @@
|
||||
#define GOSSIP_START_EVENT "Get your people to safety, we'll keep the Blue Dragonflight's forces at bay."
|
||||
#define GOSSIP_ITEM_1 "Activate the crystals when we get in trouble, right"
|
||||
#define GOSSIP_I_WANT_IN "I'm not fighting, so send me in now!"
|
||||
#define SAY_EVENT_LOCK "I'm locking the door. Good luck, and thank you for doing this."
|
||||
#define SPAWN_TIME 20000
|
||||
|
||||
enum PortalCreatures
|
||||
{
|
||||
CREATURE_AZURE_INVADER_1 = 30661,
|
||||
CREATURE_AZURE_INVADER_2 = 30961,
|
||||
CREATURE_AZURE_SPELLBREAKER_1 = 30662,
|
||||
CREATURE_AZURE_SPELLBREAKER_2 = 30962,
|
||||
CREATURE_AZURE_BINDER_1 = 30663,
|
||||
CREATURE_AZURE_BINDER_2 = 30918,
|
||||
CREATURE_AZURE_MAGE_SLAYER_1 = 30664,
|
||||
CREATURE_AZURE_MAGE_SLAYER_2 = 30963,
|
||||
CREATURE_AZURE_CAPTAIN = 30666,
|
||||
CREATURE_AZURE_SORCEROR = 30667,
|
||||
CREATURE_AZURE_RAIDER = 30668,
|
||||
CREATURE_AZURE_STALKER = 32191
|
||||
NPC_AZURE_INVADER_1 = 30661,
|
||||
NPC_AZURE_INVADER_2 = 30961,
|
||||
NPC_AZURE_SPELLBREAKER_1 = 30662,
|
||||
NPC_AZURE_SPELLBREAKER_2 = 30962,
|
||||
NPC_AZURE_BINDER_1 = 30663,
|
||||
NPC_AZURE_BINDER_2 = 30918,
|
||||
NPC_AZURE_MAGE_SLAYER_1 = 30664,
|
||||
NPC_AZURE_MAGE_SLAYER_2 = 30963,
|
||||
NPC_AZURE_CAPTAIN = 30666,
|
||||
NPC_AZURE_SORCEROR = 30667,
|
||||
NPC_AZURE_RAIDER = 30668,
|
||||
NPC_AZURE_STALKER = 32191
|
||||
};
|
||||
|
||||
enum AzureInvaderSpells
|
||||
@@ -59,7 +60,7 @@ enum AzureSellbreakerSpells
|
||||
SPELL_ARCANE_BLAST = 58462,
|
||||
SPELL_SLOW = 25603,
|
||||
SPELL_CHAINS_OF_ICE = 58464,
|
||||
SPELL_CONE_OF_COLD = 58463
|
||||
SPELL_CONE_OF_COLD = 58463,
|
||||
};
|
||||
|
||||
enum AzureBinderSpells
|
||||
@@ -67,7 +68,7 @@ enum AzureBinderSpells
|
||||
SPELL_ARCANE_BARRAGE = 58456,
|
||||
SPELL_ARCANE_EXPLOSION = 58455,
|
||||
SPELL_FROST_NOVA = 58458,
|
||||
SPELL_FROSTBOLT = 58457
|
||||
SPELL_FROSTBOLT = 58457,
|
||||
};
|
||||
|
||||
enum AzureMageSlayerSpells
|
||||
@@ -85,7 +86,7 @@ enum AzureCaptainSpells
|
||||
enum AzureSorcerorSpells
|
||||
{
|
||||
SPELL_ARCANE_STREAM = 60181,
|
||||
SPELL_MANA_DETONATION = 60182
|
||||
SPELL_MANA_DETONATION = 60182,
|
||||
};
|
||||
|
||||
enum AzureRaiderSpells
|
||||
@@ -114,7 +115,7 @@ enum TrashDoorSpell
|
||||
enum Spells
|
||||
{
|
||||
SPELL_PORTAL_CHANNEL = 58012,
|
||||
SPELL_CRYSTAL_ACTIVATION = 57804,
|
||||
SPELL_CRYSTAL_ACTIVATION = 57804, // visual effect
|
||||
SPELL_ARCANE_SPHERE_PASSIVE = 44263
|
||||
};
|
||||
|
||||
@@ -242,9 +243,21 @@ const float SaboteurFinalPos6[5][3] =
|
||||
{1931.063354f, 848.468445f, 47.190434f}
|
||||
};
|
||||
|
||||
const Position MovePosition = {1806.955566f, 803.851807f, 44.363323f, 0.0f};
|
||||
const Position playerTeleportPosition = {1830.531006f, 803.939758f, 44.340508f, 6.281611f};
|
||||
const Position sinclariOutsidePosition = {1817.315674f, 804.060608f, 44.363998f, 0.0f};
|
||||
const Position PortalLocation[] =
|
||||
{
|
||||
{ 1877.51f, 850.104f, 44.6599f, 4.7822f }, // WP 1
|
||||
{ 1936.07f, 803.198f, 53.3749f, 3.12414f }, // WP 3
|
||||
{ 1890.64f, 753.471f, 48.7224f, 1.71042f }, // WP 5
|
||||
};
|
||||
|
||||
#define MAX_PRE_EVENT_PORTAL 3
|
||||
|
||||
ObjectGuid preEventPortalGUID[MAX_PRE_EVENT_PORTAL] = { ObjectGuid::Empty };
|
||||
|
||||
const Position MovePosition = { 1806.955566f, 803.851807f, 44.363323f, 0.0f };
|
||||
const Position playerTeleportPosition = { 1830.531006f, 803.939758f, 44.340508f, 6.281611f };
|
||||
const Position sinclariOutsidePosition = { 1820.429810f, 804.066040f, 44.363998f, 0.0f };
|
||||
const Position sinclariCrystalPosition = { 1828.868286f, 798.468811f, 44.363998f, 3.890467f };
|
||||
|
||||
class npc_sinclari_vh : public CreatureScript
|
||||
{
|
||||
@@ -258,7 +271,7 @@ public:
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF+1:
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
ENSURE_AI(npc_sinclari_vh::npc_sinclariAI, (creature->AI()))->uiPhase = 1;
|
||||
ENSURE_AI(npc_sinclari_vh::npc_sinclariAI, creature->AI())->uiPhase = 1;
|
||||
if (InstanceScript* instance = creature->GetInstanceScript())
|
||||
instance->SetData(DATA_MAIN_EVENT_PHASE, SPECIAL);
|
||||
break;
|
||||
@@ -296,17 +309,12 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_sinclariAI>(creature);
|
||||
}
|
||||
|
||||
struct npc_sinclariAI : public ScriptedAI
|
||||
{
|
||||
npc_sinclariAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
@@ -325,6 +333,9 @@ public:
|
||||
Initialize();
|
||||
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
for (uint8 i = 0; i < MAX_PRE_EVENT_PORTAL; i++)
|
||||
if (TempSummon* summon = me->SummonCreature(NPC_TELEPORTATION_PORTAL, PortalLocation[i], TEMPSUMMON_MANUAL_DESPAWN))
|
||||
preEventPortalGUID[i] = summon->GetGUID();
|
||||
|
||||
std::list<Creature*> GuardList;
|
||||
me->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f);
|
||||
@@ -345,8 +356,6 @@ public:
|
||||
|
||||
void UpdateAI(uint32 uiDiff) override
|
||||
{
|
||||
ScriptedAI::UpdateAI(uiDiff);
|
||||
|
||||
if (uiPhase)
|
||||
{
|
||||
if (uiTimer <= uiDiff)
|
||||
@@ -354,25 +363,17 @@ public:
|
||||
switch (uiPhase)
|
||||
{
|
||||
case 1:
|
||||
Talk(SAY_SINCLARI_1);
|
||||
uiTimer = 4000;
|
||||
uiPhase = 2;
|
||||
me->SetWalk(true);
|
||||
me->GetMotionMaster()->MovePoint(0, sinclariCrystalPosition);
|
||||
uiTimer = 1000;
|
||||
uiPhase = 6;
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
std::list<Creature*> GuardList;
|
||||
me->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f);
|
||||
if (!GuardList.empty())
|
||||
for (std::list<Creature*>::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr)
|
||||
{
|
||||
if (Creature* pGuard = *itr)
|
||||
{
|
||||
pGuard->SetWalk(false);
|
||||
pGuard->GetMotionMaster()->MovePoint(0, MovePosition);
|
||||
}
|
||||
}
|
||||
uiTimer = 6000;
|
||||
uiPhase = 3;
|
||||
me->SetFacingTo(me->GetOrientation() - 3.14f);
|
||||
Talk(SAY_SINCLARI_1);
|
||||
uiTimer = 1500;
|
||||
uiPhase = 7;
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
@@ -385,7 +386,6 @@ public:
|
||||
if (Creature* pGuard = *itr)
|
||||
{
|
||||
pGuard->SetVisible(false);
|
||||
pGuard->SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
}
|
||||
uiTimer = 2000;
|
||||
@@ -398,11 +398,58 @@ public:
|
||||
uiPhase = 5;
|
||||
break;
|
||||
case 5:
|
||||
instance->SetData(DATA_MAIN_EVENT_PHASE, IN_PROGRESS);
|
||||
me->SetFacingTo(0.006673f);
|
||||
me->Say(SAY_EVENT_LOCK, LANG_UNIVERSAL, me); // need to change to db say
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
uiTimer = 3000;
|
||||
uiPhase = 8;
|
||||
break;
|
||||
case 6:
|
||||
me->GetMotionMaster()->MovementExpired();
|
||||
me->HandleEmoteCommand(EMOTE_STATE_USE_STANDING);
|
||||
uiTimer = 2000;
|
||||
uiPhase = 2;
|
||||
break;
|
||||
case 7:
|
||||
{
|
||||
std::list<Creature*> creatures;
|
||||
GetCreatureListWithEntryInGrid(creatures, me, NPC_TELEPORTATION_PORTAL, 200.0f);
|
||||
GetCreatureListWithEntryInGrid(creatures, me, NPC_AZURE_BINDER_1, 200.0f);
|
||||
GetCreatureListWithEntryInGrid(creatures, me, NPC_AZURE_MAGE_SLAYER_1, 200.0f);
|
||||
GetCreatureListWithEntryInGrid(creatures, me, NPC_AZURE_INVADER_1, 200.0f);
|
||||
DoCast(SPELL_CRYSTAL_ACTIVATION);
|
||||
if (!creatures.empty())
|
||||
{
|
||||
for (std::list<Creature*>::iterator itr = creatures.begin(); itr != creatures.end(); ++itr)
|
||||
(*itr)->DisappearAndDie();
|
||||
}
|
||||
uiTimer = 500;
|
||||
uiPhase = 9;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
instance->SetData(DATA_MAIN_EVENT_PHASE, IN_PROGRESS);
|
||||
uiTimer = 0;
|
||||
uiPhase = 0;
|
||||
break;
|
||||
case 9:
|
||||
{
|
||||
std::list<Creature*> GuardList;
|
||||
me->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f);
|
||||
if (!GuardList.empty())
|
||||
for (std::list<Creature*>::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr)
|
||||
{
|
||||
if (Creature* pGuard = *itr)
|
||||
{
|
||||
pGuard->SetReactState(REACT_PASSIVE);
|
||||
pGuard->SetWalk(false);
|
||||
pGuard->GetMotionMaster()->MovePoint(0, MovePosition);
|
||||
}
|
||||
}
|
||||
uiTimer = 4000;
|
||||
uiPhase = 3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else uiTimer -= uiDiff;
|
||||
@@ -415,6 +462,10 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_sinclariAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_azure_saboteur : public CreatureScript
|
||||
@@ -422,14 +473,9 @@ class npc_azure_saboteur : public CreatureScript
|
||||
public:
|
||||
npc_azure_saboteur() : CreatureScript("npc_azure_saboteur") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_azure_saboteurAI>(creature);
|
||||
}
|
||||
|
||||
struct npc_azure_saboteurAI : public npc_escortAI
|
||||
{
|
||||
npc_azure_saboteurAI(Creature* creature):npc_escortAI(creature)
|
||||
npc_azure_saboteurAI(Creature* creature) : npc_escortAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
bHasGotMovingPoints = false;
|
||||
@@ -532,13 +578,16 @@ public:
|
||||
{
|
||||
me->CastSpell(me, SABOTEUR_SHIELD_DISRUPTION, false);
|
||||
me->DisappearAndDie();
|
||||
Creature* pSaboPort = ObjectAccessor::GetCreature((*me), instance->GetGuidData(DATA_SABOTEUR_PORTAL));
|
||||
if (pSaboPort)
|
||||
if (Creature* pSaboPort = ObjectAccessor::GetCreature((*me), instance->GetGuidData(DATA_SABOTEUR_PORTAL)))
|
||||
pSaboPort->DisappearAndDie();
|
||||
instance->SetData(DATA_START_BOSS_ENCOUNTER, 1);
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_azure_saboteurAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_teleportation_portal_vh : public CreatureScript
|
||||
@@ -546,11 +595,6 @@ class npc_teleportation_portal_vh : public CreatureScript
|
||||
public:
|
||||
npc_teleportation_portal_vh() : CreatureScript("npc_teleportation_portal_vh") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_teleportation_portalAI>(creature);
|
||||
}
|
||||
|
||||
struct npc_teleportation_portalAI : public ScriptedAI
|
||||
{
|
||||
npc_teleportation_portalAI(Creature* creature) : ScriptedAI(creature), listOfMobs(me)
|
||||
@@ -558,6 +602,9 @@ public:
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
uiTypeOfMobsPortal = urand(0, 1); // 0 - elite mobs 1 - portal guardian or portal keeper with regular mobs
|
||||
|
||||
if (instance->GetData(DATA_MAIN_EVENT_PHASE) == NOT_STARTED)
|
||||
uiTypeOfMobsPortal = 2;
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
@@ -583,13 +630,15 @@ public:
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override { }
|
||||
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (instance->GetData(DATA_REMOVE_NPC) == 1)
|
||||
if (instance->GetData(DATA_MAIN_EVENT_PHASE) == IN_PROGRESS)
|
||||
{
|
||||
me->DespawnOrUnsummon();
|
||||
instance->SetData(DATA_REMOVE_NPC, 0);
|
||||
if (instance->GetData(DATA_REMOVE_NPC) == 1)
|
||||
{
|
||||
me->DespawnOrUnsummon();
|
||||
instance->SetData(DATA_REMOVE_NPC, 0);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 uiWaveCount = instance->GetData(DATA_WAVE_COUNT);
|
||||
@@ -608,7 +657,7 @@ public:
|
||||
uint8 k = uiWaveCount < 12 ? 2 : 3;
|
||||
for (uint8 i = 0; i < k; ++i)
|
||||
{
|
||||
uint32 entry = RAND(CREATURE_AZURE_CAPTAIN, CREATURE_AZURE_RAIDER, CREATURE_AZURE_STALKER, CREATURE_AZURE_SORCEROR);
|
||||
uint32 entry = RAND(NPC_AZURE_CAPTAIN, NPC_AZURE_RAIDER, NPC_AZURE_STALKER, NPC_AZURE_SORCEROR);
|
||||
DoSummon(entry, me, 2.0f, 20000, TEMPSUMMON_DEAD_DESPAWN);
|
||||
}
|
||||
me->SetVisible(false);
|
||||
@@ -633,14 +682,14 @@ public:
|
||||
uint8 k = instance->GetData(DATA_WAVE_COUNT) < 12 ? 3 : 4;
|
||||
for (uint8 i = 0; i < k; ++i)
|
||||
{
|
||||
uint32 entry = RAND(CREATURE_AZURE_INVADER_1, CREATURE_AZURE_INVADER_2, CREATURE_AZURE_SPELLBREAKER_1, CREATURE_AZURE_SPELLBREAKER_2, CREATURE_AZURE_MAGE_SLAYER_1, CREATURE_AZURE_MAGE_SLAYER_2, CREATURE_AZURE_BINDER_1, CREATURE_AZURE_BINDER_2);
|
||||
uint32 entry = RAND(NPC_AZURE_INVADER_1, NPC_AZURE_INVADER_2, NPC_AZURE_SPELLBREAKER_1, NPC_AZURE_SPELLBREAKER_2, NPC_AZURE_MAGE_SLAYER_1, NPC_AZURE_MAGE_SLAYER_2, NPC_AZURE_BINDER_1, NPC_AZURE_BINDER_2);
|
||||
DoSummon(entry, me, 2.0f, 20000, TEMPSUMMON_DEAD_DESPAWN);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bPortalGuardianOrKeeperOrEliteSpawn = true;
|
||||
uint32 entry = RAND(CREATURE_PORTAL_GUARDIAN, CREATURE_PORTAL_KEEPER);
|
||||
uint32 entry = RAND(NPC_PORTAL_GUARDIAN, NPC_PORTAL_KEEPER);
|
||||
if (Creature* pPortalKeeper = DoSummon(entry, me, 2.0f, 0, TEMPSUMMON_DEAD_DESPAWN))
|
||||
me->CastSpell(pPortalKeeper, SPELL_PORTAL_CHANNEL, false);
|
||||
}
|
||||
@@ -653,37 +702,71 @@ public:
|
||||
me->RemoveCorpse();
|
||||
}
|
||||
break;
|
||||
case 2: // Pre-event
|
||||
if (uiSpawnTimer <= diff)
|
||||
{
|
||||
uint32 entry = RAND(NPC_AZURE_INVADER_1, NPC_AZURE_MAGE_SLAYER_1, NPC_AZURE_BINDER_1);
|
||||
DoSummon(entry, me, 2.0f, 20000, TEMPSUMMON_DEAD_DESPAWN);
|
||||
uiSpawnTimer = SPAWN_TIME;
|
||||
} else uiSpawnTimer -= diff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
instance->SetData(DATA_WAVE_COUNT, instance->GetData(DATA_WAVE_COUNT)+1);
|
||||
if (instance->GetData(DATA_MAIN_EVENT_PHASE) == IN_PROGRESS)
|
||||
instance->SetData(DATA_WAVE_COUNT, instance->GetData(DATA_WAVE_COUNT) + 1);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned) override
|
||||
{
|
||||
listOfMobs.Summon(summoned);
|
||||
instance->SetGuidData(DATA_ADD_TRASH_MOB, summoned->GetGUID());
|
||||
if (instance->GetData(DATA_MAIN_EVENT_PHASE) == IN_PROGRESS)
|
||||
{
|
||||
listOfMobs.Summon(summoned);
|
||||
instance->SetGuidData(DATA_ADD_TRASH_MOB, summoned->GetGUID());
|
||||
}
|
||||
}
|
||||
|
||||
void SummonedCreatureDies(Creature* summoned, Unit* /*killer*/) override
|
||||
{
|
||||
listOfMobs.Despawn(summoned);
|
||||
instance->SetGuidData(DATA_DEL_TRASH_MOB, summoned->GetGUID());
|
||||
if (instance->GetData(DATA_MAIN_EVENT_PHASE) == IN_PROGRESS)
|
||||
{
|
||||
listOfMobs.Despawn(summoned);
|
||||
instance->SetGuidData(DATA_DEL_TRASH_MOB, summoned->GetGUID());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_teleportation_portalAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
struct violet_hold_trashAI : public npc_escortAI
|
||||
{
|
||||
violet_hold_trashAI(Creature* creature):npc_escortAI(creature)
|
||||
violet_hold_trashAI(Creature* creature) : npc_escortAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
bHasGotMovingPoints = false;
|
||||
portalLocationID = instance->GetData(DATA_PORTAL_LOCATION);
|
||||
secondPortalRouteID = 0;
|
||||
|
||||
|
||||
if (instance->GetData(DATA_MAIN_EVENT_PHASE) == NOT_STARTED)
|
||||
{
|
||||
if (Creature* portal = me->FindNearestCreature(NPC_TELEPORTATION_PORTAL, 10.0f))
|
||||
{
|
||||
ObjectGuid portalGUID = portal->GetGUID();
|
||||
for (uint8 i = 0; i < MAX_PRE_EVENT_PORTAL; i++)
|
||||
if (portalGUID == preEventPortalGUID[i])
|
||||
portalLocationID = i * 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
portalLocationID = instance->GetData(DATA_PORTAL_LOCATION);
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -698,7 +781,7 @@ struct violet_hold_trashAI : public npc_escortAI
|
||||
{
|
||||
case 0:
|
||||
if (waypointId == 5)
|
||||
CreatureStartAttackDoor();
|
||||
CreatureStartAttackDoor();
|
||||
break;
|
||||
case 1:
|
||||
if ((waypointId == 8 && secondPortalRouteID == 0) || (waypointId == 7 && secondPortalRouteID == 1))
|
||||
@@ -706,7 +789,7 @@ struct violet_hold_trashAI : public npc_escortAI
|
||||
break;
|
||||
case 2:
|
||||
if (waypointId == 7)
|
||||
CreatureStartAttackDoor();
|
||||
CreatureStartAttackDoor();
|
||||
break;
|
||||
case 3:
|
||||
if (waypointId == 8)
|
||||
@@ -723,7 +806,7 @@ struct violet_hold_trashAI : public npc_escortAI
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32) override
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (instance->GetData(DATA_MAIN_EVENT_PHASE) != IN_PROGRESS)
|
||||
me->CastStop();
|
||||
@@ -778,6 +861,8 @@ struct violet_hold_trashAI : public npc_escortAI
|
||||
SetDespawnAtEnd(false);
|
||||
Start(true, true);
|
||||
}
|
||||
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
@@ -791,7 +876,6 @@ struct violet_hold_trashAI : public npc_escortAI
|
||||
DoCast(SPELL_DESTROY_DOOR_SEAL);
|
||||
instance->SetData(DATA_NPC_PRESENCE_AT_DOOR_ADD, 1);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class npc_azure_invader : public CreatureScript
|
||||
@@ -799,11 +883,6 @@ class npc_azure_invader : public CreatureScript
|
||||
public:
|
||||
npc_azure_invader() : CreatureScript("npc_azure_invader") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_azure_invaderAI>(creature);
|
||||
}
|
||||
|
||||
struct npc_azure_invaderAI : public violet_hold_trashAI
|
||||
{
|
||||
npc_azure_invaderAI(Creature* creature) : violet_hold_trashAI(creature)
|
||||
@@ -833,12 +912,11 @@ public:
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
violet_hold_trashAI::UpdateAI(diff);
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->GetEntry() == CREATURE_AZURE_INVADER_1)
|
||||
if (me->GetEntry() == NPC_AZURE_INVADER_1)
|
||||
{
|
||||
if (uiCleaveTimer <= diff)
|
||||
{
|
||||
@@ -848,14 +926,13 @@ public:
|
||||
|
||||
if (uiImpaleTimer <= diff)
|
||||
{
|
||||
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
|
||||
if (target)
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_IMPALE);
|
||||
uiImpaleTimer = 4000;
|
||||
} else uiImpaleTimer -= diff;
|
||||
}
|
||||
|
||||
if (me->GetEntry() == CREATURE_AZURE_INVADER_2)
|
||||
if (me->GetEntry() == NPC_AZURE_INVADER_2)
|
||||
{
|
||||
if (uiBrutalStrikeTimer <= diff)
|
||||
{
|
||||
@@ -876,6 +953,10 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_azure_invaderAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_azure_binder : public CreatureScript
|
||||
@@ -883,11 +964,6 @@ class npc_azure_binder : public CreatureScript
|
||||
public:
|
||||
npc_azure_binder() : CreatureScript("npc_azure_binder") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_azure_binderAI>(creature);
|
||||
}
|
||||
|
||||
struct npc_azure_binderAI : public violet_hold_trashAI
|
||||
{
|
||||
npc_azure_binderAI(Creature* creature) : violet_hold_trashAI(creature)
|
||||
@@ -917,12 +993,11 @@ public:
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
violet_hold_trashAI::UpdateAI(diff);
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->GetEntry() == CREATURE_AZURE_BINDER_1)
|
||||
if (me->GetEntry() == NPC_AZURE_BINDER_1)
|
||||
{
|
||||
if (uiArcaneExplosionTimer <= diff)
|
||||
{
|
||||
@@ -930,16 +1005,15 @@ public:
|
||||
uiArcaneExplosionTimer = 5000;
|
||||
} else uiArcaneExplosionTimer -= diff;
|
||||
|
||||
if (uiArcainBarrageTimer <= diff)
|
||||
if (uiArcainBarrageTimer <= diff)
|
||||
{
|
||||
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
|
||||
if (target)
|
||||
DoCast(target, SPELL_ARCANE_BARRAGE);
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_ARCANE_BARRAGE);
|
||||
uiArcainBarrageTimer = 6000;
|
||||
} else uiArcainBarrageTimer -= diff;
|
||||
}
|
||||
|
||||
if (me->GetEntry() == CREATURE_AZURE_BINDER_2)
|
||||
if (me->GetEntry() == NPC_AZURE_BINDER_2)
|
||||
{
|
||||
if (uiFrostNovaTimer <= diff)
|
||||
{
|
||||
@@ -949,8 +1023,7 @@ public:
|
||||
|
||||
if (uiFrostboltTimer <= diff)
|
||||
{
|
||||
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
|
||||
if (target)
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_FROSTBOLT);
|
||||
uiFrostboltTimer = 6000;
|
||||
} else uiFrostboltTimer -= diff;
|
||||
@@ -960,6 +1033,10 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_azure_binderAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_azure_mage_slayer : public CreatureScript
|
||||
@@ -967,11 +1044,6 @@ class npc_azure_mage_slayer : public CreatureScript
|
||||
public:
|
||||
npc_azure_mage_slayer() : CreatureScript("npc_azure_mage_slayer") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_azure_mage_slayerAI>(creature);
|
||||
}
|
||||
|
||||
struct npc_azure_mage_slayerAI : public violet_hold_trashAI
|
||||
{
|
||||
npc_azure_mage_slayerAI(Creature* creature) : violet_hold_trashAI(creature)
|
||||
@@ -997,12 +1069,11 @@ public:
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
violet_hold_trashAI::UpdateAI(diff);
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->GetEntry() == CREATURE_AZURE_MAGE_SLAYER_1)
|
||||
if (me->GetEntry() == NPC_AZURE_MAGE_SLAYER_1)
|
||||
{
|
||||
if (uiArcaneEmpowermentTimer <= diff)
|
||||
{
|
||||
@@ -1011,12 +1082,11 @@ public:
|
||||
} else uiArcaneEmpowermentTimer -= diff;
|
||||
}
|
||||
|
||||
if (me->GetEntry() == CREATURE_AZURE_MAGE_SLAYER_2)
|
||||
if (me->GetEntry() == NPC_AZURE_MAGE_SLAYER_2)
|
||||
{
|
||||
if (uiSpellLockTimer <= diff)
|
||||
{
|
||||
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
|
||||
if (target)
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_SPELL_LOCK);
|
||||
uiSpellLockTimer = 9000;
|
||||
} else uiSpellLockTimer -= diff;
|
||||
@@ -1026,6 +1096,10 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_azure_mage_slayerAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_azure_raider : public CreatureScript
|
||||
@@ -1033,11 +1107,6 @@ class npc_azure_raider : public CreatureScript
|
||||
public:
|
||||
npc_azure_raider() : CreatureScript("npc_azure_raider") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_azure_raiderAI>(creature);
|
||||
}
|
||||
|
||||
struct npc_azure_raiderAI : public violet_hold_trashAI
|
||||
{
|
||||
npc_azure_raiderAI(Creature* creature) : violet_hold_trashAI(creature)
|
||||
@@ -1063,7 +1132,6 @@ public:
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
violet_hold_trashAI::UpdateAI(diff);
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
@@ -1084,6 +1152,10 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_azure_raiderAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_azure_stalker : public CreatureScript
|
||||
@@ -1114,7 +1186,6 @@ public:
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
violet_hold_trashAI::UpdateAI(diff);
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
@@ -1123,8 +1194,7 @@ public:
|
||||
{
|
||||
if (_tacticalBlinkTimer <= diff)
|
||||
{
|
||||
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40, true);
|
||||
if (target)
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40, true))
|
||||
DoCast(target, SPELL_TACTICAL_BLINK);
|
||||
_tacticalBlinkTimer = 6000;
|
||||
_tacticalBlinkCast = true;
|
||||
@@ -1135,8 +1205,8 @@ public:
|
||||
{
|
||||
if (_backstabTimer <= diff)
|
||||
{
|
||||
Unit* target = SelectTarget(SELECT_TARGET_NEAREST, 0, 10, true);
|
||||
DoCast(target, SPELL_BACKSTAB);
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_NEAREST, 0, 10, true))
|
||||
DoCast(target, SPELL_BACKSTAB);
|
||||
_tacticalBlinkCast = false;
|
||||
_backstabTimer =1300;
|
||||
} else _backstabTimer -= diff;
|
||||
@@ -1191,43 +1261,39 @@ public:
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
violet_hold_trashAI::UpdateAI(diff);
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->GetEntry() == CREATURE_AZURE_SPELLBREAKER_1)
|
||||
if (me->GetEntry() == NPC_AZURE_SPELLBREAKER_1)
|
||||
{
|
||||
if (uiArcaneBlastTimer <= diff)
|
||||
{
|
||||
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
|
||||
if (target)
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_ARCANE_BLAST);
|
||||
uiArcaneBlastTimer = 6000;
|
||||
} else uiArcaneBlastTimer -= diff;
|
||||
|
||||
if (uiSlowTimer <= diff)
|
||||
{
|
||||
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
|
||||
if (target)
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_SLOW);
|
||||
uiSlowTimer = 5000;
|
||||
} else uiSlowTimer -= diff;
|
||||
}
|
||||
|
||||
if (me->GetEntry() == CREATURE_AZURE_SPELLBREAKER_2)
|
||||
if (me->GetEntry() == NPC_AZURE_SPELLBREAKER_2)
|
||||
{
|
||||
if (uiChainsOfIceTimer <= diff)
|
||||
{
|
||||
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
|
||||
if (target)
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_CHAINS_OF_ICE);
|
||||
uiChainsOfIceTimer = 7000;
|
||||
} else uiChainsOfIceTimer -= diff;
|
||||
|
||||
if (uiConeOfColdTimer <= diff)
|
||||
{
|
||||
DoCast(SPELL_CONE_OF_COLD);
|
||||
DoCast(SPELL_CONE_OF_COLD);
|
||||
uiConeOfColdTimer = 5000;
|
||||
} else uiConeOfColdTimer -= diff;
|
||||
}
|
||||
@@ -1247,11 +1313,6 @@ class npc_azure_captain : public CreatureScript
|
||||
public:
|
||||
npc_azure_captain() : CreatureScript("npc_azure_captain") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_azure_captainAI>(creature);
|
||||
}
|
||||
|
||||
struct npc_azure_captainAI : public violet_hold_trashAI
|
||||
{
|
||||
npc_azure_captainAI(Creature* creature) : violet_hold_trashAI(creature)
|
||||
@@ -1277,7 +1338,6 @@ public:
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
violet_hold_trashAI::UpdateAI(diff);
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
@@ -1298,6 +1358,10 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_azure_captainAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_azure_sorceror : public CreatureScript
|
||||
@@ -1305,11 +1369,6 @@ class npc_azure_sorceror : public CreatureScript
|
||||
public:
|
||||
npc_azure_sorceror() : CreatureScript("npc_azure_sorceror") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_azure_sorcerorAI>(creature);
|
||||
}
|
||||
|
||||
struct npc_azure_sorcerorAI : public violet_hold_trashAI
|
||||
{
|
||||
npc_azure_sorcerorAI(Creature* creature) : violet_hold_trashAI(creature)
|
||||
@@ -1337,15 +1396,13 @@ public:
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
violet_hold_trashAI::UpdateAI(diff);
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (uiArcaneStreamTimer <= diff)
|
||||
{
|
||||
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
|
||||
if (target)
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_ARCANE_STREAM);
|
||||
uiArcaneStreamTimer = urand(0, 5000)+5000;
|
||||
uiArcaneStreamTimerStartingValueHolder = uiArcaneStreamTimer;
|
||||
@@ -1360,8 +1417,12 @@ public:
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_azure_sorcerorAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_violet_hold_arcane_sphere : public CreatureScript
|
||||
{
|
||||
@@ -1419,6 +1480,33 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class spell_crystal_activation : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_crystal_activation() : SpellScriptLoader("spell_crystal_activation") { }
|
||||
|
||||
class spell_crystal_activation_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_crystal_activation_SpellScript);
|
||||
|
||||
void HandleSendEvent(SpellEffIndex effIndex)
|
||||
{
|
||||
if (GetHitUnit()->GetEntry() == NPC_VIOLET_HOLD_GUARD)
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_crystal_activation_SpellScript::HandleSendEvent, EFFECT_0, SPELL_EFFECT_SEND_EVENT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_crystal_activation_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_violet_hold()
|
||||
{
|
||||
new npc_sinclari_vh();
|
||||
@@ -1434,4 +1522,5 @@ void AddSC_violet_hold()
|
||||
new npc_azure_saboteur();
|
||||
new npc_violet_hold_arcane_sphere();
|
||||
new go_activation_crystal();
|
||||
new spell_crystal_activation();
|
||||
}
|
||||
@@ -18,13 +18,18 @@
|
||||
#ifndef DEF_VIOLET_HOLD_H
|
||||
#define DEF_VIOLET_HOLD_H
|
||||
|
||||
#define DataHeader "VIO"
|
||||
#define DataHeader "VH"
|
||||
|
||||
uint32 const EncounterCount = 3;
|
||||
|
||||
enum Data
|
||||
{
|
||||
// Main encounters
|
||||
DATA_1ST_BOSS_EVENT,
|
||||
DATA_2ND_BOSS_EVENT,
|
||||
DATA_CYANIGOSA_EVENT,
|
||||
DATA_CYANIGOSA,
|
||||
|
||||
// Misc
|
||||
DATA_WAVE_COUNT,
|
||||
DATA_REMOVE_NPC,
|
||||
DATA_PORTAL_LOCATION,
|
||||
@@ -38,10 +43,8 @@ enum Data
|
||||
DATA_ACTIVATE_CRYSTAL,
|
||||
DATA_MAIN_EVENT_PHASE,
|
||||
DATA_DEFENSELESS,
|
||||
};
|
||||
|
||||
enum Data64
|
||||
{
|
||||
// Bosses
|
||||
DATA_MORAGG,
|
||||
DATA_EREKEM,
|
||||
DATA_EREKEM_GUARD_1,
|
||||
@@ -50,7 +53,8 @@ enum Data64
|
||||
DATA_LAVANTHOR,
|
||||
DATA_XEVOZZ,
|
||||
DATA_ZURAMAT,
|
||||
DATA_CYANIGOSA,
|
||||
|
||||
// Cells
|
||||
DATA_MORAGG_CELL,
|
||||
DATA_EREKEM_CELL,
|
||||
DATA_EREKEM_LEFT_GUARD_CELL,
|
||||
@@ -59,6 +63,8 @@ enum Data64
|
||||
DATA_LAVANTHOR_CELL,
|
||||
DATA_XEVOZZ_CELL,
|
||||
DATA_ZURAMAT_CELL,
|
||||
|
||||
// Misc
|
||||
DATA_MAIN_DOOR,
|
||||
DATA_SINCLARI,
|
||||
DATA_TELEPORTATION_PORTAL,
|
||||
@@ -81,33 +87,50 @@ enum Bosses
|
||||
|
||||
enum CreaturesIds
|
||||
{
|
||||
CREATURE_TELEPORTATION_PORTAL = 31011,
|
||||
CREATURE_PORTAL_GUARDIAN = 30660,
|
||||
CREATURE_PORTAL_KEEPER = 30695,
|
||||
CREATURE_XEVOZZ = 29266,
|
||||
CREATURE_LAVANTHOR = 29312,
|
||||
CREATURE_ICHORON = 29313,
|
||||
CREATURE_ZURAMAT = 29314,
|
||||
CREATURE_EREKEM = 29315,
|
||||
CREATURE_EREKEM_GUARD = 29395,
|
||||
CREATURE_MORAGG = 29316,
|
||||
CREATURE_CYANIGOSA = 31134,
|
||||
CREATURE_SINCLARI = 30658,
|
||||
CREATURE_SABOTEOUR = 31079,
|
||||
NPC_VIOLET_HOLD_GUARD = 30659,
|
||||
NPC_DEFENSE_SYSTEM = 30837
|
||||
NPC_TELEPORTATION_PORTAL = 31011,
|
||||
NPC_PORTAL_GUARDIAN = 30660,
|
||||
NPC_PORTAL_KEEPER = 30695,
|
||||
NPC_XEVOZZ = 29266,
|
||||
NPC_LAVANTHOR = 29312,
|
||||
NPC_ICHORON = 29313,
|
||||
NPC_ZURAMAT = 29314,
|
||||
NPC_EREKEM = 29315,
|
||||
NPC_EREKEM_GUARD = 29395,
|
||||
NPC_MORAGG = 29316,
|
||||
NPC_CYANIGOSA = 31134,
|
||||
NPC_SINCLARI = 30658,
|
||||
NPC_SABOTEOUR = 31079,
|
||||
NPC_VIOLET_HOLD_GUARD = 30659,
|
||||
NPC_DEFENSE_SYSTEM = 30837,
|
||||
NPC_VOID_SENTRY = 29364,
|
||||
NPC_VOID_SENTRY_BALL = 29365
|
||||
};
|
||||
|
||||
enum GameObjectIds
|
||||
{
|
||||
GO_MAIN_DOOR = 191723,
|
||||
GO_XEVOZZ_DOOR = 191556,
|
||||
GO_LAVANTHOR_DOOR = 191566,
|
||||
GO_ICHORON_DOOR = 191722,
|
||||
GO_ZURAMAT_DOOR = 191565,
|
||||
GO_EREKEM_DOOR = 191564,
|
||||
GO_EREKEM_GUARD_1_DOOR = 191563,
|
||||
GO_EREKEM_GUARD_2_DOOR = 191562,
|
||||
GO_MORAGG_DOOR = 191606,
|
||||
GO_INTRO_ACTIVATION_CRYSTAL = 193615,
|
||||
GO_ACTIVATION_CRYSTAL = 193611
|
||||
};
|
||||
|
||||
enum WorldStateIds
|
||||
{
|
||||
WORLD_STATE_VH = 3816,
|
||||
WORLD_STATE_VH_PRISON_STATE = 3815,
|
||||
WORLD_STATE_VH_WAVE_COUNT = 3810,
|
||||
WORLD_STATE_VH = 3816,
|
||||
WORLD_STATE_VH_PRISON_STATE = 3815,
|
||||
WORLD_STATE_VH_WAVE_COUNT = 3810,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_ACTIVATE_CRYSTAL = 20001
|
||||
EVENT_ACTIVATE_CRYSTAL = 20001
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -161,19 +161,6 @@ class spell_ioc_gunship_portal : public SpellScriptLoader
|
||||
* Position: X: 7.305609 Y: -0.095246 Z: 34.51022 O: 0
|
||||
*/
|
||||
caster->TeleportTo(GetHitCreature()->GetWorldLocation(), TELE_TO_NOT_LEAVE_TRANSPORT);
|
||||
/*
|
||||
* HACK: This aura should be added by 20212 and 20213 but can't find any SMSG_SPELL_GO. Could't find their position.
|
||||
* ServerToClient: SMSG_AURA_UPDATE (0x0072)
|
||||
* [0] CasterGUID: Full: xxxxx Type: Unit Entry: 20212 Low: xxx
|
||||
* [0] Flags: None (0)
|
||||
* [0] Caster Level: 60
|
||||
* [0] Spell ID: 66656
|
||||
* [0] Charges: 0
|
||||
* [0] Effect Mask: 1
|
||||
* [0] Slot: 37
|
||||
* Guid: Full: xxxxx Type: Player2 Low: xxxxx
|
||||
*/
|
||||
caster->AddAura(SPELL_PARACHUTE, caster);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
|
||||
@@ -824,6 +824,60 @@ class spell_brewfest_barker_bunny : public SpellScriptLoader
|
||||
}
|
||||
};
|
||||
|
||||
enum TorchSpells
|
||||
{
|
||||
SPELL_TORCH_TOSSING_TRAINING = 45716,
|
||||
SPELL_TORCH_TOSSING_PRACTICE = 46630,
|
||||
SPELL_TORCH_TOSSING_TRAINING_SUCCESS_ALLIANCE = 45719,
|
||||
SPELL_TORCH_TOSSING_TRAINING_SUCCESS_HORDE = 46651,
|
||||
SPELL_BRAZIERS_HIT = 45724
|
||||
};
|
||||
|
||||
// 45724 - Braziers Hit!
|
||||
class spell_midsummer_braziers_hit : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_midsummer_braziers_hit() : SpellScriptLoader("spell_midsummer_braziers_hit") { }
|
||||
|
||||
class spell_midsummer_braziers_hit_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_midsummer_braziers_hit_AuraScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_TORCH_TOSSING_TRAINING) || !sSpellMgr->GetSpellInfo(SPELL_TORCH_TOSSING_PRACTICE))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
Player* player = GetTarget()->ToPlayer();
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
if ((player->HasAura(SPELL_TORCH_TOSSING_TRAINING) && GetStackAmount() == 8) || (player->HasAura(SPELL_TORCH_TOSSING_PRACTICE) && GetStackAmount() == 20))
|
||||
{
|
||||
if (player->GetTeam() == ALLIANCE)
|
||||
player->CastSpell(player, SPELL_TORCH_TOSSING_TRAINING_SUCCESS_ALLIANCE, true);
|
||||
else if (player->GetTeam() == HORDE)
|
||||
player->CastSpell(player, SPELL_TORCH_TOSSING_TRAINING_SUCCESS_HORDE, true);
|
||||
Remove();
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectApply += AuraEffectApplyFn(spell_midsummer_braziers_hit_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AuraEffectHandleModes(AURA_EFFECT_HANDLE_REAPPLY));
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_midsummer_braziers_hit_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_holiday_spell_scripts()
|
||||
{
|
||||
// Love is in the Air
|
||||
@@ -850,4 +904,6 @@ void AddSC_holiday_spell_scripts()
|
||||
new spell_brewfest_relay_race_intro_force_player_to_throw();
|
||||
new spell_brewfest_dismount_ram();
|
||||
new spell_brewfest_barker_bunny();
|
||||
// Midsummer Fire Festival
|
||||
new spell_midsummer_braziers_hit();
|
||||
}
|
||||
@@ -2496,6 +2496,35 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// 13790 13793 13811 13814 - Among the Champions
|
||||
// 13665 13745 13750 13756 13761 13767 13772 13777 13782 13787 - The Grand Melee
|
||||
class spell_q13665_q13790_bested_trigger : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_q13665_q13790_bested_trigger() : SpellScriptLoader("spell_q13665_q13790_bested_trigger") { }
|
||||
|
||||
class spell_q13665_q13790_bested_trigger_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_q13665_q13790_bested_trigger_SpellScript);
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Unit* target = GetHitUnit()->GetCharmerOrOwnerOrSelf();
|
||||
target->CastSpell(target, uint32(GetEffectValue()));
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_q13665_q13790_bested_trigger_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_q13665_q13790_bested_trigger_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_quest_spell_scripts()
|
||||
{
|
||||
new spell_q55_sacred_cleansing();
|
||||
@@ -2555,5 +2584,5 @@ void AddSC_quest_spell_scripts()
|
||||
new spell_q14100_q14111_make_player_destroy_totems();
|
||||
new spell_q10929_fumping();
|
||||
new spell_q28813_get_our_boys_back_dummy();
|
||||
new spell_q28813_set_health_random();
|
||||
new spell_q13665_q13790_bested_trigger();
|
||||
}
|
||||
@@ -117,6 +117,9 @@ DatabaseLoader& DatabaseLoader::AddDatabase(DatabaseWorkerPool<T>& pool, std::st
|
||||
|
||||
bool DatabaseLoader::Load()
|
||||
{
|
||||
if (!_updateFlags)
|
||||
TC_LOG_INFO("sql.updates", "Automatic database updates are disabled for all databases!");
|
||||
|
||||
if (!OpenDatabases())
|
||||
return false;
|
||||
|
||||
|
||||
@@ -358,14 +358,14 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_DEL_GO_RESPAWN_BY_INSTANCE, "DELETE FROM gameobject_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_ASYNC);
|
||||
|
||||
// GM Tickets
|
||||
PrepareStatement(CHAR_SEL_GM_TICKETS, "SELECT ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, haveTicket FROM gm_tickets", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_REP_GM_TICKET, "REPLACE INTO gm_tickets (ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, haveTicket) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_GM_TICKET, "DELETE FROM gm_tickets WHERE ticketId = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_PLAYER_GM_TICKETS, "DELETE FROM gm_tickets WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_GM_TICKETS, "SELECT id, playerGuid, name, description, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, needMoreHelp FROM gm_ticket", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_REP_GM_TICKET, "REPLACE INTO gm_ticket (id, playerGuid, name, description, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, needMoreHelp) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_GM_TICKET, "DELETE FROM gm_ticket WHERE id = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_PLAYER_GM_TICKETS, "DELETE FROM gm_ticket WHERE playerGuid = ?", CONNECTION_ASYNC);
|
||||
|
||||
// GM Survey/subsurvey/lag report
|
||||
PrepareStatement(CHAR_INS_GM_SURVEY, "INSERT INTO gm_surveys (guid, surveyId, mainSurvey, overallComment, createTime) VALUES (?, ?, ?, ?, UNIX_TIMESTAMP(NOW()))", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_GM_SUBSURVEY, "INSERT INTO gm_subsurveys (surveyId, subsurveyId, rank, comment) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_GM_SURVEY, "INSERT INTO gm_survey (guid, surveyId, mainSurvey, comment, createTime) VALUES (?, ?, ?, ?, UNIX_TIMESTAMP(NOW()))", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_GM_SUBSURVEY, "INSERT INTO gm_subsurvey (surveyId, questionId, answer, answerComment) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_LAG_REPORT, "INSERT INTO lag_reports (guid, lagType, mapId, posX, posY, posZ, latency, createTime) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
|
||||
// LFG Data
|
||||
@@ -396,7 +396,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_UPD_PETITION_NAME, "UPDATE petition SET name = ? WHERE petitionguid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_PETITION_SIGNATURE, "INSERT INTO petition_sign (ownerguid, petitionguid, playerguid, player_account) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_ACCOUNT_ONLINE, "UPDATE characters SET online = 0 WHERE account = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_GROUP, "INSERT INTO groups (guid, leaderGuid, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, groupType, difficulty, raiddifficulty, masterLooterGuid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_GROUP, "INSERT INTO groups (guid, leaderGuid, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, groupType, difficulty, raidDifficulty, masterLooterGuid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_GROUP_MEMBER, "INSERT INTO group_member (guid, memberGuid, memberFlags, subgroup, roles) VALUES(?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_GROUP_MEMBER, "DELETE FROM group_member WHERE memberGuid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_GROUP_INSTANCE_PERM_BINDING, "DELETE FROM group_instance WHERE guid = ? AND instance = ?", CONNECTION_ASYNC);
|
||||
@@ -406,7 +406,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_UPD_GROUP_MEMBER_FLAG, "UPDATE group_member SET memberFlags = ? WHERE memberGuid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_GROUP_DIFFICULTY, "UPDATE groups SET difficulty = ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_GROUP_RAID_DIFFICULTY, "UPDATE groups SET raiddifficulty = ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_ALL_GM_TICKETS, "TRUNCATE TABLE gm_tickets", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_ALL_GM_TICKETS, "TRUNCATE TABLE gm_ticket", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_INVALID_SPELL_TALENTS, "DELETE FROM character_talent WHERE spell = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_INVALID_SPELL_SPELLS, "DELETE FROM character_spell WHERE spell = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_DELETE_INFO, "UPDATE characters SET deleteInfos_Name = name, deleteInfos_Account = account, deleteDate = UNIX_TIMESTAMP(), name = '', account = 0 WHERE guid = ?", CONNECTION_ASYNC);
|
||||
@@ -438,7 +438,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_DEL_CHARACTER_SOCIAL, "DELETE FROM character_social WHERE guid = ? AND friend = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_CHARACTER_SOCIAL_NOTE, "UPDATE character_social SET note = ? WHERE guid = ? AND friend = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_CHARACTER_POSITION, "UPDATE characters SET position_x = ?, position_y = ?, position_z = ?, orientation = ?, map = ?, zone = ?, trans_x = 0, trans_y = 0, trans_z = 0, transguid = 0, taxi_path = '' WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_AURA_FROZEN, "SELECT characters.name, character_aura.remaintime FROM characters LEFT JOIN character_aura ON (characters.guid = character_aura.guid) WHERE character_aura.spell = 9454", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_AURA_FROZEN, "SELECT characters.name, character_aura.remainTime FROM characters LEFT JOIN character_aura ON (characters.guid = character_aura.guid) WHERE character_aura.spell = 9454", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_ONLINE, "SELECT name, account, map, zone FROM characters WHERE online > 0", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_CHAR_DEL_INFO_BY_GUID, "SELECT guid, deleteInfos_Name, deleteInfos_Account, deleteDate FROM characters WHERE deleteDate IS NOT NULL AND guid = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_CHAR_DEL_INFO_BY_NAME, "SELECT guid, deleteInfos_Name, deleteInfos_Account, deleteDate FROM characters WHERE deleteDate IS NOT NULL AND deleteInfos_Name LIKE CONCAT('%%', ?, '%%')", CONNECTION_SYNCH);
|
||||
@@ -566,8 +566,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_DEL_PETITION_BY_OWNER_AND_TYPE, "DELETE FROM petition WHERE ownerguid = ? AND type = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER_AND_TYPE, "DELETE FROM petition_sign WHERE ownerguid = ? AND type = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_CHAR_GLYPHS, "INSERT INTO character_glyphs (guid, spec, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6, glyph7, glyph8, glyph9) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_CHAR_TALENT_BY_SPELL_SPEC, "DELETE FROM character_talent WHERE guid = ? and spell = ? and spec = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_CHAR_TALENT, "INSERT INTO character_talent (guid, spell, spec) VALUES (?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_CHAR_TALENT_BY_SPELL_SPEC, "DELETE FROM character_talent WHERE guid = ? AND spell = ? AND talentGroup = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_CHAR_TALENT, "INSERT INTO character_talent (guid, spell, talentGroup) VALUES (?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC, "DELETE FROM character_action WHERE spec<>? AND guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_CHAR_LIST_SLOT, "UPDATE characters SET slot = ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||
|
||||
@@ -613,7 +613,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME_BY_OWNER, "DELETE FROM character_pet_declinedname WHERE owner = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME, "DELETE FROM character_pet_declinedname WHERE id = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_CHAR_PET_DECLINEDNAME, "INSERT INTO character_pet_declinedname (id, owner, genitive, dative, accusative, instrumental, prepositional) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_PET_AURA, "SELECT caster_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges FROM pet_aura WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_PET_AURA, "SELECT casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxDuration, remainTime, remainCharges FROM pet_aura WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_PET_SPELL, "SELECT spell, active FROM pet_spell WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_PET_SPELL_COOLDOWN, "SELECT spell, time FROM pet_spell_cooldown WHERE guid = ? AND time > UNIX_TIMESTAMP()", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_PET_DECLINED_NAME, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_pet_declinedname WHERE owner = ? AND id = ?", CONNECTION_SYNCH);
|
||||
@@ -623,8 +623,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_INS_PET_SPELL_COOLDOWN, "INSERT INTO pet_spell_cooldown (guid, spell, time) VALUES (?, ?, ?)", CONNECTION_BOTH);
|
||||
PrepareStatement(CHAR_DEL_PET_SPELL_BY_SPELL, "DELETE FROM pet_spell WHERE guid = ? and spell = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_PET_SPELL, "INSERT INTO pet_spell (guid, spell, active) VALUES (?, ?, ?)", CONNECTION_BOTH);
|
||||
PrepareStatement(CHAR_INS_PET_AURA, "INSERT INTO pet_aura (guid, caster_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, "
|
||||
"base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_BOTH);
|
||||
PrepareStatement(CHAR_INS_PET_AURA, "INSERT INTO pet_aura (guid, casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, "
|
||||
"base_amount0, base_amount1, base_amount2, maxDuration, remainTime, remainCharges) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_BOTH);
|
||||
PrepareStatement(CHAR_SEL_CHAR_PET_BY_ENTRY, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND id = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT_2, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND entry = ? AND (slot = ? OR slot > ?)", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_CHAR_PET_BY_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND (slot = ? OR slot > ?) ", CONNECTION_SYNCH);
|
||||
|
||||
@@ -524,7 +524,7 @@ class ByteBuffer
|
||||
lt.tm_mon = (packedDate >> 20) & 0xF;
|
||||
lt.tm_year = ((packedDate >> 24) & 0x1F) + 100;
|
||||
|
||||
return uint32(mktime(<) + timezone);
|
||||
return uint32(mktime(<));
|
||||
}
|
||||
|
||||
ByteBuffer& ReadPackedTime(uint32& time)
|
||||
|
||||
@@ -97,7 +97,7 @@ class QueryCallback
|
||||
//! Resets all underlying variables (param, result and stage)
|
||||
void Reset()
|
||||
{
|
||||
SetParam(NULL);
|
||||
SetParam(ParamType());
|
||||
FreeResult();
|
||||
ResetStage();
|
||||
}
|
||||
|
||||
@@ -239,10 +239,10 @@ bool DBUpdater<T>::Update(DatabaseWorkerPool<T>& pool)
|
||||
[&](Path const& file) { DBUpdater<T>::ApplyFile(pool, file); },
|
||||
[&](std::string const& query) -> QueryResult { return DBUpdater<T>::Retrieve(pool, query); });
|
||||
|
||||
uint32 count;
|
||||
UpdateResult result;
|
||||
try
|
||||
{
|
||||
count = updateFetcher.Update(
|
||||
result = updateFetcher.Update(
|
||||
sConfigMgr->GetBoolDefault("Updates.Redundancy", true),
|
||||
sConfigMgr->GetBoolDefault("Updates.AllowRehash", true),
|
||||
sConfigMgr->GetBoolDefault("Updates.ArchivedRedundancy", false),
|
||||
@@ -253,10 +253,13 @@ bool DBUpdater<T>::Update(DatabaseWorkerPool<T>& pool)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!count)
|
||||
TC_LOG_INFO("sql.updates", ">> %s database is up-to-date!", DBUpdater<T>::GetTableName().c_str());
|
||||
std::string const info = Trinity::StringFormat("Containing " SZFMTD " new and " SZFMTD " archived updates.",
|
||||
result.recent, result.archived);
|
||||
|
||||
if (!result.updated)
|
||||
TC_LOG_INFO("sql.updates", ">> %s database is up-to-date! %s", DBUpdater<T>::GetTableName().c_str(), info.c_str());
|
||||
else
|
||||
TC_LOG_INFO("sql.updates", ">> Applied %d %s.", count, count == 1 ? "query" : "queries");
|
||||
TC_LOG_INFO("sql.updates", ">> Applied " SZFMTD " %s. %s", result.updated, result.updated == 1 ? "query" : "queries", info.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -348,7 +351,9 @@ void DBUpdater<T>::ApplyFile(DatabaseWorkerPool<T>& pool, std::string const& hos
|
||||
// CLI Client connection info
|
||||
args.push_back("-h" + host);
|
||||
args.push_back("-u" + user);
|
||||
args.push_back("-p" + password);
|
||||
|
||||
if (!password.empty())
|
||||
args.push_back("-p" + password);
|
||||
|
||||
// Check if we want to connect through ip or socket (Unix only)
|
||||
#ifdef _WIN32
|
||||
|
||||
@@ -41,6 +41,19 @@ enum BaseLocation
|
||||
LOCATION_DOWNLOAD
|
||||
};
|
||||
|
||||
struct UpdateResult
|
||||
{
|
||||
UpdateResult()
|
||||
: updated(0), recent(0), archived(0) { }
|
||||
|
||||
UpdateResult(size_t const updated_, size_t const recent_, size_t const archived_)
|
||||
: updated(updated_), recent(recent_), archived(archived_) { }
|
||||
|
||||
size_t updated;
|
||||
size_t recent;
|
||||
size_t archived;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class DBUpdater
|
||||
{
|
||||
|
||||
@@ -154,17 +154,27 @@ UpdateFetcher::SQLUpdate UpdateFetcher::ReadSQLUpdate(boost::filesystem::path co
|
||||
return update;
|
||||
}
|
||||
|
||||
uint32 UpdateFetcher::Update(bool const redundancyChecks, bool const allowRehash, bool const archivedRedundancy, int32 const cleanDeadReferencesMaxCount) const
|
||||
UpdateResult UpdateFetcher::Update(bool const redundancyChecks, bool const allowRehash, bool const archivedRedundancy, int32 const cleanDeadReferencesMaxCount) const
|
||||
{
|
||||
LocaleFileStorage const available = GetFileList();
|
||||
AppliedFileStorage applied = ReceiveAppliedFiles();
|
||||
|
||||
size_t countRecentUpdates = 0;
|
||||
size_t countArchivedUpdates = 0;
|
||||
|
||||
// Count updates
|
||||
for (auto const& entry : applied)
|
||||
if (entry.second.state == RELEASED)
|
||||
++countRecentUpdates;
|
||||
else
|
||||
++countArchivedUpdates;
|
||||
|
||||
// Fill hash to name cache
|
||||
HashToFileNameStorage hashToName;
|
||||
for (auto entry : applied)
|
||||
hashToName.insert(std::make_pair(entry.second.hash, entry.first));
|
||||
|
||||
uint32 importedUpdates = 0;
|
||||
size_t importedUpdates = 0;
|
||||
|
||||
for (auto const& availableQuery : available)
|
||||
{
|
||||
@@ -314,7 +324,7 @@ uint32 UpdateFetcher::Update(bool const redundancyChecks, bool const allowRehash
|
||||
}
|
||||
}
|
||||
|
||||
return importedUpdates;
|
||||
return UpdateResult(importedUpdates, countRecentUpdates, countArchivedUpdates);
|
||||
}
|
||||
|
||||
std::string UpdateFetcher::CalculateHash(SQLUpdate const& query) const
|
||||
@@ -329,7 +339,6 @@ std::string UpdateFetcher::CalculateHash(SQLUpdate const& query) const
|
||||
uint32 UpdateFetcher::Apply(Path const& path) const
|
||||
{
|
||||
using Time = std::chrono::high_resolution_clock;
|
||||
using ms = std::chrono::milliseconds;
|
||||
|
||||
// Benchmark query speed
|
||||
auto const begin = Time::now();
|
||||
@@ -338,7 +347,7 @@ uint32 UpdateFetcher::Apply(Path const& path) const
|
||||
_applyFile(path);
|
||||
|
||||
// Return time the query took to apply
|
||||
return std::chrono::duration_cast<ms>(Time::now() - begin).count();
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(Time::now() - begin).count();
|
||||
}
|
||||
|
||||
void UpdateFetcher::UpdateEntry(AppliedFileEntry const& entry, uint32 const speed) const
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
std::function<void(Path const& path)> const& applyFile,
|
||||
std::function<QueryResult(std::string const&)> const& retrieve);
|
||||
|
||||
uint32 Update(bool const redundancyChecks, bool const allowRehash,
|
||||
UpdateResult Update(bool const redundancyChecks, bool const allowRehash,
|
||||
bool const archivedRedundancy, int32 const cleanDeadReferencesMaxCount) const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -17,16 +17,22 @@
|
||||
|
||||
#include "TaskScheduler.h"
|
||||
|
||||
TaskScheduler& TaskScheduler::Update()
|
||||
TaskScheduler& TaskScheduler::ClearValidator()
|
||||
{
|
||||
_now = clock_t::now();
|
||||
Dispatch();
|
||||
_predicate = EmptyValidator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TaskScheduler& TaskScheduler::Update(size_t const milliseconds)
|
||||
TaskScheduler& TaskScheduler::Update(success_t const& callback)
|
||||
{
|
||||
return Update(std::chrono::milliseconds(milliseconds));
|
||||
_now = clock_t::now();
|
||||
Dispatch(callback);
|
||||
return *this;
|
||||
}
|
||||
|
||||
TaskScheduler& TaskScheduler::Update(size_t const milliseconds, success_t const& callback)
|
||||
{
|
||||
return Update(std::chrono::milliseconds(milliseconds), callback);
|
||||
}
|
||||
|
||||
TaskScheduler& TaskScheduler::Async(std::function<void()> const& callable)
|
||||
@@ -66,13 +72,21 @@ TaskScheduler& TaskScheduler::InsertTask(TaskContainer task)
|
||||
return *this;
|
||||
}
|
||||
|
||||
void TaskScheduler::Dispatch()
|
||||
void TaskScheduler::Dispatch(success_t const& callback)
|
||||
{
|
||||
// If the validation failed abort the dispatching here.
|
||||
if (!_predicate())
|
||||
return;
|
||||
|
||||
// Process all asyncs
|
||||
while (!_asyncHolder.empty())
|
||||
{
|
||||
_asyncHolder.front()();
|
||||
_asyncHolder.pop();
|
||||
|
||||
// If the validation failed abort the dispatching here.
|
||||
if (!_predicate())
|
||||
return;
|
||||
}
|
||||
|
||||
while (!_task_holder.IsEmpty())
|
||||
@@ -86,7 +100,14 @@ void TaskScheduler::Dispatch()
|
||||
|
||||
// Invoke the context
|
||||
context.Invoke();
|
||||
|
||||
// If the validation failed abort the dispatching here.
|
||||
if (!_predicate())
|
||||
return;
|
||||
}
|
||||
|
||||
// On finish call the final callback
|
||||
callback();
|
||||
}
|
||||
|
||||
void TaskScheduler::TaskQueue::Push(TaskContainer&& task)
|
||||
|
||||
@@ -60,6 +60,10 @@ class TaskScheduler
|
||||
typedef uint32 repeated_t;
|
||||
// Task handle type
|
||||
typedef std::function<void(TaskContext)> task_handler_t;
|
||||
// Predicate type
|
||||
typedef std::function<bool()> predicate_t;
|
||||
// Success handle type
|
||||
typedef std::function<void()> success_t;
|
||||
|
||||
class Task
|
||||
{
|
||||
@@ -163,27 +167,57 @@ class TaskScheduler
|
||||
/// the next update tick.
|
||||
AsyncHolder _asyncHolder;
|
||||
|
||||
predicate_t _predicate;
|
||||
|
||||
static bool EmptyValidator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void EmptyCallback()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
TaskScheduler() : self_reference(this, [](TaskScheduler const*) { }),
|
||||
_now(clock_t::now()) { }
|
||||
TaskScheduler()
|
||||
: self_reference(this, [](TaskScheduler const*) { }), _now(clock_t::now()), _predicate(EmptyValidator) { }
|
||||
|
||||
template<typename P>
|
||||
TaskScheduler(P&& predicate)
|
||||
: self_reference(this, [](TaskScheduler const*) { }), _now(clock_t::now()), _predicate(std::forward<P>(predicate)) { }
|
||||
|
||||
TaskScheduler(TaskScheduler const&) = delete;
|
||||
TaskScheduler(TaskScheduler&&) = delete;
|
||||
TaskScheduler& operator= (TaskScheduler const&) = delete;
|
||||
TaskScheduler& operator= (TaskScheduler&&) = delete;
|
||||
|
||||
/// Sets a validator which is asked if tasks are allowed to be executed.
|
||||
template<typename P>
|
||||
TaskScheduler& SetValidator(P&& predicate)
|
||||
{
|
||||
_predicate = std::forward<P>(predicate);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Clears the validator which is asked if tasks are allowed to be executed.
|
||||
TaskScheduler& ClearValidator();
|
||||
|
||||
/// Update the scheduler to the current time.
|
||||
TaskScheduler& Update();
|
||||
/// Calls the optional callback on successfully finish.
|
||||
TaskScheduler& Update(success_t const& callback = EmptyCallback);
|
||||
|
||||
/// Update the scheduler with a difftime in ms.
|
||||
TaskScheduler& Update(size_t const milliseconds);
|
||||
/// Calls the optional callback on successfully finish.
|
||||
TaskScheduler& Update(size_t const milliseconds, success_t const& callback = EmptyCallback);
|
||||
|
||||
/// Update the scheduler with a difftime.
|
||||
/// Calls the optional callback on successfully finish.
|
||||
template<class _Rep, class _Period>
|
||||
TaskScheduler& Update(std::chrono::duration<_Rep, _Period> const& difftime)
|
||||
TaskScheduler& Update(std::chrono::duration<_Rep, _Period> const& difftime,
|
||||
success_t const& callback = EmptyCallback)
|
||||
{
|
||||
_now += difftime;
|
||||
Dispatch();
|
||||
Dispatch(callback);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -370,7 +404,7 @@ private:
|
||||
}
|
||||
|
||||
/// Dispatch remaining tasks
|
||||
void Dispatch();
|
||||
void Dispatch(success_t const& callback);
|
||||
};
|
||||
|
||||
class TaskContext
|
||||
|
||||
@@ -102,8 +102,8 @@ extern int main(int argc, char** argv)
|
||||
std::string configService;
|
||||
|
||||
auto vm = GetConsoleArguments(argc, argv, configFile, configService);
|
||||
// exit if help is enabled
|
||||
if (vm.count("help"))
|
||||
// exit if help or version is enabled
|
||||
if (vm.count("help") || vm.count("version"))
|
||||
return 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -532,6 +532,7 @@ variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile
|
||||
options_description all("Allowed options");
|
||||
all.add_options()
|
||||
("help,h", "print usage message")
|
||||
("version,v", "print version build info")
|
||||
("config,c", value<std::string>(&configFile)->default_value(_TRINITY_CORE_CONFIG), "use <arg> as configuration file")
|
||||
;
|
||||
#ifdef _WIN32
|
||||
@@ -555,6 +556,10 @@ variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile
|
||||
if (vm.count("help")) {
|
||||
std::cout << all << "\n";
|
||||
}
|
||||
else if (vm.count("version"))
|
||||
{
|
||||
std::cout << _FULLVERSION << "\n";
|
||||
}
|
||||
|
||||
return vm;
|
||||
}
|
||||
@@ -67,8 +67,8 @@ class adt_MCLQ
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
uint32 size;
|
||||
public:
|
||||
uint32 size;
|
||||
float height1;
|
||||
float height2;
|
||||
struct liquid_data{
|
||||
@@ -96,8 +96,8 @@ class adt_MCNK
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
uint32 size;
|
||||
public:
|
||||
uint32 size;
|
||||
uint32 flags;
|
||||
uint32 ix;
|
||||
uint32 iy;
|
||||
@@ -155,8 +155,8 @@ class adt_MCIN
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
uint32 size;
|
||||
public:
|
||||
uint32 size;
|
||||
struct adt_CELLS{
|
||||
uint32 offsMCNK;
|
||||
uint32 size;
|
||||
@@ -274,6 +274,7 @@ class adt_MHDR
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
public:
|
||||
uint32 size;
|
||||
|
||||
uint32 flags;
|
||||
@@ -292,7 +293,6 @@ class adt_MHDR
|
||||
uint32 data3;
|
||||
uint32 data4;
|
||||
uint32 data5;
|
||||
public:
|
||||
bool prepareLoadedData();
|
||||
adt_MCIN* getMCIN() { return offsMCIN ? (adt_MCIN *)((uint8 *)&flags+offsMCIN) : NULL; }
|
||||
adt_MH2O* getMH2O() { return offsMH2O ? (adt_MH2O *)((uint8 *)&flags+offsMH2O) : NULL; }
|
||||
|
||||
Reference in new issue
Block a user